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/06/11 16:16:51 UTC

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

Repository: syncope
Updated Branches:
  refs/heads/master 2e5fc7ecc -> d8927ef4c


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>


[64/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ReportTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ReportTest.java
deleted file mode 100644
index 9c49aae..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ReportTest.java
+++ /dev/null
@@ -1,120 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.Date;
-import javax.persistence.EntityExistsException;
-import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.persistence.api.dao.ReportDAO;
-import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
-import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.persistence.api.entity.ReportExec;
-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 ReportTest extends AbstractTest {
-
-    @Autowired
-    private ReportDAO reportDAO;
-
-    @Autowired
-    private ReportExecDAO reportExecDAO;
-
-    @Test
-    public void find() {
-        Report report = reportDAO.find(1L);
-        assertNotNull(report);
-
-        assertNotNull(report.getExecs());
-        assertFalse(report.getExecs().isEmpty());
-        assertEquals(1, report.getExecs().size());
-    }
-
-    @Test(expected = EntityExistsException.class)
-    public void saveWithExistingName() {
-        Report report = reportDAO.find(1L);
-        assertNotNull(report);
-
-        String name = report.getName();
-
-        report = entityFactory.newEntity(Report.class);
-        report.setName(name);
-
-        reportDAO.save(report);
-        reportDAO.flush();
-    }
-
-    @Test
-    public void save() {
-        Report report = reportDAO.find(1L);
-        assertNotNull(report);
-        assertEquals(1, report.getExecs().size());
-
-        ReportExec reportExec = entityFactory.newEntity(ReportExec.class);
-        reportExec.setReport(report);
-        reportExec.setStartDate(new Date());
-        reportExec.setEndDate(new Date());
-        reportExec.setStatus(ReportExecStatus.SUCCESS);
-
-        report.addExec(reportExec);
-
-        reportExec = reportExecDAO.save(reportExec);
-        assertNotNull(reportExec);
-        assertNotNull(reportExec.getKey());
-
-        reportExecDAO.flush();
-
-        report = reportDAO.find(1L);
-        assertNotNull(report);
-        assertEquals(2, report.getExecs().size());
-    }
-
-    @Test
-    public void deleteReport() {
-        reportDAO.delete(1L);
-
-        reportDAO.flush();
-
-        assertNull(reportDAO.find(1L));
-        assertNull(reportExecDAO.find(1L));
-    }
-
-    @Test
-    public void deleteReportExecution() {
-        ReportExec execution = reportExecDAO.find(1L);
-        int executionNumber = execution.getReport().getExecs().size();
-
-        reportExecDAO.delete(1L);
-
-        reportExecDAO.flush();
-
-        assertNull(reportExecDAO.find(1L));
-
-        Report report = reportDAO.find(1L);
-        assertEquals(report.getExecs().size(), executionNumber - 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 8e1e554..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ResourceTest.java
+++ /dev/null
@@ -1,306 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-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.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class ResourceTest extends AbstractTest {
-
-    @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private ConnInstanceDAO connInstanceDAO;
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private TaskDAO taskDAO;
-
-    @Autowired
-    private PolicyDAO policyDAO;
-
-    @Test
-    public void createWithPasswordPolicy() {
-        final String resourceName = "resourceWithPasswordPolicy";
-
-        PasswordPolicy policy = (PasswordPolicy) policyDAO.find(4L);
-        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
-        resource.setKey(resourceName);
-        resource.setPasswordPolicy(policy);
-
-        ConnInstance connector = connInstanceDAO.find(100L);
-        assertNotNull("connector not found", connector);
-        resource.setConnector(connector);
-
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
-
-        actual = resourceDAO.find(actual.getKey());
-        assertNotNull(actual);
-        assertNotNull(actual.getPasswordPolicy());
-
-        resourceDAO.delete(resourceName);
-        assertNull(resourceDAO.find(resourceName));
-
-        assertNotNull(policyDAO.find(4L));
-    }
-
-    @Test
-    public void save() {
-        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
-        resource.setKey("ws-target-resource-save");
-
-        // specify the connector
-        ConnInstance connector = connInstanceDAO.find(100L);
-        assertNotNull("connector not found", connector);
-
-        resource.setConnector(connector);
-
-        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++) {
-            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.add(item);
-            item.setMapping(mapping);
-        }
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
-        connObjectKey.setExtAttrName("username");
-        connObjectKey.setIntAttrName("username");
-        connObjectKey.setIntMappingType(IntMappingType.UserKey);
-        connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.setConnObjectKeyItem(connObjectKey);
-        connObjectKey.setMapping(mapping);
-
-        // map a derived attribute
-        MappingItem derived = entityFactory.newEntity(MappingItem.class);
-        derived.setConnObjectKey(false);
-        derived.setExtAttrName("fullname");
-        derived.setIntAttrName("cn");
-        derived.setIntMappingType(IntMappingType.UserDerivedSchema);
-        derived.setPurpose(MappingPurpose.PROPAGATION);
-        mapping.add(derived);
-        derived.setMapping(mapping);
-
-        // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
-        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
-
-        resourceDAO.flush();
-        resourceDAO.detach(actual);
-        connInstanceDAO.detach(connector);
-
-        // assign the new resource to an user
-        User user = userDAO.find(1L);
-        assertNotNull("user not found", user);
-
-        user.add(actual);
-
-        resourceDAO.flush();
-
-        // retrieve resource
-        resource = resourceDAO.find(actual.getKey());
-        assertNotNull(resource);
-        resourceDAO.refresh(resource);
-
-        // check connector
-        connector = connInstanceDAO.find(100L);
-        assertNotNull(connector);
-        assertNotNull(connector.getResources());
-
-        assertNotNull(resource.getConnector());
-        assertTrue(resource.getConnector().equals(connector));
-
-        // check mappings
-        List<? extends MappingItem> items = resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems();
-        assertNotNull(items);
-        assertEquals(5, items.size());
-
-        // check user
-        user = userDAO.find(1L);
-        assertNotNull(user);
-        assertNotNull(user.getResources());
-        assertTrue(user.getResources().contains(actual));
-    }
-
-    @Test
-    public void delete() {
-        ExternalResource resource = resourceDAO.find("resource-testdb");
-        assertNotNull("find to delete did not work", resource);
-
-        // -------------------------------------
-        // Get originally associated connector
-        // -------------------------------------
-        ConnInstance connector = resource.getConnector();
-        assertNotNull(connector);
-        // -------------------------------------
-
-        // -------------------------------------
-        // Get originally associated users
-        // -------------------------------------
-        List<User> users = userDAO.findByResource(resource);
-        assertNotNull(users);
-
-        Set<Long> userIds = new HashSet<>();
-        for (User user : users) {
-            userIds.add(user.getKey());
-        }
-        // -------------------------------------
-
-        // Get tasks
-        List<PropagationTask> propagationTasks = taskDAO.findAll(resource, TaskType.PROPAGATION);
-        assertFalse(propagationTasks.isEmpty());
-
-        // delete resource
-        resourceDAO.delete(resource.getKey());
-
-        // close the transaction
-        resourceDAO.flush();
-
-        // resource must be removed
-        ExternalResource actual = resourceDAO.find("resource-testdb");
-        assertNull("delete did not work", actual);
-
-        // resource must be not referenced any more from users
-        for (Long id : userIds) {
-            User actualUser = userDAO.find(id);
-            assertNotNull(actualUser);
-            for (ExternalResource res : userDAO.findAllResources(actualUser)) {
-                assertFalse(res.getKey().equalsIgnoreCase(resource.getKey()));
-            }
-        }
-
-        // resource must be not referenced any more from the connector
-        ConnInstance actualConnector = connInstanceDAO.find(connector.getKey());
-        assertNotNull(actualConnector);
-        for (ExternalResource res : actualConnector.getResources()) {
-            assertFalse(res.getKey().equalsIgnoreCase(resource.getKey()));
-        }
-
-        // there must be no tasks
-        for (PropagationTask task : propagationTasks) {
-            assertNull(taskDAO.find(task.getKey()));
-        }
-    }
-
-    @Test
-    public void emptyMapping() {
-        ExternalResource ldap = resourceDAO.find("resource-ldap");
-        assertNotNull(ldap);
-        assertNotNull(ldap.getProvision(anyTypeDAO.findUser()).getMapping());
-        assertNotNull(ldap.getProvision(anyTypeDAO.findGroup()).getMapping());
-
-        List<? extends MappingItem> items = ldap.getProvision(anyTypeDAO.findGroup()).getMapping().getItems();
-        assertNotNull(items);
-        assertFalse(items.isEmpty());
-        List<Long> itemKeys = new ArrayList<>(items.size());
-        for (MappingItem item : items) {
-            itemKeys.add(item.getKey());
-        }
-
-        ldap.remove(ldap.getProvision(anyTypeDAO.findGroup()));
-
-        // need to avoid any class not defined in this Maven module
-        ldap.getPropagationActionsClassNames().clear();
-
-        resourceDAO.save(ldap);
-        resourceDAO.flush();
-
-        for (Long itemId : itemKeys) {
-            assertNull(entityManager.find(JPAMappingItem.class, itemId));
-        }
-    }
-
-    @Test
-    public void issue243() {
-        ExternalResource csv = resourceDAO.find("resource-csv");
-        assertNotNull(csv);
-
-        int origMapItems = csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size();
-
-        MappingItem newMapItem = entityFactory.newEntity(MappingItem.class);
-        newMapItem.setIntMappingType(IntMappingType.Username);
-        newMapItem.setExtAttrName("TEST");
-        newMapItem.setPurpose(MappingPurpose.PROPAGATION);
-        csv.getProvision(anyTypeDAO.findUser()).getMapping().add(newMapItem);
-
-        resourceDAO.save(csv);
-        resourceDAO.flush();
-
-        csv = resourceDAO.find("resource-csv");
-        assertNotNull(csv);
-        assertEquals(origMapItems + 1, csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 5fdc803..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RoleTest.java
+++ /dev/null
@@ -1,167 +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.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-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.AnyTypeKind;
-import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-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.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.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-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;
-
-@Transactional
-public class RoleTest extends AbstractTest {
-
-    @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    /**
-     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
-     * required for avoiding creating new transaction - good for general use case but bad for the way how
-     * this test class is architected.
-     */
-    private Collection<Role> findDynRoleMemberships(final User user) {
-        TypedQuery<Role> query = entityManager.createQuery(
-                "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
-                + " e WHERE :user MEMBER OF e.users", Role.class);
-        query.setParameter("user", user);
-
-        return query.getResultList();
-    }
-
-    @Test
-    public void dynMembership() {
-        // 0. create user matching the condition below
-        User user = entityFactory.newEntity(User.class);
-        user.setUsername("username");
-        user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("other"));
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(plainSchemaDAO.find("cool"));
-        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        user = userDAO.save(user);
-        Long newUserKey = user.getKey();
-        assertNotNull(newUserKey);
-
-        // 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 actual = roleDAO.save(role);
-        assertNotNull(actual);
-
-        roleDAO.flush();
-
-        // 2. verify that dynamic membership is there
-        actual = roleDAO.find(actual.getKey());
-        assertNotNull(actual);
-        assertNotNull(actual.getDynMembership());
-        assertNotNull(actual.getDynMembership().getKey());
-        assertEquals(actual, actual.getDynMembership().getRole());
-
-        // 3. verify that expected users have the created role dynamically assigned
-        assertEquals(2, actual.getDynMembership().getMembers().size());
-        assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getDynMembership().getMembers(), new Transformer<User, Long>() {
-
-                    @Override
-                    public Long transform(final User input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
-
-        user = userDAO.find(4L);
-        assertNotNull(user);
-        Collection<Role> dynRoleMemberships = findDynRoleMemberships(user);
-        assertEquals(1, dynRoleMemberships.size());
-        assertTrue(dynRoleMemberships.contains(actual.getDynMembership().getRole()));
-
-        // 4. delete the new user and verify that dynamic membership was updated
-        userDAO.delete(newUserKey);
-
-        userDAO.flush();
-
-        actual = roleDAO.find(actual.getKey());
-        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();
-
-        roleDAO.delete(actual);
-
-        roleDAO.flush();
-
-        assertNull(entityManager.find(JPADynRoleMembership.class, dynMembershipKey));
-
-        dynRoleMemberships = findDynRoleMemberships(user);
-        assertTrue(dynRoleMemberships.isEmpty());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SecurityQuestionTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SecurityQuestionTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SecurityQuestionTest.java
deleted file mode 100644
index a3deb6e..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/SecurityQuestionTest.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.core.persistence.jpa.relationship;
-
-import static org.junit.Assert.assertNull;
-
-import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-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 SecurityQuestionTest extends AbstractTest {
-
-    @Autowired
-    private SecurityQuestionDAO securityQuestionDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Test
-    public void test() {
-        User user = userDAO.find(4L);
-        assertNull(user.getSecurityQuestion());
-        assertNull(user.getSecurityAnswer());
-
-        user.setSecurityQuestion(securityQuestionDAO.find(1L));
-        user.setSecurityAnswer("Rossi");
-        userDAO.save(user);
-
-        userDAO.flush();
-
-        securityQuestionDAO.delete(1L);
-
-        userDAO.flush();
-
-        user = userDAO.find(4L);
-
-        assertNull(user.getSecurityQuestion());
-        assertNull(user.getSecurityAnswer());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 76621a1..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/TaskTest.java
+++ /dev/null
@@ -1,295 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-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.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;
-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.core.persistence.api.attrvalue.validation.InvalidEntityException;
-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.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;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class TaskTest extends AbstractTest {
-
-    @Autowired
-    private TaskDAO taskDAO;
-
-    @Autowired
-    private TaskExecDAO taskExecDAO;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Test
-    public void read() {
-        PropagationTask task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        assertNotNull(task.getExecs());
-        assertFalse(task.getExecs().isEmpty());
-        assertEquals(1, task.getExecs().size());
-    }
-
-    @Test
-    public void save() {
-        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
-        assertNotNull(resource);
-
-        User user = userDAO.find(2L);
-        assertNotNull(user);
-
-        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
-        task.setResource(resource);
-        task.setAnyTypeKind(AnyTypeKind.USER);
-        task.setPropagationMode(PropagationMode.TWO_PHASES);
-        task.setPropagationOperation(ResourceOperation.CREATE);
-        task.setConnObjectKey("one@two.com");
-
-        Set<Attribute> attributes = new HashSet<>();
-        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
-        attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
-        task.setAttributes(attributes);
-
-        task = taskDAO.save(task);
-        assertNotNull(task);
-
-        PropagationTask actual = taskDAO.find(task.getKey());
-        assertEquals(task, actual);
-
-        taskDAO.flush();
-
-        resource = resourceDAO.find("ws-target-resource-1");
-        assertTrue(taskDAO.findAll(resource, TaskType.PROPAGATION).contains(task));
-    }
-
-    @Test
-    public void addPropagationTaskExecution() {
-        PropagationTask task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        int executionNumber = task.getExecs().size();
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setTask(task);
-        execution.setStatus(PropagationTaskExecStatus.CREATED.name());
-        task.addExec(execution);
-        execution.setStartDate(new Date());
-
-        taskDAO.save(task);
-        taskDAO.flush();
-
-        task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        assertEquals(executionNumber + 1, task.getExecs().size());
-    }
-
-    @Test
-    public void addSyncTaskExecution() {
-        SyncTask task = taskDAO.find(4L);
-        assertNotNull(task);
-
-        int executionNumber = task.getExecs().size();
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setStatus("Text-free status");
-        execution.setTask(task);
-        task.addExec(execution);
-        execution.setMessage("A message");
-
-        taskDAO.save(task);
-        taskDAO.flush();
-
-        task = taskDAO.find(4L);
-        assertNotNull(task);
-
-        assertEquals(executionNumber + 1, task.getExecs().size());
-    }
-
-    @Test
-    public void addPushTaskExecution() {
-        PushTask task = taskDAO.find(13L);
-        assertNotNull(task);
-
-        int executionNumber = task.getExecs().size();
-
-        TaskExec execution = entityFactory.newEntity(TaskExec.class);
-        execution.setStatus("Text-free status");
-        execution.setTask(task);
-        task.addExec(execution);
-        execution.setMessage("A message");
-
-        taskDAO.save(task);
-        taskDAO.flush();
-
-        task = taskDAO.find(13L);
-        assertNotNull(task);
-
-        assertEquals(executionNumber + 1, task.getExecs().size());
-    }
-
-    @Test
-    public void deleteTask() {
-        taskDAO.delete(1L);
-
-        taskDAO.flush();
-
-        assertNull(taskDAO.find(1L));
-        assertNull(taskExecDAO.find(1L));
-    }
-
-    @Test
-    public void deleteTaskExecution() {
-        TaskExec execution = taskExecDAO.find(1L);
-        int executionNumber = execution.getTask().getExecs().size();
-
-        taskExecDAO.delete(1L);
-
-        taskExecDAO.flush();
-
-        assertNull(taskExecDAO.find(1L));
-
-        PropagationTask task = taskDAO.find(1L);
-        assertEquals(task.getExecs().size(), executionNumber - 1);
-    }
-
-    @Test
-    public void saveSyncTask() {
-        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.add(template);
-        task.setCronExpression("BLA BLA");
-        task.setMatchingRule(MatchingRule.UPDATE);
-        task.setUnmatchingRule(UnmatchingRule.PROVISION);
-
-        // this save() fails because of an invalid Cron Expression
-        InvalidEntityException exception = null;
-        try {
-            taskDAO.save(task);
-        } catch (InvalidEntityException e) {
-            exception = e;
-        }
-        assertNotNull(exception);
-
-        task.setCronExpression(null);
-        // this save() fails because a SyncTask requires a target resource
-        exception = null;
-        try {
-            taskDAO.save(task);
-        } catch (InvalidEntityException e) {
-            exception = e;
-        }
-        assertNotNull(exception);
-
-        task.setResource(resource);
-        task.getActionsClassNames().add(getClass().getName());
-
-        // this save() fails because jobActionsClassName does not implement 
-        // the right interface
-        exception = null;
-        try {
-            taskDAO.save(task);
-        } catch (InvalidEntityException e) {
-            exception = e;
-        }
-        assertNotNull(exception);
-
-        task.getActionsClassNames().clear();
-        task.getActionsClassNames().add(SyncActions.class.getName());
-        // this save() finally works
-        task = taskDAO.save(task);
-        assertNotNull(task);
-
-        SyncTask actual = taskDAO.find(task.getKey());
-        assertEquals(task, actual);
-    }
-
-    @Test
-    public void issueSYNCOPE144() {
-        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
-        assertNotNull(resource);
-
-        SyncTask task = entityFactory.newEntity(SyncTask.class);
-
-        task.setResource(resource);
-        task.setName("issueSYNCOPE144");
-        task.setDescription("issueSYNCOPE144 Description");
-        task.getActionsClassNames().add(SyncActions.class.getName());
-        task.setMatchingRule(MatchingRule.UPDATE);
-        task.setUnmatchingRule(UnmatchingRule.PROVISION);
-
-        task = taskDAO.save(task);
-        assertNotNull(task);
-
-        SyncTask actual = taskDAO.find(task.getKey());
-        assertEquals(task, actual);
-        assertEquals("issueSYNCOPE144", actual.getName());
-        assertEquals("issueSYNCOPE144 Description", actual.getDescription());
-
-        actual.setName("issueSYNCOPE144_2");
-        actual.setDescription("issueSYNCOPE144 Description_2");
-
-        actual = taskDAO.save(actual);
-        assertNotNull(actual);
-        assertEquals("issueSYNCOPE144_2", actual.getName());
-        assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 5a12044..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/UserTest.java
+++ /dev/null
@@ -1,126 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-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.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.URelationship;
-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 UserTest extends AbstractTest {
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private PlainAttrValueDAO plainAttrValueDAO;
-
-    @Test
-    public void delete() {
-        List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L));
-        assertFalse(memberships.isEmpty());
-        List<URelationship> relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
-        assertFalse(relationships.isEmpty());
-
-        userDAO.delete(4L);
-
-        userDAO.flush();
-
-        assertNull(userDAO.find(4L));
-        assertNull(plainAttrDAO.find(550L, UPlainAttr.class));
-        assertNull(plainAttrValueDAO.find(22L, UPlainAttrValue.class));
-        assertNotNull(plainSchemaDAO.find("loginDate"));
-
-        memberships = groupDAO.findUMemberships(groupDAO.find(7L));
-        assertTrue(memberships.isEmpty());
-        relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
-        assertTrue(relationships.isEmpty());
-    }
-
-    @Test
-    public void ships() {
-        User user = userDAO.find(4L);
-        assertNotNull(user);
-        assertEquals(1, user.getMemberships().size());
-        assertEquals(7L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
-
-        user.remove(user.getMemberships().get(0));
-
-        UMembership newM = entityFactory.newEntity(UMembership.class);
-        newM.setLeftEnd(user);
-        newM.setRightEnd(groupDAO.find(13L));
-        user.add(newM);
-
-        userDAO.save(user);
-
-        userDAO.flush();
-
-        user = userDAO.find(4L);
-        assertEquals(1, user.getMemberships().size());
-        assertEquals(13L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
-        assertEquals(1, user.getRelationships().size());
-        assertEquals(1L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
-
-        user.remove(user.getRelationships().get(0));
-
-        URelationship newR = entityFactory.newEntity(URelationship.class);
-        newR.setLeftEnd(user);
-        newR.setRightEnd(anyObjectDAO.find(2L));
-        user.add(newR);
-
-        userDAO.save(user);
-
-        userDAO.flush();
-
-        user = userDAO.find(4L);
-        assertEquals(1, user.getRelationships().size());
-        assertEquals(2L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 7b11faa..8b4740a 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -112,6 +112,9 @@ under the License.
   <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
           specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
 
+  <RelationshipType name="inclusion" description="Models the act that an object is included in another"/>
+  <RelationshipType name="neighborhood"/>
+  
   <AnyTypeClass name="generic membership"/>
 
   <AnyType name="USER" kind="USER"/>
@@ -141,8 +144,8 @@ under the License.
   <AnyObject id="2" realm_id="1" type_name="PRINTER"
              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"/>
+  
+  <ARelationship id="1" left_anyObject_id="1" right_anyObject_id="2" type_name="neighborhood"/>
   
   <SyncopeRole id="1" name="User reviewer"/>
   <SyncopeRole_entitlements entitlement="USER_READ" role_id="1"/>
@@ -254,7 +257,7 @@ under the License.
                 creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
   
-  <URelationship id="1" user_id="4" anyObject_id="1"/>
+  <URelationship id="1" user_id="4" anyObject_id="1" type_name="neighborhood"/>
 
   <UMembership id="1" user_id="1" group_id="1"/>
   <UMembership id="2" user_id="2" group_id="1"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RelationshipTypeDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RelationshipTypeDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RelationshipTypeDataBinder.java
new file mode 100644
index 0000000..3e940ee
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/RelationshipTypeDataBinder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.to.RelationshipTypeTO;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+
+public interface RelationshipTypeDataBinder {
+
+    RelationshipType create(RelationshipTypeTO relationshipTypeTO);
+
+    void update(RelationshipType relationshipType, RelationshipTypeTO relationshipTypeTO);
+
+    RelationshipTypeTO getRelationshipTypeTO(RelationshipType relationshipType);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RelationshipTypeDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RelationshipTypeDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RelationshipTypeDataBinderImpl.java
new file mode 100644
index 0000000..4d324cf
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/RelationshipTypeDataBinderImpl.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.provisioning.java.data;
+
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+import org.apache.syncope.core.provisioning.api.data.RelationshipTypeDataBinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RelationshipTypeDataBinderImpl implements RelationshipTypeDataBinder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RelationshipTypeDataBinder.class);
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Override
+    public RelationshipType create(final RelationshipTypeTO relationshipTypeTO) {
+        RelationshipType relationshipType = entityFactory.newEntity(RelationshipType.class);
+        update(relationshipType, relationshipTypeTO);
+        return relationshipType;
+    }
+
+    @Override
+    public void update(final RelationshipType relationshipType, final RelationshipTypeTO relationshipTypeTO) {
+        if (relationshipType.getKey() == null) {
+            relationshipType.setKey(relationshipTypeTO.getKey());
+        }
+
+        relationshipType.setDescription(relationshipTypeTO.getDescription());
+    }
+
+    @Override
+    public RelationshipTypeTO getRelationshipTypeTO(final RelationshipType relationshipType) {
+        RelationshipTypeTO relationshipTypeTO = new RelationshipTypeTO();
+
+        relationshipTypeTO.setKey(relationshipType.getKey());
+        relationshipTypeTO.setDescription(relationshipType.getDescription());
+
+        return relationshipTypeTO;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.java
new file mode 100644
index 0000000..6e1958e
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RelationshipTypeServiceImpl.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.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
+import org.apache.syncope.core.logic.RelationshipTypeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RelationshipTypeServiceImpl extends AbstractServiceImpl implements RelationshipTypeService {
+
+    @Autowired
+    private RelationshipTypeLogic logic;
+
+    @Override
+    public List<RelationshipTypeTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public RelationshipTypeTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final RelationshipTypeTO anyTypeTO) {
+        RelationshipTypeTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final RelationshipTypeTO anyTypeTO) {
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 77e4c50..7c36611 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
@@ -63,6 +63,7 @@ import org.apache.syncope.common.rest.api.service.ReportService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.apache.syncope.common.rest.api.service.RealmService;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
 import org.apache.syncope.common.rest.api.service.RoleService;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
@@ -158,6 +159,8 @@ public abstract class AbstractITCase {
 
     protected static AnyTypeService anyTypeService;
 
+    protected static RelationshipTypeService relationshipTypeService;
+
     protected static RealmService realmService;
 
     protected static AnyObjectService anyObjectService;
@@ -232,6 +235,7 @@ public abstract class AbstractITCase {
         syncopeService = adminClient.getService(SyncopeService.class);
         anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
         anyTypeService = adminClient.getService(AnyTypeService.class);
+        relationshipTypeService = adminClient.getService(RelationshipTypeService.class);
         realmService = adminClient.getService(RealmService.class);
         anyObjectService = adminClient.getService(AnyObjectService.class);
         roleService = adminClient.getService(RoleService.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
new file mode 100644
index 0000000..3d8d82f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RelationshipTypeITCase.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.RelationshipTypeService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RelationshipTypeITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        RelationshipTypeTO otherType = relationshipTypeService.read("inclusion");
+        assertNotNull(otherType);
+        assertEquals("inclusion", otherType.getKey());
+    }
+
+    @Test
+    public void list() {
+        List<RelationshipTypeTO> list = relationshipTypeService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        RelationshipTypeTO newType = new RelationshipTypeTO();
+        newType.setKey("new type");
+        newType.setDescription("description");
+
+        Response response = relationshipTypeService.create(newType);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newType = getObject(response.getLocation(), RelationshipTypeService.class, RelationshipTypeTO.class);
+        assertNotNull(newType);
+        assertEquals("description", newType.getDescription());
+
+        newType.setDescription("new description");
+        relationshipTypeService.update(newType);
+
+        newType = relationshipTypeService.read(newType.getKey());
+        assertNotNull(newType);
+        assertEquals("new description", newType.getDescription());
+
+        relationshipTypeService.delete(newType.getKey());
+
+        try {
+            relationshipTypeService.read(newType.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidName() {
+        RelationshipTypeTO newType = new RelationshipTypeTO();
+        newType.setKey("membership");
+        try {
+            relationshipTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidRelationshipType, e.getType());
+        }
+    }
+}


[29/70] 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/master
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;
-    }
-}


[23/70] 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> {
+}


[42/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
index 5dc3f5c..37bf12c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AbstractTaskITCase.java
@@ -57,7 +57,9 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         private final boolean dryRun;
 
-        public ThreadExec(AbstractTaskITCase test, Long taskKey, int maxWaitSeconds, boolean dryRun) {
+        public ThreadExec(
+                final AbstractTaskITCase test, final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+
             this.test = test;
             this.taskKey = taskKey;
             this.maxWaitSeconds = maxWaitSeconds;
@@ -66,7 +68,7 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
 
         @Override
         public TaskExecTO call() throws Exception {
-            return test.execSyncTask(taskKey, maxWaitSeconds, dryRun);
+            return test.execProvisioningTask(taskKey, maxWaitSeconds, dryRun);
         }
     }
 
@@ -85,7 +87,7 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
         }
     }
 
-    protected TaskExecTO execSyncTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+    protected TaskExecTO execProvisioningTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
         AbstractTaskTO taskTO = taskService.read(taskKey);
         assertNotNull(taskTO);
         assertNotNull(taskTO.getExecutions());
@@ -117,17 +119,17 @@ public abstract class AbstractTaskITCase extends AbstractITCase {
         return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
     }
 
-    protected Map<Long, TaskExecTO> execSyncTasks(
+    protected Map<Long, TaskExecTO> execProvisioningTasks(
             final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
 
-        final ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
-        final List<Future<TaskExecTO>> futures = new ArrayList<>();
+        ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
+        List<Future<TaskExecTO>> futures = new ArrayList<>();
 
         for (Long key : taskKeys) {
             futures.add(service.submit(new ThreadExec(this, key, maxWaitSeconds, dryRun)));
         }
 
-        final Map<Long, TaskExecTO> res = new HashMap<>();
+        Map<Long, TaskExecTO> res = new HashMap<>();
 
         for (Future<TaskExecTO> future : futures) {
             TaskExecTO taskExecTO = future.get(100, TimeUnit.SECONDS);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fcb988b..1a086e2 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
@@ -18,12 +18,14 @@
  */
 package org.apache.syncope.fit.core.reference;
 
+import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.CamelRouteTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -147,8 +149,14 @@ public class CamelRouteITCase extends AbstractITCase {
             schemaTO.setType(AttrSchemaType.String);
             createSchema(SchemaType.PLAIN, schemaTO);
 
+            AnyTypeClassTO typeClass = new AnyTypeClassTO();
+            typeClass.setKey("camelAttribute");
+            typeClass.getPlainSchemas().add(schemaTO.getKey());
+            anyTypeClassService.create(typeClass);
+
             UserTO userTO = new UserTO();
             userTO.setRealm(SyncopeConstants.ROOT_REALM);
+            userTO.getAuxClasses().add(typeClass.getKey());
             String userId = getUUIDString() + "camelUser@syncope.apache.org";
             userTO.setUsername(userId);
             userTO.setPassword("password123");

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 7c1ca19..e311e41 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
@@ -27,20 +27,15 @@ import static org.junit.Assert.fail;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.to.AttrTO;
 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.ClientExceptionType;
 import org.apache.syncope.common.lib.types.EntityViolationType;
@@ -153,91 +148,4 @@ public class ConfigurationITCase extends AbstractITCase {
             assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
         }
     }
-
-    private static String[] substringsBetween(final String str, final String open, final String close) {
-        if (str == null || StringUtils.isEmpty(open) || StringUtils.isEmpty(close)) {
-            return null;
-        }
-        final int strLen = str.length();
-        if (strLen == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        final int closeLen = close.length();
-        final int openLen = open.length();
-        final List<String> list = new ArrayList<>();
-        int pos = 0;
-        while (pos < strLen - closeLen) {
-            int start = StringUtils.indexOfIgnoreCase(str, open, pos);
-            if (start < 0) {
-                break;
-            }
-            start += openLen;
-            final int end = StringUtils.indexOfIgnoreCase(str, close, start);
-            if (end < 0) {
-                break;
-            }
-            list.add(str.substring(start, end));
-            pos = end + closeLen;
-        }
-        if (list.isEmpty()) {
-            return null;
-        }
-        return list.toArray(new String[list.size()]);
-    }
-
-    @Test
-    public void issueSYNCOPE629() throws IOException {
-        PlainSchemaTO membershipKey = new PlainSchemaTO();
-        membershipKey.setKey("membershipKey" + getUUIDString());
-        membershipKey.setType(AttrSchemaType.String);
-        createSchema(SchemaType.PLAIN, membershipKey);
-
-        PlainSchemaTO groupKey = new PlainSchemaTO();
-        groupKey.setKey("group"
-                + "Key" + getUUIDString());
-        groupKey.setType(AttrSchemaType.String);
-        createSchema(SchemaType.PLAIN, groupKey);
-
-        GroupTO groupTO = new GroupTO();
-        groupTO.setRealm("/");
-        groupTO.setName("aGroup" + getUUIDString());
-        groupTO = createGroup(groupTO);
-
-        try {
-            Response response = configurationService.export();
-            assertNotNull(response);
-            assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
-            assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
-            String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
-            assertNotNull(contentDisposition);
-
-            Object entity = response.getEntity();
-            assertTrue(entity instanceof InputStream);
-            String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
-            assertFalse(configExport.isEmpty());
-            assertTrue(configExport.length() > 1000);
-
-            String[] result = substringsBetween(configExport, "<GPLAINATTRTEMPLATE", "/>");
-            assertNotNull(result);
-            boolean rattrExists = false;
-            for (String entry : result) {
-                if (entry.contains(groupKey.getKey())) {
-                    rattrExists = true;
-                }
-            }
-            assertTrue(rattrExists);
-
-            result = substringsBetween(configExport, "<MPLAINATTRTEMPLATE", "/>");
-            assertNotNull(result);
-            boolean mattrExists = false;
-            for (String entry : result) {
-                if (entry.contains(membershipKey.getKey())) {
-                    mattrExists = true;
-                }
-            }
-            assertTrue(mattrExists);
-        } finally {
-            deleteGroup(groupTO.getKey());
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 5d75e7c..2cd33a5 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
@@ -273,7 +273,7 @@ public class ConnectorITCase extends AbstractITCase {
         List<ResourceTO> result = new ArrayList<>();
 
         for (ResourceTO resource : input) {
-            if (connectorKey.equals(resource.getConnectorId())) {
+            if (connectorKey.equals(resource.getConnector())) {
                 result.add(resource);
             }
         }
@@ -320,7 +320,7 @@ public class ConnectorITCase extends AbstractITCase {
         long connId = connInstanceTO.getKey();
 
         // Link resourceTO to the new connector instance.
-        resourceTO.setConnectorId(connId);
+        resourceTO.setConnector(connId);
         // ----------------------------------
 
         // ----------------------------------
@@ -639,7 +639,7 @@ public class ConnectorITCase extends AbstractITCase {
             ResourceTO resourceTO = new ResourceTO();
 
             resourceTO.setKey(resourceName);
-            resourceTO.setConnectorId(connectorTO.getKey());
+            resourceTO.setConnector(connectorTO.getKey());
 
             conf = new HashSet<>();
             endpoint.getValues().clear();

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e13e400..ae823e1 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
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.fit.core.reference;
 
+import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
@@ -27,6 +28,7 @@ import java.util.Properties;
 import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.RoleTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -65,9 +67,15 @@ public class ExceptionMapperITCase extends AbstractITCase {
         schemaTO.setUniqueConstraint(true);
         createSchema(SchemaType.PLAIN, schemaTO);
 
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("camelAttribute");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
         // 2. create an user with mandatory attributes and unique
         UserTO userTO1 = new UserTO();
         userTO1.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO1.getAuxClasses().add(typeClass.getKey());
         String userId1 = getUUIDString() + "issue654_1@syncope.apache.org";
         userTO1.setUsername(userId1);
         userTO1.setPassword("password123");
@@ -82,6 +90,7 @@ public class ExceptionMapperITCase extends AbstractITCase {
         // 3. create an other user with mandatory attributes and unique with the same value of userTO1
         UserTO userTO2 = new UserTO();
         userTO2.setRealm(SyncopeConstants.ROOT_REALM);
+        userTO2.getAuxClasses().add(typeClass.getKey());
         String userId2 = getUUIDString() + "issue654_2@syncope.apache.org";
         userTO2.setUsername(userId2);
         userTO2.setPassword("password123");

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 d0a4be1..391e8e7 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
@@ -44,6 +44,8 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.ReferenceMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
@@ -418,6 +420,7 @@ public class GroupITCase extends AbstractITCase {
     public void deprovision() {
         GroupTO actual = createGroup(getSampleTO("deprovision"));
         assertNotNull(actual);
+        assertNotNull(actual.getKey());
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), actual.getKey()));
 
@@ -507,8 +510,8 @@ public class GroupITCase extends AbstractITCase {
     }
 
     @Test
-    public void createWithMandatorySchemaNotTemplate() {
-        // 1. create a group mandatory schema
+    public void createWithMandatorySchema() {
+        // 1. create a mandatory schema
         PlainSchemaTO badge = new PlainSchemaTO();
         badge.setKey("badge" + getUUIDString());
         badge.setMandatoryCondition("true");
@@ -521,24 +524,40 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(groupTO);
         assertFalse(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
 
-        // 3. add a template for badge to the group just created - 
-        // failure since no values are provided and it is mandatory
-        GroupMod groupMod = new GroupMod();
-        groupMod.setKey(groupTO.getKey());
+        // 3. add the new mandatory schema to the default group type
+        AnyTypeTO type = anyTypeService.read(AnyTypeKind.GROUP.name());
+        String typeClassName = type.getClasses().get(0);
+        AnyTypeClassTO typeClass = anyTypeClassService.read(typeClassName);
+        typeClass.getPlainSchemas().add(badge.getKey());
+        anyTypeClassService.update(typeClassName, typeClass);
+        typeClass = anyTypeClassService.read(typeClassName);
+        assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
 
         try {
-            updateGroup(groupMod);
-            fail();
-        } catch (SyncopeClientException e) {
-            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
-        }
+            // 4. update group: failure since no values are provided and it is mandatory
+            GroupMod groupMod = new GroupMod();
+            groupMod.setKey(groupTO.getKey());
+
+            try {
+                updateGroup(groupMod);
+                fail();
+            } catch (SyncopeClientException e) {
+                assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+            }
 
-        // 4. also add an actual attribute for badge - it will work        
-        groupMod.getPlainAttrsToUpdate().add(attrMod(badge.getKey(), "xxxxxxxxxx"));
+            // 5. also add an actual attribute for badge - it will work        
+            groupMod.getPlainAttrsToUpdate().add(attrMod(badge.getKey(), "xxxxxxxxxx"));
 
-        groupTO = updateGroup(groupMod);
-        assertNotNull(groupTO);
-        assertTrue(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
+            groupTO = updateGroup(groupMod);
+            assertNotNull(groupTO);
+            assertTrue(groupTO.getPlainAttrMap().containsKey(badge.getKey()));
+        } finally {
+            // restore the original group class
+            typeClass.getPlainSchemas().remove(badge.getKey());
+            anyTypeClassService.update(typeClassName, typeClass);
+            typeClass = anyTypeClassService.read(typeClassName);
+            assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
+        }
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e77f343..e6e450c 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
@@ -32,6 +32,7 @@ import org.apache.commons.lang3.SerializationUtils;
 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.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.UserTO;
@@ -63,8 +64,12 @@ public class PlainSchemaITCase extends AbstractITCase {
         PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertEquals(schemaTO, newPlainSchemaTO);
 
-        newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertEquals(schemaTO, newPlainSchemaTO);
+        try {
+            createSchema(SchemaType.PLAIN, schemaTO);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
     }
 
     @Test
@@ -79,8 +84,7 @@ public class PlainSchemaITCase extends AbstractITCase {
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
 
-            assertTrue(e.getElements().iterator().next().toString().
-                    contains(EntityViolationType.InvalidName.name()));
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
         }
     }
 
@@ -202,7 +206,13 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue258");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
         UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
         userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
 
         userTO = createUser(userTO);
@@ -225,7 +235,13 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue259");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
         UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
         userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1"));
         userTO = createUser(userTO);
         assertNotNull(userTO);
@@ -249,7 +265,13 @@ public class PlainSchemaITCase extends AbstractITCase {
         schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
         assertNotNull(schemaTO);
 
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("issue260");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
+
         UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
+        userTO.getAuxClasses().add(typeClass.getKey());
         userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
         userTO = createUser(userTO);
         assertNotNull(userTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 1f498cc..9a169c3 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
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.fit.core.reference;
 
+import static org.apache.syncope.fit.core.reference.AbstractITCase.anyTypeClassService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -31,6 +32,7 @@ import java.util.Set;
 import javax.ws.rs.core.Response;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
 import org.apache.syncope.common.lib.to.MappingTO;
 import org.apache.syncope.common.lib.to.NotificationTO;
@@ -120,12 +122,12 @@ public class PushTaskITCase extends AbstractTaskITCase {
     public void pushMatchingUnmatchingGroups() {
         assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
 
-        execSyncTask(23L, 50, false);
+        execProvisioningTask(23L, 50, false);
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertTrue(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
 
-        execSyncTask(23L, 50, false);
+        execProvisioningTask(23L, 50, false);
 
         assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), 3L));
         assertFalse(groupService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
@@ -144,17 +146,17 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Unmatching --> Assign --> dryRuyn
         // ------------------------------------------
-        execSyncTask(13L, 50, true);
+        execProvisioningTask(13L, 50, true);
         assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
         assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
         // ------------------------------------------
 
-        final Set<Long> pushTaskIds = new HashSet<>();
+        Set<Long> pushTaskIds = new HashSet<>();
         pushTaskIds.add(13L);
         pushTaskIds.add(14L);
         pushTaskIds.add(15L);
         pushTaskIds.add(16L);
-        execSyncTasks(pushTaskIds, 50, false);
+        execProvisioningTasks(pushTaskIds, 50, false);
 
         // ------------------------------------------
         // Unatching --> Ignore
@@ -199,17 +201,17 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Matching --> Deprovision --> dryRuyn
         // ------------------------------------------
-        execSyncTask(19L, 50, true);
+        execProvisioningTask(19L, 50, true);
         assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
         // ------------------------------------------
 
-        final Set<Long> pushTaskIds = new HashSet<>();
-        pushTaskIds.add(18L);
-        pushTaskIds.add(19L);
-        pushTaskIds.add(16L);
+        Set<Long> pushTaskKeys = new HashSet<>();
+        pushTaskKeys.add(18L);
+        pushTaskKeys.add(19L);
+        pushTaskKeys.add(16L);
 
-        execSyncTasks(pushTaskIds, 50, false);
+        execProvisioningTasks(pushTaskKeys, 50, false);
 
         // ------------------------------------------
         // Matching --> Deprovision && Ignore
@@ -230,16 +232,16 @@ public class PushTaskITCase extends AbstractTaskITCase {
         // ------------------------------------------
         // Matching --> Link
         // ------------------------------------------
-        execSyncTask(20L, 50, false);
+        execProvisioningTask(20L, 50, false);
         assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
         assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
         // ------------------------------------------
 
-        pushTaskIds.clear();
-        pushTaskIds.add(21L);
-        pushTaskIds.add(22L);
+        pushTaskKeys.clear();
+        pushTaskKeys.add(21L);
+        pushTaskKeys.add(22L);
 
-        execSyncTasks(pushTaskIds, 50, false);
+        execProvisioningTasks(pushTaskKeys, 50, false);
 
         // ------------------------------------------
         // Matching --> Unlink && Update
@@ -257,15 +259,21 @@ public class PushTaskITCase extends AbstractTaskITCase {
         schemaTO.setType(AttrSchemaType.String);
         schemaTO.setMandatoryCondition("true");
 
-        PlainSchemaTO newPlainSchemaTO = createSchema(SchemaType.PLAIN, schemaTO);
-        assertEquals(schemaTO, newPlainSchemaTO);
+        schemaTO = createSchema(SchemaType.PLAIN, schemaTO);
+        assertNotNull(schemaTO);
+
+        AnyTypeClassTO typeClass = new AnyTypeClassTO();
+        typeClass.setKey("SYNCOPE-598");
+        typeClass.getPlainSchemas().add(schemaTO.getKey());
+        anyTypeClassService.create(typeClass);
 
         // create a new sample group
         GroupTO groupTO = new GroupTO();
         groupTO.setName("all" + getUUIDString());
         groupTO.setRealm("/even");
+        groupTO.getAuxClasses().add(typeClass.getKey());
 
-        groupTO.getPlainAttrs().add(attrTO(newPlainSchemaTO.getKey(), "all"));
+        groupTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "all"));
 
         groupTO = createGroup(groupTO);
         assertNotNull(groupTO);
@@ -277,29 +285,28 @@ public class PushTaskITCase extends AbstractTaskITCase {
             // Create resource ad-hoc
             ResourceTO resourceTO = new ResourceTO();
             resourceTO.setKey(resourceName);
-            resourceTO.setConnectorId(105L);
+            resourceTO.setConnector(105L);
 
             ProvisionTO provisionTO = new ProvisionTO();
             provisionTO.setAnyType(AnyTypeKind.GROUP.name());
             provisionTO.setObjectClass(ObjectClass.GROUP_NAME);
             resourceTO.getProvisions().add(provisionTO);
 
-            MappingTO rmapping = new MappingTO();
-            provisionTO.setMapping(rmapping);
+            MappingTO mapping = new MappingTO();
+            provisionTO.setMapping(mapping);
 
             MappingItemTO item = new MappingItemTO();
             item.setIntMappingType(IntMappingType.GroupPlainSchema);
             item.setExtAttrName("cn");
-            item.setIntAttrName(newPlainSchemaTO.getKey());
+            item.setIntAttrName(schemaTO.getKey());
             item.setConnObjectKey(true);
             item.setPurpose(MappingPurpose.BOTH);
-            rmapping.setConnObjectKeyItem(item);
+            mapping.setConnObjectKeyItem(item);
 
-            rmapping.setConnObjectLink("'cn=' + " + newPlainSchemaTO.getKey() + " + ',ou=groups,o=isp'");
+            mapping.setConnObjectLink("'cn=' + " + schemaTO.getKey() + " + ',ou=groups,o=isp'");
 
             Response response = resourceService.create(resourceTO);
             newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
-
             assertNotNull(newResourceTO);
             assertNull(newResourceTO.getProvision(AnyTypeKind.USER.name()));
             assertNotNull(newResourceTO.getProvision(AnyTypeKind.GROUP.name()).getMapping());
@@ -316,11 +323,10 @@ public class PushTaskITCase extends AbstractTaskITCase {
 
             response = taskService.create(task);
             PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
-
             assertNotNull(push);
 
             // execute the new task
-            TaskExecTO pushExec = execSyncTask(push.getKey(), 50, false);
+            TaskExecTO pushExec = execProvisioningTask(push.getKey(), 50, false);
             assertTrue(PropagationTaskExecStatus.valueOf(pushExec.getStatus()).isSuccessful());
         } finally {
             groupService.delete(groupTO.getKey());
@@ -332,7 +338,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void issueSYNCOPE648() {
-        //1. Create Push Task
+        // 1. Create Push Task
         PushTaskTO task = new PushTaskTO();
         task.setName("Test create Push");
         task.setResource(RESOURCE_NAME_LDAP);
@@ -343,8 +349,8 @@ public class PushTaskITCase extends AbstractTaskITCase {
         task.setMatchingRule(MatchingRule.IGNORE);
         task.setUnmatchingRule(UnmatchingRule.IGNORE);
 
-        final Response response = taskService.create(task);
-        final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+        Response response = taskService.create(task);
+        PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
         assertNotNull(actual);
 
         // 2. Create notification
@@ -368,7 +374,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
         notification = getObject(responseNotification.getLocation(), NotificationService.class, NotificationTO.class);
         assertNotNull(notification);
 
-        execSyncTask(actual.getKey(), 50, false);
+        execProvisioningTask(actual.getKey(), 50, false);
 
         NotificationTaskTO taskTO = findNotificationTaskBySender("syncope648@syncope.apache.org");
         assertNotNull(taskTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 2e6cf21..faf4701 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
@@ -58,7 +58,7 @@ public class ResourceITCase extends AbstractITCase {
         ResourceTO resourceTO = new ResourceTO();
 
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -151,7 +151,7 @@ public class ResourceITCase extends AbstractITCase {
         mapping.add(item);
 
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ConnConfProperty p = new ConnConfProperty();
         ConnConfPropSchema schema = new ConnConfPropSchema();
@@ -178,7 +178,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = RESOURCE_NAME_CREATE_SINGLE;
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -228,7 +228,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = RESOURCE_NAME_CREATE_WRONG;
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -264,7 +264,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = RESOURCE_NAME_CREATE_WRONG;
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -294,7 +294,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = "res-with-password-policy";
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
         resourceTO.setPasswordPolicy(4L);
 
         ProvisionTO provisionTO = new ProvisionTO();
@@ -342,7 +342,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = RESOURCE_NAME_UPDATE;
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(101L);
+        resourceTO.setConnector(101L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -510,7 +510,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(resource);
         assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
 
-        resource.getProvision(AnyTypeKind.USER.name()).setMapping(new MappingTO());
+        resource.getProvision(AnyTypeKind.USER.name()).setMapping(null);
         resourceService.update(name, resource);
 
         resource = resourceService.read(name);
@@ -525,7 +525,7 @@ public class ResourceITCase extends AbstractITCase {
         ResourceTO resourceTO = new ResourceTO();
 
         resourceTO.setKey(name);
-        resourceTO.setConnectorId(105L);
+        resourceTO.setConnector(105L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.GROUP.name());
@@ -586,7 +586,7 @@ public class ResourceITCase extends AbstractITCase {
         String resourceName = RESOURCE_NAME_CREATE_NONE;
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(102L);
+        resourceTO.setConnector(102L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 479c96f..1d809ea 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
@@ -126,7 +126,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals(actual.getKey(), task.getKey());
         assertEquals(actual.getJobClassName(), task.getJobClassName());
         assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
-        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.USER.name()));
+        assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name()));
     }
 
     @Test
@@ -147,6 +147,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
         inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
         inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
+        inUserTO.getAuxClasses().add("csv");
         inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         inUserTO = createUser(inUserTO);
@@ -160,7 +161,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
                     page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPre);
 
-            execSyncTask(SYNC_TASK_ID, 50, false);
+            execProvisioningTask(SYNC_TASK_ID, 50, false);
 
             // after execution of the sync task the user data should have been synced from CSV
             // and processed by user template
@@ -229,13 +230,13 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertEquals("active", userTO.getStatus());
 
             // SYNCOPE-317
-            execSyncTask(SYNC_TASK_ID, 50, false);
+            execProvisioningTask(SYNC_TASK_ID, 50, false);
 
             final Set<Long> pushTaskIds = new HashSet<>();
             pushTaskIds.add(25L);
             pushTaskIds.add(26L);
 
-            execSyncTasks(pushTaskIds, 50, false);
+            execProvisioningTasks(pushTaskIds, 50, false);
             // Matching --> UNLINK
             assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
             assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
@@ -246,7 +247,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
     @Test
     public void dryRun() {
-        TaskExecTO execution = execSyncTask(SYNC_TASK_ID, 50, true);
+        TaskExecTO execution = execProvisioningTask(SYNC_TASK_ID, 50, true);
         assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
                 "SUCCESS", execution.getStatus());
     }
@@ -254,7 +255,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     @Test
     public void reconcileFromDB() {
         // update sync task
-        TaskExecTO execution = execSyncTask(7L, 50, false);
+        TaskExecTO execution = execProvisioningTask(7L, 50, false);
         assertNotNull(execution.getStatus());
         assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
 
@@ -268,7 +269,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE");
 
         // re-execute the same SyncTask: now user must be active
-        execution = execSyncTask(7L, 50, false);
+        execution = execProvisioningTask(7L, 50, false);
         assertNotNull(execution.getStatus());
         assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
 
@@ -312,8 +313,8 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         // First of all, clear any potential conflict with existing user / group
         ldapCleanup();
 
-        // Update sync task
-        TaskExecTO execution = execSyncTask(11L, 50, false);
+        // 0. synchronize
+        TaskExecTO execution = execProvisioningTask(11L, 50, false);
 
         // 1. verify execution status
         String status = execution.getStatus();
@@ -343,19 +344,12 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         // Check for SYNCOPE-123
         assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
 
-        final GroupTO groupTO = matchingGroups.getResult().iterator().next();
+        GroupTO groupTO = matchingGroups.getResult().iterator().next();
         assertNotNull(groupTO);
         assertEquals("testLDAPGroup", groupTO.getName());
         assertEquals("true", groupTO.getPlainAttrMap().get("show").getValues().get(0));
         assertEquals(matchingUsers.getResult().iterator().next().getKey(), groupTO.getUserOwner(), 0);
         assertNull(groupTO.getGroupOwner());
-
-        // 3. verify that LDAP group membership is propagated as Syncope group membership
-        PagedResult<UserTO> members = userService.search(
-                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
-                fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()).query()).build());
-        assertNotNull(members);
-        assertEquals(1, members.getResult().size());
     }
 
     @Test
@@ -415,9 +409,9 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertNotNull(actual);
             assertEquals(task.getKey(), actual.getKey());
             assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getResources().isEmpty());
-            assertFalse(actual.getTemplates().get(AnyTypeKind.USER.name()).getMemberships().isEmpty());
+            assertFalse(((UserTO) actual.getTemplates().get(AnyTypeKind.USER.name())).getMemberships().isEmpty());
 
-            TaskExecTO execution = execSyncTask(actual.getKey(), 50, false);
+            TaskExecTO execution = execProvisioningTask(actual.getKey(), 50, false);
             final String status = execution.getStatus();
             assertNotNull(status);
             assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
@@ -436,7 +430,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE230() {
         // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
-        execSyncTask(10L, 50, false);
+        execProvisioningTask(10L, 50, false);
 
         // 3. read e-mail address for user created by the SyncTask first execution
         UserTO userTO = readUser("issuesyncope230");
@@ -449,7 +443,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
 
         // 5. re-execute the SyncTask
-        execSyncTask(10L, 50, false);
+        execProvisioningTask(10L, 50, false);
 
         // 6. verify that the e-mail was updated
         userTO = readUser("issuesyncope230");
@@ -511,7 +505,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         userService.update(userMod.getKey(), userMod);
 
-        execSyncTask(actual.getKey(), 50, false);
+        execProvisioningTask(actual.getKey(), 50, false);
 
         SyncTaskTO executed = taskService.read(actual.getKey());
         assertEquals(1, executed.getExecutions().size());
@@ -535,7 +529,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             assertEquals(1, userTO.getPropagationStatusTOs().size());
             assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
 
-            TaskExecTO taskExecTO = execSyncTask(24L, 50, false);
+            TaskExecTO taskExecTO = execProvisioningTask(24L, 50, false);
 
             assertNotNull(taskExecTO.getStatus());
             assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful());
@@ -551,6 +545,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     @Test
     public void issueSYNCOPE307() {
         UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
+        userTO.getAuxClasses().add("csv");
 
         AttrTO csvuserid = new AttrTO();
         csvuserid.setSchema("csvuserid");
@@ -583,7 +578,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
         taskService.update(task.getKey(), task);
-        execSyncTask(task.getKey(), 50, false);
+        execProvisioningTask(task.getKey(), 50, false);
 
         // check for sync policy
         userTO = userService.read(userTO.getKey());
@@ -640,7 +635,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals(actual.getKey(), syncTask.getKey());
         assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
 
-        TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
+        TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
         final String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
@@ -692,11 +687,11 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         // 5. Update the LDAP Connector to retrieve passwords
         ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
-        ConnInstanceTO resourceConnector = connectorService.read(ldapResource.getConnectorId());
+        ConnInstanceTO resourceConnector = connectorService.read(ldapResource.getConnector());
         ConnConfProperty property = resourceConnector.getConfigurationMap().get("retrievePasswordsWithSearch");
         property.getValues().clear();
         property.getValues().add(Boolean.TRUE);
-        connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+        connectorService.update(ldapResource.getConnector(), resourceConnector);
 
         // 6. Sync the user from the resource
         SyncTaskTO syncTask = new SyncTaskTO();
@@ -717,8 +712,8 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertEquals(actual.getKey(), syncTask.getKey());
         assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
 
-        TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
-        final String status = execution.getStatus();
+        TaskExecTO execution = execProvisioningTask(syncTask.getKey(), 50, false);
+        String status = execution.getStatus();
         assertNotNull(status);
         assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
 
@@ -731,7 +726,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         taskService.delete(syncTask.getKey());
         property.getValues().clear();
         property.getValues().add(Boolean.FALSE);
-        connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+        connectorService.update(ldapResource.getConnector(), resourceConnector);
         deleteUser(updatedUser.getKey());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 107c953..4574b5b 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
@@ -95,12 +95,18 @@ import org.springframework.jdbc.core.JdbcTemplate;
 @FixMethodOrder(MethodSorters.JVM)
 public class UserITCase extends AbstractITCase {
 
-    private String getStringAttribute(final ConnObjectTO connObjectTO, final String attrName) {
-        return connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0);
-    }
+    private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+        @Override
+        protected SimpleDateFormat initialValue() {
+            SimpleDateFormat sdf = new SimpleDateFormat();
+            sdf.applyPattern("yyyy-MM-dd");
+            return sdf;
+        }
+    };
 
     private boolean getBooleanAttribute(final ConnObjectTO connObjectTO, final String attrName) {
-        return Boolean.parseBoolean(getStringAttribute(connObjectTO, attrName));
+        return Boolean.parseBoolean(connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0));
     }
 
     public static UserTO getUniqueSampleTO(final String email) {
@@ -120,7 +126,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getPlainAttrs().add(attrTO("type", "a type"));
         userTO.getPlainAttrs().add(attrTO("userId", uid));
         userTO.getPlainAttrs().add(attrTO("email", uid));
-        userTO.getPlainAttrs().add(attrTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
+        userTO.getPlainAttrs().add(attrTO("loginDate", DATE_FORMAT.get().format(new Date())));
         userTO.getDerAttrs().add(attrTO("cn", null));
         userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
         return userTO;
@@ -261,6 +267,7 @@ public class UserITCase extends AbstractITCase {
             assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
         }
 
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         userTO = createUser(userTO);
@@ -655,7 +662,7 @@ public class UserITCase extends AbstractITCase {
 
         userMod.getDerAttrsToAdd().add("cn");
         userMod.getMembershipsToAdd().add(8L);
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+        userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getRightKey());
 
         userTO = updateUser(userMod);
         assertNotNull(userTO);
@@ -1102,6 +1109,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
 
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         MembershipTO membershipTO = new MembershipTO();
@@ -1157,6 +1165,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         MembershipTO memb12 = new MembershipTO();
@@ -1186,7 +1195,7 @@ public class UserITCase extends AbstractITCase {
         UserMod userMod = new UserMod();
         userMod.setKey(actual.getKey());
 
-        userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getKey());
+        userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getRightKey());
 
         actual = updateUser(userMod);
         assertNotNull(actual);
@@ -1219,7 +1228,7 @@ public class UserITCase extends AbstractITCase {
         userMod = new UserMod();
         userMod.setKey(actual.getKey());
 
-        userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getKey());
+        userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getRightKey());
 
         actual = updateUser(userMod);
         assertNotNull(actual);
@@ -1490,6 +1499,7 @@ public class UserITCase extends AbstractITCase {
     @Test
     public void mappingPurpose() {
         UserTO userTO = getUniqueSampleTO("mpurpose@apache.org");
+        userTO.getAuxClasses().add("csv");
 
         AttrTO csvuserid = new AttrTO();
         csvuserid.setSchema("csvuserid");
@@ -1526,7 +1536,7 @@ public class UserITCase extends AbstractITCase {
 
     @Test
     public void bulkActions() {
-        final BulkAction bulkAction = new BulkAction();
+        BulkAction bulkAction = new BulkAction();
 
         for (int i = 0; i < 10; i++) {
             UserTO userTO = getUniqueSampleTO("bulk_" + i + "@apache.org");
@@ -1598,7 +1608,7 @@ public class UserITCase extends AbstractITCase {
         // 4. remove membership
         UserMod userMod = new UserMod();
         userMod.setKey(userTO.getKey());
-        userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+        userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getRightKey());
 
         userTO = updateUser(userMod);
         assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
@@ -1746,6 +1756,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
         userTO.getResources().add(RESOURCE_NAME_CSV);
 
@@ -1772,6 +1783,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         UserTO actual = createUser(userTO);
@@ -1810,6 +1822,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
         userTO.getResources().add(RESOURCE_NAME_CSV);
 
@@ -1841,6 +1854,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         UserTO actual = createUser(userTO);
@@ -1875,6 +1889,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
         userTO.getResources().add(RESOURCE_NAME_CSV);
 
@@ -1906,6 +1921,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         UserTO actual = createUser(userTO);
@@ -1941,6 +1957,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         UserTO actual = createUser(userTO);
@@ -2280,6 +2297,7 @@ public class UserITCase extends AbstractITCase {
         userTO.getPlainAttrs().add(attrTO("email", "syncope391@syncope.apache.org"));
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
+        userTO.getAuxClasses().add("csv");
         userTO.getResources().add(RESOURCE_NAME_CSV);
         userTO = createUser(userTO, false);
         assertNotNull(userTO);
@@ -2299,6 +2317,7 @@ public class UserITCase extends AbstractITCase {
         userTO.setPassword("passwordTESTNULL1");
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         userTO.getResources().add(RESOURCE_NAME_CSV);
@@ -2319,6 +2338,7 @@ public class UserITCase extends AbstractITCase {
         userTO.setPassword("passwordTESTNULL1");
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
         userTO.getResources().add(RESOURCE_NAME_CSV);
@@ -2347,6 +2367,7 @@ public class UserITCase extends AbstractITCase {
             userTO.setPassword(null);
             userTO.getDerAttrs().clear();
             userTO.getVirAttrs().clear();
+            userTO.getAuxClasses().add("csv");
             userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
             userTO.getResources().add(RESOURCE_NAME_CSV);
@@ -2369,11 +2390,11 @@ public class UserITCase extends AbstractITCase {
         userTO.getMemberships().clear();
         userTO.getDerAttrs().clear();
         userTO.getVirAttrs().clear();
+        userTO.getAuxClasses().add("csv");
         userTO.getDerAttrs().add(attrTO("csvuserid", null));
 
-        MembershipTO membershipTO = new MembershipTO();
-        membershipTO.setRightKey(12L);
-        userTO.getMemberships().add(membershipTO);
+        userTO.getAuxClasses().add("generic membership");
+        userTO.getPlainAttrs().add(attrTO("postalAddress", "postalAddress"));
 
         userTO.getResources().add(RESOURCE_NAME_LDAP);
 
@@ -2388,9 +2409,7 @@ public class UserITCase extends AbstractITCase {
 
         UserMod userMod = new UserMod();
         userMod.setKey(actual.getKey());
-
-        userMod.getMembershipsToAdd().add(12L);
-        userMod.getMembershipsToRemove().add(actual.getMemberships().iterator().next().getKey());
+        userMod.getPlainAttrsToUpdate().add(attrMod("postalAddress", "newPostalAddress"));
 
         actual = updateUser(userMod);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 457f66d..3bbb7e1 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
@@ -74,10 +74,19 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form.getTaskId());
         assertNull(form.getOwner());
 
-        // 3. claim task from rossini, not in group 7 (designated for approval in workflow definition): fail
-        UserWorkflowService userService2 = clientFactory.create(
-                "rossini", ADMIN_PWD).getService(UserWorkflowService.class);
+        // 3. claim task as rossini, with role 2 granting entitlement to claim forms but not in group 7,
+        // designated for approval in workflow definition: fail
+        UserTO rossini = userService.read(1L);
+        if (!rossini.getRoles().contains(2L)) {
+            UserMod userMod = new UserMod();
+            userMod.setKey(1L);
+            userMod.getRolesToAdd().add(2L);
+            rossini = updateUser(userMod);
+        }
+        assertTrue(rossini.getRoles().contains(2L));
 
+        UserWorkflowService userService2 = clientFactory.create("rossini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
         try {
             userService2.claimForm(form.getTaskId());
             fail();
@@ -85,10 +94,9 @@ public class UserWorkflowITCase extends AbstractITCase {
             assertEquals(ClientExceptionType.Workflow, e.getType());
         }
 
-        // 4. claim task from bellini, in role 2
-        UserWorkflowService userService3 = clientFactory.create(
-                "bellini", ADMIN_PWD).getService(UserWorkflowService.class);
-
+        // 4. claim task from bellini, with role 2 and in group 7
+        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
         form = userService3.claimForm(form.getTaskId());
         assertNotNull(form);
         assertNotNull(form.getTaskId());
@@ -237,9 +245,8 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form);
 
         // 3. first claim ny bellini ....
-        UserWorkflowService userService3 = clientFactory.create(
-                "bellini", ADMIN_PWD).getService(UserWorkflowService.class);
-
+        UserWorkflowService userService3 = clientFactory.create("bellini", ADMIN_PWD).
+                getService(UserWorkflowService.class);
         form = userService3.claimForm(form.getTaskId());
         assertNotNull(form);
         assertNotNull(form.getTaskId());
@@ -250,7 +257,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form);
 
         // 5. approve user
-        final Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
         props.get("approve").setValue(Boolean.TRUE.toString());
         form.getProperties().clear();
         form.getProperties().addAll(props.values());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 a373df5..2c2065f 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
@@ -228,7 +228,7 @@ public class VirAttrITCase extends AbstractITCase {
         assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
 
         // 3. update virtual attribute directly
-        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
 
         String value = jdbcTemplate.queryForObject(
                 "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
@@ -296,6 +296,7 @@ public class VirAttrITCase extends AbstractITCase {
 
             // create a new user
             UserTO userTO = UserITCase.getUniqueSampleTO("syncope397@syncope.apache.org");
+            userTO.getAuxClasses().add("csv");
             userTO.getResources().clear();
             userTO.getMemberships().clear();
             userTO.getDerAttrs().clear();
@@ -450,7 +451,7 @@ public class VirAttrITCase extends AbstractITCase {
         ResourceTO resourceTO = new ResourceTO();
 
         resourceTO.setKey(resourceName);
-        resourceTO.setConnectorId(107L);
+        resourceTO.setConnector(107L);
 
         ProvisionTO provisionTO = new ProvisionTO();
         provisionTO.setAnyType(AnyTypeKind.USER.name());
@@ -463,7 +464,7 @@ public class VirAttrITCase extends AbstractITCase {
         MappingItemTO item = new MappingItemTO();
         item.setIntAttrName("aLong");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setExtAttrName(groupName);
+        item.setExtAttrName("ID");
         item.setPurpose(MappingPurpose.PROPAGATION);
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);


[25/70] 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);
                 }


[12/70] 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);


[31/70] syncope git commit: [SYNCOPE-666] Fix naming

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 992507b..32f660e 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
@@ -56,10 +56,10 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
     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);
         }
 
@@ -71,11 +71,11 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
     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);
         }
 
@@ -104,11 +104,11 @@ public class LDAPPasswordSyncActions extends DefaultSyncActions {
     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) {
                 byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
                 char[] encodedHex = Hex.encode(encodedPasswordBytes);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 e751522..8982824 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
@@ -163,10 +163,10 @@ public class SyncUtils {
         return result;
     }
 
-    private AnyDAO<?> getAnyDAO(final MappingItem accountIdItem) {
-        return AnyTypeKind.USER == accountIdItem.getIntMappingType().getAnyTypeKind()
+    private AnyDAO<?> getAnyDAO(final MappingItem connObjectKeyItem) {
+        return AnyTypeKind.USER == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
                 ? userDAO
-                : AnyTypeKind.ANY_OBJECT == accountIdItem.getIntMappingType().getAnyTypeKind()
+                : AnyTypeKind.ANY_OBJECT == connObjectKeyItem.getIntMappingType().getAnyTypeKind()
                         ? anyObjectDAO
                         : groupDAO;
     }
@@ -238,7 +238,7 @@ public class SyncUtils {
                 break;
 
             default:
-                LOG.error("Invalid accountId type '{}'", connObjectKeyItem.getIntMappingType());
+                LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
         }
 
         return result;
@@ -356,7 +356,7 @@ public class SyncUtils {
     /**
      * Find users / groups based on mapped uid value (or previous uid value, if updated).
      *
-     * @param uid for finding by account id
+     * @param uid for finding by connObjectKey
      * @param connObj for finding by attribute value
      * @param provision external resource
      * @param anyUtils any util

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 dc1ea5a..e4a436f 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
@@ -113,8 +113,8 @@ public class UserPushResultHandlerImpl extends AbstractPushResultHandler impleme
     }
 
     @Override
-    protected String getName(final Any<?, ?, ?> subject) {
-        return User.class.cast(subject).getUsername();
+    protected String getName(final Any<?, ?, ?> any) {
+        return User.class.cast(any).getUsername();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 3e99286..8487fa8 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
@@ -40,8 +40,8 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
     }
 
     @Override
-    protected String getName(final AnyTO subjectTO) {
-        return UserTO.class.cast(subjectTO).getUsername();
+    protected String getName(final AnyTO anyTO) {
+        return UserTO.class.cast(anyTO).getUsername();
     }
 
     @Override
@@ -55,8 +55,8 @@ public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler impleme
     }
 
     @Override
-    protected AnyTO doCreate(final AnyTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
-        UserTO userTO = UserTO.class.cast(subjectTO);
+    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
+        UserTO userTO = UserTO.class.cast(anyTO);
 
         Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
         Map.Entry<Long, List<PropagationStatus>> created = userProvisioningManager.create(userTO, true, true, enabled,

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 51245e4..969dd89 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
@@ -92,7 +92,7 @@ public class ResourceDataBinderTest extends AbstractTest {
         item.setIntAttrName("userId");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setExtAttrName("campo1");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setMandatoryCondition("false");
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 e13018f..e2ddbc9 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
@@ -82,7 +82,7 @@ public class CamelRouteLoader implements SyncopeLoader {
     }
 
     private boolean loadRoutesFor(final AnyTypeKind anyTypeKind) {
-        final String sql = String.format("SELECT * FROM %s WHERE SUBJECTTYPE = ?", CamelRoute.class.getSimpleName());
+        final String sql = String.format("SELECT * FROM %s WHERE ANYTYPEKIND = ?", CamelRoute.class.getSimpleName());
         final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
         final List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql, new Object[] { anyTypeKind.name() });
         return rows.isEmpty();
@@ -104,7 +104,7 @@ public class CamelRouteLoader implements SyncopeLoader {
 
     private void loadRoutes(final Resource resource, final AnyTypeKind anyTypeKind) {
         if (loadRoutesFor(anyTypeKind)) {
-            String query = String.format("INSERT INTO %s(NAME, SUBJECTTYPE, CONTENT) VALUES (?, ?, ?)",
+            String query = String.format("INSERT INTO %s(NAME, ANYTYPEKIND, CONTENT) VALUES (?, ?, ?)",
                     CamelRoute.class.getSimpleName());
             JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
index 7c132a1..18aadcc 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
@@ -36,8 +36,8 @@ public class CamelGroupProvisioningManager
         extends AbstractCamelProvisioningManager implements GroupProvisioningManager {
 
     @Override
-    public Pair<Long, List<PropagationStatus>> create(final GroupTO subject) {
-        return create(subject, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO any) {
+        return create(any, Collections.<String>emptySet());
     }
 
     @Override
@@ -82,21 +82,21 @@ public class CamelGroupProvisioningManager
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod subjectMod) {
-        return update(subjectMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod anyMod) {
+        return update(anyMod, Collections.<String>emptySet());
     }
 
     @Override
     @SuppressWarnings("unchecked")
     public Pair<Long, List<PropagationStatus>> update(
-            final GroupMod subjectMod, final Set<String> excludedResources) {
+            final GroupMod anyMod, final Set<String> excludedResources) {
 
         PollingConsumer pollingConsumer = getConsumer("direct:updateGroupPort");
 
         Map<String, Object> props = new HashMap<>();
         props.put("excludedResources", excludedResources);
 
-        sendMessage("direct:updateGroup", subjectMod, props);
+        sendMessage("direct:updateGroup", anyMod, props);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 5b20fa1..a258751 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
@@ -214,10 +214,10 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
-    public Long link(final UserMod subjectMod) {
+    public Long link(final UserMod anyMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:linkPort");
 
-        sendMessage("direct:linkUser", subjectMod);
+        sendMessage("direct:linkUser", anyMod);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
index a22f2eb..8dc8bde 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateInSyncProcessor.java
@@ -48,7 +48,7 @@ public class GroupCreateInSyncProcessor implements Processor {
     public void process(final Exchange exchange) {
         WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
 
-        GroupTO actual = exchange.getProperty("subject", GroupTO.class);
+        GroupTO actual = exchange.getProperty("any", GroupTO.class);
         Map<Long, String> groupOwnerMap = exchange.getProperty("groupOwnerMap", Map.class);
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
index 6805a5e..4ab62e3 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupCreateProcessor.java
@@ -51,11 +51,11 @@ public class GroupCreateProcessor implements Processor {
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
-        GroupTO subject = exchange.getProperty("subject", GroupTO.class);
+        GroupTO any = exchange.getProperty("any", GroupTO.class);
         Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
 
         List<PropagationTask> tasks =
-                propagationManager.getGroupCreateTasks(created, subject.getVirAttrs(), excludedResource);
+                propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResource);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 212cccd..f452ffd 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
@@ -59,8 +59,8 @@ public class GroupDeleteProcessor implements Processor {
 
     @Override
     public void process(final Exchange exchange) throws Exception {
-        Long subjectKey = exchange.getIn().getBody(Long.class);
-        Group group = groupDAO.find(subjectKey);
+        Long anyKey = exchange.getIn().getBody(Long.class);
+        Group group = groupDAO.find(anyKey);
 
         final List<PropagationTask> tasks = new ArrayList<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index fc18e83..7a2f455 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -51,11 +51,11 @@ public class GroupUpdateProcessor implements Processor {
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
-        GroupMod subjectMod = exchange.getProperty("subjectMod", GroupMod.class);
+        GroupMod anyMod = exchange.getProperty("anyMod", GroupMod.class);
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
-                subjectMod.getVirAttrsToRemove(), subjectMod.getVirAttrsToUpdate(), excludedResources);
+                anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), excludedResources);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
index 63aa0d3..f897f90 100644
--- a/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/groupRoutes.xml
@@ -21,7 +21,7 @@ under the License.
      
   <route id="createGroup">
     <from uri="direct:createGroup"/>
-    <setProperty propertyName="subject">
+    <setProperty propertyName="any">
       <simple>${body}</simple>
     </setProperty>
     <doTry>
@@ -40,7 +40,7 @@ under the License.
                
   <route id="createGroupSync">
     <from uri="direct:createGroupInSync"/>
-    <setProperty propertyName="subject">
+    <setProperty propertyName="any">
       <simple>${body}</simple>
     </setProperty>
     <doTry>
@@ -59,7 +59,7 @@ under the License.
          
   <route id="updateGroup">
     <from uri="direct:updateGroup"/>
-    <setProperty propertyName="subjectMod">
+    <setProperty propertyName="anyMod">
       <simple>${body}</simple>
     </setProperty>
     <doTry>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAnyTransformer.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAnyTransformer.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAnyTransformer.java
new file mode 100644
index 0000000..b92d976
--- /dev/null
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAnyTransformer.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.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.core.provisioning.api.AnyTransformer;
+
+/**
+ * Class for integration tests: transform (by making it double) any attribute value for defined schema.
+ */
+public class DoubleValueAnyTransformer implements AnyTransformer {
+
+    private static final String NAME = "makeItDouble";
+
+    @Override
+    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());
+                for (String value : attr.getValues()) {
+                    try {
+                        values.add(String.valueOf(2 * Long.valueOf(value)));
+                    } catch (NumberFormatException e) {
+                        // ignore
+                    }
+                }
+                attr.getValues().clear();
+                attr.getValues().addAll(values);
+            }
+        }
+
+        return input;
+    }
+
+    @Override
+    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());
+                for (String value : attr.getValuesToBeAdded()) {
+                    try {
+                        values.add(String.valueOf(2 * Long.valueOf(value)));
+                    } catch (NumberFormatException e) {
+                        // ignore
+                    }
+                }
+                attr.getValuesToBeAdded().clear();
+                attr.getValuesToBeAdded().addAll(values);
+            }
+        }
+
+        return input;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
deleted file mode 100644
index ec5d437..0000000
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/DoubleValueAttributableTransformer.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.fit.core.reference;
-
-import java.util.ArrayList;
-import java.util.List;
-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.core.provisioning.api.AnyTransformer;
-
-/**
- * Class for integration tests: transform (by making it double) any attribute value for defined schema.
- */
-public class DoubleValueAttributableTransformer implements AnyTransformer {
-
-    private static final String NAME = "makeItDouble";
-
-    @Override
-    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());
-                for (String value : attr.getValues()) {
-                    try {
-                        values.add(String.valueOf(2 * Long.valueOf(value)));
-                    } catch (NumberFormatException e) {
-                        // ignore
-                    }
-                }
-                attr.getValues().clear();
-                attr.getValues().addAll(values);
-            }
-        }
-
-        return input;
-    }
-
-    @Override
-    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());
-                for (String value : attr.getValuesToBeAdded()) {
-                    try {
-                        values.add(String.valueOf(2 * Long.valueOf(value)));
-                    } catch (NumberFormatException e) {
-                        // ignore
-                    }
-                }
-                attr.getValuesToBeAdded().clear();
-                attr.getValuesToBeAdded().addAll(values);
-            }
-        }
-
-        return input;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 9e37c09..8974c82 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
@@ -39,12 +39,12 @@ public class TestSyncActions extends DefaultSyncActions {
 
     @Override
     public <T extends AnyTO> SyncDelta beforeProvision(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
         AttrTO attrTO = null;
-        for (int i = 0; i < subject.getPlainAttrs().size(); i++) {
-            AttrTO plainAttr = CollectionUtils.get(subject.getPlainAttrs(), i);
+        for (int i = 0; i < any.getPlainAttrs().size(); i++) {
+            AttrTO plainAttr = CollectionUtils.get(any.getPlainAttrs(), i);
             if ("fullname".equals(plainAttr.getSchema())) {
                 attrTO = plainAttr;
             }
@@ -52,7 +52,7 @@ public class TestSyncActions extends DefaultSyncActions {
         if (attrTO == null) {
             attrTO = new AttrTO();
             attrTO.setSchema("fullname");
-            subject.getPlainAttrs().add(attrTO);
+            any.getPlainAttrs().add(attrTO);
         }
         attrTO.getValues().clear();
         attrTO.getValues().add(String.valueOf(counter++));
@@ -62,10 +62,10 @@ public class TestSyncActions extends DefaultSyncActions {
 
     @Override
     public <T extends AnyTO> SyncDelta beforeAssign(
-            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject)
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T any)
             throws JobExecutionException {
 
-        if (subject instanceof UserTO && "test2".equals(UserTO.class.cast(subject).getUsername())) {
+        if (any instanceof UserTO && "test2".equals(UserTO.class.cast(any).getUsername())) {
             throw new IgnoreProvisionException();
         }
 
@@ -76,13 +76,13 @@ public class TestSyncActions extends DefaultSyncActions {
     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 {
 
-        subjectMod.getPlainAttrsToRemove().add("fullname");
+        anyMod.getPlainAttrsToRemove().add("fullname");
 
         AttrMod fullnameMod = null;
-        for (AttrMod attrMod : subjectMod.getPlainAttrsToUpdate()) {
+        for (AttrMod attrMod : anyMod.getPlainAttrsToUpdate()) {
             if ("fullname".equals(attrMod.getSchema())) {
                 fullnameMod = attrMod;
             }
@@ -90,7 +90,7 @@ public class TestSyncActions extends DefaultSyncActions {
         if (fullnameMod == null) {
             fullnameMod = new AttrMod();
             fullnameMod.setSchema("fullname");
-            subjectMod.getPlainAttrsToUpdate().add(fullnameMod);
+            anyMod.getPlainAttrsToUpdate().add(fullnameMod);
         }
 
         fullnameMod.getValuesToBeAdded().clear();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/fit/core-reference/src/main/resources/logic.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/logic.properties b/fit/core-reference/src/main/resources/logic.properties
index 2fcb844..7ff308d 100644
--- a/fit/core-reference/src/main/resources/logic.properties
+++ b/fit/core-reference/src/main/resources/logic.properties
@@ -14,5 +14,5 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-attributableTransformer=org.apache.syncope.fit.core.reference.DoubleValueAttributableTransformer
+anyTransformer=org.apache.syncope.fit.core.reference.DoubleValueAnyTransformer
 logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 019c1c8..8005b24 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
@@ -198,7 +198,7 @@ public class AuthenticationITCase extends AbstractITCase {
                 getService(UserService.class);
 
         PagedResult<UserTO> matchedUsers = userService2.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("key").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
@@ -217,7 +217,7 @@ public class AuthenticationITCase extends AbstractITCase {
         UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
 
         matchedUsers = userService3.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm("/even/two").
+                SyncopeClient.getAnySearchQueryBuilder().realm("/even/two").
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
         assertTrue(matchedUsers.getResult().isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 5fcc1e9..5d75e7c 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
@@ -660,7 +660,7 @@ public class ConnectorITCase extends AbstractITCase {
             mapItem.setExtAttrName("uid");
             mapItem.setIntAttrName("userId");
             mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
-            mapItem.setAccountid(true);
+            mapItem.setConnObjectKey(true);
             mapping.setConnObjectKeyItem(mapItem);
             // ----------------------------------------
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 281fb1a..d0a4be1 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
@@ -149,7 +149,7 @@ public class GroupITCase extends AbstractITCase {
     @Test
     public void list() {
         PagedResult<GroupTO> groupTOs =
-                groupService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
+                groupService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
         assertNotNull(groupTOs);
         assertTrue(groupTOs.getResult().size() >= 8);
         for (GroupTO groupTO : groupTOs.getResult()) {
@@ -546,14 +546,14 @@ public class GroupITCase extends AbstractITCase {
         GroupService unauthenticated = clientFactory.createAnonymous().getService(GroupService.class);
         try {
             unauthenticated.
-                    list(SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
+                    list(SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
             fail();
         } catch (AccessControlException e) {
             assertNotNull(e);
         }
 
         GroupService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(GroupService.class);
-        assertFalse(anonymous.list(SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+        assertFalse(anonymous.list(SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 build()).
                 getResult().isEmpty());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 ef525d5..1f498cc 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
@@ -291,7 +291,7 @@ public class PushTaskITCase extends AbstractTaskITCase {
             item.setIntMappingType(IntMappingType.GroupPlainSchema);
             item.setExtAttrName("cn");
             item.setIntAttrName(newPlainSchemaTO.getKey());
-            item.setAccountid(true);
+            item.setConnObjectKey(true);
             item.setPurpose(MappingPurpose.BOTH);
             rmapping.setConnObjectKeyItem(item);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 21c3e92..2e6cf21 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
@@ -86,7 +86,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setAccountid(false);
+        item.setConnObjectKey(false);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
@@ -138,7 +138,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserId);
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
@@ -146,7 +146,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setExtAttrName("fullname");
         item.setIntAttrName("cn");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setAccountid(false);
+        item.setConnObjectKey(false);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 
@@ -191,7 +191,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(item);
 
@@ -205,7 +205,7 @@ public class ResourceITCase extends AbstractITCase {
         item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.GroupId);
         item.setExtAttrName("groupId");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.SYNCHRONIZATION);
         mapping.setConnObjectKeyItem(item);
 
@@ -241,7 +241,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
@@ -277,7 +277,7 @@ public class ResourceITCase extends AbstractITCase {
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();
@@ -309,7 +309,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setExtAttrName("userId");
         item.setIntAttrName("userId");
         item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
@@ -374,7 +374,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
         item.setIntMappingType(IntMappingType.UserId);
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
@@ -599,13 +599,13 @@ public class ResourceITCase extends AbstractITCase {
         MappingItemTO item = new MappingItemTO();
         item.setIntMappingType(IntMappingType.UserId);
         item.setExtAttrName("userId");
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(item);
 
         MappingItemTO item2 = new MappingItemTO();
         item2.setIntMappingType(IntMappingType.UserPlainSchema);
-        item2.setAccountid(false);
+        item2.setConnObjectKey(false);
         item2.setIntAttrName("gender");
         item2.setExtAttrName("gender");
         item2.setPurpose(MappingPurpose.NONE);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 02ccb5e..3f1eb0a 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
@@ -45,7 +45,7 @@ public class SearchITCase extends AbstractITCase {
     public void searchUser() {
         // LIKE
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
         assertNotNull(matchedUsers);
@@ -57,7 +57,7 @@ public class SearchITCase extends AbstractITCase {
 
         // ISNULL
         matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
         assertFalse(matchedUsers.getResult().isEmpty());
@@ -75,7 +75,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchByUsernameAndKey() {
         PagedResult<UserTO> matchingUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("username").equalTo("rossini").and("key").lessThan(2).query()).build());
         assertNotNull(matchingUsers);
@@ -87,7 +87,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchByGroupNameAndKey() {
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("name").equalTo("root").and("key").lessThan(2).query()).build());
         assertNotNull(matchingGroups);
@@ -99,7 +99,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchByGroup() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(1L).query()).
                 build());
         assertNotNull(matchedUsers);
@@ -122,7 +122,7 @@ public class SearchITCase extends AbstractITCase {
         assertNotNull(group);
 
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
                 build());
         assertNotNull(matchedUsers);
@@ -140,7 +140,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchByRole() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(3L).query()).
                 build());
         assertNotNull(matchedUsers);
@@ -164,7 +164,7 @@ public class SearchITCase extends AbstractITCase {
         assertNotNull(role);
 
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
                 build());
         assertNotNull(matchedUsers);
@@ -182,7 +182,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchUserByResourceName() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
                 build());
         assertNotNull(matchedUsers);
@@ -201,7 +201,7 @@ public class SearchITCase extends AbstractITCase {
     public void paginatedSearch() {
         // LIKE
         PagedResult<UserTO> matchingUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).page(1).size(2).build());
         assertNotNull(matchingUsers);
@@ -213,7 +213,7 @@ public class SearchITCase extends AbstractITCase {
 
         // ISNULL
         matchingUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).page(2).size(2).
                 build());
         assertNotNull(matchingUsers);
@@ -222,18 +222,18 @@ public class SearchITCase extends AbstractITCase {
     }
 
     @Test
-    public void searchByBooleanSubjectCond() {
+    public void searchByBooleanAnyCond() {
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("show").equalTo("true").query()).build());
         assertNotNull(matchingGroups);
         assertFalse(matchingGroups.getResult().isEmpty());
     }
 
     @Test
-    public void searchByRelationshipSubjectCond() {
+    public void searchByRelationshipAnyCond() {
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("userOwner").equalTo(5).query()).build());
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
@@ -243,7 +243,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void nested() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
         assertNotNull(matchedUsers);
 
@@ -256,7 +256,7 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void orderBy() {
         PagedResult<UserTO> matchedUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
                 orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
         assertNotNull(matchedUsers);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 868deee..479c96f 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
@@ -156,7 +156,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         // -----------------------------
         try {
             int usersPre = userService.list(
-                    SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                    SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                     page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPre);
 
@@ -212,7 +212,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
             // check for sync results
             int usersPost = userService.list(
-                    SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                    SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                     page(1).size(1).build()).getTotalCount();
             assertNotNull(usersPost);
             assertEquals(usersPre + 8, usersPost);
@@ -282,7 +282,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
      */
     private void ldapCleanup() {
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
                 build());
         if (matchingGroups.getSize() > 0) {
@@ -294,7 +294,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             }
         }
         PagedResult<UserTO> matchingUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
                 build());
         if (matchingUsers.getSize() > 0) {
@@ -322,14 +322,14 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         // 2. verify that synchronized group is found, with expected attributes
         PagedResult<GroupTO> matchingGroups = groupService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getGroupSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query()).
                 build());
         assertNotNull(matchingGroups);
         assertEquals(1, matchingGroups.getResult().size());
 
         PagedResult<UserTO> matchingUsers = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query()).
                 build());
         assertNotNull(matchingUsers);
@@ -352,7 +352,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         // 3. verify that LDAP group membership is propagated as Syncope group membership
         PagedResult<UserTO> members = userService.search(
-                SyncopeClient.getSubjectSearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(groupTO.getKey()).query()).build());
         assertNotNull(members);
         assertEquals(1, members.getResult().size());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 9c67d13..107c953 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
@@ -531,7 +531,7 @@ public class UserITCase extends AbstractITCase {
     @Test
     public void list() {
         PagedResult<UserTO> users = userService.list(
-                SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
+                SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
         assertNotNull(users);
         assertFalse(users.getResult().isEmpty());
 
@@ -543,7 +543,7 @@ public class UserITCase extends AbstractITCase {
     @Test
     public void paginatedList() {
         PagedResult<UserTO> users = userService.list(
-                SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
+                SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
         assertNotNull(users);
         assertFalse(users.getResult().isEmpty());
         assertEquals(2, users.getResult().size());
@@ -552,13 +552,13 @@ public class UserITCase extends AbstractITCase {
             assertNotNull(user);
         }
 
-        users = userService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+        users = userService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 page(2).size(2).build());
         assertNotNull(users);
         assertEquals(2, users.getPage());
         assertEquals(2, users.getResult().size());
 
-        users = userService.list(SyncopeClient.getSubjectListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+        users = userService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 page(100).size(2).build());
         assertNotNull(users);
         assertTrue(users.getResult().isEmpty());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 e161258..a373df5 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
@@ -465,7 +465,7 @@ public class VirAttrITCase extends AbstractITCase {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setExtAttrName(groupName);
         item.setPurpose(MappingPurpose.PROPAGATION);
-        item.setAccountid(true);
+        item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
 
         item = new MappingItemTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/src/site/xdoc/security.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/security.xml b/src/site/xdoc/security.xml
index fc5619e..436c083 100644
--- a/src/site/xdoc/security.xml
+++ b/src/site/xdoc/security.xml
@@ -63,7 +63,7 @@ under the License.
 
       <subsection name="CVE-2014-0111: Remote code execution by an authenticated administrator">	
         <p>In the various places in which Apache Commons JEXL expressions are allowed (derived schema definition, 
-          user / group templates, account links of resource mappings) a malicious administrator can inject Java code 
+          user / group templates, connObjectLinks of resource mappings) a malicious administrator can inject Java code 
           that can be executed remotely by the JEE container running the Apache Syncope core.</p>
 
         <p>


[33/70] syncope git commit: [SYNCOPE-666] Several JPA tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 4767422..c9b551a 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
@@ -34,12 +34,17 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 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.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 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.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 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.Group;
@@ -47,6 +52,7 @@ 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.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -59,6 +65,12 @@ public class GroupTest extends AbstractTest {
     private EntityManager entityManager;
 
     @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -137,7 +149,7 @@ public class GroupTest extends AbstractTest {
     }
 
     @Test
-    public void dynMembership() {
+    public void udynMembership() {
         // 0. create user matching the condition below
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
@@ -215,4 +227,97 @@ public class GroupTest extends AbstractTest {
         assertTrue(dynGroupMemberships.isEmpty());
     }
 
+    /**
+     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO} method with same signature:
+     * required for avoiding creating of a new transaction - good for general use case but bad for the way how
+     * this test class is architected.
+     */
+    private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
+                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void adynMembership() {
+        // 0. create any object matching the condition below
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setType(anyTypeDAO.find("OTHER"));
+        anyObject.setRealm(realmDAO.find("/even/two"));
+
+        APlainAttr attribute = entityFactory.newEntity(APlainAttr.class);
+        attribute.setSchema(plainSchemaDAO.find("cool"));
+        attribute.setOwner(anyObject);
+        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        anyObject.add(attribute);
+
+        anyObject = anyObjectDAO.save(anyObject);
+        Long newAnyObjectKey = anyObject.getKey();
+        assertNotNull(newAnyObjectKey);
+
+        // 1. create group with dynamic membership
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
+        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setGroup(group);
+
+        group.setADynMembership(dynMembership);
+
+        Group actual = groupDAO.save(group);
+        assertNotNull(actual);
+
+        groupDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = groupDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getADynMembership());
+        assertNotNull(actual.getADynMembership().getKey());
+        assertEquals(actual, actual.getADynMembership().getGroup());
+
+        // 3. verify that expected any objects have the created group dynamically assigned
+        assertEquals(2, actual.getADynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(2L, newAnyObjectKey)),
+                CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() {
+
+                    @Override
+                    public Long transform(final AnyObject input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        anyObject = anyObjectDAO.find(2L);
+        assertNotNull(anyObject);
+        Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject);
+        assertEquals(1, dynGroupMemberships.size());
+        assertTrue(dynGroupMemberships.contains(actual.getADynMembership().getGroup()));
+
+        // 4. delete the new any object and verify that dynamic membership was updated
+        anyObjectDAO.delete(newAnyObjectKey);
+
+        anyObjectDAO.flush();
+
+        actual = groupDAO.find(actual.getKey());
+        assertEquals(1, actual.getADynMembership().getMembers().size());
+        assertEquals(2L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
+
+        // 5. delete group and verify that dynamic membership was also removed
+        Long dynMembershipKey = actual.getADynMembership().getKey();
+
+        groupDAO.delete(actual);
+
+        groupDAO.flush();
+
+        assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey));
+
+        dynGroupMemberships = findDynGroupMemberships(anyObject);
+        assertTrue(dynGroupMemberships.isEmpty());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 f038917..5a12044 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
@@ -18,11 +18,14 @@
  */
 package org.apache.syncope.core.persistence.jpa.relationship;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 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;
@@ -31,6 +34,8 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 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.URelationship;
+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;
@@ -40,6 +45,9 @@ import org.springframework.transaction.annotation.Transactional;
 public class UserTest extends AbstractTest {
 
     @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
     private UserDAO userDAO;
 
     @Autowired
@@ -55,7 +63,12 @@ public class UserTest extends AbstractTest {
     private PlainAttrValueDAO plainAttrValueDAO;
 
     @Test
-    public void test() {
+    public void delete() {
+        List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L));
+        assertFalse(memberships.isEmpty());
+        List<URelationship> relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
+        assertFalse(relationships.isEmpty());
+
         userDAO.delete(4L);
 
         userDAO.flush();
@@ -65,7 +78,49 @@ public class UserTest extends AbstractTest {
         assertNull(plainAttrValueDAO.find(22L, UPlainAttrValue.class));
         assertNotNull(plainSchemaDAO.find("loginDate"));
 
-        List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L));
+        memberships = groupDAO.findUMemberships(groupDAO.find(7L));
         assertTrue(memberships.isEmpty());
+        relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
+        assertTrue(relationships.isEmpty());
+    }
+
+    @Test
+    public void ships() {
+        User user = userDAO.find(4L);
+        assertNotNull(user);
+        assertEquals(1, user.getMemberships().size());
+        assertEquals(7L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
+
+        user.remove(user.getMemberships().get(0));
+
+        UMembership newM = entityFactory.newEntity(UMembership.class);
+        newM.setLeftEnd(user);
+        newM.setRightEnd(groupDAO.find(13L));
+        user.add(newM);
+
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+        assertEquals(1, user.getMemberships().size());
+        assertEquals(13L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
+        assertEquals(1, user.getRelationships().size());
+        assertEquals(1L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
+
+        user.remove(user.getRelationships().get(0));
+
+        URelationship newR = entityFactory.newEntity(URelationship.class);
+        newR.setLeftEnd(user);
+        newR.setRightEnd(anyObjectDAO.find(2L));
+        user.add(newR);
+
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+        assertEquals(1, user.getRelationships().size());
+        assertEquals(2L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 fa63e84..8d2ef54 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -112,10 +112,24 @@ under the License.
   <Policy DTYPE="SyncPolicy" id="9" description="sync policy for java rule" type="SYNC" 
           specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"groupAltSearchSchemas":[]}'/>
 
+  <AnyTypeClass name="generic membership"/>
+
   <AnyType name="USER" kind="USER"/>
+  <AnyTypeClass name="minimal user"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="minimal user"/>
+  <AnyTypeClass name="other"/>
+  <AnyType_AnyTypeClass anyType_name="USER" anyTypeClass_name="other"/>
+
   <AnyType name="GROUP" kind="GROUP"/>
+  <AnyTypeClass name="minimal group"/>
+  <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
+  
   <AnyType name="OTHER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal other"/>
+  <AnyType_AnyTypeClass anyType_name="OTHER" anyTypeClass_name="minimal other"/>
       
+  <AnyTypeClass name="csv"/>
+
   <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"/>
@@ -229,14 +243,18 @@ under the License.
                 realm_id="1"
                 creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="12" anyTypeClass_name="csv"/>  
   <SyncopeGroup id="13" name="bGroupForPropagation"
                 realm_id="1"
                 creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  <SyncopeGroup_AnyTypeClass group_id="13" anyTypeClass_name="csv"/>  
   <SyncopeGroup id="14" name="artDirector"
                 realm_id="1"
                 creator="admin" lastModifier="admin" 
                 creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+  
+  <URelationship id="1" user_id="4" anyObject_id="1"/>
 
   <UMembership id="1" user_id="1" group_id="1"/>
   <UMembership id="2" user_id="2" group_id="1"/>
@@ -246,84 +264,90 @@ under the License.
   <UMembership id="6" user_id="2" group_id="3"/>
   <UMembership id="7" user_id="5" group_id="14"/>
 
-  <PlainSchema name="fullname" type="String"
+  <PlainSchema name="fullname" type="String" anyTypeClass_name="minimal user"
                mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"/>
-  <PlainSchema name="userId" type="String"
+  <PlainSchema name="userId" type="String" anyTypeClass_name="minimal user"
                mandatoryCondition="true" multivalue="0" uniqueConstraint="1" readonly="0"
                validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="loginDate" type="Date"
+  <PlainSchema name="loginDate" type="Date" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"
                conversionPattern="yyyy-MM-dd"/>
-  <PlainSchema name="firstname" type="String"
+  <PlainSchema name="firstname" type="String" anyTypeClass_name="minimal user"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="surname" type="String"
+  <PlainSchema name="surname" type="String" anyTypeClass_name="minimal user"
                mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="type" type="String"
+  <PlainSchema name="type" type="String" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="email" type="String"
+  <PlainSchema name="email" type="String" anyTypeClass_name="minimal user"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                validatorClass="org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
-  <PlainSchema name="activationDate" type="Date"
+  <PlainSchema name="activationDate" type="Date" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="uselessReadonly" type="String"
+  <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <PlainSchema name="cool" type="Boolean"
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="minimal other" 
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="gender" type="Enum"
+  <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                enumerationValues="M;F"/>
-  <PlainSchema name="aLong" type="Long"
+  <PlainSchema name="aLong" type="Long" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="makeItDouble" type="Long"
+  <PlainSchema name="makeItDouble" type="Long" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="obscure" type="Encrypted"
+  <PlainSchema name="obscure" type="Encrypted" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
-  <PlainSchema name="photo" type="Binary"
+  <PlainSchema name="photo" type="Binary" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                mimeType="image/jpeg"/>
 
-  <DerSchema name="csvuserid" expression="firstname + ',' + surname"/>
-  <DerSchema name="cn" expression="surname + ', ' + firstname"/>
-  <DerSchema name="noschema" expression="surname + ', ' + notfound"/>
+  <DerSchema name="csvuserid" expression="firstname + ',' + surname" anyTypeClass_name="csv"/>
+  <DerSchema name="cn" expression="surname + ', ' + firstname" anyTypeClass_name="minimal user"/>
+  <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
 
-  <VirSchema name="virtualdata"/>
+  <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
 
-  <PlainSchema name="icon" type="String"
+  <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
-  <PlainSchema name="show" type="Boolean"
+  <PlainSchema name="show" type="Boolean" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_sx" type="String"
+  <PlainSchema name="rderived_sx" type="String" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="rderived_dx" type="String"
+  <PlainSchema name="rderived_dx" type="String" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>           
-  <PlainSchema name="title" type="String"
+  <PlainSchema name="title" type="String" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
 
-  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"/>
-  <DerSchema name="displayProperty" expression="icon + ': ' + show"/>
-  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"/>
+  <DerSchema name="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="displayProperty" expression="icon + ': ' + show"
+             anyTypeClass_name="minimal group"/>
+  <DerSchema name="rderToBePropagated" expression="rderived_sx + '-' + rderived_dx"
+             anyTypeClass_name="minimal group"/>
 
-  <VirSchema name="rvirtualdata"/>
+  <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
 
-  <!-- rderiveddata is used to verify der schema deletion -->
   <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/>
 
-  <PlainSchema name="subscriptionDate" type="Date"
+  <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
-  <PlainSchema name="mderived_sx" type="String"
+  <PlainSchema name="mderived_sx" type="String" anyTypeClass_name="generic membership"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
-  <PlainSchema name="mderived_dx" type="String"
+  <PlainSchema name="mderived_dx" type="String" anyTypeClass_name="generic membership"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>          
-  <PlainSchema name="postalAddress" type="String"
+  <PlainSchema name="postalAddress" type="String" anyTypeClass_name="generic membership"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
 
   <DerSchema name="mderiveddata" expression="mderived_sx + '-' + mderived_dx"/>
-  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx"/>
+  <DerSchema name="mderToBePropagated" expression="mderived_sx + '-' + mderived_dx" 
+             anyTypeClass_name="generic membership"/>
 
   <VirSchema name="mvirtualdata"/>
+        
+  <APlainAttr id="1" owner_id="2" schema_name="cool"/>
+  <APlainAttrValue id="1" attribute_id="1" booleanValue="1"/>
   
   <UPlainAttr id="99" owner_id="1" schema_name="type"/>
   <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
@@ -1035,13 +1059,13 @@ under the License.
 
   <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"/> 
+                traceLevel="FAILURES"/> 
   <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" 
                 sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
-                traceLevel="FAILURES" userAbout="token!=$null"/> 
+                traceLevel="FAILURES"/> 
   <Notification_events Notification_id="2" event="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
 
   <Notification id="10" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" 


[02/70] 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",


[16/70] 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");
-    }
-
 }


[14/70] 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);
     }


[51/70] syncope git commit: [SYNCOPE-666] Tests working as application/xml as well

Posted by il...@apache.org.
[SYNCOPE-666] Tests working as application/xml as well


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

Branch: refs/heads/master
Commit: 64d475e528edf8c9cbd2d9959a07a9124c23431a
Parents: 54de398
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 13:18:46 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 13:18:46 2015 +0200

----------------------------------------------------------------------
 .../console/rest/ConnectorRestClient.java       |  4 +--
 .../client/console/rest/GroupRestClient.java    | 14 ++++-----
 .../client/console/rest/UserRestClient.java     | 23 +++++++--------
 client/lib/pom.xml                              |  6 +++-
 .../common/lib/mod/ResourceAssociationMod.java  |  6 ++--
 .../syncope/common/lib/to/BulkActionResult.java |  2 ++
 .../syncope/common/lib/to/NotificationTO.java   |  3 --
 .../apache/syncope/common/lib/wrap/AnyKey.java  |  5 ++++
 .../syncope/common/lib/wrap/BooleanWrap.java    | 30 ++++++++++++++++++++
 .../syncope/common/lib/wrap/ResourceKey.java    | 30 ++++++++++++++++++++
 .../syncope/common/lib/wrap/ResourceName.java   | 30 --------------------
 .../common/rest/api/CollectionWrapper.java      |  6 ++--
 .../rest/api/service/ConnectorService.java      |  3 +-
 .../common/rest/api/service/GroupService.java   |  6 ++--
 .../rest/api/service/ResourceService.java       |  4 ++-
 .../common/rest/api/service/UserService.java    |  4 +--
 .../rest/cxf/service/ConnectorServiceImpl.java  |  7 +++--
 .../core/rest/cxf/service/GroupServiceImpl.java | 10 +++----
 .../rest/cxf/service/ResourceServiceImpl.java   |  7 +++--
 .../core/rest/cxf/service/UserServiceImpl.java  |  8 +++---
 .../core/reference/AuthenticationITCase.java    |  4 +--
 .../fit/core/reference/ConnectorITCase.java     | 12 ++++----
 .../syncope/fit/core/reference/GroupITCase.java | 18 ++++++------
 .../fit/core/reference/SyncTaskITCase.java      |  6 ++--
 .../syncope/fit/core/reference/UserITCase.java  | 18 ++++++------
 pom.xml                                         |  5 ++++
 26 files changed, 160 insertions(+), 111 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index e6f8488..70ef70e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -159,7 +159,7 @@ public class ConnectorRestClient extends BaseRestClient {
 
         boolean check = false;
         try {
-            check = getService(ConnectorService.class).check(toBeChecked);
+            check = getService(ConnectorService.class).check(toBeChecked).getElement();
         } catch (Exception e) {
             LOG.error("While checking {}", toBeChecked, e);
         }
@@ -170,7 +170,7 @@ public class ConnectorRestClient extends BaseRestClient {
     public boolean check(final ResourceTO resourceTO) {
         boolean check = false;
         try {
-            check = getService(ResourceService.class).check(resourceTO);
+            check = getService(ResourceService.class).check(resourceTO).getElement();
         } catch (Exception e) {
             LOG.error("Connector not found {}", resourceTO.getConnector(), e);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 073e7c3..ef490e2 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
@@ -32,7 +32,7 @@ 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.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.GroupService;
@@ -124,7 +124,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+                            ResourceKey.class));
             resetClient(GroupService.class);
         }
     }
@@ -134,7 +134,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             service.bulkAssociation(groupId, ResourceAssociationActionType.LINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+                            ResourceKey.class));
             resetClient(GroupService.class);
         }
     }
@@ -145,7 +145,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
@@ -158,7 +158,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             result = service.bulkAssociation(groupId, ResourceAssociationActionType.PROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
@@ -171,7 +171,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
@@ -184,7 +184,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             GroupService service = getService(etag, GroupService.class);
             result = service.bulkAssociation(groupId, ResourceAssociationActionType.ASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 45272c3..b2fb4e3 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
@@ -34,7 +34,7 @@ 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.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.common.rest.api.service.UserService;
@@ -152,7 +152,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
             service.bulkDeassociation(userId, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+                            ResourceKey.class));
             resetClient(UserService.class);
         }
     }
@@ -162,9 +162,8 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+                            ResourceKey.class));
             service.bulkAssociation(userId, ResourceAssociationActionType.LINK, associationMod);
 
             resetClient(UserService.class);
@@ -177,7 +176,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
             result = service.bulkDeassociation(userId, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
@@ -192,9 +191,8 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+                            ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
@@ -211,7 +209,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
             result = service.bulkDeassociation(userId, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class)).
+                            ResourceKey.class)).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
@@ -226,9 +224,8 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceName.class));
+            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
+                            ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/client/lib/pom.xml
----------------------------------------------------------------------
diff --git a/client/lib/pom.xml b/client/lib/pom.xml
index 3de5d20..a119827 100644
--- a/client/lib/pom.xml
+++ b/client/lib/pom.xml
@@ -47,7 +47,11 @@ under the License.
       <groupId>org.apache.cxf</groupId>
       <artifactId>cxf-rt-rs-client</artifactId>
     </dependency>
-
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-databinding-jaxb</artifactId>
+    </dependency>
+    
     <dependency>
       <groupId>com.fasterxml.jackson.jaxrs</groupId>
       <artifactId>jackson-jaxrs-json-provider</artifactId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
index f381104..f894c26 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
@@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 
 /**
  * This class is used to specify the willing to create associations between user and external references.
@@ -43,7 +43,7 @@ public class ResourceAssociationMod extends AbstractBaseBean {
     /**
      * Target external resources.
      */
-    private final List<ResourceName> targetResources = new ArrayList<ResourceName>();
+    private final List<ResourceKey> targetResources = new ArrayList<ResourceKey>();
 
     /**
      * Indicate the willing to change password on target external resources.
@@ -58,7 +58,7 @@ public class ResourceAssociationMod extends AbstractBaseBean {
     @XmlElementWrapper(name = "resources")
     @XmlElement(name = "resource")
     @JsonProperty("resources")
-    public List<ResourceName> getTargetResources() {
+    public List<ResourceKey> getTargetResources() {
         return targetResources;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
index 9b44b3f..03710ce 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
@@ -29,6 +29,7 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.AbstractBaseBean;
@@ -37,6 +38,7 @@ import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 @XmlRootElement(name = "bulkActionResult")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
+@XmlSeeAlso(BulkActionResult.Status.class)
 public class BulkActionResult extends AbstractBaseBean {
 
     private static final long serialVersionUID = 2868894178821778133L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 7cb6556..5487410 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
@@ -24,8 +24,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -38,7 +36,6 @@ import org.apache.syncope.common.lib.types.TraceLevel;
 
 @XmlRootElement(name = "notification")
 @XmlType
-@XmlAccessorType(XmlAccessType.FIELD)
 public class NotificationTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = -6145117115632592612L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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
index 6db8870..0eb6eef 100644
--- 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
@@ -18,6 +18,11 @@
  */
 package org.apache.syncope.common.lib.wrap;
 
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "anyKey")
+@XmlType
 public class AnyKey extends AbstractWrappable<Long> {
 
     private static final long serialVersionUID = -8664228651057889297L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/BooleanWrap.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/BooleanWrap.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/BooleanWrap.java
new file mode 100644
index 0000000..3be7643
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/BooleanWrap.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.wrap;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "booleanWrap")
+@XmlType
+public class BooleanWrap extends AbstractWrappable<Boolean> {
+
+    private static final long serialVersionUID = 3762310846902669241L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ResourceKey.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ResourceKey.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ResourceKey.java
new file mode 100644
index 0000000..1b06c5b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ResourceKey.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.wrap;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "resourceKey")
+@XmlType
+public class ResourceKey extends AbstractWrappable<String> {
+
+    private static final long serialVersionUID = -175720097924079573L;
+
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
index e493f94..94bf21f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
@@ -40,7 +40,7 @@ public final class CollectionWrapper {
     public static <E, T extends AbstractWrappable<E>> List<T> wrap(
             final Collection<E> collection, final Class<T> reference) {
 
-        List<T> response = new ArrayList<T>();
+        List<T> response = new ArrayList<>();
         for (E element : collection) {
             response.add(AbstractWrappable.getInstance(reference, element));
         }
@@ -48,7 +48,7 @@ public final class CollectionWrapper {
     }
 
     public static <T extends AbstractWrappable<String>> List<String> unwrap(final Collection<T> collection) {
-        List<String> response = new ArrayList<String>();
+        List<String> response = new ArrayList<>();
         for (T item : collection) {
             response.add(item.getElement());
         }
@@ -56,7 +56,7 @@ public final class CollectionWrapper {
     }
 
     public static List<AuditLoggerName> wrapLogger(final Collection<LoggerTO> logger) {
-        List<AuditLoggerName> respons = new ArrayList<AuditLoggerName>();
+        List<AuditLoggerName> respons = new ArrayList<>();
         for (LoggerTO l : logger) {
             try {
                 respons.add(AuditLoggerName.fromLoggerName(l.getKey()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index ede49be..c4de80a 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -42,6 +42,7 @@ import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.wrap.BooleanWrap;
 
 /**
  * REST operations for connector bundles and instances.
@@ -178,7 +179,7 @@ public interface ConnectorService extends JAXRSService {
     @Path("check")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    boolean check(@NotNull ConnInstanceTO connInstanceTO);
+    BooleanWrap check(@NotNull ConnInstanceTO connInstanceTO);
 
     /**
      * Reload all connector bundles and instances.

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 635be02..001d71c 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
@@ -40,7 +40,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 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.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
 import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
@@ -172,7 +172,7 @@ public interface GroupService extends JAXRSService {
     Response bulkDeassociation(
             @NotNull @PathParam("groupKey") Long groupKey,
             @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceName> resourceNames);
+            @NotNull List<ResourceKey> resourceNames);
 
     /**
      * Executes resource-related operations on given group.
@@ -193,7 +193,7 @@ public interface GroupService extends JAXRSService {
     Response bulkAssociation(
             @NotNull @PathParam("groupKey") Long groupKey,
             @NotNull @PathParam("type") ResourceAssociationActionType type,
-            @NotNull List<ResourceName> resourceNames);
+            @NotNull List<ResourceKey> resourceNames);
 
     /**
      * Executes the provided bulk action.

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 4656dce..41204a0 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
@@ -39,6 +39,7 @@ 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.wrap.AnyKey;
+import org.apache.syncope.common.lib.wrap.BooleanWrap;
 
 /**
  * REST operations for external resources.
@@ -123,8 +124,9 @@ public interface ResourceService extends JAXRSService {
      */
     @POST
     @Path("check")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    boolean check(@NotNull ResourceTO resourceTO);
+    BooleanWrap check(@NotNull ResourceTO resourceTO);
 
     /**
      * De-associate any objects from the given resource.

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 8f9363cb..4866f95 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
@@ -45,7 +45,7 @@ import org.apache.syncope.common.lib.to.PagedResult;
 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.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
 import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
@@ -209,7 +209,7 @@ public interface UserService extends JAXRSService {
     Response bulkDeassociation(
             @NotNull @PathParam("userKey") Long userKey,
             @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceName> resourceNames);
+            @NotNull List<ResourceKey> resourceNames);
 
     /**
      * Executes resource-related operations on given user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index ac26aad..bd24f22 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -31,6 +31,7 @@ import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.wrap.BooleanWrap;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.core.logic.ConnectorLogic;
@@ -121,8 +122,10 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public boolean check(final ConnInstanceTO connInstanceTO) {
-        return logic.check(connInstanceTO);
+    public BooleanWrap check(final ConnInstanceTO connInstanceTO) {
+        BooleanWrap result = new BooleanWrap();
+        result.setElement(logic.check(connInstanceTO));
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 5c640f0..98a23a6 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
@@ -32,7 +32,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 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.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
 import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
@@ -131,7 +131,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
 
     @Override
     public Response bulkDeassociation(
-            final Long groupKey, final ResourceDeassociationActionType type, final List<ResourceName> resourceNames) {
+            final Long groupKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
 
         GroupTO group = logic.read(groupKey);
 
@@ -158,7 +158,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceName resourceName : resourceNames) {
+            for (ResourceKey resourceName : resourceNames) {
                 result.getResults().put(resourceName.getElement(),
                         updated.getResources().contains(resourceName.getElement())
                                 ? BulkActionResult.Status.FAILURE
@@ -176,7 +176,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
 
     @Override
     public Response bulkAssociation(
-            final Long groupKey, final ResourceAssociationActionType type, final List<ResourceName> resourceNames) {
+            final Long groupKey, final ResourceAssociationActionType type, final List<ResourceKey> resourceNames) {
 
         GroupTO group = logic.read(groupKey);
 
@@ -203,7 +203,7 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceName resourceName : resourceNames) {
+            for (ResourceKey resourceName : resourceNames) {
                 result.getResults().put(resourceName.getElement(),
                         updated.getResources().contains(resourceName.getElement())
                                 ? BulkActionResult.Status.FAILURE

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 48d6445..b6c3f50 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
@@ -31,6 +31,7 @@ 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.wrap.AnyKey;
+import org.apache.syncope.common.lib.wrap.BooleanWrap;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.apache.syncope.core.logic.AbstractResourceAssociator;
@@ -92,8 +93,10 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public boolean check(final ResourceTO resourceTO) {
-        return logic.check(resourceTO);
+    public BooleanWrap check(final ResourceTO resourceTO) {
+        BooleanWrap result = new BooleanWrap();
+        result.setElement(logic.check(resourceTO));
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 9ea1279..192b4e0 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
@@ -35,7 +35,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
 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.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.AnyListQuery;
@@ -155,7 +155,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
 
     @Override
     public Response bulkDeassociation(
-            final Long userKey, final ResourceDeassociationActionType type, final List<ResourceName> resourceNames) {
+            final Long userKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
 
         final UserTO user = logic.read(userKey);
 
@@ -182,7 +182,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
         BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceName resourceName : resourceNames) {
+            for (ResourceKey resourceName : resourceNames) {
                 result.getResults().put(
                         resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
                                 ? BulkActionResult.Status.FAILURE
@@ -237,7 +237,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
         BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceName resourceName : associationMod.getTargetResources()) {
+            for (ResourceKey resourceName : associationMod.getTargetResources()) {
                 result.getResults().put(resourceName.getElement(),
                         updated.getResources().contains(resourceName.getElement())
                                 ? BulkActionResult.Status.FAILURE

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 6ea8cb0..5102e9b 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
@@ -52,7 +52,7 @@ import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.types.SchemaType;
-import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.apache.syncope.common.rest.api.service.UserService;
@@ -354,7 +354,7 @@ public class AuthenticationITCase extends AbstractITCase {
         // 2. unlink the resource from the created user
         assertNotNull(userService.bulkDeassociation(user.getKey(),
                 ResourceDeassociationActionType.UNLINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         // 3. change password on Syncope

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 2cd33a5..1136f02 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
@@ -449,7 +449,7 @@ public class ConnectorITCase extends AbstractITCase {
         connectorTO.setDisplayName("H2Test");
 
         // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+        Set<ConnConfProperty> conf = new HashSet<>();
 
         ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
         jdbcDriverSchema.setName("jdbcDriver");
@@ -517,14 +517,14 @@ public class ConnectorITCase extends AbstractITCase {
         // set connector configuration
         connectorTO.getConfiguration().addAll(conf);
 
-        assertTrue(connectorService.check(connectorTO));
+        assertTrue(connectorService.check(connectorTO).getElement());
 
         conf.remove(password);
         password.getValues().clear();
         password.getValues().add("password");
         conf.add(password);
 
-        assertFalse(connectorService.check(connectorTO));
+        assertFalse(connectorService.check(connectorTO).getElement());
     }
 
     @Test
@@ -594,7 +594,7 @@ public class ConnectorITCase extends AbstractITCase {
         connectorTO.setDisplayName("WSSoap");
 
         // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+        Set<ConnConfProperty> conf = new HashSet<>();
 
         ConnConfPropSchema userSchema = new ConnConfPropSchema();
         userSchema.setName("endpoint");
@@ -621,7 +621,7 @@ public class ConnectorITCase extends AbstractITCase {
         connectorTO.getConfiguration().addAll(conf);
 
         try {
-            assertFalse(connectorService.check(connectorTO));
+            assertFalse(connectorService.check(connectorTO).getElement());
 
             Response response = connectorService.create(connectorTO);
             if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
@@ -667,7 +667,7 @@ public class ConnectorITCase extends AbstractITCase {
             // ----------------------------------------
             // Check connection without saving the resource ....
             // ----------------------------------------
-            assertTrue(resourceService.check(resourceTO));
+            assertTrue(resourceService.check(resourceTO).getElement());
             // ----------------------------------------
         } finally {
             // Remove connector from db to make test re-runnable

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 6cf1313..017f802 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
@@ -62,7 +62,7 @@ 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.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -326,7 +326,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -353,7 +353,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
                 ResourceAssociationActionType.LINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -376,7 +376,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -408,7 +408,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
                 ResourceAssociationActionType.ASSIGN,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -426,7 +426,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -458,7 +458,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
                 ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -484,7 +484,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
                 ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap("resource-ldap", ResourceName.class)).
+                CollectionWrapper.wrap("resource-ldap", ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -494,7 +494,7 @@ public class GroupITCase extends AbstractITCase {
 
         assertNotNull(groupService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 1d809ea..ee02b26 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
@@ -55,7 +55,7 @@ import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
 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.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.service.TaskService;
 import org.apache.syncope.core.misc.security.Encryptor;
@@ -290,7 +290,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             for (GroupTO group : matchingGroups.getResult()) {
                 groupService.bulkDeassociation(group.getKey(),
                         ResourceDeassociationActionType.UNLINK,
-                        CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+                        CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 groupService.delete(group.getKey());
             }
         }
@@ -302,7 +302,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
             for (UserTO user : matchingUsers.getResult()) {
                 userService.bulkDeassociation(user.getKey(),
                         ResourceDeassociationActionType.UNLINK,
-                        CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+                        CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
                 userService.delete(user.getKey());
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/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 4574b5b..c0ab43d 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
@@ -73,7 +73,7 @@ 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.TaskType;
-import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
 import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -1766,7 +1766,7 @@ public class UserITCase extends AbstractITCase {
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNLINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
@@ -1798,7 +1798,7 @@ public class UserITCase extends AbstractITCase {
         }
 
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
 
         assertNotNull(userService.bulkAssociation(
                 actual.getKey(), ResourceAssociationActionType.LINK, associationMod).readEntity(BulkActionResult.class));
@@ -1832,7 +1832,7 @@ public class UserITCase extends AbstractITCase {
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.UNASSIGN,
-                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
@@ -1869,7 +1869,7 @@ public class UserITCase extends AbstractITCase {
         }
 
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
@@ -1899,7 +1899,7 @@ public class UserITCase extends AbstractITCase {
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());
@@ -1936,7 +1936,7 @@ public class UserITCase extends AbstractITCase {
         }
 
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
@@ -1972,7 +1972,7 @@ public class UserITCase extends AbstractITCase {
         }
 
         final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
         associationMod.setChangePwd(true);
         associationMod.setPassword("password");
 
@@ -1987,7 +1987,7 @@ public class UserITCase extends AbstractITCase {
 
         assertNotNull(userService.bulkDeassociation(actual.getKey(),
                 ResourceDeassociationActionType.DEPROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+                CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
                 readEntity(BulkActionResult.class));
 
         actual = userService.read(actual.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/64d475e5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f094962..fae9f6e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -493,6 +493,11 @@ under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-rt-databinding-jaxb</artifactId>
+        <version>${cxf.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.cxf</groupId>
         <artifactId>cxf-rt-rs-client</artifactId>
         <version>${cxf.version}</version>
       </dependency>      


[19/70] 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/70] 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());
         }


[30/70] syncope git commit: Merge branch 'master' into SYNCOPE-666

Posted by il...@apache.org.
Merge branch 'master' into SYNCOPE-666


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

Branch: refs/heads/master
Commit: a5408c5e12ed77f0545fa33ac957d04bdb8d96e3
Parents: 081d9a0 55d846e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue May 26 07:42:02 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue May 26 07:42:02 2015 +0200

----------------------------------------------------------------------
 .../apache/syncope/client/console/panels/AbstractSearchPanel.java   | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------



[66/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
new file mode 100644
index 0000000..5385600
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+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.TaskExecDAO;
+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.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskExecTest extends AbstractTest {
+
+    @Autowired
+    private TaskExecDAO taskExecDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Test
+    public void findAll() {
+        List<TaskExec> list = taskExecDAO.findAll(TaskType.PROPAGATION);
+        assertEquals(2, list.size());
+
+        list = taskExecDAO.findAll(TaskType.SCHEDULED);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.SYNCHRONIZATION);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.NOTIFICATION);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void findLatestStarted() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        TaskExec latestStarted = taskExecDAO.findLatestStarted(task);
+        assertNotNull(latestStarted);
+        assertEquals(Long.valueOf(1L), latestStarted.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE214() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        String faultyMessage = "A faulty message";
+        faultyMessage = faultyMessage.replace('a', '\0');
+
+        TaskExec exec = entityFactory.newEntity(TaskExec.class);
+        exec.setStartDate(new Date());
+        exec.setEndDate(new Date());
+        exec.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+        exec.setMessage(faultyMessage);
+
+        task.addExec(exec);
+        exec.setTask(task);
+
+        exec = taskExecDAO.save(exec);
+        assertNotNull(exec);
+
+        assertEquals(faultyMessage.replace('\0', '\n'), exec.getMessage());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
new file mode 100644
index 0000000..4f4b02c
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+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.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.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;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskTest extends AbstractTest {
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void findWithoutExecs() {
+        List<PropagationTask> tasks = taskDAO.findToExec(TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertEquals(3, tasks.size());
+    }
+
+    @Test
+    public void findAll() {
+        assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
+        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
+    }
+
+    @Test
+    public void savePropagationTask() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+
+        User user = userDAO.find(2L);
+        assertNotNull(user);
+
+        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
+        task.setResource(resource);
+        task.setAnyTypeKind(AnyTypeKind.USER);
+        task.setPropagationMode(PropagationMode.TWO_PHASES);
+        task.setPropagationOperation(ResourceOperation.CREATE);
+        task.setConnObjectKey("one@two.com");
+
+        Set<Attribute> attributes = new HashSet<>();
+        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
+        attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
+        task.setAttributes(attributes);
+
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        PropagationTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+    }
+
+    @Test
+    public void delete() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        ExternalResource resource = task.getResource();
+        assertNotNull(resource);
+
+        taskDAO.delete(task);
+        task = taskDAO.find(1L);
+        assertNull(task);
+
+        resource = resourceDAO.find(resource.getKey());
+        assertNotNull(resource);
+        assertFalse(taskDAO.findAll(resource, TaskType.PROPAGATION).contains(task));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
new file mode 100644
index 0000000..587f31d
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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;
+import org.apache.syncope.core.misc.policy.InvalidPasswordPolicySpecException;
+import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class UserTest extends AbstractTest {
+
+    @Autowired
+    private PasswordGenerator passwordGenerator;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertEquals("did not get expected number of users ", 5, list.size());
+    }
+
+    @Test
+    public void count() {
+        Integer count = userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+        assertNotNull(count);
+        assertEquals(5, count, 0);
+    }
+
+    @Test
+    public void findAllByPageAndSize() {
+        // get first page
+        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page with uncomplete set
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 3);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get unexistent page
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 3, 2);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByDerAttributeValue() {
+        final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio");
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrValue() {
+        userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrExpression() {
+        userDAO.findByDerAttrValue("noschema", "Antonio, Maria");
+    }
+
+    @Test
+    public void findByAttributeValue() {
+        final UPlainAttrValue fullnameValue = entityFactory.newEntity(UPlainAttrValue.class);
+        fullnameValue.setStringValue("Gioacchino Rossini");
+
+        final List<User> list = userDAO.findByAttrValue("fullname", fullnameValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByAttributeBooleanValue() {
+        final UPlainAttrValue coolValue = entityFactory.newEntity(UPlainAttrValue.class);
+        coolValue.setBooleanValue(true);
+
+        final List<User> list = userDAO.findByAttrValue("cool", coolValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findById() {
+        User user = userDAO.find(1L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(3L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(6L);
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void findByUsername() {
+        User user = userDAO.find("rossini");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("vivaldi");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("user6");
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void save() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.setCreationDate(new Date());
+
+        user.setPassword("pass", CipherAlgorithm.SHA256);
+
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertNotNull(e);
+        }
+
+        user.setPassword("password", CipherAlgorithm.SHA256);
+
+        user.setUsername("username!");
+
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertNotNull(e);
+        }
+
+        user.setUsername("username");
+
+        User actual = userDAO.save(user);
+        assertNotNull("expected save to work", actual);
+        assertEquals(1, actual.getPasswordHistory().size());
+    }
+
+    @Test
+    public void delete() {
+        User user = userDAO.find(3L);
+
+        userDAO.delete(user.getKey());
+
+        User actual = userDAO.find(3L);
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issue237() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.setCreationDate(new Date());
+
+        user.setPassword("password123", CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE391() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setPassword(null, CipherAlgorithm.AES);
+        user.setRealm(realmDAO.find("/even/two"));
+
+        User actual = userDAO.save(user);
+        assertNull(user.getPassword());
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE226() {
+        User user = userDAO.find(5L);
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+
+        user.setPassword(password, CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void testPasswordGenerator() {
+        User user = userDAO.find(5L);
+
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+        user.setPassword(password, CipherAlgorithm.SHA);
+        userDAO.save(user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
new file mode 100644
index 0000000..95111c6
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.inner;
+
+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.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.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+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.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 VirAttrTest extends AbstractTest {
+
+    @Autowired
+    private VirAttrDAO virAttrDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<UVirAttr> list = virAttrDAO.findAll(UVirAttr.class);
+        assertEquals("did not get expected number of derived attributes ", 1, list.size());
+    }
+
+    @Test
+    public void findById() {
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void saveUVirAttribute() {
+        VirSchema virSchema = virSchemaDAO.find("virtualdata");
+        assertNotNull(virSchema);
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UVirAttr virAttr = entityFactory.newEntity(UVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setSchema(virSchema);
+
+        virAttr = virAttrDAO.save(virAttr);
+
+        UVirAttr actual = virAttrDAO.find(virAttr.getKey(), UVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void saveGVirAttribute() {
+        VirSchema virSchema = virSchemaDAO.find("rvirtualdata");
+        assertNotNull(virSchema);
+
+        Group owner = groupDAO.find(3L);
+        assertNotNull("did not get expected membership", owner);
+
+        GVirAttr virAttr = entityFactory.newEntity(GVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setSchema(virSchema);
+
+        virAttr = virAttrDAO.save(virAttr);
+
+        GVirAttr actual = virAttrDAO.find(virAttr.getKey(), GVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void delete() {
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
+        String attributeSchemaName = attribute.getSchema().getKey();
+
+        virAttrDAO.delete(attribute.getKey(), UVirAttr.class);
+
+        UVirAttr actual = virAttrDAO.find(1000L, UVirAttr.class);
+        assertNull("delete did not work", actual);
+
+        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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
new file mode 100644
index 0000000..fc56739
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+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 VirSchemaTest extends AbstractTest {
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<VirSchema> list = virSchemaDAO.findAll();
+        assertEquals(4, list.size());
+    }
+
+    @Test
+    public void findByName() {
+        VirSchema attributeSchema = virSchemaDAO.find("virtualdata");
+        assertNotNull("did not find expected virtual attribute schema", attributeSchema);
+    }
+
+    @Test
+    public void save() {
+        VirSchema virtualAttributeSchema = entityFactory.newEntity(VirSchema.class);
+        virtualAttributeSchema.setKey("virtual");
+        virtualAttributeSchema.setReadonly(true);
+
+        virSchemaDAO.save(virtualAttributeSchema);
+
+        VirSchema actual = virSchemaDAO.find("virtual");
+        assertNotNull("expected save to work", actual);
+        assertTrue(actual.isReadonly());
+    }
+
+    @Test
+    public void delete() {
+        VirSchema virtualdata = virSchemaDAO.find("virtualdata");
+
+        virSchemaDAO.delete(virtualdata.getKey());
+
+        VirSchema actual = virSchemaDAO.find("virtualdata");
+        assertNull("delete did not work", actual);
+
+        // ------------- //
+        VirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata");
+        assertNotNull(rvirtualdata);
+
+        virSchemaDAO.delete(rvirtualdata.getKey());
+
+        actual = virSchemaDAO.find("rvirtualdata");
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        VirSchema schema = entityFactory.newEntity(VirSchema.class);
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            virSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
new file mode 100644
index 0000000..79f96ed
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/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.outer;
+
+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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
new file mode 100644
index 0000000..29b97a3
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+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 AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        PlainSchema surname = plainSchemaDAO.find("surname");
+        assertNotNull(surname);
+        assertTrue(minimalUser.getPlainSchemas().contains(surname));
+        int before = minimalUser.getPlainSchemas().size();
+
+        plainSchemaDAO.delete("surname");
+
+        anyTypeClassDAO.flush();
+
+        minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+        assertEquals(before, minimalUser.getPlainSchemas().size() + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
new file mode 100644
index 0000000..b3712d8
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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 AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+        assertNotNull(other);
+        assertTrue(userType.getClasses().contains(other));
+        int before = userType.getClasses().size();
+
+        anyTypeClassDAO.delete("other");
+
+        anyTypeDAO.flush();
+
+        userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(before, userType.getClasses().size() + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
new file mode 100644
index 0000000..0046679
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class ConnInstanceTest extends AbstractTest {
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private ConnInstanceDAO connInstanceDAO;
+
+    @Test
+    public void deleteCascade() {
+        ConnInstance connInstance = connInstanceDAO.find(103L);
+        assertNotNull(connInstance);
+
+        List<? extends ExternalResource> resources = connInstance.getResources();
+        assertNotNull(resources);
+        assertFalse(resources.isEmpty());
+
+        connInstanceDAO.delete(connInstance.getKey());
+
+        connInstanceDAO.flush();
+
+        ConnInstance actual = connInstanceDAO.find(103L);
+        assertNull(actual);
+
+        for (ExternalResource resource : resources) {
+            assertNull(resourceDAO.find(resource.getKey()));
+        }
+    }
+
+    /**
+     * Connector change used to miss connector bean registration.
+     *
+     * http://code.google.com/p/syncope/issues/detail?id=176
+     */
+    @Test
+    public void issue176() {
+        ConnInstance connInstance = connInstanceDAO.find(103L);
+        assertNotNull(connInstance);
+        assertTrue(connInstance.getCapabilities().isEmpty());
+
+        List<? extends ExternalResource> resources = connInstance.getResources();
+        assertNotNull(resources);
+        assertEquals(4, resources.size());
+        assertTrue(
+                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
+
+        connInstance.addCapability(ConnectorCapability.SEARCH);
+
+        connInstance = connInstanceDAO.save(connInstance);
+        assertNotNull(connInstance);
+        assertFalse(connInstance.getCapabilities().isEmpty());
+
+        resources = connInstance.getResources();
+        assertNotNull(resources);
+        assertEquals(4, resources.size());
+        assertTrue(
+                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
+                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
new file mode 100644
index 0000000..fcbe239
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertNull;
+
+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.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class DerSchemaTest extends AbstractTest {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Test
+    public void test() {
+        DerSchema schema = derSchemaDAO.find("cn");
+
+        derSchemaDAO.delete(schema.getKey());
+
+        derSchemaDAO.flush();
+
+        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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
new file mode 100644
index 0000000..d208106
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -0,0 +1,328 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+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.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.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.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+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.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.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+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;
+
+@Transactional
+public class GroupTest extends AbstractTest {
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveWithTwoOwners() {
+        Group root = groupDAO.find("root");
+        assertNotNull("did not find expected group", root);
+
+        User user = userDAO.find(1L);
+        assertNotNull("did not find expected user", user);
+
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("error");
+        group.setUserOwner(user);
+        group.setGroupOwner(root);
+
+        groupDAO.save(group);
+    }
+
+    @Test
+    public void findByOwner() {
+        Group group = groupDAO.find(6L);
+        assertNotNull("did not find expected group", group);
+
+        User user = userDAO.find(5L);
+        assertNotNull("did not find expected user", user);
+
+        assertEquals(user, group.getUserOwner());
+
+        List<Group> ownedGroups = groupDAO.findOwnedByUser(user.getKey());
+        assertFalse(ownedGroups.isEmpty());
+        assertEquals(1, ownedGroups.size());
+        assertTrue(ownedGroups.contains(group));
+    }
+
+    @Test
+    public void delete() {
+        groupDAO.delete(2L);
+
+        groupDAO.flush();
+
+        assertNull(groupDAO.find(2L));
+        assertEquals(userDAO.findAllGroups(userDAO.find(2L)).size(), 2);
+        assertNull(plainAttrDAO.find(700L, GPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(41L, GPlainAttrValue.class));
+        assertNotNull(plainSchemaDAO.find("icon"));
+    }
+
+    /**
+     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
+     * required for avoiding creating of a new transaction - good for general use case but bad for the way how
+     * this test class is architected.
+     */
+    private Collection<Group> findDynGroupMemberships(final User user) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
+                + " e WHERE :user MEMBER OF e.users", Group.class);
+        query.setParameter("user", user);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void udynMembership() {
+        // 0. create user matching the condition below
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.add(anyTypeClassDAO.find("other"));
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        user = userDAO.save(user);
+        Long newUserKey = user.getKey();
+        assertNotNull(newUserKey);
+
+        // 1. create group with dynamic membership
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        UDynGroupMembership dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
+        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setGroup(group);
+
+        group.setUDynMembership(dynMembership);
+
+        Group actual = groupDAO.save(group);
+        assertNotNull(actual);
+
+        groupDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = groupDAO.find(actual.getKey());
+        assertNotNull(actual);
+        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.getUDynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
+                CollectionUtils.collect(actual.getUDynMembership().getMembers(), new Transformer<User, Long>() {
+
+                    @Override
+                    public Long transform(final User input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        user = userDAO.find(4L);
+        assertNotNull(user);
+        Collection<Group> dynGroupMemberships = findDynGroupMemberships(user);
+        assertEquals(1, dynGroupMemberships.size());
+        assertTrue(dynGroupMemberships.contains(actual.getUDynMembership().getGroup()));
+
+        // 4. delete the new user and verify that dynamic membership was updated
+        userDAO.delete(newUserKey);
+
+        userDAO.flush();
+
+        actual = groupDAO.find(actual.getKey());
+        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.getUDynMembership().getKey();
+
+        groupDAO.delete(actual);
+
+        groupDAO.flush();
+
+        assertNull(entityManager.find(JPAUDynGroupMembership.class, dynMembershipKey));
+
+        dynGroupMemberships = findDynGroupMemberships(user);
+        assertTrue(dynGroupMemberships.isEmpty());
+    }
+
+    /**
+     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO} method with same signature:
+     * required for avoiding creating of a new transaction - good for general use case but bad for the way how
+     * this test class is architected.
+     */
+    private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
+                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void adynMembership() {
+        // 0. create any object matching the condition below
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setType(anyTypeDAO.find("PRINTER"));
+        anyObject.setRealm(realmDAO.find("/even/two"));
+
+        APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
+        attr.setOwner(anyObject);
+        attr.setSchema(plainSchemaDAO.find("model"));
+        attr.add("Canon MFC8030", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        anyObject.add(attr);
+
+        anyObject = anyObjectDAO.save(anyObject);
+        Long newAnyObjectKey = anyObject.getKey();
+        assertNotNull(newAnyObjectKey);
+
+        // 1. create group with dynamic membership
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
+        dynMembership.setFIQLCond("model==Canon MFC8030");
+        dynMembership.setGroup(group);
+
+        group.setADynMembership(dynMembership);
+
+        Group actual = groupDAO.save(group);
+        assertNotNull(actual);
+
+        groupDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = groupDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getADynMembership());
+        assertNotNull(actual.getADynMembership().getKey());
+        assertEquals(actual, actual.getADynMembership().getGroup());
+
+        // 3. verify that expected any objects have the created group dynamically assigned
+        assertEquals(2, actual.getADynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
+                CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() {
+
+                    @Override
+                    public Long transform(final AnyObject input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        anyObject = anyObjectDAO.find(1L);
+        assertNotNull(anyObject);
+        Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject);
+        assertEquals(1, dynGroupMemberships.size());
+        assertTrue(dynGroupMemberships.contains(actual.getADynMembership().getGroup()));
+
+        // 4. delete the new any object and verify that dynamic membership was updated
+        anyObjectDAO.delete(newAnyObjectKey);
+
+        anyObjectDAO.flush();
+
+        actual = groupDAO.find(actual.getKey());
+        assertEquals(1, actual.getADynMembership().getMembers().size());
+        assertEquals(1L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
+
+        // 5. delete group and verify that dynamic membership was also removed
+        Long dynMembershipKey = actual.getADynMembership().getKey();
+
+        groupDAO.delete(actual);
+
+        groupDAO.flush();
+
+        assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey));
+
+        dynGroupMemberships = findDynGroupMemberships(anyObject);
+        assertTrue(dynGroupMemberships.isEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
new file mode 100644
index 0000000..2e46caf
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+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.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+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.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.UserDAO;
+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.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.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 PlainAttrTest extends AbstractTest {
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void deleteAttribute() {
+        plainAttrDAO.delete(117L, UPlainAttr.class);
+
+        plainAttrDAO.flush();
+
+        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
+    }
+
+    @Test
+    public void deleteAttributeValue() {
+        UPlainAttrValue value = plainAttrValueDAO.find(14L, UPlainAttrValue.class);
+        int attributeValueNumber = value.getAttr().getValues().size();
+
+        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
+
+        plainAttrValueDAO.flush();
+
+        assertNull(plainAttrValueDAO.find(value.getKey(), UPlainAttrValue.class));
+
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        User user = userDAO.find(1L);
+        user.setPassword("password123", CipherAlgorithm.SHA);
+        assertNotNull(user);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        PlainSchema color = entityFactory.newEntity(PlainSchema.class);
+        color.setType(AttrSchemaType.Enum);
+        color.setKey("color");
+        color.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+
+        color = plainSchemaDAO.save(color);
+
+        other.add(color);
+        color.setAnyTypeClass(other);
+
+        plainSchemaDAO.flush();
+
+        color = plainSchemaDAO.find("color");
+        assertNotNull("expected save to work", color);
+        assertEquals(other, color.getAnyTypeClass());
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(color);
+        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+        userDAO.flush();
+
+        user = userDAO.find(1L);
+        assertNotNull(user);
+        assertNotNull(user.getPlainAttr(color.getKey()));
+        assertNotNull(user.getPlainAttr(color.getKey()).getValues());
+        assertEquals(user.getPlainAttr(color.getKey()).getValues().size(), 1);
+    }
+
+    @Test
+    public void derAttrFromSpecialAttrs() {
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
+
+        sderived = derSchemaDAO.save(sderived);
+
+        derSchemaDAO.flush();
+
+        other.add(sderived);
+        sderived.setAnyTypeClass(other);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(other, sderived.getAnyTypeClass());
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
+        assertTrue(value.endsWith("[0]"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
new file mode 100644
index 0000000..0917d27
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+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.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.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PlainSchemaTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Test
+    public void deleteFullname() {
+        // 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").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+
+            if ("fullname".equals(item.getIntAttrName())) {
+                item.setConnObjectKey(false);
+            } else if ("surname".equals(item.getIntAttrName())) {
+                item.setConnObjectKey(true);
+            }
+        }
+
+        // search for user schema fullname
+        PlainSchema schema = plainSchemaDAO.find("fullname");
+        assertNotNull(schema);
+
+        // check for associated mappings
+        Set<MappingItem> mapItems = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
+                        mapItems.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertFalse(mapItems.isEmpty());
+
+        // delete user schema fullname
+        plainSchemaDAO.delete("fullname");
+
+        plainSchemaDAO.flush();
+
+        // check for schema deletion
+        schema = plainSchemaDAO.find("fullname");
+        assertNull(schema);
+
+        plainSchemaDAO.clear();
+
+        // check for mappings deletion
+        mapItems = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if ("fullname".equals(mapItem.getIntAttrName())) {
+                        mapItems.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertTrue(mapItems.isEmpty());
+
+        assertNull(plainAttrDAO.find(100L, UPlainAttr.class));
+        assertNull(plainAttrDAO.find(300L, UPlainAttr.class));
+        assertNull(userDAO.find(1L).getPlainAttr("fullname"));
+        assertNull(userDAO.find(3L).getPlainAttr("fullname"));
+    }
+
+    @Test
+    public void deleteSurname() {
+        // search for user schema fullname
+        PlainSchema schema = plainSchemaDAO.find("surname");
+        assertNotNull(schema);
+
+        // check for associated mappings
+        Set<MappingItem> mappings = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
+                        mappings.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertFalse(mappings.isEmpty());
+
+        // delete user schema fullname
+        plainSchemaDAO.delete("surname");
+
+        plainSchemaDAO.flush();
+
+        // check for schema deletion
+        schema = plainSchemaDAO.find("surname");
+        assertNull(schema);
+    }
+
+    @Test
+    public void deleteALong() {
+        assertEquals(6, resourceDAO.find("resource-db-sync").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+
+        plainSchemaDAO.delete("aLong");
+        assertNull(plainSchemaDAO.find("aLong"));
+
+        plainSchemaDAO.flush();
+
+        assertEquals(5, resourceDAO.find("resource-db-sync").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
new file mode 100644
index 0000000..d55fa62
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+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.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
+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 RealmTest extends AbstractTest {
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Test
+    public void test() {
+        Realm realm = realmDAO.find("/odd");
+        assertNotNull(realm);
+
+        Role role = roleDAO.find(1L);
+        assertTrue(role.getRealms().contains(realm));
+
+        int beforeSize = role.getRealms().size();
+
+        realmDAO.delete(realm);
+
+        realmDAO.flush();
+
+        role = roleDAO.find(1L);
+        assertEquals(beforeSize - 1, role.getRealms().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
new file mode 100644
index 0000000..713ea64
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.Date;
+import javax.persistence.EntityExistsException;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.ReportExec;
+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 ReportTest extends AbstractTest {
+
+    @Autowired
+    private ReportDAO reportDAO;
+
+    @Autowired
+    private ReportExecDAO reportExecDAO;
+
+    @Test
+    public void find() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        assertNotNull(report.getExecs());
+        assertFalse(report.getExecs().isEmpty());
+        assertEquals(1, report.getExecs().size());
+    }
+
+    @Test(expected = EntityExistsException.class)
+    public void saveWithExistingName() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        String name = report.getName();
+
+        report = entityFactory.newEntity(Report.class);
+        report.setName(name);
+
+        reportDAO.save(report);
+        reportDAO.flush();
+    }
+
+    @Test
+    public void save() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+        assertEquals(1, report.getExecs().size());
+
+        ReportExec reportExec = entityFactory.newEntity(ReportExec.class);
+        reportExec.setReport(report);
+        reportExec.setStartDate(new Date());
+        reportExec.setEndDate(new Date());
+        reportExec.setStatus(ReportExecStatus.SUCCESS);
+
+        report.addExec(reportExec);
+
+        reportExec = reportExecDAO.save(reportExec);
+        assertNotNull(reportExec);
+        assertNotNull(reportExec.getKey());
+
+        reportExecDAO.flush();
+
+        report = reportDAO.find(1L);
+        assertNotNull(report);
+        assertEquals(2, report.getExecs().size());
+    }
+
+    @Test
+    public void deleteReport() {
+        reportDAO.delete(1L);
+
+        reportDAO.flush();
+
+        assertNull(reportDAO.find(1L));
+        assertNull(reportExecDAO.find(1L));
+    }
+
+    @Test
+    public void deleteReportExecution() {
+        ReportExec execution = reportExecDAO.find(1L);
+        int executionNumber = execution.getReport().getExecs().size();
+
+        reportExecDAO.delete(1L);
+
+        reportExecDAO.flush();
+
+        assertNull(reportExecDAO.find(1L));
+
+        Report report = reportDAO.find(1L);
+        assertEquals(report.getExecs().size(), executionNumber - 1);
+    }
+}


[67/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
new file mode 100644
index 0000000..70665ed
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConnInstanceTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+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 ConnInstanceTest extends AbstractTest {
+
+    @Autowired
+    private ConnInstanceDAO connInstanceDAO;
+
+    @Test
+    public void findAll() {
+        List<ConnInstance> connectors = connInstanceDAO.findAll();
+        assertNotNull(connectors);
+        assertFalse(connectors.isEmpty());
+    }
+
+    @Test
+    public void findById() {
+        ConnInstance connectorInstance = connInstanceDAO.find(100L);
+
+        assertNotNull("findById did not work", connectorInstance);
+
+        assertEquals("invalid connector name",
+                "net.tirasa.connid.bundles.soap.WebServiceConnector", connectorInstance.getConnectorName());
+
+        assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connectorInstance.getBundleName());
+    }
+
+    @Test
+    public void save() throws ClassNotFoundException {
+        ConnInstance connInstance = entityFactory.newEntity(ConnInstance.class);
+
+        connInstance.setLocation(new File(System.getProperty("java.io.tmpdir")).toURI().toString());
+
+        // set connector version
+        connInstance.setVersion("1.0");
+
+        // set connector name
+        connInstance.setConnectorName("WebService");
+
+        // set bundle name
+        connInstance.setBundleName("org.apache.syncope.core.persistence.test.util");
+
+        connInstance.setDisplayName("New");
+
+        connInstance.setConnRequestTimeout(60);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://host.domain");
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        endpoint.getValues().add("Provisioning");
+
+        conf.add(endpoint);
+        conf.add(servicename);
+
+        // set connector configuration
+        connInstance.setConfiguration(conf);
+        assertFalse(connInstance.getConfiguration().isEmpty());
+
+        // perform save operation
+        ConnInstance actual = connInstanceDAO.save(connInstance);
+
+        assertNotNull("save did not work", actual.getKey());
+
+        assertTrue("save did not work", actual.getKey() > 100L);
+
+        assertEquals("save did not work for \"name\" attribute", "WebService", actual.getConnectorName());
+
+        assertEquals("save did not work for \"bundle name\" attribute", "org.apache.syncope.core.persistence.test.util",
+                actual.getBundleName());
+
+        assertEquals("save did not work for \"majorVersion\" attribute", "1.0", connInstance.getVersion());
+
+        assertEquals("New", actual.getDisplayName());
+
+        assertEquals(60, actual.getConnRequestTimeout(), 0);
+
+        conf = connInstance.getConfiguration();
+        assertFalse(conf.isEmpty());
+
+        assertNotNull("configuration retrieving failed", conf);
+        assertTrue(conf.size() == 2);
+    }
+
+    @Test
+    public void delete() {
+        ConnInstance connectorInstance = connInstanceDAO.find(100L);
+        assertNotNull("find to delete did not work", connectorInstance);
+
+        connInstanceDAO.delete(connectorInstance.getKey());
+
+        ConnInstance actual = connInstanceDAO.find(100L);
+        assertNull("delete did not work", actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerAttrTest.java
new file mode 100644
index 0000000..cd336ae
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerAttrTest.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+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.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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.group.GDerAttr;
+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.UPlainAttrValue;
+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 DerAttrTest extends AbstractTest {
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void findAll() {
+        List<UDerAttr> list = derAttrDAO.findAll(UDerAttr.class);
+        assertEquals("did not get expected number of derived attributes ", 2, list.size());
+    }
+
+    @Test
+    public void findById() {
+        UDerAttr attribute = derAttrDAO.find(100L, UDerAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void saveUDerAttribute() {
+        DerSchema cnSchema = derSchemaDAO.find("cn");
+        assertNotNull(cnSchema);
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(cnSchema);
+
+        derAttr = derAttrDAO.save(derAttr);
+
+        UDerAttr actual = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(derAttr, actual);
+
+        UPlainAttrValue firstname = owner.getPlainAttr("firstname").getValues().iterator().next();
+        UPlainAttrValue surname = owner.getPlainAttr("surname").getValues().iterator().next();
+
+        assertEquals(surname.getValue() + ", " + firstname.getValue(), derAttr.getValue(owner.getPlainAttrs()));
+    }
+
+    @Test
+    public void saveGDerAttribute() {
+        DerSchema schema = derSchemaDAO.find("rderiveddata");
+        assertNotNull(schema);
+
+        Group owner = groupDAO.find(1L);
+        assertNotNull("did not get expected user", owner);
+
+        GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(schema);
+
+        derAttr = derAttrDAO.save(derAttr);
+
+        GDerAttr actual = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(derAttr, actual);
+
+        GPlainAttrValue sx = owner.getPlainAttr("rderived_sx").getValues().iterator().next();
+        GPlainAttrValue dx = owner.getPlainAttr("rderived_dx").getValues().iterator().next();
+
+        assertEquals(sx.getValue() + "-" + dx.getValue(), derAttr.getValue(owner.getPlainAttrs()));
+    }
+
+    @Test
+    public void delete() {
+        UDerAttr attribute = derAttrDAO.find(100L, UDerAttr.class);
+        String schemaName = attribute.getSchema().getKey();
+
+        derAttrDAO.delete(attribute.getKey(), UDerAttr.class);
+
+        UDerAttr actual = derAttrDAO.find(100L, UDerAttr.class);
+        assertNull("delete did not work", actual);
+
+        DerSchema attributeSchema = derSchemaDAO.find(schemaName);
+        assertNotNull("user derived attribute schema deleted when deleting values", attributeSchema);
+    }
+
+    @Test
+    public void issueSYNCOPE134User() {
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("status + ' - ' + username + ' - ' + creationDate + '[' + failedLogins + ']'");
+
+        sderived = derSchemaDAO.save(sderived);
+
+        derSchemaDAO.flush();
+
+        other.add(sderived);
+        sderived.setAnyTypeClass(other);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(other, sderived.getAnyTypeClass());
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+        owner.add(other);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("active - vivaldi - 2010-10-20"));
+        assertTrue(value.endsWith("[0]"));
+    }
+
+    @Test
+    public void issueSYNCOPE134Group() {
+        AnyTypeClass genericMembership = anyTypeClassDAO.find("generic membership");
+
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("name");
+
+        sderived = derSchemaDAO.save(sderived);
+
+        derSchemaDAO.flush();
+
+        genericMembership.add(sderived);
+        sderived.setAnyTypeClass(genericMembership);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(genericMembership, sderived.getAnyTypeClass());
+
+        Group owner = groupDAO.find(7L);
+        assertNotNull("did not get expected group", owner);
+        owner.add(genericMembership);
+
+        GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("managingDirector"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerSchemaTest.java
new file mode 100644
index 0000000..c62ab6e
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/DerSchemaTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+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 DerSchemaTest extends AbstractTest {
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<DerSchema> list = derSchemaDAO.findAll();
+        assertEquals(9, list.size());
+    }
+
+    @Test
+    public void findByName() {
+        DerSchema attributeSchema = derSchemaDAO.find("cn");
+        assertNotNull("did not find expected derived attribute schema", attributeSchema);
+    }
+
+    @Test
+    public void save() {
+        DerSchema derivedAttributeSchema = entityFactory.newEntity(DerSchema.class);
+        derivedAttributeSchema.setKey("cn2");
+        derivedAttributeSchema.setExpression("firstname surname");
+
+        derSchemaDAO.save(derivedAttributeSchema);
+
+        DerSchema actual = derSchemaDAO.find("cn2");
+        assertNotNull("expected save to work", actual);
+        assertEquals(derivedAttributeSchema, actual);
+    }
+
+    @Test
+    public void delete() {
+        DerSchema cn = derSchemaDAO.find("cn");
+        assertNotNull(cn);
+
+        derSchemaDAO.delete(cn.getKey());
+
+        DerSchema actual = derSchemaDAO.find("cn");
+        assertNull("delete did not work", actual);
+
+        // ------------- //
+        DerSchema rderiveddata = derSchemaDAO.find("rderiveddata");
+        assertNotNull(rderiveddata);
+
+        derSchemaDAO.delete(rderiveddata.getKey());
+
+        actual = derSchemaDAO.find("rderiveddata");
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        DerSchema schema = entityFactory.newEntity(DerSchema.class);
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            derSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.java
new file mode 100644
index 0000000..c6a31ef
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GroupTest.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.inner;
+
+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.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+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 GroupTest extends AbstractTest {
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<Group> list = groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertEquals("did not get expected number of groups ", 14, list.size());
+    }
+
+    @Test
+    public void find() {
+        Group group = groupDAO.find("root");
+        assertNotNull("did not find expected group", group);
+    }
+
+    @Test
+    public void save() {
+        Group group = entityFactory.newEntity(Group.class);
+        group.setName("secondChild");
+        group.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
+
+        group = groupDAO.save(group);
+
+        Group actual = groupDAO.find(group.getKey());
+        assertNotNull("expected save to work", actual);
+    }
+
+    @Test
+    public void delete() {
+        Group group = groupDAO.find(4L);
+        groupDAO.delete(group.getKey());
+
+        Group actual = groupDAO.find(4L);
+        assertNull("delete did not work", actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/NotificationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/NotificationTest.java
new file mode 100644
index 0000000..150b924
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/NotificationTest.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.inner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+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;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class NotificationTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private NotificationDAO notificationDAO;
+
+    @Test
+    public void find() {
+        Notification notification = notificationDAO.find(10L);
+        assertNotNull(notification);
+        assertNotNull(notification.getEvents());
+        assertFalse(notification.getEvents().isEmpty());
+        assertNotNull(notification.getAbout(anyTypeDAO.findUser()));
+        assertNotNull(notification.getRecipients());
+
+    }
+
+    @Test
+    public void findAll() {
+        List<Notification> notifications = notificationDAO.findAll();
+        assertNotNull(notifications);
+        assertFalse(notifications.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.getEvents().add("save");
+
+        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
+        about.setNotification(notification);
+        notification.add(about);
+        about.setAnyType(anyTypeDAO.findUser());
+        about.set("fake search condition");
+
+        notification.setRecipients("fake recipients");
+
+        notification.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+    }
+
+    @Test
+    public void delete() {
+        notificationDAO.delete(10L);
+        assertNull(notificationDAO.find(10L));
+    }
+
+    @Test
+    public void issueSYNCOPE445() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.getEvents().add("save");
+
+        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.setRecipientAttrName("email");
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+        notification.getStaticRecipients().add("syncope445@syncope.apache.org");
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        assertNotNull(actual.getStaticRecipients());
+        assertFalse(actual.getStaticRecipients().isEmpty());
+    }
+
+    @Test
+    public void issueSYNCOPE446() {
+        Notification notification = entityFactory.newEntity(Notification.class);
+        notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
+
+        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);
+
+        notification.getStaticRecipients().add("syncope446@syncope.apache.org");
+
+        notification.setSender("syncope@syncope.apache.org");
+        notification.setSubject("Test notification");
+        notification.setTemplate("test");
+
+        Notification actual = notificationDAO.save(notification);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+        assertNotNull(actual.getStaticRecipients());
+        assertFalse(actual.getStaticRecipients().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
new file mode 100644
index 0000000..108e622
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainAttrTest.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+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.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;
+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.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;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PlainAttrTest extends AbstractTest {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void findById() {
+        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+        attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void read() {
+        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
+        assertNotNull(attribute);
+        assertTrue(attribute.getValues().isEmpty());
+        assertNotNull(attribute.getUniqueValue());
+    }
+
+    @Test
+    public void save() throws ClassNotFoundException {
+        User user = userDAO.find(1L);
+
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
+        assertNotNull(emailSchema);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(emailSchema);
+
+        Exception thrown = null;
+        try {
+            attr.add("john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+            attr.add("mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNull("no validation exception expected here ", thrown);
+
+        try {
+            attr.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNotNull("validation exception expected here ", thrown);
+    }
+
+    @Test
+    public void saveWithEnum() throws ClassNotFoundException {
+        User user = userDAO.find(1L);
+        assertNotNull(user);
+
+        PlainSchema gender = plainSchemaDAO.find("gender");
+        assertNotNull(gender);
+        assertNotNull(gender.getType());
+        assertNotNull(gender.getEnumerationValues());
+
+        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
+        attribute.setOwner(user);
+        attribute.setSchema(gender);
+        user.add(attribute);
+
+        Exception thrown = null;
+
+        try {
+            attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNotNull("validation exception expected here ", thrown);
+
+        attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+
+        InvalidEntityException iee = null;
+        try {
+            userDAO.save(user);
+        } catch (InvalidEntityException e) {
+            iee = e;
+        }
+        assertNull(iee);
+    }
+
+    @Test
+    public void validateAndSave() {
+        User user = userDAO.find(1L);
+
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
+        assertNotNull(emailSchema);
+
+        PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
+        assertNotNull(fullnameSchema);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(emailSchema);
+
+        UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
+        uauv.setAttr(attr);
+        uauv.setSchema(fullnameSchema);
+        uauv.setStringValue("a value");
+
+        attr.setUniqueValue(uauv);
+
+        user.add(attr);
+
+        InvalidEntityException iee = null;
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            iee = e;
+        }
+        assertNotNull(iee);
+        // for attribute
+        assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
+        // for uauv
+        assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema));
+    }
+
+    @Test
+    public void saveWithEncrypted() throws Exception {
+        User user = userDAO.find(1L);
+
+        PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
+        assertNotNull(obscureSchema);
+        assertNotNull(obscureSchema.getSecretKey());
+        assertNotNull(obscureSchema.getCipherAlgorithm());
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(obscureSchema);
+        attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+
+        UPlainAttr obscure = user.getPlainAttr("obscure");
+        assertNotNull(obscure);
+        assertEquals(1, obscure.getValues().size());
+        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
+                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
+    }
+
+    @Test
+    public void saveWithBinary() throws UnsupportedEncodingException {
+        User user = userDAO.find(1L);
+
+        PlainSchema photoSchema = plainSchemaDAO.find("photo");
+        assertNotNull(photoSchema);
+        assertNotNull(photoSchema.getMimeType());
+
+        byte[] bytes = new byte[20];
+        new Random().nextBytes(bytes);
+        String photoB64Value = new String(Base64.encode(bytes), SyncopeConstants.DEFAULT_CHARSET);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(photoSchema);
+        attr.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+
+        UPlainAttr obscure = user.getPlainAttr("photo");
+        assertNotNull(obscure);
+        assertEquals(1, obscure.getValues().size());
+        assertTrue(Arrays.equals(bytes, obscure.getValues().get(0).getBinaryValue()));
+    }
+
+    @Test
+    public void delete() {
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        String attrSchemaName = attribute.getSchema().getKey();
+
+        plainAttrDAO.delete(attribute.getKey(), UPlainAttr.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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
new file mode 100644
index 0000000..119ae6d
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+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.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.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PlainSchemaTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<PlainSchema> schemas = plainSchemaDAO.findAll();
+        assertEquals(42, schemas.size());
+    }
+
+    @Test
+    public void findByName() {
+        PlainSchema schema = plainSchemaDAO.find("fullname");
+        assertNotNull("did not find expected attribute schema", schema);
+    }
+
+    @Test
+    public void findAttrs() {
+        PlainSchema schema = plainSchemaDAO.find("icon");
+        assertNotNull(schema);
+
+        List<GPlainAttr> attrs = plainSchemaDAO.findAttrs(schema, GPlainAttr.class);
+        assertNotNull(attrs);
+        assertFalse(attrs.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
+        schema.setKey("secondaryEmail");
+        schema.setType(AttrSchemaType.String);
+        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
+        schema.setMandatoryCondition("false");
+        schema.setMultivalue(true);
+
+        plainSchemaDAO.save(schema);
+
+        PlainSchema actual = plainSchemaDAO.find("secondaryEmail");
+        assertNotNull("expected save to work", actual);
+        assertEquals(schema, actual);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveNonValid() {
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
+        schema.setKey("secondaryEmail");
+        schema.setType(AttrSchemaType.String);
+        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
+        schema.setMandatoryCondition("false");
+        schema.setMultivalue(true);
+        schema.setUniqueConstraint(true);
+
+        plainSchemaDAO.save(schema);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
+        schema.setType(AttrSchemaType.Enum);
+        schema.setKey("color");
+
+        Exception ex = null;
+        try {
+            plainSchemaDAO.save(schema);
+        } catch (Exception e) {
+            ex = e;
+        }
+        assertNotNull(ex);
+
+        schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+        schema.setEnumerationKeys("1" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "2");
+
+        plainSchemaDAO.save(schema);
+
+        PlainSchema actual = plainSchemaDAO.find(schema.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getEnumerationKeys());
+        assertFalse(actual.getEnumerationKeys().isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidSchema() {
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
+        schema.setKey("username");
+        plainSchemaDAO.save(schema);
+    }
+
+    @Test
+    public void delete() {
+        PlainSchema firstname = plainSchemaDAO.find("firstname");
+
+        plainSchemaDAO.delete(firstname.getKey());
+
+        PlainSchema actual = plainSchemaDAO.find("firstname");
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            plainSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
new file mode 100644
index 0000000..ed11445
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PolicyTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+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;
+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 PolicyTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Test
+    public void findAll() {
+        List<Policy> policies = policyDAO.findAll();
+        assertNotNull(policies);
+        assertFalse(policies.isEmpty());
+    }
+
+    @Test
+    public void findById() {
+        Policy policy = policyDAO.find(1L);
+        assertNotNull("findById did not work", policy);
+    }
+
+    @Test
+    public void findByType() {
+        List<? extends Policy> policies = policyDAO.find(PolicyType.SYNC);
+        assertNotNull("findById did not work", policies);
+        assertFalse(policies.isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidPolicy() {
+        PasswordPolicySpec passwordPolicy = new PasswordPolicySpec();
+        passwordPolicy.setMaxLength(8);
+        passwordPolicy.setMinLength(6);
+
+        SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
+        policy.setSpecification(passwordPolicy);
+        policy.setDescription("sync policy");
+
+        policyDAO.save(policy);
+    }
+
+    @Test
+    public void create() {
+        SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
+
+        final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
+        final String syncGRuleName = "net.tirasa.sync.correlation.TirasaGRule";
+
+        SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
+
+        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");
+
+        policy = policyDAO.save(policy);
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.SYNC, policy.getType());
+        assertEquals(syncURuleName,
+                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findUser().getKey()).getJavaRule());
+        assertEquals(syncGRuleName,
+                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findGroup().getKey()).getJavaRule());
+    }
+
+    @Test
+    public void update() {
+        PasswordPolicySpec specification = new PasswordPolicySpec();
+        specification.setMaxLength(8);
+        specification.setMinLength(6);
+
+        Policy policy = policyDAO.find(2L);
+        assertNotNull(policy);
+        policy.setSpecification(specification);
+
+        policy = policyDAO.save(policy);
+
+        assertNotNull(policy);
+        assertEquals(PolicyType.PASSWORD, policy.getType());
+        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMaxLength(), 8);
+        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMinLength(), 6);
+    }
+
+    @Test
+    public void delete() {
+        Policy policy = policyDAO.find(1L);
+        assertNotNull("find to delete did not work", policy);
+
+        policyDAO.delete(policy);
+
+        Policy actual = policyDAO.find(1L);
+        assertNull("delete did not work", actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
new file mode 100644
index 0000000..3fef2ce
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+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.MalformedPathException;
+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.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+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 RealmTest extends AbstractTest {
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Test
+    public void getRoot() {
+        assertNotNull(realmDAO.getRoot());
+    }
+
+    @Test
+    public void find() {
+        Realm realm = realmDAO.find(1L);
+        assertNotNull(realm);
+        assertEquals(SyncopeConstants.ROOT_REALM, realm.getName());
+        assertEquals(SyncopeConstants.ROOT_REALM, realm.getFullPath());
+
+        realm = realmDAO.find(3L);
+        assertNotNull(realm);
+        assertEquals("even", realm.getName());
+        assertEquals("/even", realm.getFullPath());
+        assertEquals(1, realm.getParent().getKey(), 0);
+        assertEquals(realmDAO.getRoot(), realm.getParent());
+
+        realm = realmDAO.find("/even/two");
+        assertNotNull(realm);
+        assertEquals(4, realm.getKey(), 0);
+        assertEquals("two", realm.getName());
+        assertEquals("/even/two", realm.getFullPath());
+    }
+
+    @Test(expected = MalformedPathException.class)
+    public void findInvalidPath() {
+        realmDAO.find("even/two");
+    }
+
+    @Test
+    public void findChildren() {
+        List<Realm> children = realmDAO.findChildren(realmDAO.find(SyncopeConstants.ROOT_REALM));
+        assertEquals(2, children.size());
+        assertTrue(children.contains(realmDAO.find("/odd")));
+        assertTrue(children.contains(realmDAO.find("/even")));
+
+        children = realmDAO.findChildren(realmDAO.find("/odd"));
+        assertTrue(children.isEmpty());
+    }
+
+    @Test
+    public void findDescendants() {
+        assertTrue(CollectionUtils.disjunction(realmDAO.findAll(), realmDAO.findDescendants(realmDAO.getRoot())).
+                isEmpty());
+    }
+
+    @Test
+    public void findAll() {
+        List<Realm> list = realmDAO.findAll();
+        assertNotNull(list);
+        assertFalse(list.isEmpty());
+        for (Realm realm : list) {
+            assertNotNull(realm);
+        }
+    }
+
+    @Test
+    public void save() {
+        Realm realm = entityFactory.newEntity(Realm.class);
+        realm.setName("last");
+        realm.setParent(realmDAO.find("/even/two"));
+        assertNull(realm.getKey());
+
+        Realm actual = realmDAO.save(realm);
+        assertNotNull(actual.getKey());
+        assertEquals("last", actual.getName());
+        assertEquals("/even/two/last", actual.getFullPath());
+        assertEquals(realmDAO.find("/even/two"), actual.getParent());
+        assertEquals(5L, realm.getAccountPolicy().getKey(), 0);
+        assertEquals(2L, realm.getPasswordPolicy().getKey(), 0);
+
+        realm = actual;
+        realm.setAccountPolicy((AccountPolicy) policyDAO.find(6L));
+        realm.setPasswordPolicy((PasswordPolicy) policyDAO.find(4L));
+
+        actual = realmDAO.save(realm);
+        assertEquals(6L, actual.getAccountPolicy().getKey(), 0);
+        assertEquals(4L, actual.getPasswordPolicy().getKey(), 0);
+    }
+
+    @Test
+    public void saveInvalidName() {
+        Realm realm = entityFactory.newEntity(Realm.class);
+        realm.setName(" a name");
+        realm.setParent(realmDAO.getRoot());
+
+        try {
+            realmDAO.save(realm);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidRealm));
+        }
+    }
+
+    @Test
+    public void saveNullParent() {
+        Realm realm = entityFactory.newEntity(Realm.class);
+        realm.setName("name");
+        realm.setParent(null);
+
+        try {
+            realmDAO.save(realm);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidRealm));
+        }
+    }
+
+    @Test
+    public void delete() {
+        Realm realm = entityFactory.newEntity(Realm.class);
+        realm.setName("name");
+        realm.setParent(realmDAO.getRoot());
+
+        Realm actual = realmDAO.save(realm);
+        assertNotNull(actual);
+
+        Long key = actual.getKey();
+        assertNotNull(realmDAO.find(key));
+
+        realmDAO.delete(key);
+        assertNull(realmDAO.find(key));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RelationshipTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RelationshipTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RelationshipTypeTest.java
new file mode 100644
index 0000000..9aee7f1
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RelationshipTypeTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+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 RelationshipTypeTest extends AbstractTest {
+
+    @Autowired
+    private RelationshipTypeDAO relationshipTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Test
+    public void find() {
+        RelationshipType inclusion = relationshipTypeDAO.find("inclusion");
+        assertNotNull(inclusion);
+        assertEquals("inclusion", inclusion.getKey());
+    }
+
+    @Test
+    public void findAll() {
+        List<RelationshipType> list = relationshipTypeDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        RelationshipType newType = entityFactory.newEntity(RelationshipType.class);
+        newType.setKey("new type");
+        newType.setDescription("description");
+
+        newType = relationshipTypeDAO.save(newType);
+        assertNotNull(newType);
+        assertEquals("description", newType.getDescription());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidName() {
+        RelationshipType newType = entityFactory.newEntity(RelationshipType.class);
+        newType.setKey("membership");
+        relationshipTypeDAO.save(newType);
+    }
+
+    @Test
+    public void delete() {
+        RelationshipType type = relationshipTypeDAO.find("neighborhood");
+        assertNotNull(type);
+
+        relationshipTypeDAO.delete(type.getKey());
+        assertNull(relationshipTypeDAO.find("neighborhood"));
+    }
+
+    @Test
+    public void deleteOnAnyObject() {
+        RelationshipType neighborhood = relationshipTypeDAO.find("neighborhood");
+        assertNotNull(neighborhood);
+
+        AnyObject anyObject = anyObjectDAO.find(1L);
+        assertNotNull(anyObject);
+        assertNotNull(anyObject.getRelationship(neighborhood));
+
+        relationshipTypeDAO.delete("neighborhood");
+
+        relationshipTypeDAO.flush();
+
+        anyObject = anyObjectDAO.find(1L);
+        assertNotNull(anyObject);
+        assertTrue(anyObject.getRelationships().isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ReportTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ReportTest.java
new file mode 100644
index 0000000..4318813
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ReportTest.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.inner;
+
+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.common.lib.report.UserReportletConf;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.entity.Report;
+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 ReportTest extends AbstractTest {
+
+    @Autowired
+    private ReportDAO reportDAO;
+
+    @Test
+    public void find() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        report = reportDAO.find(10L);
+        assertNull(report);
+    }
+
+    @Test
+    public void findAll() {
+        List<Report> reports = reportDAO.findAll();
+        assertNotNull(reports);
+        assertEquals(1, reports.size());
+    }
+
+    @Test
+    public void save() {
+        int beforeCount = reportDAO.count();
+
+        Report report = entityFactory.newEntity(Report.class);
+        report.setName("new report");
+        report.addReportletConf(new UserReportletConf("first"));
+        report.addReportletConf(new UserReportletConf("second"));
+
+        report = reportDAO.save(report);
+        assertNotNull(report);
+        assertNotNull(report.getKey());
+
+        int afterCount = reportDAO.count();
+        assertEquals(afterCount, beforeCount + 1);
+    }
+
+    @Test
+    public void delete() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        reportDAO.delete(1L);
+
+        report = reportDAO.find(1L);
+        assertNull(report);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
new file mode 100644
index 0000000..e5cee24
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java
@@ -0,0 +1,372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+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.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.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+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");
+        assertNotNull("findById did not work", resource);
+
+        ConnInstance connector = resource.getConnector();
+        assertNotNull("connector not found", connector);
+        assertEquals("invalid connector name",
+                "net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
+        assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connector.getBundleName());
+
+        Mapping mapping = resource.getProvision(anyTypeDAO.findUser()).getMapping();
+        assertFalse("no mapping specified", mapping.getItems().isEmpty());
+
+        assertTrue(CollectionUtils.exists(mapping.getItems(), new Predicate<MappingItem>() {
+
+            @Override
+            public boolean evaluate(final MappingItem item) {
+                return 100 == item.getKey();
+            }
+        }));
+    }
+
+    @Test
+    public void findAll() {
+        List<ExternalResource> resources = resourceDAO.findAll();
+        assertNotNull(resources);
+        assertEquals(19, resources.size());
+    }
+
+    @Test
+    public void findAllByPriority() {
+        List<ExternalResource> resources = resourceDAO.findAllByPriority();
+        assertNotNull(resources);
+        assertFalse(resources.isEmpty());
+    }
+
+    @Test
+    public void getConnObjectKey() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
+        assertNotNull(resource);
+        assertEquals("fullname",
+                resource.getProvision(anyTypeDAO.findUser()).getMapping().getConnObjectKeyItem().getIntAttrName());
+    }
+
+    @Test
+    public void save() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-basic-save");
+        resource.setPropagationPriority(2);
+        resource.setPropagationPrimary(true);
+
+        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);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("fullname");
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
+        connObjectKey.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(connObjectKey);
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getConnector());
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertFalse(actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems().isEmpty());
+        assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
+        assertTrue(actual.isPropagationPrimary());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidMappingIntAttr() {
+        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);
+
+        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);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setConnObjectKey(true);
+        connObjectKey.setIntMappingType(IntMappingType.UserPlainSchema);
+        mapping.add(connObjectKey);
+
+        // save the resource
+        resourceDAO.save(resource);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    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);
+
+        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);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setConnObjectKey(true);
+        connObjectKey.setIntMappingType(IntMappingType.UserVirtualSchema);
+        mapping.setConnObjectKeyItem(connObjectKey);
+
+        // save the resource
+        resourceDAO.save(resource);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidMappingExtAttr() {
+        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);
+
+        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);
+
+        MappingItem item = entityFactory.newEntity(MappingItem.class);
+        item.setConnObjectKey(true);
+        item.setIntAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        mapping.add(item);
+
+        item = entityFactory.newEntity(MappingItem.class);
+        item.setIntAttrName("userId");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        mapping.add(item);
+
+        resourceDAO.save(resource);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidProvision() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("invalidProvision");
+
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("fullname");
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
+        connObjectKey.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(connObjectKey);
+
+        provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findGroup());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        // save the resource
+        resourceDAO.save(resource);
+    }
+
+    @Test
+    public void saveWithGroupMappingType() {
+        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);
+
+        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);
+
+        MappingItem item = entityFactory.newEntity(MappingItem.class);
+        item.setIntAttrName("fullname");
+        item.setExtAttrName("fullname");
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        item = entityFactory.newEntity(MappingItem.class);
+        item.setIntAttrName("icon");
+        item.setExtAttrName("icon");
+        item.setIntMappingType(IntMappingType.GroupPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        item = entityFactory.newEntity(MappingItem.class);
+        item.setIntAttrName("mderiveddata");
+        item.setExtAttrName("mderiveddata");
+        item.setIntMappingType(IntMappingType.AnyObjectDerivedSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.add(item);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+
+        int items = 0;
+        for (MappingItem mapItem : actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+            items++;
+
+            if ("icon".equals(mapItem.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(AnyTypeKind.GROUP, mapItem.getIntMappingType().toString()));
+            }
+            if ("mderiveddata".equals(mapItem.getIntAttrName())) {
+                assertTrue(IntMappingType.contains(AnyTypeKind.ANY_OBJECT, mapItem.getIntMappingType().toString()));
+            }
+        }
+        assertEquals(3, items);
+    }
+
+    @Test
+    public void delete() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
+        assertNotNull(resource);
+
+        resourceDAO.delete(resource.getKey());
+
+        ExternalResource actual = resourceDAO.find("ws-target-resource-2");
+        assertNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+        try {
+            resourceDAO.save(resource);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void issueSYNCOPE645() {
+        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);
+
+        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);
+
+        final MappingItem item = entityFactory.newEntity(MappingItem.class);
+        item.setIntAttrName("icon");
+        item.setExtAttrName("icon");
+        item.setIntMappingType(IntMappingType.GroupPlainSchema);
+        item.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(item);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RoleTest.java
new file mode 100644
index 0000000..bf2c012
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RoleTest.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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.Entitlement;
+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.entity.Role;
+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 RoleTest extends AbstractTest {
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void find() {
+        Role role1 = roleDAO.find(2L);
+        assertNotNull(role1);
+        assertNotNull(role1.getName());
+        assertFalse(role1.getRealms().isEmpty());
+        assertFalse(role1.getEntitlements().isEmpty());
+        assertTrue(role1.getEntitlements().contains(Entitlement.USER_LIST));
+
+        Role role2 = roleDAO.find(role1.getName());
+        assertEquals(role1, role2);
+    }
+
+    @Test
+    public void findAll() {
+        List<Role> list = roleDAO.findAll();
+        assertNotNull(list);
+        assertFalse(list.isEmpty());
+        for (Role role : list) {
+            assertNotNull(role);
+        }
+    }
+
+    @Test
+    public void save() {
+        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);
+
+        Role actual = roleDAO.save(role);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void delete() {
+        assertNotNull(roleDAO.find(3L));
+
+        roleDAO.delete(3L);
+        assertNull(roleDAO.find(3L));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SecurityQuestionTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SecurityQuestionTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SecurityQuestionTest.java
new file mode 100644
index 0000000..f17146e
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/SecurityQuestionTest.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.jpa.inner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
+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 SecurityQuestionTest extends AbstractTest {
+
+    @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Test
+    public void find() {
+        SecurityQuestion securityQuestion = securityQuestionDAO.find(1L);
+        assertNotNull(securityQuestion);
+        assertNotNull(securityQuestion.getContent());
+    }
+
+    @Test
+    public void findAll() {
+        List<SecurityQuestion> securityQuestions = securityQuestionDAO.findAll();
+        assertNotNull(securityQuestions);
+        assertFalse(securityQuestions.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        SecurityQuestion securityQuestion = entityFactory.newEntity(SecurityQuestion.class);
+        securityQuestion.setContent("What is your favorite pet's name?");
+
+        SecurityQuestion actual = securityQuestionDAO.save(securityQuestion);
+        assertNotNull(actual);
+        assertNotNull(actual.getKey());
+    }
+
+    @Test
+    public void delete() {
+        securityQuestionDAO.delete(1L);
+        assertNull(securityQuestionDAO.find(1L));
+    }
+}


[36/70] syncope git commit: [SYNCOPE-666] Final JPA tests

Posted by il...@apache.org.
[SYNCOPE-666] Final JPA tests


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

Branch: refs/heads/master
Commit: 63108c8f89ba92c5517133545df2350971c703b5
Parents: 419fccf
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed May 27 11:41:00 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed May 27 11:41:00 2015 +0200

----------------------------------------------------------------------
 .../persistence/jpa/entity/AbstractAttr.java    | 130 ++++++++++
 .../persistence/jpa/entity/AbstractDerAttr.java |  10 +-
 .../persistence/jpa/entity/AbstractEntity.java  |   3 -
 .../jpa/entity/AbstractPlainAttr.java           |   6 +-
 .../persistence/jpa/entity/AbstractVirAttr.java |  10 +-
 .../persistence/jpa/entity/JPAAnyTypeClass.java |  36 +--
 .../jpa/entity/conf/JPACPlainAttr.java          |  14 ++
 .../persistence/jpa/entity/conf/JPAConf.java    |   8 +-
 .../resources/META-INF/spring-orm-oracle.xml    | 178 +++++++++-----
 .../resources/META-INF/spring-orm-sqlserver.xml | 178 +++++++++-----
 .../core/persistence/jpa/entity/AttrTest.java   | 236 ------------------
 .../persistence/jpa/entity/DerAttrTest.java     |  35 ++-
 .../persistence/jpa/entity/PlainAttrTest.java   | 237 +++++++++++++++++++
 .../persistence/jpa/relationship/AttrTest.java  | 156 ------------
 .../persistence/jpa/relationship/GroupTest.java |  25 +-
 .../jpa/relationship/PlainAttrTest.java         | 179 ++++++++++++++
 .../persistence/jpa/relationship/RoleTest.java  |  15 +-
 17 files changed, 877 insertions(+), 579 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
new file mode 100644
index 0000000..4f4a3ec
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.Transient;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.Attr;
+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.Schema;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+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.TypeExtension;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+
+public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>>
+        extends AbstractEntity<Long> implements Attr<S, O> {
+
+    private static final long serialVersionUID = -7722134717360731874L;
+
+    @Transient
+    private Set<PlainSchema> allowedPlainSchemas;
+
+    @Transient
+    private Set<DerSchema> allowedDerSchemas;
+
+    @Transient
+    private Set<VirSchema> allowedVirSchemas;
+
+    private void populateClasses(final Collection<? extends AnyTypeClass> anyTypeClasses) {
+        synchronized (this) {
+            if (getSchema() instanceof PlainSchema) {
+                if (allowedPlainSchemas == null) {
+                    allowedPlainSchemas = new HashSet<>();
+                }
+                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+                    allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas());
+                }
+            } else if (getSchema() instanceof DerSchema) {
+                if (allowedDerSchemas == null) {
+                    allowedDerSchemas = new HashSet<>();
+                }
+                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+                    allowedDerSchemas.addAll(anyTypeClass.getDerSchemas());
+                }
+            } else if (getSchema() instanceof VirSchema) {
+                if (allowedVirSchemas == null) {
+                    allowedVirSchemas = new HashSet<>();
+                }
+                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+                    allowedVirSchemas.addAll(anyTypeClass.getVirSchemas());
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Set<S> getAllowedSchemas() {
+        Set<S> result = Collections.emptySet();
+
+        if (getSchema() instanceof PlainSchema) {
+            if (allowedPlainSchemas == null) {
+                allowedPlainSchemas = new HashSet<>();
+            }
+            result = (Set<S>) allowedPlainSchemas;
+        } else if (getSchema() instanceof DerSchema) {
+            if (allowedDerSchemas == null) {
+                allowedDerSchemas = new HashSet<>();
+            }
+            result = (Set<S>) allowedDerSchemas;
+        } else if (getSchema() instanceof VirSchema) {
+            if (allowedVirSchemas == null) {
+                allowedVirSchemas = new HashSet<>();
+            }
+            result = (Set<S>) allowedVirSchemas;
+        }
+
+        return result;
+    }
+
+    protected void checkSchema(final S schema) {
+        if (schema == null || getOwner() == null) {
+            throw new IllegalStateException("First set owner then schema and finally add values");
+        }
+
+        populateClasses(getOwner().getType().getClasses());
+        populateClasses(getOwner().getAuxClasses());
+        if (getOwner() instanceof User) {
+            for (UMembership memb : ((User) getOwner()).getMemberships()) {
+                for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
+                    populateClasses(typeExtension.getAuxClasses());
+                }
+            }
+        }
+        if (getOwner() instanceof AnyObject) {
+            for (AMembership memb : ((AnyObject) getOwner()).getMemberships()) {
+                for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
+                    populateClasses(typeExtension.getAuxClasses());
+                }
+            }
+        }
+
+        if (!getAllowedSchemas().contains(schema)) {
+            throw new IllegalArgumentException(schema + " not allowed for this instance");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 60dae3c..fba234d 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
@@ -33,7 +33,8 @@ import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 
 @MappedSuperclass
-public abstract class AbstractDerAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements DerAttr<O> {
+public abstract class AbstractDerAttr<O extends Any<?, ?, ?>>
+        extends AbstractAttr<DerSchema, O> implements DerAttr<O> {
 
     private static final long serialVersionUID = 4740924251090424771L;
 
@@ -56,9 +57,10 @@ public abstract class AbstractDerAttr<O extends Any<?, ?, ?>> extends AbstractEn
     }
 
     @Override
-    public void setSchema(final DerSchema derSchema) {
-        checkType(derSchema, JPADerSchema.class);
-        this.schema = (JPADerSchema) derSchema;
+    public void setSchema(final DerSchema schema) {
+        checkType(schema, JPADerSchema.class);
+        this.schema = (JPADerSchema) schema;
+        checkSchema(this.schema);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
index dfd706d..1b8ab54 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
@@ -34,9 +34,6 @@ public abstract class AbstractEntity<KEY> implements Entity<KEY> {
 
     private static final long serialVersionUID = -9017214159540857901L;
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractEntity.class);
 
     protected void checkType(final Object object, final Class<?> clazz) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 a93cc45..4bab427 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
@@ -37,13 +37,14 @@ import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrCheck;
 
 @MappedSuperclass
 @PlainAttrCheck
-public abstract class AbstractPlainAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements PlainAttr<O> {
+public abstract class AbstractPlainAttr<O extends Any<?, ?, ?>>
+        extends AbstractAttr<PlainSchema, O> implements PlainAttr<O> {
 
     private static final long serialVersionUID = -9115431608821806124L;
 
     @ManyToOne(fetch = FetchType.EAGER)
     @Column(name = "schema_name")
-    private JPAPlainSchema schema;
+    protected JPAPlainSchema schema;
 
     @Override
     public PlainSchema getSchema() {
@@ -54,6 +55,7 @@ public abstract class AbstractPlainAttr<O extends Any<?, ?, ?>> extends Abstract
     public void setSchema(final PlainSchema schema) {
         checkType(schema, JPAPlainSchema.class);
         this.schema = (JPAPlainSchema) schema;
+        checkSchema(this.schema);
     }
 
     protected abstract boolean addForMultiValue(PlainAttrValue attrValue);

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 1ed64f3..946b09b 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
@@ -33,7 +33,8 @@ import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
 @MappedSuperclass
-public abstract class AbstractVirAttr<O extends Any<?, ?, ?>> extends AbstractEntity<Long> implements VirAttr<O> {
+public abstract class AbstractVirAttr<O extends Any<?, ?, ?>>
+        extends AbstractAttr<VirSchema, O> implements VirAttr<O> {
 
     private static final long serialVersionUID = 5023204776925954907L;
 
@@ -74,8 +75,9 @@ public abstract class AbstractVirAttr<O extends Any<?, ?, ?>> extends AbstractEn
     }
 
     @Override
-    public void setSchema(final VirSchema virSchema) {
-        checkType(virSchema, JPAVirSchema.class);
-        this.schema = (JPAVirSchema) virSchema;
+    public void setSchema(final VirSchema schema) {
+        checkType(schema, JPAVirSchema.class);
+        this.schema = (JPAVirSchema) schema;
+        checkSchema(this.schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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
index e4f0db9..6fba644 100644
--- 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
@@ -63,15 +63,15 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean add(final PlainSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
-        return this.plainSchemas.add((JPAPlainSchema) facet);
+    public boolean add(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        return this.plainSchemas.add((JPAPlainSchema) schema);
     }
 
     @Override
-    public boolean remove(final PlainSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
-        return this.plainSchemas.remove((JPAPlainSchema) facet);
+    public boolean remove(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        return this.plainSchemas.remove((JPAPlainSchema) schema);
     }
 
     @Override
@@ -80,15 +80,15 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean add(final DerSchema facet) {
-        checkType(facet, JPADerSchema.class);
-        return this.derSchemas.add((JPADerSchema) facet);
+    public boolean add(final DerSchema schema) {
+        checkType(schema, JPADerSchema.class);
+        return this.derSchemas.add((JPADerSchema) schema);
     }
 
     @Override
-    public boolean remove(final DerSchema facet) {
-        checkType(facet, JPADerSchema.class);
-        return this.derSchemas.remove((JPADerSchema) facet);
+    public boolean remove(final DerSchema schema) {
+        checkType(schema, JPADerSchema.class);
+        return this.derSchemas.remove((JPADerSchema) schema);
     }
 
     @Override
@@ -97,15 +97,15 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     }
 
     @Override
-    public boolean add(final VirSchema facet) {
-        checkType(facet, JPAVirSchema.class);
-        return this.virSchemas.add((JPAVirSchema) facet);
+    public boolean add(final VirSchema schema) {
+        checkType(schema, JPAVirSchema.class);
+        return this.virSchemas.add((JPAVirSchema) schema);
     }
 
     @Override
-    public boolean remove(final VirSchema facet) {
-        checkType(facet, JPAVirSchema.class);
-        return this.virSchemas.remove((JPAVirSchema) facet);
+    public boolean remove(final VirSchema schema) {
+        checkType(schema, JPAVirSchema.class);
+        return this.virSchemas.remove((JPAVirSchema) schema);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 6fd6c1e..b6b683b 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
@@ -31,11 +31,13 @@ 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.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.Conf;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 
 /**
  * Configuration attribute.
@@ -90,6 +92,18 @@ public class JPACPlainAttr extends AbstractPlainAttr<Conf> implements CPlainAttr
         this.owner = (JPAConf) owner;
     }
 
+    /**
+     * Explicitly overrides default schema check (used for users, groups and any objects) since Conf does not own any
+     * type reference.
+     *
+     * @param schema schema for this attribute
+     */
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
+    }
+
     @Override
     protected boolean addForMultiValue(final PlainAttrValue attrValue) {
         checkType(attrValue, JPACPlainAttrValue.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 be3fa19..3253f66 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
@@ -54,13 +54,7 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
     @Valid
-    private List<JPACPlainAttr> plainAttrs;
-
-    public JPAConf() {
-        super();
-
-        plainAttrs = new ArrayList<>();
-    }
+    private List<JPACPlainAttr> plainAttrs = new ArrayList<>();
 
     @Override
     public Long getKey() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index 8c58d33..c592c31 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.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>
@@ -48,6 +48,33 @@ under the License.
     </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.anyobject.JPAAMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_AMembership" pk-column-value="SEQ_AMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole">
     <attributes>
       <id name="id">
@@ -56,8 +83,8 @@ under the License.
       </id>
     </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 +101,74 @@ 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.user.JPAUMembership">
     <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_UMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_UMembership" pk-column-value="SEQ_UMembership" 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.group.JPAGroup">
     <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_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.user.JPAUMapping">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
+    <attributes>
+      <id name="id">
+        <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.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 +182,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,39 +206,39 @@ 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">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MPlainAttr" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttr" pk-column-value="SEQ_MPlainAttr" initial-value="1000"/>
+        <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
+        <table-generator name="SEQ_CAttrPlain" pk-column-value="SEQ_CAttrPlain" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MPlainAttrTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttrTemplate" pk-column-value="SEQ_MPlainAttrTemplate" initial-value="1000"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>dateValue</column-name>
+        <column-name>stringValue</column-name>
+        <column-name>doubleValue</column-name>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
-        <table-generator name="SEQ_CAttrPlain" pk-column-value="SEQ_CAttrPlain" initial-value="1000"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
-  </entity>
-    
+  </entity>    
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue">
     <attributes>
       <id name="id">
@@ -241,14 +287,14 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" 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.conf.JPACPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -261,31 +307,25 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <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.conf.JPACPlainAttrUniqueValue">
-    <table>
-      <unique-constraint>
-        <column-name>booleanValue</column-name>
-        <column-name>dateValue</column-name>
-        <column-name>stringValue</column-name>
-        <column-name>doubleValue</column-name>
-        <column-name>longValue</column-name>
-        <column-name>schema_name</column-name>
-      </unique-constraint>
-    </table>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyFilter">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_AnyFilter" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyFilter" pk-column-value="SEQ_AnyFilter" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
@@ -340,6 +380,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">
@@ -348,6 +397,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/63108c8f/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index bd7f664..c592c31 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.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>
@@ -48,6 +48,33 @@ under the License.
     </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.anyobject.JPAAMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_AMembership" pk-column-value="SEQ_AMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole">
     <attributes>
       <id name="id">
@@ -57,7 +84,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"/>
@@ -65,7 +92,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  
+
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
     <attributes>
       <id name="id">
@@ -74,63 +101,74 @@ 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.user.JPAUMembership">
     <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_UMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_UMembership" pk-column-value="SEQ_UMembership" 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.group.JPAGroup">
     <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_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.user.JPAUMapping">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
+    <attributes>
+      <id name="id">
+        <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.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 +182,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,39 +206,39 @@ 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">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MPlainAttr" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttr" pk-column-value="SEQ_MPlainAttr" initial-value="1000"/>
+        <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
+        <table-generator name="SEQ_CAttrPlain" pk-column-value="SEQ_CAttrPlain" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MPlainAttrTemplate" strategy="TABLE"/>
-        <table-generator name="SEQ_MPlainAttrTemplate" pk-column-value="SEQ_MPlainAttrTemplate" initial-value="1000"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>dateValue</column-name>
+        <column-name>stringValue</column-name>
+        <column-name>doubleValue</column-name>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
-        <table-generator name="SEQ_CAttrPlain" pk-column-value="SEQ_CAttrPlain" initial-value="1000"/>
+        <generated-value generator="SEQ_APlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
-  </entity>
-    
+  </entity>    
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue">
     <attributes>
       <id name="id">
@@ -241,14 +287,14 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue">
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" 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.conf.JPACPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -261,31 +307,25 @@ under the License.
     </table>
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_CPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue">
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <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.conf.JPACPlainAttrUniqueValue">
-    <table>
-      <unique-constraint>
-        <column-name>booleanValue</column-name>
-        <column-name>dateValue</column-name>
-        <column-name>stringValue</column-name>
-        <column-name>doubleValue</column-name>
-        <column-name>longValue</column-name>
-        <column-name>schema_name</column-name>
-      </unique-constraint>
-    </table>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyFilter">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+        <generated-value generator="SEQ_AnyFilter" strategy="TABLE"/>
+        <table-generator name="SEQ_AnyFilter" pk-column-value="SEQ_AnyFilter" initial-value="1000"/>
       </id>
     </attributes>
   </entity>
@@ -340,6 +380,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">
@@ -348,6 +397,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/63108c8f/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
deleted file mode 100644
index a0d12a6..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AttrTest.java
+++ /dev/null
@@ -1,236 +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 static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-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.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;
-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.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;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class AttrTest extends AbstractTest {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Test
-    public void findById() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-        attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-    }
-
-    @Test
-    public void read() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull(attribute);
-        assertTrue(attribute.getValues().isEmpty());
-        assertNotNull(attribute.getUniqueValue());
-    }
-
-    @Test
-    public void save() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-
-        PlainSchema emailSchema = plainSchemaDAO.find("email");
-        assertNotNull(emailSchema);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(emailSchema);
-        attribute.setOwner(user);
-
-        Exception thrown = null;
-        try {
-            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.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-    }
-
-    @Test
-    public void saveWithEnum() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-        assertNotNull(user);
-
-        PlainSchema gender = plainSchemaDAO.find("gender");
-        assertNotNull(gender);
-        assertNotNull(gender.getType());
-        assertNotNull(gender.getEnumerationValues());
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(gender);
-        attribute.setOwner(user);
-        user.add(attribute);
-
-        Exception thrown = null;
-
-        try {
-            attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-
-        attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNull(iee);
-    }
-
-    @Test
-    public void validateAndSave() {
-        User user = userDAO.find(1L);
-
-        PlainSchema emailSchema = plainSchemaDAO.find("email");
-        assertNotNull(emailSchema);
-
-        PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
-        assertNotNull(fullnameSchema);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(emailSchema);
-
-        UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
-        uauv.setAttr(attribute);
-        uauv.setSchema(fullnameSchema);
-        uauv.setStringValue("a value");
-
-        attribute.setUniqueValue(uauv);
-
-        user.add(attribute);
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-            fail();
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNotNull(iee);
-        // for attribute
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
-        // for uauv
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema));
-    }
-
-    @Test
-    public void saveWithEncrypted() throws Exception {
-        User user = userDAO.find(1L);
-
-        PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
-        assertNotNull(obscureSchema);
-        assertNotNull(obscureSchema.getSecretKey());
-        assertNotNull(obscureSchema.getCipherAlgorithm());
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(obscureSchema);
-        attribute.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        attribute.setOwner(user);
-        user.add(attribute);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("obscure");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
-                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
-    }
-
-    @Test
-    public void saveWithBinary() throws UnsupportedEncodingException {
-        User user = userDAO.find(1L);
-
-        PlainSchema photoSchema = plainSchemaDAO.find("photo");
-        assertNotNull(photoSchema);
-        assertNotNull(photoSchema.getMimeType());
-
-        final byte[] bytes = new byte[20];
-        new Random().nextBytes(bytes);
-        final String photoB64Value = new String(Base64.encode(bytes), SyncopeConstants.DEFAULT_ENCODING);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(photoSchema);
-        attribute.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        attribute.setOwner(user);
-        user.add(attribute);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("photo");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertTrue(Arrays.equals(bytes, obscure.getValues().get(0).getBinaryValue()));
-    }
-
-    @Test
-    public void delete() {
-        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        String attrSchemaName = attribute.getSchema().getKey();
-
-        plainAttrDAO.delete(attribute.getKey(), UPlainAttr.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/63108c8f/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 11381e5..f64e314 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
@@ -25,10 +25,12 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 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.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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.group.GDerAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
@@ -56,6 +58,9 @@ public class DerAttrTest extends AbstractTest {
     @Autowired
     private DerSchemaDAO derSchemaDAO;
 
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
     @Test
     public void findAll() {
         List<UDerAttr> list = derAttrDAO.findAll(UDerAttr.class);
@@ -132,19 +137,28 @@ public class DerAttrTest extends AbstractTest {
 
     @Test
     public void issueSYNCOPE134User() {
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
         DerSchema sderived = entityFactory.newEntity(DerSchema.class);
         sderived.setKey("sderived");
         sderived.setExpression("status + ' - ' + username + ' - ' + creationDate + '[' + failedLogins + ']'");
 
         sderived = derSchemaDAO.save(sderived);
+
         derSchemaDAO.flush();
 
-        DerSchema actual = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", actual);
-        assertEquals(sderived, actual);
+        other.add(sderived);
+        sderived.setAnyTypeClass(other);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(other, sderived.getAnyTypeClass());
 
         User owner = userDAO.find(3L);
         assertNotNull("did not get expected user", owner);
+        owner.add(other);
 
         UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
         derAttr.setOwner(owner);
@@ -165,19 +179,28 @@ public class DerAttrTest extends AbstractTest {
 
     @Test
     public void issueSYNCOPE134Group() {
+        AnyTypeClass genericMembership = anyTypeClassDAO.find("generic membership");
+
         DerSchema sderived = entityFactory.newEntity(DerSchema.class);
         sderived.setKey("sderived");
         sderived.setExpression("name");
 
         sderived = derSchemaDAO.save(sderived);
+
         derSchemaDAO.flush();
 
-        DerSchema actual = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", actual);
-        assertEquals(sderived, actual);
+        genericMembership.add(sderived);
+        sderived.setAnyTypeClass(genericMembership);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(genericMembership, sderived.getAnyTypeClass());
 
         Group owner = groupDAO.find(7L);
         assertNotNull("did not get expected group", owner);
+        owner.add(genericMembership);
 
         GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
         derAttr.setOwner(owner);

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
new file mode 100644
index 0000000..014ee64
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.UnsupportedEncodingException;
+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.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;
+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.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;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class PlainAttrTest extends AbstractTest {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void findById() {
+        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+        attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void read() {
+        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
+        assertNotNull(attribute);
+        assertTrue(attribute.getValues().isEmpty());
+        assertNotNull(attribute.getUniqueValue());
+    }
+
+    @Test
+    public void save() throws ClassNotFoundException {
+        User user = userDAO.find(1L);
+
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
+        assertNotNull(emailSchema);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(emailSchema);
+
+        Exception thrown = null;
+        try {
+            attr.add("john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+            attr.add("mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNull("no validation exception expected here ", thrown);
+
+        try {
+            attr.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNotNull("validation exception expected here ", thrown);
+    }
+
+    @Test
+    public void saveWithEnum() throws ClassNotFoundException {
+        User user = userDAO.find(1L);
+        assertNotNull(user);
+
+        PlainSchema gender = plainSchemaDAO.find("gender");
+        assertNotNull(gender);
+        assertNotNull(gender.getType());
+        assertNotNull(gender.getEnumerationValues());
+
+        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
+        attribute.setOwner(user);
+        attribute.setSchema(gender);
+        user.add(attribute);
+
+        Exception thrown = null;
+
+        try {
+            attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        } catch (ValidationException e) {
+            thrown = e;
+        }
+        assertNotNull("validation exception expected here ", thrown);
+
+        attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+
+        InvalidEntityException iee = null;
+        try {
+            userDAO.save(user);
+        } catch (InvalidEntityException e) {
+            iee = e;
+        }
+        assertNull(iee);
+    }
+
+    @Test
+    public void validateAndSave() {
+        User user = userDAO.find(1L);
+
+        PlainSchema emailSchema = plainSchemaDAO.find("email");
+        assertNotNull(emailSchema);
+
+        PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
+        assertNotNull(fullnameSchema);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(emailSchema);
+
+        UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
+        uauv.setAttr(attr);
+        uauv.setSchema(fullnameSchema);
+        uauv.setStringValue("a value");
+
+        attr.setUniqueValue(uauv);
+
+        user.add(attr);
+
+        InvalidEntityException iee = null;
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            iee = e;
+        }
+        assertNotNull(iee);
+        // for attribute
+        assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
+        // for uauv
+        assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema));
+    }
+
+    @Test
+    public void saveWithEncrypted() throws Exception {
+        User user = userDAO.find(1L);
+
+        PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
+        assertNotNull(obscureSchema);
+        assertNotNull(obscureSchema.getSecretKey());
+        assertNotNull(obscureSchema.getCipherAlgorithm());
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(obscureSchema);
+        attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+
+        UPlainAttr obscure = user.getPlainAttr("obscure");
+        assertNotNull(obscure);
+        assertEquals(1, obscure.getValues().size());
+        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
+                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
+    }
+
+    @Test
+    public void saveWithBinary() throws UnsupportedEncodingException {
+        User user = userDAO.find(1L);
+
+        PlainSchema photoSchema = plainSchemaDAO.find("photo");
+        assertNotNull(photoSchema);
+        assertNotNull(photoSchema.getMimeType());
+
+        final byte[] bytes = new byte[20];
+        new Random().nextBytes(bytes);
+        final String photoB64Value = new String(Base64.encode(bytes), SyncopeConstants.DEFAULT_ENCODING);
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(photoSchema);
+        attr.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+
+        UPlainAttr obscure = user.getPlainAttr("photo");
+        assertNotNull(obscure);
+        assertEquals(1, obscure.getValues().size());
+        assertTrue(Arrays.equals(bytes, obscure.getValues().get(0).getBinaryValue()));
+    }
+
+    @Test
+    public void delete() {
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        String attrSchemaName = attribute.getSchema().getKey();
+
+        plainAttrDAO.delete(attribute.getKey(), UPlainAttr.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/63108c8f/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
deleted file mode 100644
index ef500fe..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AttrTest.java
+++ /dev/null
@@ -1,156 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-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.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.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.UserDAO;
-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.UPlainAttr;
-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;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class AttrTest extends AbstractTest {
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Autowired
-    private PlainAttrValueDAO plainAttrValueDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Test
-    public void deleteAttribute() {
-        plainAttrDAO.delete(117L, UPlainAttr.class);
-
-        plainAttrDAO.flush();
-
-        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
-        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
-    }
-
-    @Test
-    public void deleteAttributeValue() {
-        UPlainAttrValue value = plainAttrValueDAO.find(14L, UPlainAttrValue.class);
-        int attributeValueNumber = value.getAttr().getValues().size();
-
-        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
-
-        plainAttrValueDAO.flush();
-
-        assertNull(plainAttrValueDAO.find(value.getKey(), UPlainAttrValue.class));
-
-        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
-    }
-
-    @Test
-    public void checkForEnumType() {
-        User user = userDAO.find(1L);
-        user.setPassword("password123", CipherAlgorithm.SHA);
-        assertNotNull(user);
-
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setType(AttrSchemaType.Enum);
-        schema.setKey("color");
-        schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
-
-        PlainSchema actualSchema = plainSchemaDAO.save(schema);
-        assertNotNull(actualSchema);
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setSchema(actualSchema);
-        attr.setOwner(user);
-        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        userDAO.save(user);
-        userDAO.flush();
-
-        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() {
-        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
-        sderived.setKey("sderived");
-        sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
-
-        sderived = derSchemaDAO.save(sderived);
-        derSchemaDAO.flush();
-
-        DerSchema actual = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", actual);
-        assertEquals(sderived, actual);
-
-        User owner = userDAO.find(3L);
-        assertNotNull("did not get expected user", owner);
-
-        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(sderived);
-
-        derAttr = derAttrDAO.save(derAttr);
-        derAttrDAO.flush();
-
-        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
-        assertNotNull("expected save to work", derAttr);
-
-        String value = derAttr.getValue(owner.getPlainAttrs());
-        assertNotNull(value);
-        assertFalse(value.isEmpty());
-        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
-        assertTrue(value.endsWith("[0]"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 c9b551a..b32e970 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
@@ -35,6 +35,7 @@ import org.apache.commons.collections4.Transformer;
 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.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
@@ -88,6 +89,9 @@ public class GroupTest extends AbstractTest {
     @Autowired
     private PlainAttrValueDAO plainAttrValueDAO;
 
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
     @Test(expected = InvalidEntityException.class)
     public void saveWithTwoOwners() {
         Group root = groupDAO.find("root");
@@ -154,12 +158,13 @@ public class GroupTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.add(anyTypeClassDAO.find("minimal other"));
 
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(plainSchemaDAO.find("cool"));
-        attribute.setOwner(user);
-        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attribute);
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
 
         user = userDAO.save(user);
         Long newUserKey = user.getKey();
@@ -248,11 +253,11 @@ public class GroupTest extends AbstractTest {
         anyObject.setType(anyTypeDAO.find("OTHER"));
         anyObject.setRealm(realmDAO.find("/even/two"));
 
-        APlainAttr attribute = entityFactory.newEntity(APlainAttr.class);
-        attribute.setSchema(plainSchemaDAO.find("cool"));
-        attribute.setOwner(anyObject);
-        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
-        anyObject.add(attribute);
+        APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
+        attr.setOwner(anyObject);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        anyObject.add(attr);
 
         anyObject = anyObjectDAO.save(anyObject);
         Long newAnyObjectKey = anyObject.getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
new file mode 100644
index 0000000..ae4220c
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.assertFalse;
+import static org.junit.Assert.assertNotNull;
+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.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+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.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.UserDAO;
+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.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.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 PlainAttrTest extends AbstractTest {
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void deleteAttribute() {
+        plainAttrDAO.delete(117L, UPlainAttr.class);
+
+        plainAttrDAO.flush();
+
+        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
+    }
+
+    @Test
+    public void deleteAttributeValue() {
+        UPlainAttrValue value = plainAttrValueDAO.find(14L, UPlainAttrValue.class);
+        int attributeValueNumber = value.getAttr().getValues().size();
+
+        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
+
+        plainAttrValueDAO.flush();
+
+        assertNull(plainAttrValueDAO.find(value.getKey(), UPlainAttrValue.class));
+
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        User user = userDAO.find(1L);
+        user.setPassword("password123", CipherAlgorithm.SHA);
+        assertNotNull(user);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        PlainSchema color = entityFactory.newEntity(PlainSchema.class);
+        color.setType(AttrSchemaType.Enum);
+        color.setKey("color");
+        color.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+
+        color = plainSchemaDAO.save(color);
+
+        other.add(color);
+        color.setAnyTypeClass(other);
+
+        plainSchemaDAO.flush();
+
+        color = plainSchemaDAO.find("color");
+        assertNotNull("expected save to work", color);
+        assertEquals(other, color.getAnyTypeClass());
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(color);
+        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+        userDAO.flush();
+
+        user = userDAO.find(1L);
+        assertNotNull(user);
+        assertNotNull(user.getPlainAttr(color.getKey()));
+        assertNotNull(user.getPlainAttr(color.getKey()).getValues());
+        assertEquals(user.getPlainAttr(color.getKey()).getValues().size(), 1);
+    }
+
+    @Test
+    public void derAttrFromSpecialAttrs() {
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
+
+        sderived = derSchemaDAO.save(sderived);
+
+        derSchemaDAO.flush();
+
+        other.add(sderived);
+        sderived.setAnyTypeClass(other);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(other, sderived.getAnyTypeClass());
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
+        assertTrue(value.endsWith("[0]"));
+    }
+}


[08/70] 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));
     }
 }


[07/70] 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(


[35/70] syncope git commit: [SYNCOPE-666] Final JPA tests

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/63108c8f/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 5f2504b..71fa878 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
@@ -32,6 +32,7 @@ import org.apache.commons.collections4.CollectionUtils;
 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.persistence.api.dao.AnyTypeClassDAO;
 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;
@@ -64,6 +65,9 @@ public class RoleTest extends AbstractTest {
     @Autowired
     private UserDAO userDAO;
 
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
     /**
      * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
      * required for avoiding creating new transaction - good for general use case but bad for the way how
@@ -84,12 +88,13 @@ public class RoleTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
+        user.add(anyTypeClassDAO.find("minimal other"));
 
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(plainSchemaDAO.find("cool"));
-        attribute.setOwner(user);
-        attribute.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attribute);
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
 
         user = userDAO.save(user);
         Long newUserKey = user.getKey();


[34/70] syncope git commit: [SYNCOPE-666] Several JPA tests added

Posted by il...@apache.org.
[SYNCOPE-666] Several JPA tests added


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

Branch: refs/heads/master
Commit: 419fccfeba9ebd63112e98e00350e5be90706ce8
Parents: a78a6f1
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue May 26 16:55:56 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue May 26 16:55:56 2015 +0200

----------------------------------------------------------------------
 .../common/lib/types/EntityViolationType.java   |   1 +
 .../core/persistence/api/dao/AnyObjectDAO.java  |   6 +
 .../core/persistence/api/dao/AnyTypeDAO.java    |   3 +
 .../core/persistence/api/dao/DerSchemaDAO.java  |  12 +-
 .../persistence/api/dao/PlainSchemaDAO.java     |  12 +-
 .../core/persistence/api/dao/SchemaDAO.java     |  39 +++++++
 .../core/persistence/api/dao/VirSchemaDAO.java  |  13 +--
 .../core/persistence/api/entity/Schema.java     |   4 +
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |  40 ++++++-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |  35 ++++++
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |  34 +++---
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |  17 ++-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |  15 +++
 .../core/persistence/jpa/dao/JPAUserDAO.java    |   7 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |  15 +++
 .../core/persistence/jpa/entity/JPAAnyType.java |   2 +
 .../persistence/jpa/entity/JPAAnyTypeClass.java |  25 +---
 .../persistence/jpa/entity/JPADerSchema.java    |  16 +++
 .../jpa/entity/JPAEntityFactory.java            |  22 ++++
 .../persistence/jpa/entity/JPAPlainSchema.java  |  16 +++
 .../persistence/jpa/entity/JPAVirSchema.java    |  16 +++
 .../jpa/entity/resource/JPAProvision.java       |   2 +
 .../jpa/validation/entity/AnyTypeCheck.java     |  41 +++++++
 .../jpa/validation/entity/AnyTypeValidator.java |  56 +++++++++
 .../entity/ExternalResourceValidator.java       |  28 ++++-
 .../src/main/resources/META-INF/spring-orm.xml  |  20 +++-
 .../persistence/jpa/entity/AnyObjectTest.java   |  75 ++++++++++++
 .../jpa/entity/AnyTypeClassTest.java            |  81 +++++++++++++
 .../persistence/jpa/entity/AnyTypeTest.java     | 114 +++++++++++++++++++
 .../persistence/jpa/entity/ResourceTest.java    |  51 ++++++++-
 .../jpa/relationship/AnyTypeClassTest.java      |  62 ++++++++++
 .../jpa/relationship/AnyTypeTest.java           |  66 +++++++++++
 .../persistence/jpa/relationship/GroupTest.java | 107 ++++++++++++++++-
 .../persistence/jpa/relationship/UserTest.java  |  59 +++++++++-
 .../src/test/resources/content.xml              |  96 ++++++++++------
 35 files changed, 1078 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 2192bd5..6e05a52 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
@@ -25,6 +25,7 @@ public enum EntityViolationType {
 
     Standard(""),
     InvalidAccountPolicy("org.apache.syncope.core.persistence.validation.accountpolicy"),
+    InvalidAnyType("org.apache.syncope.core.persistence.validation.anytype"),
     InvalidConnInstanceLocation("org.apache.syncope.core.persistence.validation.conninstance.location"),
     InvalidConnPoolConf("org.apache.syncope.core.persistence.validation.conninstance.poolConf"),
     InvalidMapping("org.apache.syncope.core.persistence.validation.mapping"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index d01511f..bd2f938 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -20,9 +20,11 @@ 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.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 
 public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
@@ -30,6 +32,10 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
     List<Group> findDynGroupMemberships(AnyObject anyObject);
 
+    List<ARelationship> findARelationships(AnyObject anyObject);
+
+    List<URelationship> findURelationships(AnyObject anyObject);
+
     Collection<Group> findAllGroups(AnyObject anyObject);
 
     Collection<Long> findAllGroupKeys(AnyObject anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index bef6812..32483b5 100644
--- 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
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 
 public interface AnyTypeDAO extends DAO<AnyType, String> {
 
@@ -29,6 +30,8 @@ public interface AnyTypeDAO extends DAO<AnyType, String> {
 
     AnyType findGroup();
 
+    List<AnyType> findByTypeClass(AnyTypeClass anyTypeClass);
+
     List<AnyType> findAll();
 
     AnyType save(AnyType anyType);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 d943b83..70161f9 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
@@ -18,19 +18,9 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 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> {
+public interface DerSchemaDAO extends SchemaDAO<DerSchema, DerAttr<?>> {
 
-    DerSchema find(String name);
-
-    List<DerSchema> findAll();
-
-    <T extends DerAttr<?>> List<T> findAttrs(DerSchema schema, Class<T> reference);
-
-    DerSchema save(DerSchema derSchema);
-
-    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 2dda81e..df51db4 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
@@ -18,19 +18,9 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 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> {
+public interface PlainSchemaDAO extends SchemaDAO<PlainSchema, PlainAttr<?>> {
 
-    PlainSchema find(String name);
-
-    List<PlainSchema> findAll();
-
-    <T extends PlainAttr<?>> List<T> findAttrs(PlainSchema schema, Class<T> reference);
-
-    PlainSchema save(PlainSchema derSchema);
-
-    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java
new file mode 100644
index 0000000..4b36115
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.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;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.Attr;
+import org.apache.syncope.core.persistence.api.entity.Schema;
+
+public interface SchemaDAO<S extends Schema, A extends Attr<S, ?>> extends DAO<S, String> {
+
+    S find(String name);
+
+    List<S> findByAnyTypeClass(AnyTypeClass anyTypeClass);
+
+    List<S> findAll();
+
+    <T extends A> List<T> findAttrs(S schema, Class<T> reference);
+
+    S save(S derSchema);
+
+    void delete(String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 fc6c7fa..2bcd81c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
@@ -18,19 +18,8 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 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> {
-
-    VirSchema find(String name);
-
-    List<VirSchema> findAll();
-
-    <T extends VirAttr<?>> List<T> findAttrs(VirSchema virSchema, Class<T> reference);
-
-    VirSchema save(VirSchema derSchema);
-
-    void delete(String key);
+public interface VirSchemaDAO extends SchemaDAO<VirSchema, VirAttr<?>> {
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
index cef3701..ec6bf50 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
@@ -22,6 +22,10 @@ import org.apache.syncope.common.lib.types.AttrSchemaType;
 
 public interface Schema extends Entity<String> {
 
+    AnyTypeClass getAnyTypeClass();
+
+    void setAnyTypeClass(AnyTypeClass anyTypeClass);
+
     AttrSchemaType getType();
 
     String getMandatoryCondition();

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index fd99019..298f5c4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -32,14 +32,20 @@ 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.dao.GroupDAO;
 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.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
@@ -47,6 +53,9 @@ import org.springframework.transaction.annotation.Transactional;
 @Repository
 public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObjectDAO {
 
+    @Autowired
+    private GroupDAO groupDAO;
+
     @Override
     protected AnyUtils init() {
         return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.ANY_OBJECT);
@@ -77,6 +86,35 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     }
 
     @Override
+    public List<ARelationship> findARelationships(final AnyObject anyObject) {
+        TypedQuery<ARelationship> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAARelationship.class.getSimpleName()
+                + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public List<URelationship> findURelationships(final AnyObject anyObject) {
+        TypedQuery<URelationship> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAURelationship.class.getSimpleName()
+                + " e WHERE e.rightEnd=:anyObject", URelationship.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public AnyObject save(final AnyObject anyObject) {
+        AnyObject merged = super.save(anyObject);
+
+        groupDAO.refreshDynMemberships(merged);
+
+        return merged;
+    }
+
+    @Override
     public void delete(final AnyObject any) {
         for (Group group : findDynGroupMemberships(any)) {
             group.getADynMembership().remove(any);
@@ -90,7 +128,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     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);
+                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);
 
         return query.getResultList();

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 4d82d31..3339c9a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -21,13 +21,34 @@ 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.dao.AnyTypeDAO;
+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.VirSchemaDAO;
+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.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.JPAAnyTypeClass;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
 @Repository
 public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implements AnyTypeClassDAO {
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
     @Override
     public AnyTypeClass find(final String key) {
         return entityManager.find(JPAAnyTypeClass.class, key);
@@ -52,6 +73,20 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
             return;
         }
 
+        for (PlainSchema schema : plainSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+        for (DerSchema schema : derSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+        for (VirSchema schema : virSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+
+        for (AnyType type : anyTypeDAO.findByTypeClass(anyTypeClass)) {
+            type.remove(anyTypeClass);
+        }
+
         entityManager.remove(anyTypeClass);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index bbbf859..4342811 100644
--- 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
@@ -23,9 +23,9 @@ 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.api.entity.AnyTypeClass;
 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 {
@@ -35,27 +35,25 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
         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);
+        return find(AnyTypeKind.USER.name());
     }
 
-    @Transactional(readOnly = false)
     @Override
     public AnyType findGroup() {
-        return find(AnyTypeKind.GROUP);
+        return find(AnyTypeKind.GROUP.name());
+    }
+
+    public List<AnyType> findByTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAAnyType.class.getSimpleName()).
+                append(" e WHERE :anyTypeClass MEMBER OF e.classes");
+
+        TypedQuery<AnyType> query = entityManager.createQuery(queryString.toString(), AnyType.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
     }
 
     @Override
@@ -77,6 +75,10 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
             return;
         }
 
+        if (anyType.equals(findUser()) || anyType.equals(findGroup())) {
+            throw new IllegalArgumentException(key + " cannot be deleted");
+        }
+
         entityManager.remove(anyType);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 c3c10bf..a849ef5 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
@@ -24,6 +24,7 @@ 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.AnyTypeClass;
 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;
@@ -48,6 +49,18 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
     }
 
     @Override
+    public List<DerSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPADerSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<DerSchema> query = entityManager.createQuery(queryString.toString(), DerSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<DerSchema> findAll() {
         TypedQuery<DerSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
@@ -56,7 +69,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public <T extends DerAttr<?>> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
-        final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
@@ -89,6 +102,8 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
             resourceDAO.deleteMapping(key, anyUtils.derIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 a922946..50865c3 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
@@ -24,6 +24,7 @@ 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.AnyTypeClass;
 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;
@@ -48,6 +49,18 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
     }
 
     @Override
+    public List<PlainSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAPlainSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<PlainSchema> query = entityManager.createQuery(queryString.toString(), PlainSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<PlainSchema> findAll() {
         TypedQuery<PlainSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class);
@@ -89,6 +102,8 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             resourceDAO.deleteMapping(key, anyUtils.plainIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 8c6aaa7..7045ddc 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
@@ -45,7 +45,6 @@ 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.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;
@@ -152,11 +151,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User save(final User user) {
-        User merged = entityManager.merge(user);
-        for (UVirAttr virAttr : merged.getVirAttrs()) {
-            virAttr.getValues().clear();
-            virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues());
-        }
+        User merged = super.save(user);
 
         roleDAO.refreshDynMemberships(merged);
         groupDAO.refreshDynMemberships(merged);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 ed4f6b6..cc4ffe4 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
@@ -24,6 +24,7 @@ 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.AnyTypeClass;
 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;
@@ -48,6 +49,18 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
     }
 
     @Override
+    public List<VirSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAVirSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<VirSchema> query = entityManager.createQuery(queryString.toString(), VirSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<VirSchema> findAll() {
         TypedQuery<VirSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
@@ -89,6 +102,8 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
             resourceDAO.deleteMapping(key, anyUtils.virIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 2615520..d50cdba 100644
--- 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
@@ -34,9 +34,11 @@ 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;
+import org.apache.syncope.core.persistence.jpa.validation.entity.AnyTypeCheck;
 
 @Entity
 @Table(name = JPAAnyType.TABLE)
+@AnyTypeCheck
 @Cacheable
 public class JPAAnyType extends AbstractEntity<String> implements AnyType {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 5c52097..e4f0db9 100644
--- 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
@@ -21,12 +21,9 @@ 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;
@@ -46,25 +43,13 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     @Id
     private String name;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "anyTypeClass_name"),
-            inverseJoinColumns =
-            @JoinColumn(name = "plainSchema_name"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     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"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     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"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     private List<JPAVirSchema> virSchemas = new ArrayList<>();
 
     @Override
@@ -102,7 +87,7 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
 
     @Override
     public boolean remove(final DerSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
+        checkType(facet, JPADerSchema.class);
         return this.derSchemas.remove((JPADerSchema) facet);
     }
 
@@ -119,7 +104,7 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
 
     @Override
     public boolean remove(final VirSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
+        checkType(facet, JPAVirSchema.class);
         return this.virSchemas.remove((JPAVirSchema) facet);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 0b9a31b..62fc5d6 100644
--- 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
@@ -22,8 +22,10 @@ import javax.persistence.Cacheable;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
 
@@ -40,6 +42,9 @@ public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Column(nullable = false)
     private String expression;
 
@@ -54,6 +59,17 @@ public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public String getExpression() {
         return expression;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 92f9855..6a152b0 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
@@ -22,6 +22,8 @@ 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.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 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.DerSchema;
@@ -43,7 +45,11 @@ 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.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.ARelationship;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 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;
@@ -77,7 +83,11 @@ 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.anyobject.JPAADynGroupMembership;
 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.JPAAnyObject;
 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;
@@ -128,6 +138,12 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAPushPolicy();
         } else if (reference.equals(SyncPolicy.class)) {
             result = (T) new JPASyncPolicy();
+        } else if (reference.equals(AnyTypeClass.class)) {
+            result = (T) new JPAAnyTypeClass();
+        } else if (reference.equals(AnyType.class)) {
+            result = (T) new JPAAnyType();
+        } else if (reference.equals(AnyObject.class)) {
+            result = (T) new JPAAnyObject();
         } else if (reference.equals(Role.class)) {
             result = (T) new JPARole();
         } else if (reference.equals(User.class)) {
@@ -156,6 +172,12 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAConnInstance();
         } else if (reference.equals(PlainSchema.class)) {
             result = (T) new JPAPlainSchema();
+        } else if (reference.equals(APlainAttr.class)) {
+            result = (T) new JPAAPlainAttr();
+        } else if (reference.equals(APlainAttrValue.class)) {
+            result = (T) new JPAAPlainAttrValue();
+        } else if (reference.equals(APlainAttrUniqueValue.class)) {
+            result = (T) new JPAAPlainAttrUniqueValue();
         } else if (reference.equals(UPlainAttr.class)) {
             result = (T) new JPAUPlainAttr();
         } else if (reference.equals(UPlainAttrValue.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 5f767e0..d4935e9 100644
--- 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
@@ -26,6 +26,7 @@ import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.Lob;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.Transient;
 import javax.validation.constraints.Max;
@@ -34,6 +35,7 @@ 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.AnyTypeClass;
 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;
@@ -52,6 +54,9 @@ public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchem
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Column(nullable = false)
     @Enumerated(EnumType.STRING)
     private AttrSchemaType type;
@@ -122,6 +127,17 @@ public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchem
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public AttrSchemaType getType() {
         return type;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index f7cf717..d268aff 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
@@ -22,10 +22,12 @@ import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.OneToOne;
 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.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
 
@@ -42,6 +44,9 @@ public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Basic
     @Min(0)
     @Max(1)
@@ -64,6 +69,17 @@ public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public AttrSchemaType getType() {
         return AttrSchemaType.String;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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
index 273b79d..8e13879 100644
--- 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
@@ -27,6 +27,7 @@ import javax.persistence.ManyToOne;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
+import javax.validation.constraints.NotNull;
 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;
@@ -55,6 +56,7 @@ public class JPAProvision extends AbstractEntity<Long> implements Provision {
     @ManyToOne
     private JPAAnyType anyType;
 
+    @NotNull
     private String objectClass;
 
     @Lob

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java
new file mode 100644
index 0000000..957fd71
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.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.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = AnyTypeValidator.class)
+@Documented
+public @interface AnyTypeCheck {
+
+    String message() default "{org.apache.syncope.core.persistence.validation.anytype}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
new file mode 100644
index 0000000..5619295
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+
+public class AnyTypeValidator extends AbstractValidator<AnyTypeCheck, AnyType> {
+
+    @Override
+    public boolean isValid(final AnyType object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        boolean isValid;
+        switch (object.getKind()) {
+            case USER:
+                isValid = AnyTypeKind.USER.name().equalsIgnoreCase(object.getKey());
+                break;
+
+            case GROUP:
+                isValid = AnyTypeKind.GROUP.name().equalsIgnoreCase(object.getKey());
+                break;
+
+            case ANY_OBJECT:
+            default:
+                isValid = !AnyTypeKind.USER.name().equalsIgnoreCase(object.getKey())
+                        && !AnyTypeKind.GROUP.name().equalsIgnoreCase(object.getKey());
+        }
+
+        if (!isValid) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidAnyType, "Name / kind mismatch")).
+                    addPropertyNode("name").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 f888374..9ad2082 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
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
+import java.util.HashSet;
+import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
@@ -138,12 +140,26 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             }
         }
 
-        return CollectionUtils.matchesAll(resource.getProvisions(), new Predicate<Provision>() {
+        final Set<String> objectClasses = new HashSet<>();
+        boolean validMappings = CollectionUtils.matchesAll(resource.getProvisions(),
+                new Predicate<Provision>() {
+
+                    @Override
+                    public boolean evaluate(final Provision provision) {
+                        if (provision.getObjectClass() != null) {
+                            objectClasses.add(provision.getObjectClass().getObjectClassValue());
+                        }
+                        return isValid(provision.getAnyType(), provision.getMapping(), context);
+                    }
+                });
+
+        if (objectClasses.size() < resource.getProvisions().size()) {
+            context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,
+                    "Each provision requires a different ObjectClass")).
+                    addPropertyNode("provisions").addConstraintViolation();
+            return false;
+        }
 
-            @Override
-            public boolean evaluate(final Provision provision) {
-                return isValid(provision.getAnyType(), provision.getMapping(), context);
-            }
-        });
+        return validMappings;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 9d300d0..746314c 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
@@ -66,6 +66,15 @@ under the License.
     </attributes>
   </entity>
   
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_AMembership" pk-column-value="SEQ_AMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole">
     <attributes>
       <id name="id">
@@ -83,7 +92,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  
+
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
     <attributes>
       <id name="id">
@@ -102,6 +111,15 @@ under the License.
     </attributes>
   </entity>
   
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_UMembership" pk-column-value="SEQ_UMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup">
     <attributes>
       <id name="id">

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
new file mode 100644
index 0000000..e3a4a74
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+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.anyobject.AnyObject;
+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 AnyObjectTest extends AbstractTest {
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<AnyObject> list = anyObjectDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void find() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        assertNotNull(anyObject);
+        assertNotNull(anyObject.getType());
+        assertFalse(anyObject.getType().getClasses().isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
+
+        anyObject = anyObjectDAO.save(anyObject);
+        assertNotNull(anyObject);
+    }
+
+    @Test
+    public void delete() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        anyObjectDAO.delete(anyObject.getKey());
+
+        AnyObject actual = anyObjectDAO.find(2L);
+        assertNull(actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
new file mode 100644
index 0000000..c77ea93
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.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.core.persistence.jpa.entity;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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 AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyTypeClass minimalGroup = anyTypeClassDAO.find("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyTypeClass> list = anyTypeClassDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyTypeClass newClass = entityFactory.newEntity(AnyTypeClass.class);
+        newClass.setKey("new class");
+        newClass.add(plainSchemaDAO.find("firstname"));
+
+        newClass = anyTypeClassDAO.save(newClass);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        anyTypeClassDAO.delete(minimalUser.getKey());
+        assertNull(anyTypeClassDAO.find("minimal user"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
new file mode 100644
index 0000000..2337a32
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.assertNull;
+
+import java.util.List;
+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.AnyTypeClassDAO;
+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.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyType groupType = anyTypeDAO.findGroup();
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyType otherType = anyTypeDAO.find("OTHER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("OTHER", otherType.getKey());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyType> list = anyTypeDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.add(anyTypeClassDAO.find("generic membership"));
+        newType.add(anyTypeClassDAO.find("csv"));
+
+        newType = anyTypeDAO.save(newType);
+        assertNotNull(newType);
+        assertFalse(newType.getClasses().isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidKind() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidName() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test
+    public void delete() {
+        AnyType otherType = anyTypeDAO.find("OTHER");
+        assertNotNull(otherType);
+
+        anyTypeDAO.delete(otherType.getKey());
+        assertNull(anyTypeDAO.find("OTHER"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void deleteInvalid() {
+        anyTypeDAO.delete(anyTypeDAO.findUser().getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 ad6c37c..5fd6f53 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
@@ -41,6 +41,7 @@ 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.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -108,6 +109,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -146,6 +148,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -159,8 +162,7 @@ public class ResourceTest extends AbstractTest {
         mapping.add(connObjectKey);
 
         // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -173,6 +175,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -186,8 +189,7 @@ public class ResourceTest extends AbstractTest {
         mapping.setConnObjectKeyItem(connObjectKey);
 
         // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
     }
 
     @Test(expected = InvalidEntityException.class)
@@ -200,6 +202,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -218,8 +221,42 @@ public class ResourceTest extends AbstractTest {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         mapping.add(item);
 
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidProvision() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("invalidProvision");
+
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("fullname");
+        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(connObjectKey);
+
+        provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findGroup());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        // save the resource
+        resourceDAO.save(resource);
     }
 
     @Test
@@ -232,6 +269,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -312,6 +350,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
new file mode 100644
index 0000000..4b5f2f5
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+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 AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        PlainSchema surname = plainSchemaDAO.find("surname");
+        assertNotNull(surname);
+        assertTrue(minimalUser.getPlainSchemas().contains(surname));
+        int before = minimalUser.getPlainSchemas().size();
+
+        plainSchemaDAO.delete("surname");
+
+        anyTypeClassDAO.flush();
+
+        minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+        assertEquals(before, minimalUser.getPlainSchemas().size() + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
new file mode 100644
index 0000000..e6a919d
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.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.jpa.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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 AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+        assertNotNull(other);
+        assertTrue(userType.getClasses().contains(other));
+        int before = userType.getClasses().size();
+
+        anyTypeClassDAO.delete("other");
+
+        try {
+        anyTypeDAO.flush();
+        } catch(Exception e) {
+            System.err.println("EEEEEEEEEEEE");
+            e.printStackTrace();
+        }
+        
+        userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(before, userType.getClasses().size() + 1);
+    }
+}


[61/70] syncope git commit: Merge branch 'master' into SYNCOPE-666

Posted by il...@apache.org.
Merge branch 'master' into SYNCOPE-666


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

Branch: refs/heads/master
Commit: 6239afa23516938740b5be9ef791bb724ffd1252
Parents: a45a46b 2e5fc7e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jun 10 16:02:35 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jun 10 16:02:35 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/6239afa2/pom.xml
----------------------------------------------------------------------


[06/70] 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());
     }
 }


[49/70] syncope git commit: [SYNCOPE-666] Cleanup

Posted by il...@apache.org.
[SYNCOPE-666] Cleanup


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

Branch: refs/heads/master
Commit: a64ef15f1dd69b09226c4dac27551cfd3988c7e9
Parents: 1da1ea4
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 5 18:04:33 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 5 18:04:33 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/to/AnyTypeClassTO.java   |  6 +--
 .../apache/syncope/common/lib/to/AnyTypeTO.java |  6 +--
 .../common/lib/to/ConnIdObjectClassTO.java      |  2 +-
 .../common/lib/to/PropagationStatus.java        |  3 --
 .../syncope/common/lib/to/ResourceTO.java       |  9 ++--
 .../common/lib/types/IntMappingType.java        | 18 +++----
 .../syncope/common/rest/api/RESTHeaders.java    | 13 +----
 .../rest/api/service/ConnectorService.java      | 54 ++++++++++----------
 .../rest/api/service/ResourceService.java       | 34 ++++++------
 .../syncope/core/misc/ConnObjectUtils.java      |  4 +-
 .../apache/syncope/core/misc/MappingUtils.java  |  6 +--
 .../jpa/entity/resource/JPAMappingItem.java     |  6 +--
 .../persistence/jpa/entity/ResourceTest.java    |  4 +-
 .../jpa/relationship/ResourceTest.java          |  2 +-
 .../src/test/resources/content.xml              |  4 +-
 .../core/provisioning/java/sync/SyncUtils.java  |  6 +--
 .../rest/cxf/service/AbstractServiceImpl.java   |  2 +-
 .../cxf/service/AnyTypeClassServiceImpl.java    |  2 +-
 .../rest/cxf/service/AnyTypeServiceImpl.java    |  2 +-
 .../rest/cxf/service/ConnectorServiceImpl.java  | 26 +++++-----
 .../cxf/service/NotificationServiceImpl.java    |  2 +-
 .../rest/cxf/service/PolicyServiceImpl.java     |  2 +-
 .../core/rest/cxf/service/RealmServiceImpl.java |  2 +-
 .../rest/cxf/service/ReportServiceImpl.java     |  2 +-
 .../rest/cxf/service/ResourceServiceImpl.java   | 36 ++++++-------
 .../core/rest/cxf/service/RoleServiceImpl.java  |  2 +-
 .../rest/cxf/service/SchemaServiceImpl.java     |  2 +-
 .../service/SecurityQuestionServiceImpl.java    |  2 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |  2 +-
 .../rest/cxf/service/UserSelfServiceImpl.java   |  2 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |  2 +-
 .../fit/core/reference/AbstractITCase.java      |  2 +-
 .../syncope/fit/core/reference/GroupITCase.java |  2 +-
 .../fit/core/reference/ResourceITCase.java      | 16 +++---
 34 files changed, 135 insertions(+), 150 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
index 1afbe4d..9b696f8 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -33,7 +33,7 @@ public class AnyTypeClassTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = -591757688607551266L;
 
-    private String name;
+    private String key;
 
     private final List<String> plainSchemas = new ArrayList<>();
 
@@ -42,11 +42,11 @@ public class AnyTypeClassTO extends AbstractBaseBean {
     private final List<String> virSchemas = new ArrayList<>();
 
     public String getKey() {
-        return name;
+        return key;
     }
 
     public void setKey(final String key) {
-        this.name = key;
+        this.key = key;
     }
 
     @XmlElementWrapper(name = "plainSchemas")

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
index 9618bf5..3722b81 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
@@ -34,18 +34,18 @@ public class AnyTypeTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 6771657557616874373L;
 
-    private String name;
+    private String key;
 
     private AnyTypeKind kind;
 
     private final List<String> classes = new ArrayList<>();
 
     public String getKey() {
-        return name;
+        return key;
     }
 
     public void setKey(final String key) {
-        this.name = key;
+        this.key = key;
     }
 
     public AnyTypeKind getKind() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
index 14810bb..c562b69 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
@@ -38,7 +38,7 @@ public class ConnIdObjectClassTO extends AbstractBaseBean {
         ACCOUNT("__ACCOUNT__"),
         GROUP("__GROUP__");
 
-        private String specialName;
+        private final String specialName;
 
         private DefaultType(final String specialName) {
             this.specialName = specialName;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
index de844be..38a8da7 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationStatus.java
@@ -30,9 +30,6 @@ import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
 @XmlType
 public class PropagationStatus extends AbstractBaseBean {
 
-    /**
-     * Serial version ID.
-     */
     private static final long serialVersionUID = 3921498450222857690L;
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 dcec457..7fbac89 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
@@ -40,10 +40,7 @@ public class ResourceTO extends AbstractAnnotatedBean {
 
     private static final long serialVersionUID = -9193551354041698963L;
 
-    /**
-     * The resource identifier is the name.
-     */
-    private String name;
+    private String key;
 
     /**
      * The resource type is identified by the associated connector.
@@ -98,11 +95,11 @@ public class ResourceTO extends AbstractAnnotatedBean {
     }
 
     public String getKey() {
-        return name;
+        return key;
     }
 
     public void setKey(final String key) {
-        this.name = key;
+        this.key = key;
     }
 
     public boolean isEnforceMandatoryCondition() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 1b50f43..3537bc5 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
@@ -38,7 +38,7 @@ public enum IntMappingType {
     UserPlainSchema(AnyTypeKind.USER),
     UserDerivedSchema(AnyTypeKind.USER),
     UserVirtualSchema(AnyTypeKind.USER),
-    UserId(AnyTypeKind.USER),
+    UserKey(AnyTypeKind.USER),
     Username(AnyTypeKind.USER),
     Password(AnyTypeKind.USER),
     // -------------------------
@@ -47,7 +47,7 @@ public enum IntMappingType {
     GroupPlainSchema(AnyTypeKind.GROUP),
     GroupDerivedSchema(AnyTypeKind.GROUP),
     GroupVirtualSchema(AnyTypeKind.GROUP),
-    GroupId(AnyTypeKind.GROUP),
+    GroupKey(AnyTypeKind.GROUP),
     GroupName(AnyTypeKind.GROUP),
     GroupOwnerSchema(AnyTypeKind.GROUP),
     // -------------------------
@@ -56,7 +56,7 @@ public enum IntMappingType {
     AnyPlainSchema(AnyTypeKind.ANY_OBJECT),
     AnyDerivedSchema(AnyTypeKind.ANY_OBJECT),
     AnyVirtualSchema(AnyTypeKind.ANY_OBJECT),
-    AnyId(AnyTypeKind.ANY_OBJECT);
+    AnyKey(AnyTypeKind.ANY_OBJECT);
 
     private final AnyTypeKind anyTypeKind;
 
@@ -117,9 +117,9 @@ public enum IntMappingType {
     }
 
     public static Set<IntMappingType> getEmbedded() {
-        return EnumSet.of(IntMappingType.UserId, IntMappingType.Username, IntMappingType.Password,
-                IntMappingType.GroupId, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema,
-                IntMappingType.AnyId);
+        return EnumSet.of(IntMappingType.UserKey, IntMappingType.Username, IntMappingType.Password,
+                IntMappingType.GroupKey, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema,
+                IntMappingType.AnyKey);
     }
 
     /**
@@ -167,7 +167,7 @@ public enum IntMappingType {
         UserPlainSchema,
         UserDerivedSchema,
         UserVirtualSchema,
-        UserId,
+        UserKey,
         Username,
         Password;
 
@@ -181,7 +181,7 @@ public enum IntMappingType {
         GroupPlainSchema,
         GroupDerivedSchema,
         GroupVirtualSchema,
-        GroupId,
+        GroupKey,
         GroupName,
         GroupOwnerSchema;
 
@@ -195,7 +195,7 @@ public enum IntMappingType {
         AnyPlainSchema,
         AnyDerivedSchema,
         AnyVirtualSchema,
-        AnyId;
+        AnyKey;
 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 307bbba..4d19e31 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -23,22 +23,13 @@ package org.apache.syncope.common.rest.api;
  */
 public final class RESTHeaders {
 
-    /**
-     * UserId option key.
-     */
-    public static final String USER_ID = "X-Syncope-User-Id";
+    public static final String USER_KEY = "X-Syncope-User-Key";
 
-    /**
-     * Username option key.
-     */
     public static final String USERNAME = "X-Syncope-Username";
 
     public static final String OWNED_ENTITLEMENTS = "X-Syncope-Entitlements";
 
-    /**
-     * HTTP header key for object ID assigned to an object after its creation.
-     */
-    public static final String RESOURCE_ID = "X-Syncope-Id";
+    public static final String RESOURCE_KEY = "X-Syncope-Key";
 
     /**
      * Declares the type of exception being raised.

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index 91d982e..ede49be 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -63,56 +63,56 @@ public interface ConnectorService extends JAXRSService {
     /**
      * Returns configuration for given connector instance.
      *
-     * @param connInstanceKey connector instance id to read configuration from
+     * @param key connector instance key to read configuration from
      * @return configuration for given connector instance
      */
     @GET
-    @Path("{connInstanceKey}/configuration")
+    @Path("{key}/configuration")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<ConnConfProperty> getConfigurationProperties(@NotNull @PathParam("connInstanceKey") Long connInstanceKey);
+    List<ConnConfProperty> getConfigurationProperties(@NotNull @PathParam("key") Long key);
 
     /**
-     * Returns schema names for connector bundle matching the given connector instance id.
+     * Returns schema names for connector bundle matching the given connector instance key.
      *
-     * @param connInstanceKey connector instance id to be used for schema lookup
+     * @param key connector instance key to be used for schema lookup
      * @param connInstanceTO connector instance object to provide special configuration properties
      * @param includeSpecial if set to true, special schema names (like '__PASSWORD__') will be included;
      * default is false
-     * @return schema names for connector bundle matching the given connector instance id
+     * @return schema names for connector bundle matching the given connector instance key
      */
     @POST
-    @Path("{connInstanceKey}/schemaNames")
+    @Path("{key}/schemaNames")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<PlainSchemaTO> getSchemaNames(@NotNull @PathParam("connInstanceKey") Long connInstanceKey,
+    List<PlainSchemaTO> getSchemaNames(@NotNull @PathParam("key") Long key,
             @NotNull ConnInstanceTO connInstanceTO,
             @QueryParam("includeSpecial") @DefaultValue("false") boolean includeSpecial);
 
     /**
-     * Returns supported object classes for connector bundle matching the given connector instance id.
+     * Returns supported object classes for connector bundle matching the given connector instance key.
      *
-     * @param connInstanceKey connector instance id to be used for schema lookup
+     * @param key connector instance key to be used for schema lookup
      * @param connInstanceTO connector instance object to provide special configuration properties
-     * @return supported object classes for connector bundle matching the given connector instance id
+     * @return supported object classes for connector bundle matching the given connector instance key
      */
     @POST
-    @Path("{connInstanceKey}/supportedObjectClasses")
+    @Path("{key}/supportedObjectClasses")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     List<ConnIdObjectClassTO> getSupportedObjectClasses(
-            @NotNull @PathParam("connInstanceKey") Long connInstanceKey,
+            @NotNull @PathParam("key") Long key,
             @NotNull ConnInstanceTO connInstanceTO);
 
     /**
-     * Returns connector instance with matching id.
+     * Returns connector instance with matching key.
      *
-     * @param connInstanceKey connector instance id to be read
-     * @return connector instance with matching id
+     * @param key connector instance key to be read
+     * @return connector instance with matching key
      */
     @GET
-    @Path("{connInstanceKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ConnInstanceTO read(@NotNull @PathParam("connInstanceKey") Long connInstanceKey);
+    ConnInstanceTO read(@NotNull @PathParam("key") Long key);
 
     /**
      * Returns connector instance for matching resource.
@@ -151,24 +151,24 @@ public interface ConnectorService extends JAXRSService {
     Response create(@NotNull ConnInstanceTO connInstanceTO);
 
     /**
-     * Updates the connector instance matching the provided id.
+     * Updates the connector instance matching the provided key.
      *
-     * @param connInstanceKey connector instance id to be updated
+     * @param key connector instance key to be updated
      * @param connInstanceTO connector instance to be stored
      */
     @PUT
-    @Path("{connInstanceKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("connInstanceKey") Long connInstanceKey, @NotNull ConnInstanceTO connInstanceTO);
+    void update(@NotNull @PathParam("key") Long key, @NotNull ConnInstanceTO connInstanceTO);
 
     /**
-     * Deletes the connector instance matching the provided id.
+     * Deletes the connector instance matching the provided key.
      *
-     * @param connInstanceKey connector instance id to be deleted
+     * @param key connector instance key to be deleted
      */
     @DELETE
-    @Path("{connInstanceKey}")
-    void delete(@NotNull @PathParam("connInstanceKey") Long connInstanceKey);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 
     /**
      * @param connInstanceTO connector instance to be used for connection check
@@ -190,7 +190,7 @@ public interface ConnectorService extends JAXRSService {
     /**
      * Executes the provided bulk action.
      *
-     * @param bulkAction list of connector instance ids against which the bulk action will be performed.
+     * @param bulkAction list of connector instance keys against which the bulk action will be performed.
      * @return Bulk action result
      */
     @POST

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 48ba21a..4656dce 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
@@ -49,27 +49,27 @@ 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 key Name of resource to read connector object from
      * @param anyTypeKey any object type
-     * @param key any object key
+     * @param anyKey any object key
      * @return connector object from the external resource, for the given type and key
      */
     @GET
-    @Path("{resourceKey}/{anyTypeKey}/{key}")
+    @Path("{key}/{anyTypeKey}/{anyKey}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ConnObjectTO readConnObject(@NotNull @PathParam("resourceKey") String resourceKey,
-            @NotNull @PathParam("anyTypeKey") String anyTypeKey, @NotNull @PathParam("key") Long key);
+    ConnObjectTO readConnObject(@NotNull @PathParam("key") String key,
+            @NotNull @PathParam("anyTypeKey") String anyTypeKey, @NotNull @PathParam("anyKey") Long anyKey);
 
     /**
      * Returns the resource with matching name.
      *
-     * @param resourceKey Name of resource to be read
+     * @param key Name of resource to be read
      * @return resource with matching name
      */
     @GET
-    @Path("{resourceKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ResourceTO read(@NotNull @PathParam("resourceKey") String resourceKey);
+    ResourceTO read(@NotNull @PathParam("key") String key);
 
     /**
      * Returns a list of all resources.
@@ -97,23 +97,23 @@ public interface ResourceService extends JAXRSService {
     /**
      * Updates the resource matching the given name.
      *
-     * @param resourceKey name of resource to be updated
+     * @param key name of resource to be updated
      * @param resourceTO resource to be stored
      */
     @PUT
-    @Path("{resourceKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("resourceKey") String resourceKey, @NotNull ResourceTO resourceTO);
+    void update(@NotNull @PathParam("key") String key, @NotNull ResourceTO resourceTO);
 
     /**
      * Deletes the resource matching the given name.
      *
-     * @param resourceKey name of resource to be deleted
+     * @param key name of resource to be deleted
      */
     @DELETE
-    @Path("{resourceKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void delete(@NotNull @PathParam("resourceKey") String resourceKey);
+    void delete(@NotNull @PathParam("key") String key);
 
     /**
      * Checks whether the connection to resource could be established.
@@ -129,7 +129,7 @@ public interface ResourceService extends JAXRSService {
     /**
      * De-associate any objects from the given resource.
      *
-     * @param resourceKey name of resource
+     * @param key name of resource
      * @param anyTypeKey any object kind
      * @param type resource de-association action type
      * @param keys any object keys against which the bulk action will be performed
@@ -140,10 +140,10 @@ public interface ResourceService extends JAXRSService {
                 value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
     })
     @POST
-    @Path("{resourceKey}/bulkDeassociation/{anyTypeKey}/{type}")
+    @Path("{key}/bulkDeassociation/{anyTypeKey}/{type}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    BulkActionResult bulkDeassociation(@NotNull @PathParam("resourceKey") String resourceKey,
+    BulkActionResult bulkDeassociation(@NotNull @PathParam("key") String key,
             @NotNull @PathParam("anyTypeKey") String anyTypeKey,
             @NotNull @PathParam("type") ResourceDeassociationActionType type, @NotNull List<AnyKey> keys);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 766c5cf..c86ee7c 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
@@ -204,8 +204,8 @@ public class ConnObjectUtils {
 
             AttrTO attrTO;
             switch (item.getIntMappingType()) {
-                case UserId:
-                case GroupId:
+                case UserKey:
+                case GroupKey:
                     break;
 
                 case Password:

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 2efae81..97008d0 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
@@ -528,9 +528,9 @@ public final class MappingUtils {
                 }
                 break;
 
-            case UserId:
-            case GroupId:
-            case AnyId:
+            case UserKey:
+            case GroupKey:
+            case AnyKey:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     attrValue = anyUtils.newPlainAttrValue();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
index d9c1af2..2aa587f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -141,9 +141,9 @@ public class JPAMappingItem extends AbstractEntity<Long> implements MappingItem
         final String name;
 
         switch (getIntMappingType()) {
-            case UserId:
-            case GroupId:
-            case AnyId:
+            case UserKey:
+            case GroupKey:
+            case AnyKey:
                 name = "id";
                 break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 5fd6f53..ee9a9f7 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
@@ -120,7 +120,7 @@ public class ResourceTest extends AbstractTest {
         MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("fullname");
-        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
         connObjectKey.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(connObjectKey);
 
@@ -242,7 +242,7 @@ public class ResourceTest extends AbstractTest {
         MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("fullname");
-        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
         connObjectKey.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(connObjectKey);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 33e8669..8e1e554 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
@@ -138,7 +138,7 @@ public class ResourceTest extends AbstractTest {
         MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
         connObjectKey.setExtAttrName("username");
         connObjectKey.setIntAttrName("username");
-        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
         connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
         mapping.setConnObjectKeyItem(connObjectKey);
         connObjectKey.setMapping(mapping);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 7c123a7..b61cb95 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -676,7 +676,7 @@ under the License.
   <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"
+               intMappingType="UserKey" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
   <MappingItem id="100" extAttrName="email" mapping_id="15"
                intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
@@ -907,7 +907,7 @@ under the License.
   <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" 
+               extAttrName="id" intMappingType="UserKey" 
                mandatoryCondition="true" purpose="BOTH"/>
   <MappingItem id="332" mapping_id="17" connObjectKey="0" password="0" 
                extAttrName="USERNAME" intAttrName="virtualdata" intMappingType="UserVirtualSchema"

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 b748345..71ad319 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
@@ -197,9 +197,9 @@ public class SyncUtils {
                 }
                 break;
 
-            case UserId:
-            case GroupId:
-            case AnyId:
+            case UserKey:
+            case GroupKey:
+            case AnyKey:
                 Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
                 if (any != null) {
                     result.add(any.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
index c65a409..a594bac 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
@@ -84,7 +84,7 @@ abstract class AbstractServiceImpl implements JAXRSService {
     protected Response createResponse(final Object id, final Object entity) {
         Response.ResponseBuilder builder = Response.
                 created(uriInfo.getAbsolutePathBuilder().path(String.valueOf(id)).build()).
-                header(RESTHeaders.RESOURCE_ID, id);
+                header(RESTHeaders.RESOURCE_KEY, id);
 
         switch (getPreference()) {
             case RETURN_NO_CONTENT:

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
index 47cdde2..3683e61 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
@@ -49,7 +49,7 @@ public class AnyTypeClassServiceImpl extends AbstractServiceImpl implements AnyT
         AnyTypeClassTO created = logic.create(anyTypeTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
index 9b289d5..bb3c699 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
@@ -49,7 +49,7 @@ public class AnyTypeServiceImpl extends AbstractServiceImpl implements AnyTypeSe
         AnyTypeTO created = logic.create(anyTypeTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index 9f6099c..ac26aad 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -48,13 +48,13 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
         ConnInstanceTO connInstance = logic.create(connInstanceTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(connInstance.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, connInstance.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, connInstance.getKey()).
                 build();
     }
 
     @Override
-    public void delete(final Long connInstanceKey) {
-        logic.delete(connInstanceKey);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 
     @Override
@@ -63,15 +63,15 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public List<ConnConfProperty> getConfigurationProperties(final Long connInstanceKey) {
-        return logic.getConfigurationProperties(connInstanceKey);
+    public List<ConnConfProperty> getConfigurationProperties(final Long key) {
+        return logic.getConfigurationProperties(key);
     }
 
     @Override
-    public List<PlainSchemaTO> getSchemaNames(final Long connInstanceKey, final ConnInstanceTO connInstanceTO,
+    public List<PlainSchemaTO> getSchemaNames(final Long key, final ConnInstanceTO connInstanceTO,
             final boolean includeSpecial) {
 
-        connInstanceTO.setKey(connInstanceKey);
+        connInstanceTO.setKey(key);
 
         return CollectionUtils.collect(logic.getSchemaNames(connInstanceTO, includeSpecial),
                 new Transformer<String, PlainSchemaTO>() {
@@ -86,10 +86,10 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long connInstanceKey,
+    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long key,
             final ConnInstanceTO connInstanceTO) {
 
-        connInstanceTO.setKey(connInstanceKey);
+        connInstanceTO.setKey(key);
 
         List<String> objectClasses = logic.getSupportedObjectClasses(connInstanceTO);
         List<ConnIdObjectClassTO> result = new ArrayList<>(objectClasses.size());
@@ -105,8 +105,8 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public ConnInstanceTO read(final Long connInstanceKey) {
-        return logic.read(connInstanceKey);
+    public ConnInstanceTO read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
@@ -115,8 +115,8 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public void update(final Long connInstanceKey, final ConnInstanceTO connInstanceTO) {
-        connInstanceTO.setKey(connInstanceKey);
+    public void update(final Long key, final ConnInstanceTO connInstanceTO) {
+        connInstanceTO.setKey(key);
         logic.update(connInstanceTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
index 4691189..017b0b3 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
@@ -39,7 +39,7 @@ public class NotificationServiceImpl extends AbstractServiceImpl implements Noti
         NotificationTO created = logic.create(notificationTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
index 1558120..a61e776 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
@@ -43,7 +43,7 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
         T policy = logic.create(policyTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(policy.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, policy.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, policy.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
index aba5295..ecf372d 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
@@ -51,7 +51,7 @@ public class RealmServiceImpl extends AbstractServiceImpl implements RealmServic
         RealmTO created = logic.create(StringUtils.prependIfMissing(parentPath, SyncopeConstants.ROOT_REALM), realmTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(created.getName()).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getFullPath()).
+                header(RESTHeaders.RESOURCE_KEY, created.getFullPath()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
index 3c910fa..405e105 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
@@ -52,7 +52,7 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
         ReportTO createdReportTO = logic.create(reportTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdReportTO.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, createdReportTO.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, createdReportTO.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 28b834b..48d6445 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
@@ -61,24 +61,24 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
         ResourceTO created = logic.create(resourceTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(created.getKey()).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 
     @Override
-    public void update(final String resourceKey, final ResourceTO resourceTO) {
-        resourceTO.setKey(resourceKey);
+    public void update(final String key, final ResourceTO resourceTO) {
+        resourceTO.setKey(key);
         logic.update(resourceTO);
     }
 
     @Override
-    public void delete(final String resourceKey) {
-        logic.delete(resourceKey);
+    public void delete(final String key) {
+        logic.delete(key);
     }
 
     @Override
-    public ResourceTO read(final String resourceKey) {
-        return logic.read(resourceKey);
+    public ResourceTO read(final String key) {
+        return logic.read(key);
     }
 
     @Override
@@ -87,8 +87,8 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public ConnObjectTO readConnObject(final String resourceKey, final String anyTypeKey, final Long key) {
-        return logic.readConnObject(resourceKey, anyTypeKey, key);
+    public ConnObjectTO readConnObject(final String key, final String anyTypeKey, final Long anyKey) {
+        return logic.readConnObject(key, anyTypeKey, anyKey);
     }
 
     @Override
@@ -98,7 +98,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
 
     @Override
     public BulkActionResult bulkDeassociation(
-            final String resourceKey, final String anyTypeKey, final ResourceDeassociationActionType type,
+            final String key, final String anyTypeKey, final ResourceDeassociationActionType type,
             final List<AnyKey> keys) {
 
         AbstractResourceAssociator<? extends AnyTO> associator = anyTypeKey.equalsIgnoreCase(AnyTypeKind.USER.name())
@@ -109,29 +109,29 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
 
         BulkActionResult result = new BulkActionResult();
 
-        for (AnyKey key : keys) {
-            Set<String> resources = Collections.singleton(resourceKey);
+        for (AnyKey anyKey : keys) {
+            Set<String> resources = Collections.singleton(key);
             try {
                 switch (type) {
                     case DEPROVISION:
-                        associator.deprovision(key.getElement(), resources);
+                        associator.deprovision(anyKey.getElement(), resources);
                         break;
 
                     case UNASSIGN:
-                        associator.unassign(key.getElement(), resources);
+                        associator.unassign(anyKey.getElement(), resources);
                         break;
 
                     case UNLINK:
-                        associator.unlink(key.getElement(), resources);
+                        associator.unlink(anyKey.getElement(), resources);
                         break;
 
                     default:
                 }
 
-                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.SUCCESS);
+                result.getResults().put(String.valueOf(anyKey.getElement()), BulkActionResult.Status.SUCCESS);
             } catch (Exception e) {
-                LOG.warn("While executing {} on {} {}", type, anyTypeKey, key.getElement(), e);
-                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.FAILURE);
+                LOG.warn("While executing {} on {} {}", type, anyTypeKey, anyKey.getElement(), e);
+                result.getResults().put(String.valueOf(anyKey.getElement()), BulkActionResult.Status.FAILURE);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
index 33403fd..d2efb3f 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
@@ -49,7 +49,7 @@ public class RoleServiceImpl extends AbstractServiceImpl implements RoleService
         RoleTO created = logic.create(roleTO);
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 c8d2f26..aa99255 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
@@ -41,7 +41,7 @@ public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaServ
 
         URI location = uriInfo.getAbsolutePathBuilder().path(created.getKey()).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, created.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
index 70666b6..b094adc 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
@@ -50,7 +50,7 @@ public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements
 
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, String.valueOf(created.getKey())).
+                header(RESTHeaders.RESOURCE_KEY, String.valueOf(created.getKey())).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index d42ed6a..29d4a0c 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -59,7 +59,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
 
         URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdTask.getKey())).build();
         return Response.created(location).
-                header(RESTHeaders.RESOURCE_ID, createdTask.getKey()).
+                header(RESTHeaders.RESOURCE_KEY, createdTask.getKey()).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
index d15c236..74d58d1 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
@@ -56,7 +56,7 @@ public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelf
     public Response read() {
         Pair<String, UserTO> self = logic.readSelf();
         return Response.ok().
-                header(RESTHeaders.RESOURCE_ID, self.getValue().getKey()).
+                header(RESTHeaders.RESOURCE_KEY, self.getValue().getKey()).
                 header(RESTHeaders.OWNED_ENTITLEMENTS, self.getKey()).
                 entity(self.getValue()).
                 build();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 83f09a4..9ea1279 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
@@ -62,7 +62,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     @Override
     public Response getUserKey(final String username) {
         return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
-                header(RESTHeaders.USER_ID, logic.getKey(username)).
+                header(RESTHeaders.USER_KEY, logic.getKey(username)).
                 build();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 97fc9d0..8cfec8b 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
@@ -280,7 +280,7 @@ public abstract class AbstractITCase {
 
     protected UserTO readUser(final String username) {
         return userService.read(Long.valueOf(
-                userService.getUserKey(username).getHeaderString(RESTHeaders.USER_ID)));
+                userService.getUserKey(username).getHeaderString(RESTHeaders.USER_KEY)));
     }
 
     protected UserTO updateUser(final UserMod userMod) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 391e8e7..6cf1313 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
@@ -624,7 +624,7 @@ public class GroupITCase extends AbstractITCase {
             mapping.setConnObjectLink("'cn=' + displayProperty + ',ou=groups,o=isp'");
 
             MappingItemTO description = new MappingItemTO();
-            description.setIntMappingType(IntMappingType.GroupId);
+            description.setIntMappingType(IntMappingType.GroupKey);
             description.setExtAttrName("description");
             description.setPurpose(MappingPurpose.BOTH);
             mapping.add(description);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a64ef15f/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 faf4701..a6dd805 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
@@ -78,7 +78,7 @@ public class ResourceITCase extends AbstractITCase {
         item = new MappingItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
@@ -137,7 +137,7 @@ public class ResourceITCase extends AbstractITCase {
         item = new MappingItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
@@ -189,7 +189,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);
@@ -203,7 +203,7 @@ public class ResourceITCase extends AbstractITCase {
         mapping = new MappingTO();
         provisionTO.setMapping(mapping);
         item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.GroupId);
+        item.setIntMappingType(IntMappingType.GroupKey);
         item.setExtAttrName("groupId");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.SYNCHRONIZATION);
@@ -239,7 +239,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
@@ -275,7 +275,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         mapping.setConnObjectKeyItem(item);
@@ -373,7 +373,7 @@ public class ResourceITCase extends AbstractITCase {
         item = new MappingItemTO();
         item.setExtAttrName("username");
         item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
@@ -597,7 +597,7 @@ public class ResourceITCase extends AbstractITCase {
         provisionTO.setMapping(mapping);
 
         MappingItemTO item = new MappingItemTO();
-        item.setIntMappingType(IntMappingType.UserId);
+        item.setIntMappingType(IntMappingType.UserKey);
         item.setExtAttrName("userId");
         item.setConnObjectKey(true);
         item.setPurpose(MappingPurpose.PROPAGATION);


[54/70] syncope git commit: Merge from master

Posted by il...@apache.org.
Merge from master


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

Branch: refs/heads/master
Commit: 46aaa9e89fa2da3ecc4208f17a4d7d443100d830
Parents: a8a4063 34ec671
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue Jun 9 08:15:16 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue Jun 9 08:15:16 2015 +0200

----------------------------------------------------------------------
 client/console/pom.xml                          |   12 +
 .../client/console/SyncopeConsoleSession.java   |    3 +-
 .../console/commons/ActionTableCheckGroup.java  |   40 +
 .../commons/AttributableDataProvider.java       |  103 ++
 .../client/console/commons/JexlHelpUtils.java   |   59 +
 .../client/console/pages/AbstractBasePage.java  |    6 +
 .../console/pages/AbstractStatusModalPage.java  |   30 +
 .../syncope/client/console/pages/BasePage.java  |   11 +-
 .../console/pages/BulkActionModalPage.java      |  166 +++
 .../pages/BulkActionResultModalPage.java        |   99 ++
 .../console/pages/ConnectorModalPage.java       |  477 +++++++
 .../console/pages/ProvisioningModalPage.java    |  253 ++++
 .../syncope/client/console/pages/Realms.java    |  177 +++
 .../client/console/pages/ResourceModalPage.java |  204 +++
 .../panels/AbstractSearchResultPanel.java       |  346 +++++
 .../client/console/panels/AccountPolicy.java    |   35 +
 .../console/panels/ActionDataTablePanel.java    |  145 +++
 .../console/panels/AjaxDataTablePanel.java      |  142 +++
 .../console/panels/AnnotatedBeanPanel.java      |   66 +
 .../syncope/client/console/panels/Any.java      |   35 +
 .../client/console/panels/Connectors.java       |  385 ++++++
 .../client/console/panels/DataTablePanel.java   |  113 ++
 .../client/console/panels/PasswordPolicy.java   |   35 +
 .../syncope/client/console/panels/Realm.java    |   49 +
 .../client/console/panels/RealmDetails.java     |   41 +
 .../console/panels/ResourceConnConfPanel.java   |  189 +++
 .../console/panels/ResourceDetailsPanel.java    |  306 +++++
 .../console/panels/ResourceMappingPanel.java    |  644 ++++++++++
 .../console/panels/ResourceSecurityPanel.java   |  186 +++
 .../client/console/panels/Resources.java        |  485 +++++++
 .../console/rest/ConnectorRestClient.java       |    6 +-
 .../client/console/rest/RealmRestClient.java    |   38 +
 .../client/console/topology/Topology.java       |  521 ++++++++
 .../client/console/topology/TopologyNode.java   |  123 ++
 .../console/topology/TopologyNodePanel.java     |  205 +++
 .../topology/TopologyReloadBehavior.java        |   61 +
 .../markup/html/ClearIndicatingAjaxButton.java  |   76 ++
 .../markup/html/ClearIndicatingAjaxLink.java    |   61 +
 .../repeater/data/table/ActionResultColumn.java |   77 ++
 .../data/table/CheckBoxGroupSelectorPanel.java  |   34 +
 .../html/repeater/data/table/CheckBoxPanel.java |   43 +
 .../repeater/data/table/CheckGroupColumn.java   |   54 +
 .../wicket/markup/html/form/ActionLink.java     |   85 ++
 .../markup/html/form/ActionLinksPanel.java      |  609 +++++++++
 .../markup/html/form/AjaxTextFieldPanel.java    |    4 +-
 .../html/form/IndicatingOnConfirmAjaxLink.java  |   58 +
 .../META-INF/resources/css/AdminLTE.css         |  602 ++++++---
 .../resources/css/AdminLTE_skins/_all-skins.css | 1203 +++++++++++++++---
 .../resources/css/AdminLTE_skins/skin-black.css |   66 +-
 .../resources/css/AdminLTE_skins/skin-blue.css  |   32 +-
 .../resources/css/AdminLTE_skins/skin-green.css |   27 +-
 .../css/AdminLTE_skins/skin-purple.css          |   27 +-
 .../resources/css/AdminLTE_skins/skin-red.css   |   27 +-
 .../css/AdminLTE_skins/skin-yellow.css          |   27 +-
 .../META-INF/resources/css/fieldstyle.css       |  191 +++
 .../META-INF/resources/css/syncopeConsole.css   |  177 ++-
 .../META-INF/resources/css/topology.css         |  160 +++
 .../META-INF/resources/js/AdminLTE-app.min.js   |    4 +-
 .../resources/META-INF/resources/js/topology.js |  244 ++++
 .../console/pages/AbstractStatusModalPage.html  |  122 ++
 .../pages/AbstractStatusModalPage.properties    |   19 +
 .../pages/AbstractStatusModalPage_it.properties |   19 +
 .../AbstractStatusModalPage_pt_BR.properties    |   19 +
 .../client/console/pages/BaseModalPage.html     |   23 +-
 .../syncope/client/console/pages/BasePage.html  |   16 +-
 .../console/pages/BulkActionModalPage.html      |   45 +
 .../pages/BulkActionModalPage.properties        |   17 +
 .../pages/BulkActionModalPage_it.properties     |   17 +
 .../pages/BulkActionModalPage_pt_BR.properties  |   17 +
 .../pages/BulkActionResultModalPage.html        |   57 +
 .../pages/BulkActionResultModalPage.properties  |   19 +
 .../BulkActionResultModalPage_it.properties     |   19 +
 .../BulkActionResultModalPage_pt_BR.properties  |   19 +
 .../console/pages/ConnectorModalPage.html       |  161 +++
 .../console/pages/ConnectorModalPage.properties |   43 +
 .../pages/ConnectorModalPage_it.properties      |   43 +
 .../pages/ConnectorModalPage_pt_BR.properties   |   43 +
 .../syncope/client/console/pages/Realms.html    |   79 ++
 .../client/console/pages/ResourceModalPage.html |   56 +
 .../console/pages/ResourceModalPage.properties  |   60 +
 .../pages/ResourceModalPage_it.properties       |   60 +
 .../pages/ResourceModalPage_pt_BR.properties    |   60 +
 .../panels/AbstractSearchResultPanel.html       |   43 +
 .../panels/AbstractSearchResultPanel.properties |   30 +
 .../AbstractSearchResultPanel_it.properties     |   30 +
 .../AbstractSearchResultPanel_pt_BR.properties  |   30 +
 .../client/console/panels/AccountPolicy.html    |   29 +
 .../console/panels/ActionDataTablePanel.html    |   45 +
 .../console/panels/AjaxDataTablePanel.html      |   47 +
 .../console/panels/AnnotatedBeanPanel.html      |   98 ++
 .../panels/AnnotatedBeanPanel.properties        |   20 +
 .../panels/AnnotatedBeanPanel_it.properties     |   20 +
 .../panels/AnnotatedBeanPanel_pt_BR.properties  |   20 +
 .../syncope/client/console/panels/Any.html      |   29 +
 .../client/console/panels/Connectors.html       |   57 +
 .../client/console/panels/Connectors.properties |   34 +
 .../console/panels/Connectors_it.properties     |   34 +
 .../console/panels/Connectors_pt_BR.properties  |   32 +
 .../client/console/panels/PasswordPolicy.html   |   29 +
 .../syncope/client/console/panels/Realm.html    |   93 ++
 .../client/console/panels/RealmDetails.html     |   45 +
 .../console/panels/ResourceConnConfPanel.html   |   40 +
 .../console/panels/ResourceDetailsPanel.html    |  137 ++
 .../console/panels/ResourceMappingPanel.html    |  114 ++
 .../console/panels/ResourceSecurityPanel.html   |   56 +
 .../panels/ResourceSecurityPanel.properties     |   19 +
 .../panels/ResourceSecurityPanel_it.properties  |   19 +
 .../ResourceSecurityPanel_pt_BR.properties      |   19 +
 .../client/console/panels/Resources.html        |   52 +
 .../client/console/panels/Resources.properties  |   34 +
 .../console/panels/Resources_it.properties      |   34 +
 .../console/panels/Resources_pt_BR.properties   |   32 +
 .../client/console/topology/Topology.html       |   52 +
 .../client/console/topology/Topology.properties |   17 +
 .../console/topology/TopologyNodePanel.html     |   67 +
 .../topology/TopologyNodePanel.properties       |   20 +
 .../topology/TopologyNodePanel_it.properties    |   20 +
 .../topology/TopologyNodePanel_pt_BR.properties |   20 +
 .../console/topology/Topology_it.properties     |   17 +
 .../console/topology/Topology_pt_BR.properties  |   17 +
 .../data/table/CheckBoxGroupSelectorPanel.html  |   21 +
 .../html/repeater/data/table/CheckBoxPanel.html |   23 +
 .../markup/html/form/ActionLinksPanel.html      |  173 +++
 .../markup/html/form/AjaxCheckBoxPanel.html     |   21 +
 .../html/form/AjaxDropDownChoicePanel.html      |   24 +
 .../markup/html/form/AjaxNumberFieldPanel.html  |   22 +
 .../markup/html/form/AjaxPalettePanel.html      |   23 +
 .../html/form/AjaxPasswordFieldPanel.html       |   22 +
 .../markup/html/form/AjaxTextFieldPanel.html    |   23 +
 .../markup/html/form/AjaxTextFieldPanel_1.html  |   23 +
 .../markup/html/form/BinaryFieldPanel.html      |   44 +
 .../form/CheckBoxMultipleChoiceFieldPanel.html  |   23 +
 .../markup/html/form/DateTextFieldPanel.html    |   22 +
 .../markup/html/form/DateTimeFieldPanel.html    |   21 +
 .../html/form/DateTimeFieldPanel.properties     |   17 +
 .../html/form/DateTimeFieldPanel_it.properties  |   17 +
 .../form/DateTimeFieldPanel_pt_BR.properties    |   17 +
 .../wicket/markup/html/form/FieldPanel.html     |   34 +
 .../wicket/markup/html/form/FieldPanel_1.html   |   34 +
 .../wicket/markup/html/form/LinkPanel.html      |   23 +
 .../wicket/markup/html/form/LinkPanel_1.html    |   23 +
 .../markup/html/form/MappingPurposePanel.html   |   31 +
 .../markup/html/form/MultiFieldPanel.html       |   35 +
 .../markup/html/form/MultiFieldPanel.properties |   22 +
 .../html/form/MultiFieldPanel_it.properties     |   22 +
 .../html/form/MultiFieldPanel_pt_BR.properties  |   22 +
 .../wicket/markup/html/form/NonI18nPalette.html |   69 +
 .../markup/html/form/SpinnerFieldPanel.html     |   29 +
 .../rest/api/service/ConnectorService.java      |    1 -
 pom.xml                                         |   13 +
 150 files changed, 12682 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --cc common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index c4de80a,76552e6..07fc6a4
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@@ -177,9 -176,8 +177,8 @@@ public interface ConnectorService exten
       */
      @POST
      @Path("check")
-     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
      @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
 -    boolean check(@NotNull ConnInstanceTO connInstanceTO);
 +    BooleanWrap check(@NotNull ConnInstanceTO connInstanceTO);
  
      /**
       * Reload all connector bundles and instances.

http://git-wip-us.apache.org/repos/asf/syncope/blob/46aaa9e8/pom.xml
----------------------------------------------------------------------
diff --cc pom.xml
index 805b59e,fe9519d..9011e8d
--- a/pom.xml
+++ b/pom.xml
@@@ -378,7 -379,8 +379,8 @@@ 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>
+     <jsplumb.version>1.6.4</jsplumb.version>
      
      <wicket.version>7.0.0-M5</wicket.version>
      <wicket-jqueryui.version>7.0.0-M5</wicket-jqueryui.version>


[03/70] 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);


[60/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
[SYNCOPE-666] Any* tests added


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

Branch: refs/heads/master
Commit: a45a46bba7186ef43b4877482d636901bc40cbc5
Parents: 46aaa9e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jun 10 14:33:59 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jun 10 14:33:59 2015 +0200

----------------------------------------------------------------------
 .../client/console/commons/AnyDataProvider.java | 101 ++++
 .../commons/AttributableDataProvider.java       | 103 ----
 .../console/pages/BulkActionModalPage.java      |   8 +-
 .../pages/BulkActionResultModalPage.java        |   8 +-
 .../console/pages/ProvisioningModalPage.java    |  38 +-
 .../client/console/pages/ResourceModalPage.java |  52 +-
 .../panels/AbstractSearchResultPanel.java       |  22 +-
 .../console/panels/AjaxDataTablePanel.java      |   4 +-
 .../console/panels/AnnotatedBeanPanel.java      |   4 +-
 .../console/panels/ResourceConnConfPanel.java   |  18 +-
 .../console/panels/ResourceDetailsPanel.java    |  10 +-
 .../console/panels/ResourceMappingPanel.java    | 228 +++++----
 .../client/console/panels/Resources.java        | 485 -------------------
 .../console/rest/ConnectorRestClient.java       |   6 +-
 .../client/console/rest/GroupRestClient.java    |  47 +-
 .../client/console/rest/UserRestClient.java     |  48 +-
 .../repeater/data/table/ActionResultColumn.java |  17 +-
 .../console/pages/ResourceModalPage.properties  |   6 +-
 .../pages/ResourceModalPage_it.properties       |   6 +-
 .../pages/ResourceModalPage_pt_BR.properties    |   6 +-
 .../console/panels/ResourceMappingPanel.html    |  14 +-
 .../client/console/panels/Resources.html        |  52 --
 .../client/console/panels/Resources.properties  |  34 --
 .../console/panels/Resources_it.properties      |  34 --
 .../console/panels/Resources_pt_BR.properties   |  32 --
 .../syncope/client/lib/SyncopeClient.java       |  13 +-
 .../lib/builders/AnyListQueryBuilder.java       |   1 +
 .../apache/syncope/common/lib/mod/AnyMod.java   |   2 +
 .../AbstractFiqlSearchConditionBuilder.java     |   1 +
 .../AnyObjectFiqlSearchConditionBuilder.java    |  71 +++
 .../common/lib/search/AnyObjectProperty.java    |  23 +
 .../syncope/common/lib/search/SpecialAttr.java  |   1 +
 .../common/lib/to/ConnIdObjectClassTO.java      |  74 ---
 .../apache/syncope/common/lib/to/MappingTO.java |   2 +-
 .../common/lib/types/IntMappingType.java        |  18 +-
 .../common/lib/wrap/ConnIdObjectClass.java      |  30 ++
 .../rest/api/service/AnyObjectService.java      |  49 ++
 .../common/rest/api/service/AnyService.java     | 191 ++++++++
 .../rest/api/service/ConnectorService.java      |   4 +-
 .../common/rest/api/service/GroupService.java   | 158 +-----
 .../common/rest/api/service/UserService.java    | 160 +-----
 .../syncope/core/logic/AbstractAnyLogic.java    |  16 +-
 .../syncope/core/logic/AnyObjectLogic.java      |  27 +-
 .../apache/syncope/core/logic/AnyTypeLogic.java |  10 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   1 +
 .../apache/syncope/core/logic/UserLogic.java    |   6 +
 .../syncope/core/misc/ConnObjectUtils.java      |   5 +
 .../apache/syncope/core/misc/MappingUtils.java  |  14 +-
 .../core/misc/search/SearchCondVisitor.java     |   7 +
 .../misc/search/SearchCondConverterTest.java    |  14 +
 .../core/persistence/api/dao/AnyObjectDAO.java  |   8 +-
 .../persistence/api/dao/search/AnyTypeCond.java |  40 ++
 .../persistence/api/dao/search/SearchCond.java  |  22 +-
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |  24 +-
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |  22 +
 .../persistence/jpa/entity/JPAAnyUtils.java     |   6 +-
 .../jpa/entity/resource/JPAMapping.java         |   2 +-
 .../jpa/entity/resource/JPAMappingItem.java     |   2 +-
 .../persistence/jpa/entity/AnyObjectTest.java   |  10 +
 .../persistence/jpa/entity/AnySearchTest.java   |  24 +-
 .../persistence/jpa/entity/AnyTypeTest.java     |   8 +-
 .../persistence/jpa/entity/PlainSchemaTest.java |   2 +-
 .../persistence/jpa/entity/ResourceTest.java    |   4 +-
 .../core/persistence/jpa/entity/TaskTest.java   |   2 +-
 .../persistence/jpa/relationship/GroupTest.java |  16 +-
 .../jpa/relationship/PlainSchemaTest.java       |  12 +-
 .../persistence/jpa/relationship/RoleTest.java  |   2 +-
 .../src/test/resources/content.xml              |  70 ++-
 .../provisioning/java/ConnectorFacadeProxy.java |  35 +-
 .../provisioning/java/VirAttrHandlerImpl.java   |   2 +-
 .../java/data/AbstractAnyDataBinder.java        |   2 +-
 .../java/data/AnyObjectDataBinderImpl.java      |  16 +
 .../propagation/PropagationManagerImpl.java     |   1 +
 .../provisioning/java/sync/SyncJobImpl.java     |  39 +-
 .../core/provisioning/java/sync/SyncUtils.java  |   6 +-
 .../rest/cxf/service/AbstractAnyService.java    | 290 +++++++++++
 .../rest/cxf/service/AnyObjectServiceImpl.java  |  71 +++
 .../rest/cxf/service/ConnectorServiceImpl.java  |  12 +-
 .../core/rest/cxf/service/GroupServiceImpl.java | 205 +-------
 .../core/rest/cxf/service/UserServiceImpl.java  | 259 +---------
 .../core/logic/init/CamelRouteLoader.java       |   4 +
 .../CamelAnyObjectProvisioningManager.java      | 163 +++++++
 .../processor/AnyObjectCreateProcessor.java     |  71 +++
 .../processor/AnyObjectDeleteProcessor.java     |  83 ++++
 .../AnyObjectDeprovisionProcessor.java          |  78 +++
 .../processor/AnyObjectUpdateProcessor.java     |  90 ++++
 .../src/main/resources/anyObjectRoutes.xml      | 121 +++++
 .../src/main/resources/provisioning.properties  |   2 +-
 .../main/resources/provisioningCamelContext.xml |   6 +-
 fit/build-tools/pom.xml                         |  10 +-
 .../fit/buildtools/ConnIdStartStopListener.java |   3 +-
 .../src/main/resources/buildToolsContext.xml    |   7 +-
 fit/build-tools/src/main/resources/testdb.sql   |   8 +-
 .../src/main/resources/connid.properties        |   2 +-
 .../resources/scriptedsql/CreateScript.groovy   |  52 ++
 .../resources/scriptedsql/DeleteScript.groovy   |  43 ++
 .../resources/scriptedsql/SchemaScript.groovy   |  50 ++
 .../resources/scriptedsql/SearchScript.groovy   |  94 ++++
 .../resources/scriptedsql/SyncScript.groovy     |  98 ++++
 .../resources/scriptedsql/TestScript.groovy     |  31 ++
 .../resources/scriptedsql/UpdateScript.groovy   |  67 +++
 .../fit/core/reference/AbstractITCase.java      |  35 +-
 .../fit/core/reference/AnyObjectITCase.java     | 126 +++++
 .../fit/core/reference/AnyTypeClassITCase.java  | 117 +++++
 .../fit/core/reference/AnyTypeITCase.java       | 169 +++++++
 .../fit/core/reference/ConnectorITCase.java     |  15 +-
 .../syncope/fit/core/reference/GroupITCase.java |  24 +-
 .../fit/core/reference/SearchITCase.java        |  93 ++--
 .../fit/core/reference/SyncTaskITCase.java      |  45 ++
 .../syncope/fit/core/reference/UserITCase.java  |   4 +-
 pom.xml                                         |  11 +-
 111 files changed, 3166 insertions(+), 2051 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
new file mode 100644
index 0000000..bd4183b
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/AnyDataProvider.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.commons;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+
+public class AnyDataProvider extends SortableDataProvider<AnyTO, String> {
+
+    private static final long serialVersionUID = 6267494272884913376L;
+
+    private final SortableAnyProviderComparator comparator;
+
+    private String fiql = null;
+
+    private final int paginatorRows;
+
+    private final boolean filtered;
+
+    private final AbstractAnyRestClient restClient;
+
+    private final String realm = "/";
+
+    public AnyDataProvider(final AbstractAnyRestClient restClient, final int paginatorRows, final boolean filtered) {
+        super();
+
+        this.restClient = restClient;
+        this.filtered = filtered;
+        this.paginatorRows = paginatorRows;
+
+        // default sorting
+        setSort("key", SortOrder.ASCENDING);
+
+        this.comparator = new SortableAnyProviderComparator(this);
+    }
+
+    public void setFIQL(final String fiql) {
+        this.fiql = fiql;
+    }
+
+    @Override
+    public Iterator<? extends AnyTO> iterator(final long first, final long count) {
+        List<? extends AnyTO> result;
+
+        final int page = ((int) first / paginatorRows);
+
+        if (filtered) {
+            result = fiql == null
+                    ? Collections.<AnyTO>emptyList()
+                    : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        } else {
+            result = restClient.list(realm, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
+        }
+
+        Collections.sort(result, comparator);
+        return result.iterator();
+    }
+
+    @Override
+    public long size() {
+        long result;
+
+        if (filtered) {
+            result = fiql == null
+                    ? 0
+                    : restClient.searchCount(realm, fiql);
+        } else {
+            result = restClient.count(realm);
+        }
+
+        return result;
+    }
+
+    @Override
+    public IModel<AnyTO> model(final AnyTO object) {
+        return new CompoundPropertyModel<>(object);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.java
deleted file mode 100644
index 1890a80..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/AttributableDataProvider.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.client.console.commons;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-
-public class AttributableDataProvider extends SortableDataProvider<AbstractAttributableTO, String> {
-
-    private static final long serialVersionUID = 6267494272884913376L;
-
-    private final SortableAttributableProviderComparator comparator;
-
-    private String fiql = null;
-
-    private final int paginatorRows;
-
-    private final boolean filtered;
-
-    private final AbstractSubjectRestClient restClient;
-
-    private final String realm = "/";
-
-    public AttributableDataProvider(final AbstractSubjectRestClient restClient,
-            final int paginatorRows, final boolean filtered) {
-
-        super();
-
-        this.restClient = restClient;
-        this.filtered = filtered;
-        this.paginatorRows = paginatorRows;
-
-        // default sorting
-        setSort("key", SortOrder.ASCENDING);
-
-        this.comparator = new SortableAttributableProviderComparator(this);
-    }
-
-    public void setFIQL(final String fiql) {
-        this.fiql = fiql;
-    }
-
-    @Override
-    public Iterator<? extends AbstractAttributableTO> iterator(final long first, final long count) {
-        List<? extends AbstractAttributableTO> result;
-
-        final int page = ((int) first / paginatorRows);
-
-        if (filtered) {
-            result = fiql == null
-                    ? Collections.<AbstractAttributableTO>emptyList()
-                    : restClient.search(realm, fiql, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
-        } else {
-            result = restClient.list(realm, (page < 0 ? 0 : page) + 1, paginatorRows, getSort());
-        }
-
-        Collections.sort(result, comparator);
-        return result.iterator();
-    }
-
-    @Override
-    public long size() {
-        long result;
-
-        if (filtered) {
-            result = fiql == null
-                    ? 0
-                    : restClient.searchCount(realm, fiql);
-        } else {
-            result = restClient.count(realm);
-        }
-
-        return result;
-    }
-
-    @Override
-    public IModel<AbstractAttributableTO> model(final AbstractAttributableTO object) {
-        return new CompoundPropertyModel<>(object);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
index 65dfa58..5567094 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionModalPage.java
@@ -53,7 +53,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
             final List<IColumn<T, S>> columns,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
-            final String idFieldName,
+            final String keyFieldName,
             final String pageId) {
 
         super();
@@ -92,9 +92,9 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
             final BulkAction bulkAction = new BulkAction();
             for (T item : items) {
                 try {
-                    bulkAction.getTargets().add(getTargetId(item, idFieldName).toString());
+                    bulkAction.getTargets().add(getTargetId(item, keyFieldName).toString());
                 } catch (IllegalAccessException | InvocationTargetException e) {
-                    LOG.error("Error retrieving item id {}", idFieldName, e);
+                    LOG.error("Error retrieving item id {}", keyFieldName, e);
                 }
             }
 
@@ -128,7 +128,7 @@ public class BulkActionModalPage<T, S> extends BaseModalPage {
                         final BulkActionResult res = (BulkActionResult) bulkActionExecutor.getClass().
                                 getMethod("bulkAction", BulkAction.class).invoke(bulkActionExecutor, bulkAction);
 
-                        setResponsePage(new BulkActionResultModalPage<>(window, items, columns, res, idFieldName));
+                        setResponsePage(new BulkActionResultModalPage<>(window, items, columns, res, keyFieldName));
                     } catch (NoSuchMethodException | SecurityException | IllegalAccessException 
                             | IllegalArgumentException | InvocationTargetException e) {
                         error(getString(Constants.ERROR)

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
index 72a789f..98ac15c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BulkActionResultModalPage.java
@@ -36,14 +36,12 @@ import org.apache.wicket.model.IModel;
 
 /**
  * Show user or group status after performing a successful operation.
+ *
  * @param <T>
  * @param <S>
  */
 public class BulkActionResultModalPage<T, S> extends BaseModalPage {
 
-    /**
-     * Serial version id.
-     */
     private static final long serialVersionUID = 2646115294319713724L;
 
     public BulkActionResultModalPage(
@@ -51,12 +49,12 @@ public class BulkActionResultModalPage<T, S> extends BaseModalPage {
             final Collection<T> items,
             final List<IColumn<T, S>> columns,
             final BulkActionResult results,
-            final String idFieldName) {
+            final String keyFieldName) {
 
         super();
 
         final List<IColumn<T, S>> newColumnList = new ArrayList<>(columns.subList(1, columns.size() - 1));
-        newColumnList.add(newColumnList.size(), new ActionResultColumn<T, S>(results, idFieldName));
+        newColumnList.add(newColumnList.size(), new ActionResultColumn<T, S>(results, keyFieldName));
 
         final SortableDataProvider<T, S> dataProvider = new SortableDataProvider<T, S>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
index af1d0b5..6f56bbb 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ProvisioningModalPage.java
@@ -31,15 +31,13 @@ import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.console.panels.ActionDataTablePanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.lib.SyncopeClient;
-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.BulkActionResult;
 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.ResourceDeassociationActionType;
 import org.apache.syncope.common.lib.wrap.AbstractWrappable;
-import org.apache.syncope.common.lib.wrap.SubjectKey;
+import org.apache.syncope.common.lib.wrap.AnyKey;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
@@ -54,7 +52,7 @@ import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.StringResourceModel;
 
-public class ProvisioningModalPage<T extends AbstractAttributableTO> extends AbstractStatusModalPage {
+public class ProvisioningModalPage<T extends AnyTO> extends AbstractStatusModalPage {
 
     private static final long serialVersionUID = -4285220460543213901L;
 
@@ -62,7 +60,7 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
 
     private final ResourceTO resourceTO;
 
-    private final Class<? extends AbstractAttributableTO> typeRef;
+    private final AnyTypeKind anyTypeKind;
 
     private final PageReference pageRef;
 
@@ -76,16 +74,16 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final PageReference pageRef,
             final ModalWindow window,
             final ResourceTO resourceTO,
-            final Class<T> typeRef) {
+            final AnyTypeKind anyTypeKind) {
 
         super();
 
         this.pageRef = pageRef;
         this.window = window;
         this.resourceTO = resourceTO;
-        this.typeRef = typeRef;
+        this.anyTypeKind = anyTypeKind;
 
-        statusUtils = new StatusUtils((UserTO.class.isAssignableFrom(typeRef) ? userRestClient : groupRestClient));
+        statusUtils = new StatusUtils(anyTypeKind == AnyTypeKind.USER ? userRestClient : groupRestClient);
 
         add(new Label("displayName", StringUtils.EMPTY));
 
@@ -100,8 +98,8 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
                 new StringResourceModel("resourceName", this, null, "Resource name"),
                 "resourceName", "resourceName"));
         columns.add(new PropertyColumn<StatusBean, String>(
-                new StringResourceModel("accountLink", this, null, "Account link"),
-                "accountLink", "accountLink"));
+                new StringResourceModel("connObjectLink", this, null, "ConnObjectLink"),
+                "connObjectLink", "connObjectLink"));
         columns.add(new AbstractColumn<StatusBean, String>(
                 new StringResourceModel("status", this, null, "")) {
 
@@ -198,7 +196,7 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final String fiql = SyncopeClient.getUserSearchConditionBuilder().hasResources(resourceTO.getKey()).query();
 
             final List<T> subjects = new ArrayList<>();
-            if (UserTO.class.isAssignableFrom(typeRef)) {
+            if (anyTypeKind == AnyTypeKind.USER) {
                 subjects.addAll((List<T>) userRestClient.search(
                         realm, fiql, 1, ROWS_PER_PAGE, new SortParam<>("key", true)));
             } else {
@@ -207,16 +205,16 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             }
 
             final List<ConnObjectWrapper> connObjects = statusUtils.getConnectorObjects(
-                    (List<AbstractSubjectTO>) subjects, Collections.<String>singleton(resourceTO.getKey()));
+                    (List<AnyTO>) subjects, Collections.<String>singleton(resourceTO.getKey()));
 
             final List<StatusBean> statusBeans = new ArrayList<>(connObjects.size() + 1);
             final LinkedHashMap<String, StatusBean> initialStatusBeanMap = new LinkedHashMap<>(connObjects.size());
 
             for (ConnObjectWrapper entry : connObjects) {
-                final StatusBean statusBean = statusUtils.getStatusBean(entry.getAttributable(),
+                StatusBean statusBean = statusUtils.getStatusBean(entry.getAny(),
                         entry.getResourceName(),
                         entry.getConnObjectTO(),
-                        GroupTO.class.isAssignableFrom(typeRef));
+                        anyTypeKind == AnyTypeKind.GROUP);
 
                 initialStatusBeanMap.put(entry.getResourceName(), statusBean);
                 statusBeans.add(statusBean);
@@ -233,21 +231,21 @@ public class ProvisioningModalPage<T extends AbstractAttributableTO> extends Abs
             final List<IColumn<StatusBean, String>> columns) {
 
         final List<StatusBean> beans = new ArrayList<>(table.getModelObject());
-        List<SubjectKey> subjectKeys = new ArrayList<>();
+        List<AnyKey> subjectKeys = new ArrayList<>();
         for (StatusBean bean : beans) {
             LOG.debug("Selected bean {}", bean);
-            subjectKeys.add(AbstractWrappable.getInstance(SubjectKey.class, bean.getAttributableId()));
+            subjectKeys.add(AbstractWrappable.getInstance(AnyKey.class, bean.getAnyKey()));
         }
 
         if (beans.isEmpty()) {
             window.close(target);
         } else {
             final BulkActionResult res = resourceRestClient.bulkAssociationAction(
-                    resourceTO.getKey(), typeRef, type, subjectKeys);
+                    resourceTO.getKey(), anyTypeKind.name(), type, subjectKeys);
 
             ((BasePage) pageRef.getPage()).setModalResult(true);
 
-            setResponsePage(new BulkActionResultModalPage<>(window, beans, columns, res, "attributableKey"));
+            setResponsePage(new BulkActionResultModalPage<>(window, beans, columns, res, "anyKey"));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
index aa9dbfc..e578255 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ResourceModalPage.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.client.console.pages;
 
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.panels.AnnotatedBeanPanel;
 import org.apache.syncope.client.console.panels.ResourceConnConfPanel;
@@ -25,8 +27,9 @@ import org.apache.syncope.client.console.panels.ResourceDetailsPanel;
 import org.apache.syncope.client.console.panels.ResourceMappingPanel;
 import org.apache.syncope.client.console.panels.ResourceSecurityPanel;
 import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
-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.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
@@ -66,8 +69,8 @@ public class ResourceModalPage extends BaseModalPage {
         //--------------------------------
         // Resource mapping panels
         //--------------------------------
-        form.add(new ResourceMappingPanel("umapping", resourceTO, AttributableType.USER));
-        form.add(new ResourceMappingPanel("gmapping", resourceTO, AttributableType.GROUP));
+        form.add(new ResourceMappingPanel("umapping", resourceTO, AnyTypeKind.USER));
+        form.add(new ResourceMappingPanel("gmapping", resourceTO, AnyTypeKind.GROUP));
         //--------------------------------
 
         //--------------------------------
@@ -84,7 +87,7 @@ public class ResourceModalPage extends BaseModalPage {
         form.add(new ResourceSecurityPanel("security", resourceTO));
         //--------------------------------
 
-        final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
+        AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) {
 
             private static final long serialVersionUID = -958724007591692537L;
 
@@ -92,34 +95,29 @@ public class ResourceModalPage extends BaseModalPage {
             protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                 final ResourceTO resourceTO = (ResourceTO) form.getDefaultModelObject();
 
-                boolean accountIdError = false;
+                boolean connObjectKeyError = false;
 
-                if (resourceTO.getUmapping() == null || resourceTO.getUmapping().getItems().isEmpty()) {
-                    resourceTO.setUmapping(null);
-                } else {
-                    int uAccountIdCount = 0;
-                    for (MappingItemTO item : resourceTO.getUmapping().getItems()) {
-                        if (item.isAccountid()) {
-                            uAccountIdCount++;
-                        }
-                    }
-                    accountIdError = uAccountIdCount != 1;
-                }
+                for (ProvisionTO provision : resourceTO.getProvisions()) {
+                    if (provision != null) {
+                        if (provision.getMapping() == null || provision.getMapping().getItems().isEmpty()) {
+                            resourceTO.getProvisions().remove(provision);
+                        } else {
+                            int uConnObjectKeyCount = CollectionUtils.countMatches(
+                                    provision.getMapping().getItems(), new Predicate<MappingItemTO>() {
 
-                if (resourceTO.getGmapping() == null || resourceTO.getGmapping().getItems().isEmpty()) {
-                    resourceTO.setGmapping(null);
-                } else {
-                    int rAccountIdCount = 0;
-                    for (MappingItemTO item : resourceTO.getGmapping().getItems()) {
-                        if (item.isAccountid()) {
-                            rAccountIdCount++;
+                                        @Override
+                                        public boolean evaluate(final MappingItemTO item) {
+                                            return item.isConnObjectKey();
+                                        }
+                                    });
+
+                            connObjectKeyError = uConnObjectKeyCount != 1;
                         }
                     }
-                    accountIdError |= rAccountIdCount != 1;
                 }
 
-                if (accountIdError) {
-                    error(getString("accountIdValidation"));
+                if (connObjectKeyError) {
+                    error(getString("connObjectKeyValidation"));
                     feedbackPanel.refresh(target);
                 } else {
                     try {
@@ -142,6 +140,7 @@ public class ResourceModalPage extends BaseModalPage {
             }
 
             @Override
+
             protected void onError(final AjaxRequestTarget target, final Form<?> form) {
                 feedbackPanel.refresh(target);
             }
@@ -171,6 +170,7 @@ public class ResourceModalPage extends BaseModalPage {
 
         MetaDataRoleAuthorizationStrategy.authorize(
                 submit, ENABLE, createFlag ? Entitlement.RESOURCE_CREATE : Entitlement.RESOURCE_UPDATE);
+
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
index 0af8a0b..20f62d5 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AbstractSearchResultPanel.java
@@ -21,12 +21,12 @@ package org.apache.syncope.client.console.panels;
 import java.util.Collection;
 import java.util.List;
 import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.AttributableDataProvider;
+import org.apache.syncope.client.console.commons.AnyDataProvider;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.pages.AbstractBasePage;
-import org.apache.syncope.client.console.rest.AbstractSubjectRestClient;
+import org.apache.syncope.client.console.rest.AbstractAnyRestClient;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
@@ -89,7 +89,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     @SpringBean
     protected PreferenceManager prefMan;
 
-    protected final AbstractSubjectRestClient restClient;
+    protected final AbstractAnyRestClient restClient;
 
     /**
      * Number of rows per page.
@@ -120,12 +120,12 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     /**
      * Result table.
      */
-    private AjaxDataTablePanel<AbstractAttributableTO, String> resultTable;
+    private AjaxDataTablePanel<AnyTO, String> resultTable;
 
     /**
      * Data provider used to search for users.
      */
-    private AttributableDataProvider dataProvider;
+    private AnyDataProvider dataProvider;
 
     /**
      * Modal window to be used for user profile editing. Global visibility is required ...
@@ -147,8 +147,8 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
      */
     protected final AbstractBasePage page;
 
-    protected <T extends AbstractAttributableTO> AbstractSearchResultPanel(final String id, final boolean filtered,
-            final String fiql, final PageReference pageRef, final AbstractSubjectRestClient restClient) {
+    protected <T extends AnyTO> AbstractSearchResultPanel(final String id, final boolean filtered,
+            final String fiql, final PageReference pageRef, final AbstractAnyRestClient restClient) {
 
         super(id);
 
@@ -238,7 +238,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
     }
 
     private void updateResultTable(final boolean create, final int rows) {
-        dataProvider = new AttributableDataProvider(restClient, rows, filtered);
+        dataProvider = new AnyDataProvider(restClient, rows, filtered);
         dataProvider.setFIQL(fiql);
 
         final int currentPage = resultTable != null
@@ -265,7 +265,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
         container.addOrReplace(resultTable);
     }
 
-    protected abstract List<IColumn<AbstractAttributableTO, String>> getColumns();
+    protected abstract List<IColumn<AnyTO, String>> getColumns();
 
     @Override
     public void onEvent(final IEvent<?> event) {
@@ -340,7 +340,7 @@ public abstract class AbstractSearchResultPanel extends Panel implements IEventS
         }
     }
 
-    protected abstract <T extends AbstractAttributableTO> Collection<ActionLink.ActionType> getBulkActions();
+    protected abstract <T extends AnyTO> Collection<ActionLink.ActionType> getBulkActions();
 
     protected abstract String getPageId();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
index 563bd17..daaaa23 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AjaxDataTablePanel.java
@@ -52,7 +52,7 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
             final int rowsPerPage,
             final Collection<ActionLink.ActionType> actions,
             final BaseRestClient bulkActionExecutor,
-            final String itemIdField,
+            final String itemKeyField,
             final String pageId,
             final PageReference pageRef) {
 
@@ -130,7 +130,7 @@ public class AjaxDataTablePanel<T, S> extends DataTablePanel<T, S> {
                                 columns,
                                 actions,
                                 bulkActionExecutor,
-                                itemIdField,
+                                itemKeyField,
                                 pageId);
                     }
                 });

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
index e809263..ab1e7e0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnnotatedBeanPanel.java
@@ -20,7 +20,7 @@ package org.apache.syncope.client.console.panels;
 
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.to.AbstractAnnotatedBean;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.Model;
@@ -29,7 +29,7 @@ public class AnnotatedBeanPanel extends Panel {
 
     private static final long serialVersionUID = 4228064224811390809L;
 
-    public <T extends AbstractAttributableTO> AnnotatedBeanPanel(
+    public <T extends AnyTO> AnnotatedBeanPanel(
             final String id, final AbstractAnnotatedBean sysInfoTO) {
 
         super(id);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
index c1d01e0..6f2a17b 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java
@@ -57,9 +57,9 @@ public class ResourceConnConfPanel extends Panel {
 
     private List<ConnConfProperty> connConfProperties;
 
-    private WebMarkupContainer connConfPropContainer;
+    private final WebMarkupContainer connConfPropContainer;
 
-    private AjaxButton check;
+    private final AjaxButton check;
 
     public ResourceConnConfPanel(final String id, final ResourceTO resourceTO, final boolean createFlag) {
         super(id);
@@ -103,7 +103,7 @@ public class ResourceConnConfPanel extends Panel {
 
         check.setEnabled(!connConfProperties.isEmpty());
         check.setVisible(!connConfProperties.isEmpty());
-        
+
         connConfPropContainer.add(check);
     }
 
@@ -113,10 +113,10 @@ public class ResourceConnConfPanel extends Panel {
      * @return overridable properties.
      */
     private List<ConnConfProperty> getConnConfProperties() {
-        final List<ConnConfProperty> props = new ArrayList<ConnConfProperty>();
-        final Long connectorId = resourceTO.getConnectorId();
-        if (connectorId != null && connectorId > 0) {
-            for (ConnConfProperty property : restClient.getConnectorProperties(connectorId)) {
+        List<ConnConfProperty> props = new ArrayList<>();
+        Long connectorKey = resourceTO.getConnector();
+        if (connectorKey != null && connectorKey > 0) {
+            for (ConnConfProperty property : restClient.getConnectorProperties(connectorKey)) {
                 if (property.isOverridable()) {
                     props.add(property);
                 }
@@ -125,7 +125,7 @@ public class ResourceConnConfPanel extends Panel {
         if (createFlag || resourceTO.getConnConfProperties().isEmpty()) {
             resourceTO.getConnConfProperties().clear();
         } else {
-            Map<String, ConnConfProperty> valuedProps = new HashMap<String, ConnConfProperty>();
+            Map<String, ConnConfProperty> valuedProps = new HashMap<>();
             for (ConnConfProperty prop : resourceTO.getConnConfProperties()) {
                 valuedProps.put(prop.getSchema().getName(), prop);
             }
@@ -169,7 +169,7 @@ public class ResourceConnConfPanel extends Panel {
      */
     public static class ConnConfModEvent extends ResourceEvent {
 
-        private List<ConnConfProperty> configuration;
+        private final List<ConnConfProperty> configuration;
 
         /**
          * Constructor.

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
index 3bff23f..3095b4e 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java
@@ -222,7 +222,7 @@ public class ResourceDetailsPanel extends Panel {
                 new ResourceModel("connector", "connector").getObject(),
                 new PropertyModel<ConnInstanceTO>(this, "connInstanceTO"));
         conn.setChoices(connectors.getObject());
-        conn.setChoiceRenderer(new ChoiceRenderer("displayName", "key"));
+        conn.setChoiceRenderer(new ChoiceRenderer<String>("displayName", "key"));
 
         conn.getField().setModel(new IModel<ConnInstanceTO>() {
 
@@ -235,7 +235,7 @@ public class ResourceDetailsPanel extends Panel {
 
             @Override
             public void setObject(final ConnInstanceTO connector) {
-                resourceTO.setConnectorId(connector.getKey());
+                resourceTO.setConnector(connector.getKey());
                 connInstanceTO = connector;
             }
 
@@ -270,20 +270,20 @@ public class ResourceDetailsPanel extends Panel {
      */
     private ConnInstanceTO getConectorInstanceTO(final List<ConnInstanceTO> connectorTOs, final ResourceTO resourceTO) {
         if (connectorTOs.isEmpty()) {
-            resourceTO.setConnectorId(null);
+            resourceTO.setConnector(null);
             return null;
         } else {
             // use the first element as default
             ConnInstanceTO res = connectorTOs.get(0);
 
             for (ConnInstanceTO to : connectorTOs) {
-                if (Long.valueOf(to.getKey()).equals(resourceTO.getConnectorId())) {
+                if (Long.valueOf(to.getKey()).equals(resourceTO.getConnector())) {
                     res = to;
                 }
             }
 
             // in case of no match
-            resourceTO.setConnectorId(res.getKey());
+            resourceTO.setConnector(res.getKey());
 
             return res;
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
index b00bc1b..17ae3bf 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java
@@ -36,12 +36,12 @@ import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownCho
 import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 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.AttributableType;
+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;
@@ -122,37 +122,28 @@ public class ResourceMappingPanel extends Panel {
     /**
      * User / group.
      */
-    private final AttributableType attrType;
+    private final AnyTypeKind anyTypeKind;
 
     /**
      * Mapping container.
      */
     private final WebMarkupContainer mappingContainer;
 
-    /**
-     * AccountLink container.
-     */
-    private final WebMarkupContainer accountLinkContainer;
+    private final WebMarkupContainer connObjectLinkContainer;
 
-    private final AjaxCheckBoxPanel accountLinkCheckbox;
+    private final AjaxCheckBoxPanel connObjectLinkCheckbox;
 
     private MappingTO getMapping() {
-        MappingTO result = null;
-
-        if (AttributableType.USER == this.attrType) {
-            if (this.resourceTO.getUmapping() == null) {
-                this.resourceTO.setUmapping(new MappingTO());
-            }
-            result = this.resourceTO.getUmapping();
+        ProvisionTO provision = resourceTO.getProvision(this.anyTypeKind.name());
+        if (provision == null) {
+            provision = new ProvisionTO();
+            resourceTO.getProvisions().add(provision);
         }
-        if (AttributableType.GROUP == this.attrType) {
-            if (this.resourceTO.getGmapping() == null) {
-                this.resourceTO.setGmapping(new MappingTO());
-            }
-            result = this.resourceTO.getGmapping();
+        if (provision.getMapping() == null) {
+            provision.setMapping(new MappingTO());
         }
 
-        return result;
+        return provision.getMapping();
     }
 
     /**
@@ -160,25 +151,25 @@ public class ResourceMappingPanel extends Panel {
      *
      * @param id panel id
      * @param resourceTO external resource
-     * @param attrType USER / GROUP
+     * @param anyTypeKind USER / GROUP
      */
-    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) {
+    public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AnyTypeKind anyTypeKind) {
         super(id);
         setOutputMarkupId(true);
 
         this.resourceTO = resourceTO;
-        this.attrType = attrType;
+        this.anyTypeKind = anyTypeKind;
 
         this.mappingContainer = new WebMarkupContainer("mappingContainer");
         this.mappingContainer.setOutputMarkupId(true);
         add(this.mappingContainer);
 
-        this.accountLinkContainer = new WebMarkupContainer("accountLinkContainer");
-        this.accountLinkContainer.setOutputMarkupId(true);
-        add(this.accountLinkContainer);
+        this.connObjectLinkContainer = new WebMarkupContainer("connObjectLinkContainer");
+        this.connObjectLinkContainer.setOutputMarkupId(true);
+        add(this.connObjectLinkContainer);
 
-        if (this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0) {
-            schemaNames = getSchemaNames(this.resourceTO.getConnectorId(), this.resourceTO.getConnConfProperties());
+        if (this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0) {
+            schemaNames = getSchemaNames(this.resourceTO.getConnector(), this.resourceTO.getConnConfProperties());
 
             setEnabled();
         } else {
@@ -193,7 +184,7 @@ public class ResourceMappingPanel extends Panel {
 
         final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password"));
         mappingContainer.add(passwordLabel);
-        if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+        if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) {
             passwordLabel.setVisible(false);
         }
 
@@ -213,8 +204,8 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
                     compared = 1;
                 } else if (left.getPurpose() == MappingPurpose.PROPAGATION
-                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION || right.getPurpose()
-                        == MappingPurpose.NONE)) {
+                        && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION
+                        || right.getPurpose() == MappingPurpose.NONE)) {
                     compared = -1;
                 } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION
                         && right.getPurpose() == MappingPurpose.PROPAGATION) {
@@ -225,9 +216,9 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() == MappingPurpose.NONE
                         && right.getPurpose() != MappingPurpose.NONE) {
                     compared = 1;
-                } else if (left.isAccountid()) {
+                } else if (left.isConnObjectKey()) {
                     compared = -1;
-                } else if (right.isAccountid()) {
+                } else if (right.isConnObjectKey()) {
                     compared = 1;
                 } else if (left.isPassword()) {
                     compared = -1;
@@ -251,14 +242,12 @@ public class ResourceMappingPanel extends Panel {
                     mapItem.setPurpose(MappingPurpose.BOTH);
                 }
 
-                AttributableType entity = null;
+                AnyTypeKind entity = null;
                 if (mapItem.getIntMappingType() != null) {
-                    entity = mapItem.getIntMappingType().getAttributableType();
+                    entity = mapItem.getIntMappingType().getAnyTypeKind();
                 }
 
-                final List<IntMappingType> attrTypes = new ArrayList<IntMappingType>(getAttributeTypes(entity));
-
-                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) {
+                item.add(new AjaxDecoratedCheckbox("toRemove", new Model<>(Boolean.FALSE)) {
 
                     private static final long serialVersionUID = 7170946748485726506L;
 
@@ -282,7 +271,7 @@ public class ResourceMappingPanel extends Panel {
                     protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) {
                         super.updateAjaxAttributes(attributes);
 
-                        final AjaxCallListener ajaxCallListener = new AjaxCallListener() {
+                        AjaxCallListener ajaxCallListener = new AjaxCallListener() {
 
                             private static final long serialVersionUID = 7160235486520935153L;
 
@@ -296,7 +285,7 @@ public class ResourceMappingPanel extends Panel {
                 });
 
                 final AjaxDropDownChoicePanel<String> intAttrNames =
-                        new AjaxDropDownChoicePanel<String>("intAttrNames", getString("intAttrNames"),
+                        new AjaxDropDownChoicePanel<>("intAttrNames", getString("intAttrNames"),
                                 new PropertyModel<String>(mapItem, "intAttrName"), false);
                 intAttrNames.setChoices(schemaNames);
                 intAttrNames.setRequired(true);
@@ -311,8 +300,9 @@ public class ResourceMappingPanel extends Panel {
                 });
                 item.add(intAttrNames);
 
+                final List<IntMappingType> attrTypes = new ArrayList<>(getAttributeTypes(entity));
                 final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes =
-                        new AjaxDropDownChoicePanel<IntMappingType>("intMappingTypes",
+                        new AjaxDropDownChoicePanel<>("intMappingTypes",
                                 new ResourceModel("intMappingTypes", "intMappingTypes").getObject(),
                                 new PropertyModel<IntMappingType>(mapItem, "intMappingType"));
                 intMappingTypes.setRequired(true);
@@ -320,13 +310,13 @@ public class ResourceMappingPanel extends Panel {
                 intMappingTypes.setStyleSheet(FIELD_STYLE);
                 item.add(intMappingTypes);
 
-                final AjaxDropDownChoicePanel<AttributableType> entitiesPanel =
-                        new AjaxDropDownChoicePanel<AttributableType>("entities",
-                                new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>(
-                                        entity));
-                entitiesPanel.setChoices(attrType == AttributableType.GROUP
-                        ? Collections.<AttributableType>singletonList(AttributableType.GROUP)
-                        : Arrays.asList(AttributableType.values()));
+                final AjaxDropDownChoicePanel<AnyTypeKind> entitiesPanel =
+                        new AjaxDropDownChoicePanel<>("entities",
+                                new ResourceModel("entities", "entities").getObject(),
+                                new Model<>(entity));
+                entitiesPanel.setChoices(anyTypeKind == AnyTypeKind.GROUP
+                        ? Collections.<AnyTypeKind>singletonList(AnyTypeKind.GROUP)
+                        : Arrays.asList(AnyTypeKind.values()));
                 entitiesPanel.setStyleSheet(DEF_FIELD_STYLE);
                 entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
@@ -369,16 +359,16 @@ public class ResourceMappingPanel extends Panel {
                 mandatory.setStyleSheet(SHORT_FIELD_STYLE);
                 item.add(mandatory);
 
-                final AjaxCheckBoxPanel accountId = new AjaxCheckBoxPanel("accountId",
-                        new ResourceModel("accountId", "accountId").getObject(),
-                        new PropertyModel<Boolean>(mapItem, "accountid"));
-                accountId.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+                final AjaxCheckBoxPanel connObjectKey = new AjaxCheckBoxPanel("connObjectKey",
+                        new ResourceModel("connObjectKey", "connObjectKey").getObject(),
+                        new PropertyModel<Boolean>(mapItem, "connObjectKey"));
+                connObjectKey.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
                     private static final long serialVersionUID = -1107858522700306810L;
 
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
-                        if (accountId.getModelObject()) {
+                        if (connObjectKey.getModelObject()) {
                             mapItem.setMandatoryCondition("true");
                             mandatory.setEnabled(false);
                         } else {
@@ -388,7 +378,7 @@ public class ResourceMappingPanel extends Panel {
                         target.add(mandatory);
                     }
                 });
-                item.add(accountId);
+                item.add(connObjectKey);
 
                 final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel("password",
                         new ResourceModel("password", "password").getObject(),
@@ -399,17 +389,17 @@ public class ResourceMappingPanel extends Panel {
 
                     @Override
                     protected void onUpdate(final AjaxRequestTarget target) {
-                        extAttrNames.setEnabled(!mapItem.isAccountid() && !password.getModelObject());
+                        extAttrNames.setEnabled(!mapItem.isConnObjectKey() && !password.getModelObject());
                         extAttrNames.setModelObject(null);
                         extAttrNames.setRequired(!password.getModelObject());
                         target.add(extAttrNames);
 
-                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
-                        target.add(accountId);
+                        setConnObjectKey(intMappingTypes.getModelObject(), connObjectKey, password);
+                        target.add(connObjectKey);
                     }
                 });
                 item.add(password);
-                if (AttributableType.USER != ResourceMappingPanel.this.attrType) {
+                if (AnyTypeKind.USER != ResourceMappingPanel.this.anyTypeKind) {
                     password.setVisible(false);
                 }
 
@@ -432,13 +422,13 @@ public class ResourceMappingPanel extends Panel {
                         setAttrNames(intMappingTypes.getModelObject(), intAttrNames);
                         target.add(intAttrNames);
 
-                        setAccountId(intMappingTypes.getModelObject(), accountId, password);
-                        target.add(accountId);
+                        setConnObjectKey(intMappingTypes.getModelObject(), connObjectKey, password);
+                        target.add(connObjectKey);
                     }
                 });
 
                 setAttrNames(mapItem.getIntMappingType(), intAttrNames);
-                setAccountId(mapItem.getIntMappingType(), accountId, password);
+                setConnObjectKey(mapItem.getIntMappingType(), connObjectKey, password);
             }
         };
 
@@ -456,41 +446,41 @@ public class ResourceMappingPanel extends Panel {
             }
         };
         addMappingBtn.setDefaultFormProcessing(false);
-        addMappingBtn.setEnabled(this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0);
+        addMappingBtn.setEnabled(this.resourceTO.getConnector() != null && this.resourceTO.getConnector() > 0);
         mappingContainer.add(addMappingBtn);
 
-        boolean accountLinkEnabled = false;
-        if (getMapping().getAccountLink() != null) {
-            accountLinkEnabled = true;
+        boolean connObjectLinkEnabled = false;
+        if (getMapping().getConnObjectLink() != null) {
+            connObjectLinkEnabled = true;
         }
-        accountLinkCheckbox = new AjaxCheckBoxPanel("accountLinkCheckbox",
-                new ResourceModel("accountLinkCheckbox", "accountLinkCheckbox").getObject(),
-                new Model<Boolean>(Boolean.valueOf(accountLinkEnabled)));
-        accountLinkCheckbox.setEnabled(true);
+        connObjectLinkCheckbox = new AjaxCheckBoxPanel("connObjectLinkCheckbox",
+                new ResourceModel("connObjectLinkCheckbox", "connObjectLinkCheckbox").getObject(),
+                new Model<>(connObjectLinkEnabled));
+        connObjectLinkCheckbox.setEnabled(true);
 
-        accountLinkContainer.add(accountLinkCheckbox);
+        connObjectLinkContainer.add(connObjectLinkCheckbox);
 
-        final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel("accountLink",
-                new ResourceModel("accountLink", "accountLink").getObject(),
-                new PropertyModel<String>(getMapping(), "accountLink"));
-        accountLink.setEnabled(accountLinkEnabled);
-        accountLinkContainer.add(accountLink);
+        final AjaxTextFieldPanel connObjectLink = new AjaxTextFieldPanel("connObjectLink",
+                new ResourceModel("connObjectLink", "connObjectLink").getObject(),
+                new PropertyModel<String>(getMapping(), "connObjectLink"));
+        connObjectLink.setEnabled(connObjectLinkEnabled);
+        connObjectLinkContainer.add(connObjectLink);
 
-        accountLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
+        connObjectLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
 
             private static final long serialVersionUID = -1107858522700306810L;
 
             @Override
             protected void onUpdate(final AjaxRequestTarget target) {
-                if (accountLinkCheckbox.getModelObject()) {
-                    accountLink.setEnabled(Boolean.TRUE);
-                    accountLink.setModelObject("");
+                if (connObjectLinkCheckbox.getModelObject()) {
+                    connObjectLink.setEnabled(Boolean.TRUE);
+                    connObjectLink.setModelObject("");
                 } else {
-                    accountLink.setEnabled(Boolean.FALSE);
-                    accountLink.setModelObject("");
+                    connObjectLink.setEnabled(Boolean.FALSE);
+                    connObjectLink.setModelObject("");
                 }
 
-                target.add(accountLink);
+                target.add(connObjectLink);
             }
         });
     }
@@ -504,25 +494,22 @@ public class ResourceMappingPanel extends Panel {
     }
 
     private void setEnabled() {
-        final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
-        connInstanceTO.setKey(this.resourceTO.getConnectorId());
+        ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+        connInstanceTO.setKey(this.resourceTO.getConnector());
         connInstanceTO.getConfiguration().addAll(this.resourceTO.getConnConfProperties());
 
-        List<ConnIdObjectClassTO> objectClasses = connRestClient.getSupportedObjectClasses(connInstanceTO);
+        boolean enabled = resourceTO.getProvision(anyTypeKind.name()) != null;
 
-        boolean enabled = objectClasses.isEmpty()
-                || (AttributableType.USER == attrType && objectClasses.contains(ConnIdObjectClassTO.ACCOUNT))
-                || (AttributableType.GROUP == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP));
         this.mappingContainer.setEnabled(enabled);
         this.mappingContainer.setVisible(enabled);
-        this.accountLinkContainer.setEnabled(enabled);
-        this.accountLinkContainer.setVisible(enabled);
+        this.connObjectLinkContainer.setEnabled(enabled);
+        this.connObjectLinkContainer.setVisible(enabled);
 
         if (!enabled) {
             getMapping().getItems().clear();
-            getMapping().setAccountLink(null);
-            if (this.accountLinkCheckbox != null) {
-                this.accountLinkCheckbox.setModelObject(null);
+            getMapping().setConnObjectLink(null);
+            if (this.connObjectLinkCheckbox != null) {
+                this.connObjectLinkCheckbox.setModelObject(null);
             }
         }
     }
@@ -536,10 +523,10 @@ public class ResourceMappingPanel extends Panel {
 
             mappings.removeAll();
 
-            addMappingBtn.setEnabled(resourceTO.getConnectorId() != null && resourceTO.getConnectorId() > 0);
+            addMappingBtn.setEnabled(resourceTO.getConnector() != null && resourceTO.getConnector() > 0);
 
             schemaNames.clear();
-            schemaNames.addAll(getSchemaNames(resourceTO.getConnectorId(), new HashSet<ConnConfProperty>(conf)));
+            schemaNames.addAll(getSchemaNames(resourceTO.getConnector(), new HashSet<ConnConfProperty>(conf)));
 
             setEnabled();
 
@@ -557,34 +544,35 @@ public class ResourceMappingPanel extends Panel {
         toBeUpdated.setRequired(true);
         toBeUpdated.setEnabled(true);
 
-        if (type == null || type.getAttributableType() == null) {
+        if (type == null || type.getAnyTypeKind() == null) {
             toBeUpdated.setChoices(Collections.<String>emptyList());
         } else {
             switch (type) {
                 // user attribute names
                 case UserPlainSchema:
                 case GroupPlainSchema:
-                case MembershipPlainSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames(type.getAttributableType()));
+                case AnyObjectPlainSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames());
                     break;
 
                 case UserDerivedSchema:
                 case GroupDerivedSchema:
-                case MembershipDerivedSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames(type.getAttributableType()));
+                case AnyObjectDerivedSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames());
                     break;
 
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
-                case MembershipVirtualSchema:
-                    toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames(type.getAttributableType()));
+                case AnyObjectVirtualSchema:
+                    toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames());
                     break;
 
-                case UserId:
+                case UserKey:
                 case Password:
                 case Username:
-                case GroupId:
+                case GroupKey:
                 case GroupName:
+                case AnyObjectKey:
                 default:
                     toBeUpdated.setRequired(false);
                     toBeUpdated.setEnabled(false);
@@ -594,33 +582,33 @@ public class ResourceMappingPanel extends Panel {
     }
 
     /**
-     * Enable/Disable accountId checkbox.
+     * Enable/Disable connObjectKey checkbox.
      *
      * @param type attribute type.
-     * @param accountId accountId checkbox.
+     * @param connObjectKey connObjectKey checkbox.
      * @param password password checkbox.
      */
-    private void setAccountId(final IntMappingType type, final AjaxCheckBoxPanel accountId,
-            final AjaxCheckBoxPanel password) {
+    private void setConnObjectKey(
+            final IntMappingType type, final AjaxCheckBoxPanel connObjectKey, final AjaxCheckBoxPanel password) {
 
-        if (type != null && type.getAttributableType() != null) {
+        if (type != null && type.getAnyTypeKind() != null) {
             switch (type) {
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
-                case MembershipVirtualSchema:
-                // Virtual accountId is not permitted
+                case AnyObjectVirtualSchema:
+                // Virtual connObjectKey is not permitted
                 case Password:
-                    // AccountId cannot be derived from password.
-                    accountId.setReadOnly(true);
-                    accountId.setModelObject(false);
+                    // connObjectKey cannot be derived from password.
+                    connObjectKey.setReadOnly(true);
+                    connObjectKey.setModelObject(false);
                     break;
 
                 default:
                     if (password.getModelObject()) {
-                        accountId.setReadOnly(true);
-                        accountId.setModelObject(false);
+                        connObjectKey.setReadOnly(true);
+                        connObjectKey.setModelObject(false);
                     } else {
-                        accountId.setReadOnly(false);
+                        connObjectKey.setReadOnly(false);
                     }
             }
         }
@@ -632,11 +620,11 @@ public class ResourceMappingPanel extends Panel {
      * @param entity entity.
      * @return all attribute types.
      */
-    private List<IntMappingType> getAttributeTypes(final AttributableType entity) {
+    private List<IntMappingType> getAttributeTypes(final AnyTypeKind entity) {
         final List<IntMappingType> res = new ArrayList<>();
 
         if (entity != null) {
-            res.addAll(IntMappingType.getAttributeTypes(AttributableType.valueOf(entity.name())));
+            res.addAll(IntMappingType.getAttributeTypes(entity));
         }
 
         return res;


[09/70] 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) {


[39/70] syncope git commit: [SYNCOPE-666] All but integration tests work

Posted by il...@apache.org.
[SYNCOPE-666] All but integration tests work


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

Branch: refs/heads/master
Commit: 705bfb86c37a06a538e8973cee8c4948d160bac4
Parents: c608b58
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed May 27 15:06:04 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed May 27 15:06:04 2015 +0200

----------------------------------------------------------------------
 .../client/console/rest/SchemaRestClient.java   |   1 -
 .../common/lib/types/ClientExceptionType.java   |   4 +-
 .../syncope/core/logic/AnyObjectLogic.java      |  27 +--
 .../syncope/core/logic/NotificationTest.java    |   3 -
 .../core/persistence/api/entity/Any.java        |   6 +
 .../persistence/jpa/entity/AbstractAny.java     |  92 ++++++++
 .../persistence/jpa/entity/AbstractAttr.java    |  81 +------
 .../persistence/jpa/entity/conf/JPAConf.java    |  18 ++
 .../api/AnyObjectProvisioningManager.java       |   9 -
 .../api/GroupProvisioningManager.java           |   4 -
 .../provisioning/api/ProvisioningManager.java   |   7 +
 .../api/UserProvisioningManager.java            |   2 -
 .../provisioning/api/data/UserDataBinder.java   |   8 +
 .../api/propagation/PropagationManager.java     |  23 +-
 .../DefaultAnyObjectProvisioningManager.java    | 173 +++++++++++++++
 .../java/DefaultGroupProvisioningManager.java   |  60 +++---
 .../java/DefaultUserProvisioningManager.java    | 122 ++++++-----
 .../java/data/AbstractAnyDataBinder.java        |  51 ++---
 .../java/data/AnyObjectDataBinderImpl.java      | 209 +++++++++++++++++++
 .../java/data/GroupDataBinderImpl.java          |   7 +-
 .../java/data/ResourceDataBinderImpl.java       |  49 +++--
 .../java/data/UserDataBinderImpl.java           |  21 +-
 .../propagation/PropagationManagerImpl.java     |  77 ++++---
 .../java/sync/AbstractProvisioningJob.java      |  10 +-
 .../src/main/resources/provisioning.properties  |   1 +
 .../src/main/resources/provisioningContext.xml  |   1 +
 .../java/data/ResourceDataBinderTest.java       |   5 +-
 .../java/AbstractAnyObjectWorkflowAdapter.java  |  61 ++++++
 .../java/DefaultAnyObjectWorkflowAdapter.java   | 112 ++++++++++
 .../src/main/resources/workflow.properties      |   1 +
 .../src/main/resources/workflowContext.xml      |   1 +
 .../camel/CamelGroupProvisioningManager.java    |  12 +-
 .../camel/CamelUserProvisioningManager.java     |  11 +
 .../camel/processor/GroupDeleteProcessor.java   |  16 +-
 34 files changed, 953 insertions(+), 332 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 9f7a6d2..8a145dc 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
@@ -31,7 +31,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.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.service.SchemaService;
 import org.springframework.stereotype.Component;

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 6875279..498f603 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -37,9 +37,11 @@ public enum ClientExceptionType {
     InvalidPolicy(Response.Status.BAD_REQUEST),
     InvalidConf(Response.Status.BAD_REQUEST),
     InvalidPath(Response.Status.BAD_REQUEST),
+    InvalidProvision(Response.Status.BAD_REQUEST),
     InvalidReport(Response.Status.BAD_REQUEST),
     InvalidReportExec(Response.Status.BAD_REQUEST),
-    InvalidGroups(Response.Status.BAD_REQUEST),
+    InvalidAnyObject(Response.Status.BAD_REQUEST),
+    InvalidGroup(Response.Status.BAD_REQUEST),
     InvalidSchemaDefinition(Response.Status.BAD_REQUEST),
     InvalidSearchExpression(Response.Status.BAD_REQUEST),
     InvalidPageOrSize(Response.Status.BAD_REQUEST),

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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
index 31fda37..4919097 100644
--- 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
@@ -37,9 +37,7 @@ 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;
@@ -136,7 +134,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     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(
+        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>() {
@@ -227,7 +225,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unlink(final Long anyObjectKey, final Collection<String> resources) {
-        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToRemove().addAll(resources);
         final Long updatedResult = provisioningManager.unlink(anyObjectMod);
@@ -239,7 +237,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO link(final Long anyObjectKey, final Collection<String> resources) {
-        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToAdd().addAll(resources);
         return binder.getAnyObjectTO(provisioningManager.link(anyObjectMod));
@@ -249,7 +247,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO unassign(final Long anyObjectKey, final Collection<String> resources) {
-        final AnyObjectMod anyObjectMod = new AnyObjectMod();
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
         anyObjectMod.setKey(anyObjectKey);
         anyObjectMod.getResourcesToRemove().addAll(resources);
         return update(anyObjectMod);
@@ -258,10 +256,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, 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) {
+    public AnyObjectTO assign(final Long anyObjectKey, final Collection<String> resources,
+            final boolean changePwd, final String password) {
 
-        final AnyObjectMod userMod = new AnyObjectMod();
+        AnyObjectMod userMod = new AnyObjectMod();
         userMod.setKey(anyObjectKey);
         userMod.getResourcesToAdd().addAll(resources);
         return update(userMod);
@@ -271,7 +269,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @Transactional(rollbackFor = { Throwable.class })
     @Override
     public AnyObjectTO deprovision(final Long anyObjectKey, final Collection<String> resources) {
-        final AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
 
         List<PropagationStatus> statuses = provisioningManager.deprovision(anyObjectKey, resources);
 
@@ -283,8 +281,9 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     @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) {
+    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 ...
@@ -297,7 +296,9 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @Override
-    protected AnyObjectTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException {
+    protected AnyObjectTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
         Long key = null;
 
         if (ArrayUtils.isNotEmpty(args)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 64aaa09..4401a6b 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
@@ -97,9 +97,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional
 public class NotificationTest {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(NotificationTest.class);
 
     private static final String SMTP_HOST = "localhost";

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
index 12bf9b6..0384db7 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Any.java
@@ -20,6 +20,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;
 
 public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>> extends AnnotatedEntity<Long> {
 
@@ -77,4 +78,9 @@ public interface Any<P extends PlainAttr<?>, D extends DerAttr<?>, V extends Vir
 
     List<? extends AnyTypeClass> getAuxClasses();
 
+    Set<PlainSchema> getAllowedPlainSchemas();
+
+    Set<DerSchema> getAllowedDerSchemas();
+
+    Set<VirSchema> getAllowedVirSchemas();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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
index 161927c..2e344b0 100644
--- 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
@@ -20,20 +20,33 @@ 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.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.persistence.Column;
 import javax.persistence.FetchType;
 import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
 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.AnyTypeClass;
 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.PlainAttr;
+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.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+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.TypeExtension;
 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.persistence.api.entity.user.User;
 
 @MappedSuperclass
 public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>, V extends VirAttr<?>>
@@ -50,6 +63,15 @@ public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>,
     @Column(nullable = true)
     private String status;
 
+    @Transient
+    private Set<PlainSchema> allowedPlainSchemas;
+
+    @Transient
+    private Set<DerSchema> allowedDerSchemas;
+
+    @Transient
+    private Set<VirSchema> allowedVirSchemas;
+
     @Override
     public Realm getRealm() {
         return realm;
@@ -146,4 +168,74 @@ public abstract class AbstractAny<P extends PlainAttr<?>, D extends DerAttr<?>,
     public List<? extends ExternalResource> getResources() {
         return internalGetResources();
     }
+
+    private void populateAllowedSchemas(final Collection<? extends AnyTypeClass> anyTypeClasses) {
+        for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+            allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas());
+        }
+
+        for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+            allowedDerSchemas.addAll(anyTypeClass.getDerSchemas());
+        }
+
+        for (AnyTypeClass anyTypeClass : anyTypeClasses) {
+            allowedVirSchemas.addAll(anyTypeClass.getVirSchemas());
+        }
+    }
+
+    private void populateAllowedSchemas() {
+        synchronized (this) {
+            if (allowedPlainSchemas == null) {
+                allowedPlainSchemas = new HashSet<>();
+            } else {
+                allowedPlainSchemas.clear();
+            }
+            if (allowedDerSchemas == null) {
+                allowedDerSchemas = new HashSet<>();
+            } else {
+                allowedDerSchemas.clear();
+            }
+            if (allowedVirSchemas == null) {
+                allowedVirSchemas = new HashSet<>();
+            } else {
+                allowedVirSchemas.clear();
+            }
+
+            populateAllowedSchemas(getType().getClasses());
+            populateAllowedSchemas(getAuxClasses());
+            if (this instanceof User) {
+                for (UMembership memb : ((User) this).getMemberships()) {
+                    for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
+                        populateAllowedSchemas(typeExtension.getAuxClasses());
+                    }
+                }
+            }
+            if (this instanceof AnyObject) {
+                for (AMembership memb : ((AnyObject) this).getMemberships()) {
+                    for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
+                        populateAllowedSchemas(typeExtension.getAuxClasses());
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public Set<PlainSchema> getAllowedPlainSchemas() {
+        populateAllowedSchemas();
+        return allowedPlainSchemas;
+    }
+
+    @Override
+    public Set<DerSchema> getAllowedDerSchemas() {
+        populateAllowedSchemas();
+        return allowedDerSchemas;
+    }
+
+    @Override
+    public Set<VirSchema> getAllowedVirSchemas() {
+        populateAllowedSchemas();
+        return allowedVirSchemas;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
index 4f4a3ec..914bd02 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
@@ -18,84 +18,30 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Set;
-import javax.persistence.Transient;
 import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.Attr;
 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.Schema;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-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.TypeExtension;
-import org.apache.syncope.core.persistence.api.entity.user.UMembership;
-import org.apache.syncope.core.persistence.api.entity.user.User;
 
 public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>>
         extends AbstractEntity<Long> implements Attr<S, O> {
 
     private static final long serialVersionUID = -7722134717360731874L;
 
-    @Transient
-    private Set<PlainSchema> allowedPlainSchemas;
-
-    @Transient
-    private Set<DerSchema> allowedDerSchemas;
-
-    @Transient
-    private Set<VirSchema> allowedVirSchemas;
-
-    private void populateClasses(final Collection<? extends AnyTypeClass> anyTypeClasses) {
-        synchronized (this) {
-            if (getSchema() instanceof PlainSchema) {
-                if (allowedPlainSchemas == null) {
-                    allowedPlainSchemas = new HashSet<>();
-                }
-                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
-                    allowedPlainSchemas.addAll(anyTypeClass.getPlainSchemas());
-                }
-            } else if (getSchema() instanceof DerSchema) {
-                if (allowedDerSchemas == null) {
-                    allowedDerSchemas = new HashSet<>();
-                }
-                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
-                    allowedDerSchemas.addAll(anyTypeClass.getDerSchemas());
-                }
-            } else if (getSchema() instanceof VirSchema) {
-                if (allowedVirSchemas == null) {
-                    allowedVirSchemas = new HashSet<>();
-                }
-                for (AnyTypeClass anyTypeClass : anyTypeClasses) {
-                    allowedVirSchemas.addAll(anyTypeClass.getVirSchemas());
-                }
-            }
-        }
-    }
-
     @SuppressWarnings("unchecked")
-    private Set<S> getAllowedSchemas() {
+    private Set<S> getAllowedSchemas(final O any) {
         Set<S> result = Collections.emptySet();
 
         if (getSchema() instanceof PlainSchema) {
-            if (allowedPlainSchemas == null) {
-                allowedPlainSchemas = new HashSet<>();
-            }
-            result = (Set<S>) allowedPlainSchemas;
+            result = (Set<S>) any.getAllowedPlainSchemas();
         } else if (getSchema() instanceof DerSchema) {
-            if (allowedDerSchemas == null) {
-                allowedDerSchemas = new HashSet<>();
-            }
-            result = (Set<S>) allowedDerSchemas;
+            result = (Set<S>) any.getAllowedDerSchemas();
         } else if (getSchema() instanceof VirSchema) {
-            if (allowedVirSchemas == null) {
-                allowedVirSchemas = new HashSet<>();
-            }
-            result = (Set<S>) allowedVirSchemas;
+            result = (Set<S>) any.getAllowedVirSchemas();
         }
 
         return result;
@@ -106,24 +52,7 @@ public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>>
             throw new IllegalStateException("First set owner then schema and finally add values");
         }
 
-        populateClasses(getOwner().getType().getClasses());
-        populateClasses(getOwner().getAuxClasses());
-        if (getOwner() instanceof User) {
-            for (UMembership memb : ((User) getOwner()).getMemberships()) {
-                for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
-                    populateClasses(typeExtension.getAuxClasses());
-                }
-            }
-        }
-        if (getOwner() instanceof AnyObject) {
-            for (AMembership memb : ((AnyObject) getOwner()).getMemberships()) {
-                for (TypeExtension typeExtension : memb.getRightEnd().getTypeExtensions()) {
-                    populateClasses(typeExtension.getAuxClasses());
-                }
-            }
-        }
-
-        if (!getAllowedSchemas().contains(schema)) {
+        if (!getAllowedSchemas(getOwner()).contains(schema)) {
             throw new IllegalArgumentException(schema + " not allowed for this instance");
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 3253f66..2b44253 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
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity.conf;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
 import javax.persistence.Cacheable;
 import javax.persistence.CascadeType;
 import javax.persistence.Entity;
@@ -33,8 +34,11 @@ 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.DerSchema;
+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.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 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.api.entity.resource.ExternalResource;
@@ -210,4 +214,18 @@ public class JPAConf extends AbstractAnnotatedEntity<Long> implements Conf {
         // nothing to do
     }
 
+    @Override
+    public Set<PlainSchema> getAllowedPlainSchemas() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<DerSchema> getAllowedDerSchemas() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Set<VirSchema> getAllowedVirSchemas() {
+        return Collections.emptySet();
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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
index 6b423d5..6928ffd 100644
--- 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
@@ -18,17 +18,8 @@
  */
 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);
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 0913405..1dce013 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
@@ -28,11 +28,7 @@ import org.apache.syncope.common.lib.to.GroupTO;
 
 public interface GroupProvisioningManager extends ProvisioningManager<GroupTO, GroupMod> {
 
-    Pair<Long, List<PropagationStatus>> create(GroupTO groupTO, Set<String> excludedResources);
-
     Pair<Long, List<PropagationStatus>> create(
             GroupTO groupTO, Map<Long, String> groupOwnerMap, Set<String> excludedResources);
 
-    Pair<Long, List<PropagationStatus>> update(GroupMod groupMod, Set<String> excludedResources);
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 28b2663..e517270 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
@@ -20,6 +20,7 @@ package org.apache.syncope.core.provisioning.api;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AnyMod;
 import org.apache.syncope.common.lib.to.AnyTO;
@@ -29,10 +30,16 @@ public interface ProvisioningManager<T extends AnyTO, M extends AnyMod> {
 
     Pair<Long, List<PropagationStatus>> create(T anyTO);
 
+    Pair<Long, List<PropagationStatus>> create(T anyTO, Set<String> excludedResources);
+
     Pair<Long, List<PropagationStatus>> update(M anyMod);
 
+    Pair<Long, List<PropagationStatus>> update(M anyMod, Set<String> excludedResources);
+
     List<PropagationStatus> delete(Long anyKey);
 
+    List<PropagationStatus> delete(Long anyKey, Set<String> excludedResources);
+
     Long unlink(M anyMod);
 
     Long link(M anyMod);

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 ad7a01e..810a788 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
@@ -46,8 +46,6 @@ public interface UserProvisioningManager extends ProvisioningManager<UserTO, Use
     Pair<Long, List<PropagationStatus>> update(UserMod userMod, Long key,
             ProvisioningResult result, Boolean enabled, Set<String> excludedResources);
 
-    List<PropagationStatus> delete(Long key, Set<String> excludedResources);
-
     void requestPasswordReset(Long key);
 
     void confirmPasswordReset(User user, String token, String password);

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java
index e5fbb00..942c212 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/UserDataBinder.java
@@ -35,6 +35,14 @@ public interface UserDataBinder {
 
     void create(User user, UserTO userTO, boolean storePassword);
 
+    /**
+     * Update user, given UserMod.
+     *
+     * @param toBeUpdated user to be updated
+     * @param userMod bean containing update request
+     * @return updated user + propagation by resource
+     * @see PropagationByResource
+     */
     PropagationByResource update(User toBeUpdated, UserMod userMod);
 
     boolean verifyPassword(String username, String password);

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 36821c3..cf8cde4 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
@@ -113,13 +113,24 @@ public interface PropagationManager {
     List<PropagationTask> getGroupDeleteTasks(
             Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
 
+    List<PropagationTask> getAnyObjectCreateTasks(
+            WorkflowResult<Long> wfResult, Collection<AttrTO> vAttrs, Collection<String> noPropResourceNames);
+
     List<PropagationTask> getAnyObjectCreateTasks(Long anyObjectKey, Collection<AttrTO> vAttrs,
-            PropagationByResource propByRes, List<String> noPropResourceNames);
+            PropagationByResource propByRes, Collection<String> noPropResourceNames);
+
+    List<PropagationTask> getAnyObjectUpdateTasks(WorkflowResult<Long> wfResult, Set<String> vAttrsToBeRemoved,
+            Set<AttrMod> vAttrsToBeUpdated, Set<String> noPropResourceNames);
+
+    List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey);
 
     List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, String noPropResourceName);
 
     List<PropagationTask> getAnyObjectDeleteTasks(Long anyObjectKey, Collection<String> noPropResourceNames);
 
+    List<PropagationTask> getAnyObjectDeleteTasks(
+            Long groupKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
+
     /**
      * Create the user on every associated resource.
      *
@@ -186,14 +197,4 @@ public interface PropagationManager {
     List<PropagationTask> getUserDeleteTasks(
             Long userKey, Set<String> resourceNames, Collection<String> noPropResourceNames);
 
-    /**
-     * Perform delete on each resource associated to the user. 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.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @return list of propagation tasks
-     */
-    List<PropagationTask> getUserDeleteTasks(WorkflowResult<Long> wfResult);
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
new file mode 100644
index 0000000..1bd2638
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 java.util.ArrayList;
+import java.util.Collection;
+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.lang3.tuple.ImmutablePair;
+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;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisioningManager {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectProvisioningManager.class);
+
+    @Autowired
+    protected AnyObjectWorkflowAdapter awfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> create(final AnyObjectTO anyObjectTO) {
+        return create(anyObjectTO, Collections.<String>emptySet());
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> create(
+            final AnyObjectTO anyObjectTO, final Set<String> excludedResources) {
+
+        WorkflowResult<Long> created = awfAdapter.create(anyObjectTO);
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectCreateTasks(
+                created, anyObjectTO.getVirAttrs(), excludedResources);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses());
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> update(final AnyObjectMod anyObjectMod) {
+        return update(anyObjectMod, Collections.<String>emptySet());
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> update(
+            final AnyObjectMod anyObjectMod, final Set<String> excludedResources) {
+
+        WorkflowResult<Long> updated = awfAdapter.update(anyObjectMod);
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated,
+                anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), null);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses());
+    }
+
+    @Override
+    public List<PropagationStatus> delete(final Long anyObjectKey) {
+        return delete(anyObjectKey, Collections.<String>emptySet());
+    }
+
+    @Override
+    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+        List<PropagationTask> tasks = new ArrayList<>();
+
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+        if (anyObject != null) {
+            tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey()));
+        }
+
+        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+                getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        awfAdapter.delete(anyObjectKey);
+
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public Long unlink(final AnyObjectMod anyObjectMod) {
+        return awfAdapter.update(anyObjectMod).getResult();
+    }
+
+    @Override
+    public Long link(final AnyObjectMod anyObjectMod) {
+        return awfAdapter.update(anyObjectMod).getResult();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+
+        Collection<String> noPropResourceName = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectDeleteTasks(
+                anyObjectKey, new HashSet<>(resources), noPropResourceName);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 8535dc2..c7bc1c4 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
@@ -66,16 +66,16 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     protected GroupDAO groupDAO;
 
     @Override
-    public Pair<Long, List<PropagationStatus>> create(final GroupTO any) {
-        return create(any, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO group) {
+        return create(group, Collections.<String>emptySet());
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> create(final GroupTO any, final Set<String> excludedResources) {
-        WorkflowResult<Long> created = gwfAdapter.create(any);
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO groupTO, final Set<String> excludedResources) {
+        WorkflowResult<Long> created = gwfAdapter.create(groupTO);
 
-        List<PropagationTask> tasks =
-                propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResources);
+        List<PropagationTask> tasks = propagationManager.getGroupCreateTasks(
+                created, groupTO.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
                 PropagationReporter.class);
         try {
@@ -107,18 +107,18 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod anyMod) {
-        return update(anyMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod groupObjectMod) {
+        return update(groupObjectMod, Collections.<String>emptySet());
     }
 
     @Override
     public Pair<Long, List<PropagationStatus>> update(
-            final GroupMod anyMod, final Set<String> excludedResources) {
+            final GroupMod groupMod, final Set<String> excludedResources) {
 
-        WorkflowResult<Long> updated = gwfAdapter.update(anyMod);
+        WorkflowResult<Long> updated = gwfAdapter.update(groupMod);
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
-                anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), null);
+                groupMod.getVirAttrsToRemove(), groupMod.getVirAttrsToUpdate(), excludedResources);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {
@@ -128,25 +128,35 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        Pair<Long, List<PropagationStatus>> result = new ImmutablePair<>(
-                updated.getResult(), propagationReporter.getStatuses());
-        return result;
+        return new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses());
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long anyKey) {
-        final List<PropagationTask> tasks = new ArrayList<>();
+    public List<PropagationStatus> delete(final Long groupObjectKey) {
+        return delete(groupObjectKey, Collections.<String>emptySet());
+    }
 
-        Group group = groupDAO.authFind(anyKey);
+    @Override
+    public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) {
+        List<PropagationTask> tasks = new ArrayList<>();
+
+        Group group = groupDAO.authFind(groupKey);
         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.findUsersWithTransitiveResources(group.getKey()).entrySet()) {
+
+                WorkflowResult<Long> wfResult =
+                        new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
+                tasks.addAll(propagationManager.getUserDeleteTasks(wfResult.getResult(), excludedResources));
+            }
+            for (Map.Entry<Long, PropagationByResource> entry
                     : groupDAO.findAnyObjectsWithTransitiveResources(group.getKey()).entrySet()) {
 
                 WorkflowResult<Long> wfResult =
                         new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
-                tasks.addAll(propagationManager.getUserDeleteTasks(wfResult));
+                tasks.addAll(propagationManager.getAnyObjectDeleteTasks(wfResult.getResult(), excludedResources));
             }
 
             // Generate propagation tasks for deleting this group from resources
@@ -162,18 +172,14 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
             propagationReporter.onPrimaryResourceFailure(tasks);
         }
 
-        try {
-            gwfAdapter.delete(anyKey);
-        } catch (RuntimeException e) {
-            throw e;
-        }
+        gwfAdapter.delete(groupKey);
 
         return propagationReporter.getStatuses();
     }
 
     @Override
-    public Long unlink(final GroupMod anyMod) {
-        WorkflowResult<Long> updated = gwfAdapter.update(anyMod);
+    public Long unlink(final GroupMod groupMod) {
+        WorkflowResult<Long> updated = gwfAdapter.update(groupMod);
         return updated.getResult();
     }
 
@@ -197,8 +203,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public Long link(final GroupMod anyMod) {
-        return gwfAdapter.update(anyMod).getResult();
+    public Long link(final GroupMod groupMod) {
+        return gwfAdapter.update(groupMod).getResult();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 58ecb4a..88d3094 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
@@ -77,6 +77,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
+    public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final Set<String> excludedResources) {
+        return create(userTO, false, false, null, excludedResources);
+    }
+
+    @Override
     public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
 
@@ -138,6 +143,64 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
+    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Set<String> excludedResources) {
+        return update(userMod, userMod.getKey(), new ProvisioningResult(), null, excludedResources);
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key,
+            final ProvisioningResult result, final Boolean enabled, final Set<String> excludedResources) {
+
+        WorkflowResult<Pair<UserMod, Boolean>> updated;
+        try {
+            updated = uwfAdapter.update(userMod);
+        } catch (Exception e) {
+            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", key, e);
+
+            result.setStatus(ProvisioningResult.Status.FAILURE);
+            result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
+
+            updated = new WorkflowResult<Pair<UserMod, Boolean>>(
+                    new ImmutablePair<>(userMod, false), new PropagationByResource(),
+                    new HashSet<String>());
+        }
+
+        if (enabled != null) {
+            User user = userDAO.find(key);
+
+            WorkflowResult<Long> enableUpdate = null;
+            if (user.isSuspended() == null) {
+                enableUpdate = uwfAdapter.activate(key, null);
+            } else if (enabled && user.isSuspended()) {
+                enableUpdate = uwfAdapter.reactivate(key);
+            } else if (!enabled && !user.isSuspended()) {
+                enableUpdate = uwfAdapter.suspend(key);
+            }
+
+            if (enableUpdate != null) {
+                if (enableUpdate.getPropByRes() != null) {
+                    updated.getPropByRes().merge(enableUpdate.getPropByRes());
+                    updated.getPropByRes().purge();
+                }
+                updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
+            }
+        }
+
+        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
+                updated, updated.getResult().getKey().getPassword() != null, excludedResources);
+        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
+                getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return new ImmutablePair<>(updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
+    }
+
+    @Override
     public List<PropagationStatus> delete(final Long userKey) {
         return delete(userKey, Collections.<String>emptySet());
     }
@@ -176,8 +239,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Long link(final UserMod anyMod) {
-        return uwfAdapter.update(anyMod).getResult().getKey().getKey();
+    public Long link(final UserMod userMod) {
+        return uwfAdapter.update(userMod).getResult().getKey().getKey();
     }
 
     @Override
@@ -265,61 +328,6 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final UserMod userMod, final Long key,
-            final ProvisioningResult result, final Boolean enabled, final Set<String> excludedResources) {
-
-        WorkflowResult<Pair<UserMod, Boolean>> updated;
-        try {
-            updated = uwfAdapter.update(userMod);
-        } catch (Exception e) {
-            LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", key, e);
-
-            result.setStatus(ProvisioningResult.Status.FAILURE);
-            result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
-
-            updated = new WorkflowResult<Pair<UserMod, Boolean>>(
-                    new ImmutablePair<>(userMod, false), new PropagationByResource(),
-                    new HashSet<String>());
-        }
-
-        if (enabled != null) {
-            User user = userDAO.find(key);
-
-            WorkflowResult<Long> enableUpdate = null;
-            if (user.isSuspended() == null) {
-                enableUpdate = uwfAdapter.activate(key, null);
-            } else if (enabled && user.isSuspended()) {
-                enableUpdate = uwfAdapter.reactivate(key);
-            } else if (!enabled && !user.isSuspended()) {
-                enableUpdate = uwfAdapter.suspend(key);
-            }
-
-            if (enableUpdate != null) {
-                if (enableUpdate.getPropByRes() != null) {
-                    updated.getPropByRes().merge(enableUpdate.getPropByRes());
-                    updated.getPropByRes().purge();
-                }
-                updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks());
-            }
-        }
-
-        List<PropagationTask> tasks = propagationManager.getUserUpdateTasks(
-                updated, updated.getResult().getKey().getPassword() != null, excludedResources);
-        PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().
-                getBean(PropagationReporter.class);
-        try {
-            taskExecutor.execute(tasks, propagationReporter);
-        } catch (PropagationException e) {
-            LOG.error("Error propagation primary resource", e);
-            propagationReporter.onPrimaryResourceFailure(tasks);
-        }
-
-        return new ImmutablePair<>(updated.getResult().getKey().getKey(),
-                propagationReporter.getStatuses());
-
-    }
-
-    @Override
     public void requestPasswordReset(final Long id) {
         uwfAdapter.requestPasswordReset(id);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index f63a9b4..fb01aa4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -59,6 +59,7 @@ 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.misc.ConnObjectUtils;
 import org.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.apache.syncope.core.misc.MappingUtils;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
@@ -130,6 +131,9 @@ abstract class AbstractAnyDataBinder {
     @Autowired
     protected VirAttrHandler virtAttrHander;
 
+    @Autowired
+    protected ConnObjectUtils connObjectUtils;
+
     protected void setRealm(final Any<?, ?, ?> any, final AnyMod anyMod) {
         if (StringUtils.isNotBlank(anyMod.getRealm())) {
             Realm newRealm = realmDAO.find(anyMod.getRealm());
@@ -239,8 +243,7 @@ abstract class AbstractAnyDataBinder {
         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) {
+        for (PlainSchema schema : any.getAllowedPlainSchemas()) {
             if (any.getPlainAttr(schema.getKey()) == null
                     && !schema.isReadonly()
                     && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any)
@@ -253,8 +256,7 @@ abstract class AbstractAnyDataBinder {
             }
         }
 
-        List<DerSchema> derSchemas = derSchemaDAO.findAll();
-        for (DerSchema derSchema : derSchemas) {
+        for (DerSchema derSchema : any.getAllowedDerSchemas()) {
             if (any.getDerAttr(derSchema.getKey()) == null
                     && evaluateMandatoryCondition(anyUtils, any, derSchema.getKey(),
                             anyUtils.derIntMappingType())) {
@@ -265,8 +267,7 @@ abstract class AbstractAnyDataBinder {
             }
         }
 
-        List<VirSchema> virSchemas = virSchemaDAO.findAll();
-        for (VirSchema virSchema : virSchemas) {
+        for (VirSchema virSchema : any.getAllowedVirSchemas()) {
             if (any.getVirAttr(virSchema.getKey()) == null
                     && !virSchema.isReadonly()
                     && evaluateMandatoryCondition(anyUtils, any, virSchema.getKey(),
@@ -294,7 +295,7 @@ abstract class AbstractAnyDataBinder {
             ExternalResource resource = resourceDAO.find(resourceToBeRemoved);
             if (resource != null) {
                 propByRes.add(ResourceOperation.DELETE, resource.getKey());
-                ((Any<?, ?, ?>) any).remove(resource);
+                any.remove(resource);
             }
         }
 
@@ -305,7 +306,7 @@ abstract class AbstractAnyDataBinder {
             ExternalResource resource = resourceDAO.find(resourceToBeAdded);
             if (resource != null) {
                 propByRes.add(ResourceOperation.CREATE, resource.getKey());
-                ((Any<?, ?, ?>) any).add(resource);
+                any.add(resource);
             }
         }
 
@@ -512,17 +513,15 @@ abstract class AbstractAnyDataBinder {
                     PlainAttr attr = any.getPlainAttr(schema.getKey());
                     if (attr == null) {
                         attr = anyUtils.newPlainAttr();
+                        attr.setOwner(any);
                         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);
+                    fillAttribute(attributeTO.getValues(), anyUtils, schema, attr, invalidValues);
 
-                        if (!attr.getValuesAsStrings().isEmpty()) {
-                            any.add(attr);
-                            attr.setOwner(any);
-                        }
+                    if (attr.getValuesAsStrings().isEmpty()) {
+                        attr.setOwner(null);
+                    } else {
+                        any.add(attr);
                     }
                 }
             }
@@ -538,13 +537,9 @@ abstract class AbstractAnyDataBinder {
 
             if (derSchema != null) {
                 DerAttr derAttr = anyUtils.newDerAttr();
+                derAttr.setOwner(any);
                 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);
-                }
+                any.add(derAttr);
             }
         }
 
@@ -554,13 +549,9 @@ abstract class AbstractAnyDataBinder {
 
             if (virSchema != null) {
                 VirAttr virAttr = anyUtils.newVirAttr();
+                virAttr.setOwner(any);
                 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);
-                }
+                any.add(virAttr);
             }
         }
 
@@ -574,13 +565,13 @@ abstract class AbstractAnyDataBinder {
                     "Invalid or null realm specified: " + anyTO.getRealm());
             scce.addException(noRealm);
         }
-        ((Any<?, ?, ?>) any).setRealm(realm);
+        any.setRealm(realm);
 
         for (String resourceName : anyTO.getResources()) {
             ExternalResource resource = resourceDAO.find(resourceName);
 
             if (resource != null) {
-                ((Any<?, ?, ?>) any).add(resource);
+                any.add(resource);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
new file mode 100644
index 0000000..eb7586d
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 static org.apache.syncope.core.provisioning.java.data.AbstractAnyDataBinder.LOG;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+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.misc.spring.BeanUtils;
+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.provisioning.api.data.AnyObjectDataBinder;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Transactional(rollbackFor = { Throwable.class })
+public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements AnyObjectDataBinder {
+
+    private static final String[] IGNORE_PROPERTIES = {
+        "realm", "memberships", "plainAttrs", "derAttrs", "virAttrs", "resources"
+    };
+
+    @Transactional(readOnly = true)
+    @Override
+    public AnyObjectTO getAnyObjectTO(final Long key) {
+        return getAnyObjectTO(anyObjectDAO.authFind(key));
+    }
+
+    @Override
+    public AnyObjectTO getAnyObjectTO(final AnyObject anyObject) {
+        AnyObjectTO anyObjectTO = new AnyObjectTO();
+
+        BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES);
+
+        connObjectUtils.retrieveVirAttrValues(anyObject);
+        fillTO(anyObjectTO, anyObject.getRealm().getFullPath(),
+                anyObject.getPlainAttrs(), anyObject.getDerAttrs(), anyObject.getVirAttrs(),
+                anyObjectDAO.findAllResources(anyObject));
+
+        for (AMembership membership : anyObject.getMemberships()) {
+            MembershipTO membershipTO = new MembershipTO();
+
+            membershipTO.setKey(membership.getKey());
+            membershipTO.setRightKey(membership.getRightEnd().getKey());
+            membershipTO.setGroupName(membership.getRightEnd().getName());
+
+            anyObjectTO.getMemberships().add(membershipTO);
+        }
+
+        // dynamic memberships
+        CollectionUtils.collect(anyObjectDAO.findDynGroupMemberships(anyObject), new Transformer<Group, Long>() {
+
+            @Override
+            public Long transform(final Group group) {
+                return group.getKey();
+            }
+        }, anyObjectTO.getDynGroups());
+
+        return anyObjectTO;
+    }
+
+    @Override
+    public void create(final AnyObject anyObject, final AnyObjectTO anyObjectTO) {
+        SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+        // memberships
+        for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
+            Group group = groupDAO.find(membershipTO.getRightKey());
+
+            if (group == null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring invalid group " + membershipTO.getGroupName());
+                }
+            } else {
+                AMembership membership = null;
+                if (anyObject.getKey() != null) {
+                    membership = anyObject.getMembership(group.getKey());
+                }
+                if (membership == null) {
+                    membership = entityFactory.newEntity(AMembership.class);
+                    membership.setRightEnd(group);
+                    membership.setLeftEnd(anyObject);
+
+                    anyObject.add(membership);
+                }
+            }
+        }
+
+        // realm, attributes, derived attributes, virtual attributes and resources
+        fill(anyObject, anyObjectTO, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce);
+    }
+
+    @Override
+    public PropagationByResource update(final AnyObject toBeUpdated, final AnyObjectMod anyObjectMod) {
+        // Re-merge any pending change from workflow tasks
+        final AnyObject anyObject = anyObjectDAO.save(toBeUpdated);
+
+        PropagationByResource propByRes = new PropagationByResource();
+
+        SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
+
+        Collection<String> currentResources = anyObjectDAO.findAllResourceNames(anyObject);
+
+        // fetch connObjectKeys before update
+        Map<String, String> oldConnObjectKeys = getConnObjectKeys(anyObject);
+
+        // attributes, derived attributes, virtual attributes and resources
+        propByRes.merge(fill(anyObject, anyObjectMod, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce));
+
+        // store the group ids of membership required to be added
+        Set<Long> membershipToBeAddedGroupKeys = new HashSet<>(anyObjectMod.getMembershipsToAdd());
+
+        final Set<String> toBeDeprovisioned = new HashSet<>();
+        final Set<String> toBeProvisioned = new HashSet<>();
+
+        // memberships to be removed
+        for (Long groupKey : anyObjectMod.getMembershipsToRemove()) {
+            LOG.debug("Membership to be removed for group {}", groupKey);
+
+            AMembership membership = anyObject.getMembership(groupKey);
+            if (membership == null) {
+                LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey);
+            } else {
+                if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
+                    anyObject.remove(membership);
+                } else {
+                    toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
+                }
+            }
+        }
+
+        // memberships to be added
+        for (Long groupKey : anyObjectMod.getMembershipsToAdd()) {
+            LOG.debug("Membership to be added for group {}", groupKey);
+
+            Group group = groupDAO.find(groupKey);
+            if (group == null) {
+                LOG.debug("Ignoring invalid group {}", groupKey);
+            } else {
+                AMembership membership = anyObject.getMembership(group.getKey());
+                if (membership == null) {
+                    membership = entityFactory.newEntity(AMembership.class);
+                    membership.setRightEnd(group);
+                    membership.setLeftEnd(anyObject);
+
+                    anyObject.add(membership);
+
+                    toBeProvisioned.addAll(group.getResourceNames());
+                }
+            }
+        }
+
+        propByRes.addAll(ResourceOperation.DELETE, toBeDeprovisioned);
+        propByRes.addAll(ResourceOperation.UPDATE, toBeProvisioned);
+
+        /**
+         * In case of new memberships all the current resources have to be updated in order to propagate new group and
+         * membership attribute values.
+         */
+        if (!toBeDeprovisioned.isEmpty() || !toBeProvisioned.isEmpty()) {
+            currentResources.removeAll(toBeDeprovisioned);
+            propByRes.addAll(ResourceOperation.UPDATE, currentResources);
+        }
+
+        // check if some connObjectKey was changed by the update above
+        Map<String, String> newcCnnObjectKeys = getConnObjectKeys(anyObject);
+        for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) {
+            if (newcCnnObjectKeys.containsKey(entry.getKey())
+                    && !entry.getValue().equals(newcCnnObjectKeys.get(entry.getKey()))) {
+
+                propByRes.addOldConnObjectKey(entry.getKey(), entry.getValue());
+                propByRes.add(ResourceOperation.UPDATE, entry.getKey());
+            }
+        }
+
+        return propByRes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 6bce1b1..a900e70 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
@@ -30,13 +30,11 @@ import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
-import org.apache.syncope.core.misc.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;
 
@@ -44,9 +42,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupDataBinder {
 
-    @Autowired
-    private ConnObjectUtils connObjectUtils;
-
     private void setDynMembership(final Group group, final AnyTypeKind anyTypeKind, final String dynMembershipFIQL) {
         SearchCond dynMembershipCond = SearchCondConverter.convert(dynMembershipFIQL);
         if (!dynMembershipCond.isValid()) {
@@ -77,7 +72,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         // name
-        SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroups);
+        SyncopeClientException invalidGroups = SyncopeClientException.build(ClientExceptionType.InvalidGroup);
         if (groupTO.getName() == null) {
             LOG.error("No name specified for this group");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 4930764..20b3c58 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
@@ -112,29 +112,34 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             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));
+                Provision provision = resource.getProvision(anyType);
+                if (provision == null) {
+                    provision = entityFactory.newEntity(Provision.class);
+                    provision.setResource(resource);
+                    resource.add(provision);
+                    provision.setAnyType(anyType);
+                }
+
+                if (provisionTO.getObjectClass() == null) {
+                    SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidProvision);
+                    sce.getElements().add("Null ObjectClass");
+                    throw sce;
+                }
+                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));
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 e20e405..54d10bc 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
@@ -47,7 +47,6 @@ import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.Encryptor;
 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;
@@ -71,9 +70,6 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
     private ConfDAO confDAO;
 
     @Autowired
-    private ConnObjectUtils connObjectUtils;
-
-    @Autowired
     private SecurityQuestionDAO securityQuestionDAO;
 
     @Resource(name = "adminUser")
@@ -194,14 +190,6 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         user.setSecurityAnswer(userTO.getSecurityAnswer());
     }
 
-    /**
-     * Update user, given UserMod.
-     *
-     * @param toBeUpdated user to be updated
-     * @param userMod bean containing update request
-     * @return updated user + propagation by resource
-     * @see PropagationByResource
-     */
     @Override
     public PropagationByResource update(final User toBeUpdated, final UserMod userMod) {
         // Re-merge any pending change from workflow tasks
@@ -292,13 +280,10 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             if (membership == null) {
                 LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey);
             } else {
-                if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
-                    toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
-                }
-
-                if (!membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
-                } else {
+                if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
                     user.remove(membership);
+                } else {
+                    toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
             }
         }


[43/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 73a7896..6a67ccf 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -51,6 +51,7 @@ 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.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
@@ -72,9 +73,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public abstract class AbstractPropagationTaskExecutor implements PropagationTaskExecutor {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationTaskExecutor.class);
 
     /**
@@ -299,9 +297,11 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
             Any<?, ?, ?> any = getAny(task);
             Collection<String> resources = any instanceof User
                     ? userDAO.findAllResourceNames((User) any)
-                    : any instanceof Group
-                            ? ((Group) any).getResourceNames()
-                            : Collections.<String>emptySet();
+                    : any instanceof AnyObject
+                            ? anyObjectDAO.findAllResourceNames((AnyObject) any)
+                            : any instanceof Group
+                                    ? ((Group) any).getResourceNames()
+                                    : Collections.<String>emptySet();
             if (!resources.contains(task.getResource().getKey())) {
                 LOG.debug("Delete {} on {}", beforeObj.getUid(), task.getResource().getKey());
 
@@ -339,13 +339,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
         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());
-            }
-
+            provision = task.getResource().getProvision(new ObjectClass(task.getObjectClassName()));
             connector = connFactory.getConnector(task.getResource());
 
             // Try to read remote object BEFORE any actual operation

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 6d795d8..6dbd0eb 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
@@ -46,7 +46,7 @@ import org.springframework.transaction.annotation.Transactional;
  * Simple action for propagating group memberships to LDAP groups, when the same resource is configured for both users
  * and groups.
  *
- * @see org.apache.syncope.core.sync.impl.LDAPMembershipSyncActions
+ * @see org.apache.syncope.core.provisioning.java.sync.LDAPMembershipSyncActions
  */
 public class LDAPMembershipPropagationActions extends DefaultPropagationActions {
 
@@ -85,7 +85,7 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
 
                         JexlContext jexlContext = new MapContext();
                         JexlUtils.addFieldsToContext(group, jexlContext);
-                        JexlUtils.addAttrsToContext(group.getPlainAttrs(), jexlContext);
+                        JexlUtils.addPlainAttrsToContext(group.getPlainAttrs(), jexlContext);
                         JexlUtils.addDerAttrsToContext(group.getDerAttrs(), group.getPlainAttrs(), jexlContext);
 
                         String groupConnObjectLinkLink =

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 8f52059..2649623 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
@@ -30,7 +30,6 @@ import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.mod.AttrMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AttrTO;
-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;
@@ -45,7 +44,6 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-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;
@@ -57,6 +55,7 @@ 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.provisioning.api.VirAttrHandler;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
 import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -71,9 +70,6 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public class PropagationManagerImpl implements PropagationManager {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
     protected AnyObjectDAO anyObjectDAO;
@@ -129,7 +125,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         AnyObject anyObject = anyObjectDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(anyObject, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+            virAttrHandler.fillVirtual(anyObject, vAttrs);
         }
 
         return getCreateTaskIds(anyObject, null, null, propByRes, noPropResourceNames);
@@ -146,7 +142,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         User user = userDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(user, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.USER));
+            virAttrHandler.fillVirtual(user, vAttrs);
         }
         return getCreateTaskIds(user, password, enable, propByRes, noPropResourceNames);
     }
@@ -169,7 +165,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
         Group group = groupDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
-            virAttrHandler.fillVirtual(group, vAttrs, anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+            virAttrHandler.fillVirtual(group, vAttrs);
         }
 
         return getCreateTaskIds(group, null, null, propByRes, noPropResourceNames);
@@ -287,11 +283,13 @@ public class PropagationManagerImpl implements PropagationManager {
             final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
             final PropagationByResource propByRes, final Collection<String> noPropResourceNames) {
 
-        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(any, vAttrsToBeRemoved == null
-                ? Collections.<String>emptySet()
-                : vAttrsToBeRemoved, vAttrsToBeUpdated == null
+        PropagationByResource localPropByRes = virAttrHandler.fillVirtual(
+                any,
+                vAttrsToBeRemoved == null
+                        ? Collections.<String>emptySet()
+                        : vAttrsToBeRemoved, vAttrsToBeUpdated == null
                         ? Collections.<AttrMod>emptySet()
-                        : vAttrsToBeUpdated, anyUtilsFactory.getInstance(any));
+                        : vAttrsToBeUpdated);
 
         if (propByRes == null || propByRes.isEmpty()) {
             localPropByRes.addAll(ResourceOperation.UPDATE, any.getResourceNames());
@@ -419,7 +417,7 @@ public class PropagationManagerImpl implements PropagationManager {
         if (!propByRes.get(ResourceOperation.CREATE).isEmpty()
                 && vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
 
-            connObjectUtils.retrieveVirAttrValues(any);
+            virAttrHandler.retrieveVirAttrValues(any);
 
             // update vAttrsToBeUpdated as well
             for (VirAttr<?> virAttr : any.getVirAttrs()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 4f7b744..8f80ac0 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
@@ -302,7 +302,8 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 append(' ').
                 append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
                 append(' ').
-                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size());
+                append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
+                append('\n');
         report.append("Any objects ").
                 append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
                 append(' ').

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 275f648..fd5a482 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
@@ -116,14 +116,13 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
 
         Object output = null;
         Result resultStatus = null;
-        ConnectorObject beforeObj = null;
         String operation = null;
 
-        // Try to read remote object (user / group) BEFORE any actual operation
+        // Try to read remote object BEFORE any actual operation
         Provision provision = profile.getTask().getResource().getProvision(any.getType());
         String connObjecKey = MappingUtils.getConnObjectKeyValue(any, provision);
 
-        beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
+        ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
 
         Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
 
@@ -186,7 +185,6 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan
                         default:
                         // do nothing
                     }
-
                 } else {
                     operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
                     result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 1ead6a7..6d8986a 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
@@ -109,7 +109,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
         anyTO.getResources().add(profile.getTask().getResource().getKey());
 
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
@@ -149,7 +149,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
         result.setOperation(ResourceOperation.CREATE);
         result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
@@ -270,7 +270,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                             workingDelta = action.beforeUpdate(this.getProfile(), workingDelta, before, anyMod);
                         }
 
-                        final AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
+                        AnyTO updated = doUpdate(before, anyMod, workingDelta, result);
 
                         for (SyncActions action : profile.getActions()) {
                             action.after(this.getProfile(), workingDelta, updated, result);
@@ -335,13 +335,13 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             Object output;
             Result resultStatus;
 
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
             result.setOperation(ResourceOperation.DELETE);
             result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
             result.setKey(id);
 
-            final AnyTO before = getAnyTO(id);
+            AnyTO before = getAnyTO(id);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
@@ -427,8 +427,8 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
         final List<ProvisioningResult> updResults = new ArrayList<>();
 
-        for (Long id : anys) {
-            LOG.debug("About to unassign resource {}", id);
+        for (Long key : anys) {
+            LOG.debug("About to unassign resource {}", key);
 
             Object output;
             Result resultStatus;
@@ -437,13 +437,13 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             result.setOperation(ResourceOperation.NONE);
             result.setAnyType(provision.getAnyType().getKey());
             result.setStatus(ProvisioningResult.Status.SUCCESS);
-            result.setKey(id);
+            result.setKey(key);
 
-            final AnyTO before = getAnyTO(id);
+            AnyTO before = getAnyTO(key);
 
             if (before == null) {
                 result.setStatus(ProvisioningResult.Status.FAILURE);
-                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), id));
+                result.setMessage(String.format("Any '%s(%d)' not found", provision.getAnyType().getKey(), key));
             }
 
             if (!profile.isDryRun()) {
@@ -471,7 +471,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
                         }
 
                         resultStatus = Result.SUCCESS;
-                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), id);
+                        LOG.debug("{} {} successfully updated", provision.getAnyType().getKey(), key);
                     } catch (IgnoreProvisionException e) {
                         throw e;
                     } catch (PropagationException e) {
@@ -527,11 +527,10 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
             Object output;
             Result resultStatus = Result.FAILURE;
 
-            AnyTO before = null;
-            final ProvisioningResult result = new ProvisioningResult();
+            ProvisioningResult result = new ProvisioningResult();
 
             try {
-                before = getAnyTO(id);
+                AnyTO before = getAnyTO(id);
 
                 result.setKey(id);
                 result.setName(getName(before));
@@ -590,7 +589,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         LOG.debug("Any to ignore {}", delta.getObject().getUid().getUidValue());
 
         final List<ProvisioningResult> ignoreResults = new ArrayList<>();
-        final ProvisioningResult result = new ProvisioningResult();
+        ProvisioningResult result = new ProvisioningResult();
 
         result.setKey(null);
         result.setName(delta.getObject().getUid().getUidValue());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fccecc4..cf08d8d 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
@@ -49,10 +49,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 public abstract class AbstractSyncopeResultHandler<T extends ProvisioningTask, A extends ProvisioningActions>
         implements SyncopeResultHandler<T, A> {
 
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(AbstractSyncopeResultHandler.class);
+    protected static final Logger LOG = LoggerFactory.getLogger(SyncopeResultHandler.class);
 
     @Autowired
     protected AnyObjectDAO anyObjectDAO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 b6d5ccb..860e10b 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
@@ -36,7 +36,7 @@ import org.identityconnectors.framework.common.objects.SyncDelta;
 
 public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implements GroupSyncResultHandler {
 
-    protected Map<Long, String> groupOwnerMap = new HashMap<>();
+    protected final Map<Long, String> groupOwnerMap = new HashMap<>();
 
     @Override
     public Map<Long, String> getGroupOwnerMap() {
@@ -107,7 +107,7 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
         // moved after group provisioning manager
         String groupOwner = null;
         for (AttrMod attrMod : groupMod.getPlainAttrsToUpdate()) {
-            if (attrMod.getSchema().isEmpty()) {
+            if (attrMod.getSchema().isEmpty() && !attrMod.getValuesToBeAdded().isEmpty()) {
                 groupOwner = attrMod.getValuesToBeAdded().iterator().next();
             }
         }
@@ -115,7 +115,7 @@ public class GroupSyncResultHandlerImpl extends AbstractSyncResultHandler implem
             groupOwnerMap.put(updated.getKey(), groupOwner);
         }
 
-        final GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
+        GroupTO after = groupDataBinder.getGroupTO(updated.getKey());
 
         result.setName(getName(after));
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fb2f9a4..873232f 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
@@ -46,6 +46,7 @@ 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.dao.UserDAO;
 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;
@@ -63,7 +64,7 @@ import org.springframework.beans.factory.annotation.Autowired;
  * Simple action for synchronizing LDAP groups memberships to Syncope group memberships, when the same resource is
  * configured for both users and groups.
  *
- * @see org.apache.syncope.core.propagation.impl.LDAPMembershipPropagationActions
+ * @see org.apache.syncope.core.provisioning.java.propagation.LDAPMembershipPropagationActions
  */
 public class LDAPMembershipSyncActions extends DefaultSyncActions {
 
@@ -73,6 +74,9 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
     protected AnyTypeDAO anyTypeDAO;
 
     @Autowired
+    protected UserDAO userDAO;
+
+    @Autowired
     protected GroupDAO groupDAO;
 
     @Autowired
@@ -182,7 +186,7 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
         Attribute membAttr = delta.getObject().getAttributeByName(groupMemberName);
         // if not found, perform an additional read on the underlying connector for the same connector object
         if (membAttr == null) {
-            final OperationOptionsBuilder oob = new OperationOptionsBuilder();
+            OperationOptionsBuilder oob = new OperationOptionsBuilder();
             oob.setAttributesToGet(groupMemberName);
             membAttr = connector.getObjectAttribute(ObjectClass.GROUP, delta.getUid(), oob.build(), groupMemberName);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 b13213a..b658bc4 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
@@ -27,7 +27,6 @@ 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.task.PushTask;
-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;
@@ -39,7 +38,9 @@ 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.AnyObjectPushResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.GroupPushResultHandler;
+import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
 import org.apache.syncope.core.provisioning.api.sync.UserPushResultHandler;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -111,15 +112,20 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
         profile.setDryRun(dryRun);
         profile.setResAct(null);
 
+        AnyObjectPushResultHandler ahandler =
+                (AnyObjectPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+                createBean(AnyObjectPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+        ahandler.setProfile(profile);
+
         UserPushResultHandler uhandler =
                 (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
         uhandler.setProfile(profile);
 
-        GroupPushResultHandler rhandler =
+        GroupPushResultHandler ghandler =
                 (GroupPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
                 createBean(GroupPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
-        rhandler.setProfile(profile);
+        ghandler.setProfile(profile);
 
         if (actions != null && !profile.isDryRun()) {
             for (PushActions action : actions) {
@@ -138,16 +144,32 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
                 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,
+                            : searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
                                     SearchCondConverter.convert(filter),
                                     Collections.<OrderByClause>emptyList(), provision.getAnyType().getKind());
 
                     for (Any<?, ?, ?> any : localAnys) {
+                        SyncopePushResultHandler handler;
+                        switch (provision.getAnyType().getKind()) {
+                            case USER:
+                                handler = uhandler;
+                                break;
+
+                            case GROUP:
+                                handler = ghandler;
+                                break;
+
+                            case ANY_OBJECT:
+                            default:
+                                handler = ahandler;
+                        }
+
                         try {
-                            uhandler.handle(any.getKey());
+                            handler.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);
+                            LOG.warn("Failure pushing '{}' on '{}'", any, pushTask.getResource(), e);
+                            throw new JobExecutionException(
+                                    "While pushing " + any + " on " + pushTask.getResource(), e);
                         }
                     }
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 1e19d02..479d342 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
@@ -60,8 +60,8 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
     @Autowired
     protected SyncUtils syncUtils;
 
-    protected void setGroupOwners(final GroupSyncResultHandler rhandler) {
-        for (Map.Entry<Long, String> entry : rhandler.getGroupOwnerMap().entrySet()) {
+    protected void setGroupOwners(final GroupSyncResultHandler ghandler) {
+        for (Map.Entry<Long, String> entry : ghandler.getGroupOwnerMap().entrySet()) {
             GroupMod groupMod = new GroupMod();
             groupMod.setKey(entry.getKey());
 
@@ -72,15 +72,15 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                 Long userKey = syncUtils.findMatchingAnyKey(
                         anyTypeDAO.findUser(),
                         entry.getValue(),
-                        rhandler.getProfile().getTask().getResource(),
-                        rhandler.getProfile().getConnector());
+                        ghandler.getProfile().getTask().getResource(),
+                        ghandler.getProfile().getConnector());
 
                 if (userKey == null) {
                     Long groupKey = syncUtils.findMatchingAnyKey(
                             anyTypeDAO.findGroup(),
                             entry.getValue(),
-                            rhandler.getProfile().getTask().getResource(),
-                            rhandler.getProfile().getConnector());
+                            ghandler.getProfile().getTask().getResource(),
+                            ghandler.getProfile().getConnector());
 
                     if (groupKey != null) {
                         groupMod.setGroupOwner(new ReferenceMod(groupKey));

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 8982824..b748345 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
@@ -32,9 +32,7 @@ import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValid
 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.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
@@ -69,52 +67,40 @@ import org.springframework.stereotype.Component;
 @Component
 public class SyncUtils {
 
-    /**
-     * Logger.
-     */
-    protected static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
-
-    /**
-     * Policy DAO.
-     */
-    @Autowired
-    protected PolicyDAO policyDAO;
+    private static final Logger LOG = LoggerFactory.getLogger(SyncUtils.class);
 
     /**
      * Schema DAO.
      */
     @Autowired
-    protected PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    protected AnyTypeDAO anyTypeDAO;
+    private PlainSchemaDAO plainSchemaDAO;
 
     /**
      * Any Object DAO.
      */
     @Autowired
-    protected AnyObjectDAO anyObjectDAO;
+    private AnyObjectDAO anyObjectDAO;
 
     /**
      * User DAO.
      */
     @Autowired
-    protected UserDAO userDAO;
+    private UserDAO userDAO;
 
     /**
      * Group DAO.
      */
     @Autowired
-    protected GroupDAO groupDAO;
+    private GroupDAO groupDAO;
 
     /**
      * Search DAO.
      */
     @Autowired
-    protected AnySearchDAO searchDAO;
+    private AnySearchDAO searchDAO;
 
     @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
+    private AnyUtilsFactory anyUtilsFactory;
 
     public Long findMatchingAnyKey(
             final AnyType anyType,
@@ -180,7 +166,8 @@ public class SyncUtils {
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-                final PlainAttrValue value = anyUtils.newPlainAttrValue();
+            case AnyPlainSchema:
+                PlainAttrValue value = anyUtils.newPlainAttrValue();
 
                 PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
                 if (schema == null) {
@@ -203,21 +190,24 @@ public class SyncUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
+            case AnyDerivedSchema:
                 anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), uid);
                 for (Any<?, ?, ?> any : anys) {
                     result.add(any.getKey());
                 }
                 break;
 
-            case Username:
-                User user = userDAO.find(uid);
-                if (user != null) {
-                    result.add(user.getKey());
+            case UserId:
+            case GroupId:
+            case AnyId:
+                Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
+                if (any != null) {
+                    result.add(any.getKey());
                 }
                 break;
 
-            case UserId:
-                user = userDAO.find(Long.parseLong(uid));
+            case Username:
+                User user = userDAO.find(uid);
                 if (user != null) {
                     result.add(user.getKey());
                 }
@@ -230,13 +220,6 @@ public class SyncUtils {
                 }
                 break;
 
-            case GroupId:
-                group = groupDAO.find(Long.parseLong(uid));
-                if (group != null) {
-                    result.add(group.getKey());
-                }
-                break;
-
             default:
                 LOG.error("Invalid connObjectKey type '{}'", connObjectKeyItem.getIntMappingType());
         }
@@ -354,7 +337,7 @@ public class SyncUtils {
     }
 
     /**
-     * Find users / groups based on mapped uid value (or previous uid value, if updated).
+     * Find any objects based on mapped uid value (or previous uid value, if updated).
      *
      * @param uid for finding by connObjectKey
      * @param connObj for finding by attribute value
@@ -381,9 +364,10 @@ public class SyncUtils {
             altSearchSchemas = getAltSearchSchemas(provision, syncPolicySpec);
         }
 
-        return syncRule == null ? altSearchSchemas == null || altSearchSchemas.isEmpty()
-                ? findByConnObjectKeyItem(uid, provision, anyUtils)
-                : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
+        return syncRule == null
+                ? altSearchSchemas == null || altSearchSchemas.isEmpty()
+                        ? findByConnObjectKeyItem(uid, provision, anyUtils)
+                        : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
                 : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 039337f..f2eb839 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
@@ -79,7 +79,7 @@ public class ResourceDataBinderTest extends AbstractTest {
 
         ResourceTO resourceTO = new ResourceTO();
         resourceTO.setKey("resource-issue42");
-        resourceTO.setConnectorId(100L);
+        resourceTO.setConnector(100L);
         resourceTO.setPropagationMode(PropagationMode.ONE_PHASE);
         resourceTO.setEnforceMandatoryCondition(true);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
index f031c92..18f6101 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/RestServiceExceptionMapper.java
@@ -51,6 +51,7 @@ import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValid
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
 import org.apache.syncope.core.persistence.api.dao.MalformedPathException;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UnallowedSchemaException;
 import org.apache.syncope.core.workflow.api.WorkflowException;
 import org.identityconnectors.framework.common.exceptions.ConfigurationException;
 import org.identityconnectors.framework.common.exceptions.ConnectorException;
@@ -114,6 +115,8 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception>, R
                     header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED);
         } else if (ex instanceof UnauthorizedException) {
             builder = builder(ClientExceptionType.Unauthorized, ExceptionUtils.getRootCauseMessage(ex));
+        } else if (ex instanceof UnallowedSchemaException) {
+            builder = builder(ClientExceptionType.UnallowedSchemas, ExceptionUtils.getRootCauseMessage(ex));
         } else if (ex instanceof EntityExistsException || ex instanceof DuplicateException) {
             builder = builder(ClientExceptionType.EntityExists, getJPAMessage(ex));
         } else if (ex instanceof DataIntegrityViolationException || ex instanceof JpaSystemException) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
new file mode 100644
index 0000000..47cdde2
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.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.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.core.logic.AnyTypeClassLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyTypeClassServiceImpl extends AbstractServiceImpl implements AnyTypeClassService {
+
+    @Autowired
+    private AnyTypeClassLogic logic;
+
+    @Override
+    public List<AnyTypeClassTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public AnyTypeClassTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final AnyTypeClassTO anyTypeTO) {
+        AnyTypeClassTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final String key, final AnyTypeClassTO anyTypeTO) {
+        anyTypeTO.setKey(key);
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
new file mode 100644
index 0000000..9b289d5
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.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.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.core.logic.AnyTypeLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyTypeServiceImpl extends AbstractServiceImpl implements AnyTypeService {
+
+    @Autowired
+    private AnyTypeLogic logic;
+
+    @Override
+    public List<AnyTypeTO> list() {
+        return logic.list();
+    }
+
+    @Override
+    public AnyTypeTO read(final String key) {
+        return logic.read(key);
+    }
+
+    @Override
+    public Response create(final AnyTypeTO anyTypeTO) {
+        AnyTypeTO created = logic.create(anyTypeTO);
+        URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getKey())).build();
+        return Response.created(location).
+                header(RESTHeaders.RESOURCE_ID, created.getKey()).
+                build();
+    }
+
+    @Override
+    public void update(final String key, final AnyTypeTO anyTypeTO) {
+        anyTypeTO.setKey(key);
+        logic.update(anyTypeTO);
+    }
+
+    @Override
+    public void delete(final String key) {
+        logic.delete(key);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index 618b245..9f6099c 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -135,12 +135,13 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
         BulkActionResult result = new BulkActionResult();
 
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String id : bulkAction.getTargets()) {
+            for (String key : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(Long.valueOf(id)).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(
+                            String.valueOf(logic.delete(Long.valueOf(key)).getKey()), BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
-                    LOG.error("Error performing delete for connector {}", id, e);
-                    result.add(id, BulkActionResult.Status.FAILURE);
+                    LOG.error("Error performing delete for connector {}", key, e);
+                    result.getResults().put(key, BulkActionResult.Status.FAILURE);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 c8e42a1..5c640f0 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
@@ -155,21 +155,23 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
                 updated = logic.read(groupKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -198,21 +200,23 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
                 updated = logic.read(groupKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -222,10 +226,12 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
             for (String groupKey : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(Long.valueOf(groupKey)).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(
+                            String.valueOf(logic.delete(Long.valueOf(groupKey)).getKey()),
+                            BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
                     LOG.error("Error performing delete for group {}", groupKey, e);
-                    result.add(groupKey, BulkActionResult.Status.FAILURE);
+                    result.getResults().put(groupKey, BulkActionResult.Status.FAILURE);
                 }
             }
         } else {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 7ace502..28b834b 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
@@ -107,7 +107,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
                         ? groupLogic
                         : anyObjectLogic;
 
-        BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         for (AnyKey key : keys) {
             Set<String> resources = Collections.singleton(resourceKey);
@@ -128,14 +128,14 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
                     default:
                 }
 
-                res.add(key, BulkActionResult.Status.SUCCESS);
+                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.SUCCESS);
             } catch (Exception e) {
                 LOG.warn("While executing {} on {} {}", type, anyTypeKey, key.getElement(), e);
-                res.add(key, BulkActionResult.Status.FAILURE);
+                result.getResults().put(String.valueOf(key.getElement()), BulkActionResult.Status.FAILURE);
             }
         }
 
-        return res;
+        return result;
     }
 
     @Override
@@ -145,10 +145,10 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
         if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
             for (String name : bulkAction.getTargets()) {
                 try {
-                    result.add(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);
+                    result.getResults().put(logic.delete(name).getKey(), BulkActionResult.Status.SUCCESS);
                 } catch (Exception e) {
                     LOG.error("Error performing delete for resource {}", name, e);
-                    result.add(name, BulkActionResult.Status.FAILURE);
+                    result.getResults().put(name, BulkActionResult.Status.FAILURE);
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 9da72aa..d42ed6a 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -129,10 +129,12 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
             case DELETE:
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
-                        result.add(logic.delete(Long.valueOf(taskKey)).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(taskKey)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing delete for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -141,10 +143,10 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
                         logic.execute(Long.valueOf(taskKey), true);
-                        result.add(taskKey, BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing dryrun for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -153,10 +155,10 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
                 for (String taskKey : bulkAction.getTargets()) {
                     try {
                         logic.execute(Long.valueOf(taskKey), false);
-                        result.add(taskKey, BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing execute for task {}", taskKey, e);
-                        result.add(taskKey, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 919cb0a..83f09a4 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
@@ -60,7 +60,7 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public Response getUserId(final String username) {
+    public Response getUserKey(final String username) {
         return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
                 header(RESTHeaders.USER_ID, logic.getKey(username)).
                 build();
@@ -179,21 +179,23 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                 updated = logic.read(userKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceDeassociationActionType.UNLINK) {
             for (ResourceName resourceName : resourceNames) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(
+                        resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -232,21 +234,23 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                 updated = logic.read(userKey);
         }
 
-        final BulkActionResult res = new BulkActionResult();
+        BulkActionResult result = new BulkActionResult();
 
         if (type == ResourceAssociationActionType.LINK) {
             for (ResourceName resourceName : associationMod.getTargetResources()) {
-                res.add(resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                        ? BulkActionResult.Status.FAILURE
-                        : BulkActionResult.Status.SUCCESS);
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
             }
         } else {
             for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                res.add(propagationStatusTO.getResource(), propagationStatusTO.getStatus().toString());
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
             }
         }
 
-        return modificationResponse(res);
+        return modificationResponse(result);
     }
 
     @Override
@@ -257,10 +261,12 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
             case DELETE:
                 for (String key : bulkAction.getTargets()) {
                     try {
-                        result.add(logic.delete(Long.valueOf(key)).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing delete for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -271,10 +277,11 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                     statusMod.setKey(Long.valueOf(key));
                     statusMod.setType(StatusMod.ModType.SUSPEND);
                     try {
-                        result.add(logic.status(statusMod).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing suspend for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -285,10 +292,11 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
                     statusMod.setKey(Long.valueOf(key));
                     statusMod.setType(StatusMod.ModType.REACTIVATE);
                     try {
-                        result.add(logic.status(statusMod).getKey(), BulkActionResult.Status.SUCCESS);
+                        result.getResults().put(
+                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
                         LOG.error("Error performing reactivate for user {}", key, e);
-                        result.add(key, BulkActionResult.Status.FAILURE);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 938081f..2e00cb9 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
@@ -84,15 +84,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
- * Activiti {
- *
- * @see http://www.activiti.org/} based implementation.
+ * Activiti {@link http://www.activiti.org/} based implementation.
  */
 public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class);
 
     private static final String[] PROPERTY_IGNORE_PROPS = { "type" };
@@ -258,7 +253,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
     public WorkflowResult<Pair<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
             final Boolean enabled, final boolean storePassword) {
 
-        final Map<String, Object> variables = new HashMap<>();
+        Map<String, Object> variables = new HashMap<>();
         variables.put(WF_EXECUTOR, AuthContextUtils.getAuthenticatedUsername());
         variables.put(USER_TO, userTO);
         variables.put(ENABLED, enabled);
@@ -271,8 +266,7 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
             throwException(e, "While starting " + WF_PROCESS_ID + " instance");
         }
 
-        User user =
-                runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
+        User user = runtimeService.getVariable(processInstance.getProcessInstanceId(), USER, User.class);
 
         Boolean updatedEnabled =
                 runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED, Boolean.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.java
new file mode 100644
index 0000000..f598410
--- /dev/null
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUtils.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.workflow.activiti;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.springframework.transaction.annotation.Transactional;
+
+public class ActivitiUtils {
+
+    @Transactional(readOnly = true)
+    public boolean isUserIngroup(final User user, final Long groupKey) {
+        return CollectionUtils.exists(user.getMemberships(), new Predicate<UMembership>() {
+
+            @Override
+            public boolean evaluate(final UMembership membership) {
+                return groupKey != null && groupKey.equals(membership.getRightEnd().getKey());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
index 2b568b1..658795c 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/SyncopeUserManager.java
@@ -75,8 +75,8 @@ public class SyncopeUserManager implements UserIdentityManager, SyncopeSession {
         org.apache.syncope.core.persistence.api.entity.user.User user = userDAO.find(userKey);
         if (user != null) {
             result = new ArrayList<>();
-            for (Long groupId : userDAO.findAllGroupKeys(user)) {
-                result.add(new GroupEntity(groupId.toString()));
+            for (Long groupKey : userDAO.findAllGroupKeys(user)) {
+                result.add(new GroupEntity(groupKey.toString()));
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
index d5e9b02..75f0c38 100644
--- a/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
+++ b/core/workflow-activiti/src/main/resources/workflowActivitiContext.xml
@@ -30,6 +30,8 @@ under the License.
     <property name="fallback" value="classpath:userWorkflow.bpmn20.xml"/>
   </bean>
 
+  <bean id="activitiUtils" class="org.apache.syncope.core.workflow.activiti.ActivitiUtils"/>
+
   <bean id="syncopeActivitiUserManager" class="org.apache.syncope.core.workflow.activiti.SyncopeUserManager"/>
   <bean id="syncopeActivitiGroupManager" class="org.apache.syncope.core.workflow.activiti.SyncopeGroupManager"/>
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
index 7a2f455..2aaec2a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/GroupUpdateProcessor.java
@@ -18,14 +18,18 @@
  */
 package org.apache.syncope.core.provisioning.camel.processor;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
@@ -47,15 +51,30 @@ public class GroupUpdateProcessor implements Processor {
     @Autowired
     protected PropagationTaskExecutor taskExecutor;
 
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
     @SuppressWarnings("unchecked")
     @Override
     public void process(final Exchange exchange) {
         WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
-        GroupMod anyMod = exchange.getProperty("anyMod", GroupMod.class);
+        GroupMod groupMod = exchange.getProperty("anyMod", GroupMod.class);
         Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
-                anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), excludedResources);
+                groupMod.getVirAttrsToRemove(), groupMod.getVirAttrsToUpdate(), excludedResources);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.GROUP,
+                    groupMod.getVirAttrsToRemove(),
+                    groupMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getGroupUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 355080b..e71a15a 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
@@ -25,15 +25,16 @@ 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.UserMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.provisioning.api.WorkflowResult;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.provisioning.java.VirAttrHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -57,15 +58,16 @@ public class UserUpdateProcessor implements Processor {
     @SuppressWarnings("unchecked")
     public void process(final Exchange exchange) {
         WorkflowResult<Pair<UserMod, Boolean>> updated = (WorkflowResult) exchange.getIn().getBody();
-        UserMod actual = exchange.getProperty("actual", UserMod.class);
+        UserMod userMod = exchange.getProperty("actual", UserMod.class);
 
         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(),
-                    actual.getVirAttrsToRemove(),
-                    actual.getVirAttrsToUpdate());
+                    AnyTypeKind.USER,
+                    userMod.getVirAttrsToRemove(),
+                    userMod.getVirAttrsToUpdate());
             tasks.addAll(!propByResVirAttr.isEmpty()
                     ? propagationManager.getUserUpdateTasks(updated, false, null)
                     : Collections.<PropagationTask>emptyList());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/fit/core-reference/src/main/resources/all/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/provisioning.properties b/fit/core-reference/src/main/resources/all/provisioning.properties
index 5061502..4d0ecaf 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -18,4 +18,4 @@ camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
-virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
+virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
index 9a6ee5b..df292b8 100644
--- a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
+++ b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
@@ -34,10 +34,14 @@ under the License.
     <sequenceFlow id="flow2" sourceRef="create" targetRef="createGW"/>
     <exclusiveGateway id="createGW"/>
     <sequenceFlow id="createAsAnonymous2Approval" sourceRef="createGW" targetRef="createApproval">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor == 'anonymous' || user.getStaticGroupKeys().contains(9)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${wfExecutor == 'anonymous' || activitiUtils.isUserIngroup(user, 9)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <sequenceFlow id="create2Activate" sourceRef="createGW" targetRef="enableGW">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!user.getStaticGroupKeys().contains(9)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${!activitiUtils.isUserIngroup(user, 9)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <userTask id="createApproval" name="Create approval" activiti:candidateGroups="7" activiti:formKey="createApproval">
       <extensionElements>
@@ -56,7 +60,9 @@ under the License.
     </sequenceFlow>
     <exclusiveGateway id="enableGW"/>
     <sequenceFlow id="createApprovalGW2OptIn" sourceRef="enableGW" targetRef="generateToken">
-      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${user.getStaticGroupKeys().contains(11)}]]></conditionExpression>
+      <conditionExpression xsi:type="tFormalExpression">
+        <![CDATA[${activitiUtils.isUserIngroup(user, 11)}]]>
+      </conditionExpression>
     </sequenceFlow>
     <sequenceFlow id="createApprovalGW2Activate" sourceRef="enableGW" targetRef="activate">
       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled == null}]]></conditionExpression>

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 3984c5e..97fc9d0 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
@@ -48,6 +48,8 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
 import org.apache.syncope.common.rest.api.service.ConfigurationService;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
@@ -147,6 +149,10 @@ public abstract class AbstractITCase {
 
     protected static SyncopeService syncopeService;
 
+    protected static AnyTypeClassService anyTypeClassService;
+
+    protected static AnyTypeService anyTypeService;
+
     protected static RealmService realmService;
 
     protected static RoleService roleService;
@@ -217,6 +223,8 @@ public abstract class AbstractITCase {
         adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
 
         syncopeService = adminClient.getService(SyncopeService.class);
+        anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
+        anyTypeService = adminClient.getService(AnyTypeService.class);
         realmService = adminClient.getService(RealmService.class);
         roleService = adminClient.getService(RoleService.class);
         userService = adminClient.getService(UserService.class);
@@ -272,7 +280,7 @@ public abstract class AbstractITCase {
 
     protected UserTO readUser(final String username) {
         return userService.read(Long.valueOf(
-                userService.getUserId(username).getHeaderString(RESTHeaders.USER_ID)));
+                userService.getUserKey(username).getHeaderString(RESTHeaders.USER_ID)));
     }
 
     protected UserTO updateUser(final UserMod userMod) {
@@ -361,7 +369,7 @@ public abstract class AbstractITCase {
             throws NamingException {
         ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
         final Map<String, ConnConfProperty> ldapConnConf =
-                connectorService.read(ldapRes.getConnectorId()).getConfigurationMap();
+                connectorService.read(ldapRes.getConnector()).getConfigurationMap();
 
         Properties env = new Properties();
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");


[18/70] 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() {


[05/70] 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);
         }
     }
 }


[56/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 98a23a6..2d6c6e4 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
@@ -19,98 +19,23 @@
 package org.apache.syncope.core.rest.cxf.service;
 
 import java.util.List;
-import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.GroupMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationStatus;
 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.ResourceKey;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
-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.AbstractAnyLogic;
 import org.apache.syncope.core.logic.GroupLogic;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class GroupServiceImpl extends AbstractServiceImpl implements GroupService {
+public class GroupServiceImpl extends AbstractAnyService<GroupTO, GroupMod> implements GroupService {
 
     @Autowired
     private GroupLogic logic;
 
     @Override
-    public Response create(final GroupTO groupTO) {
-        GroupTO created = logic.create(groupTO);
-        return createResponse(created.getKey(), created);
-    }
-
-    @Override
-    public Response delete(final Long groupKey) {
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO deleted = logic.delete(groupKey);
-        return modificationResponse(deleted);
-    }
-
-    @Override
-    public PagedResult<GroupTO> list(final AnyListQuery listQuery) {
-        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        return buildPagedResult(
-                logic.list(
-                        listQuery.getPage(),
-                        listQuery.getSize(),
-                        getOrderByClauses(listQuery.getOrderBy()),
-                        listQuery.getRealms()),
-                listQuery.getPage(),
-                listQuery.getSize(),
-                logic.count(listQuery.getRealms()));
-    }
-
-    @Override
-    public GroupTO read(final Long groupKey) {
-        return logic.read(groupKey);
-    }
-
-    @Override
-    public PagedResult<GroupTO> search(final AnySearchQuery searchQuery) {
-        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        SearchCond cond = getSearchCond(searchQuery.getFiql());
-        return buildPagedResult(
-                logic.search(
-                        cond,
-                        searchQuery.getPage(),
-                        searchQuery.getSize(),
-                        getOrderByClauses(searchQuery.getOrderBy()),
-                        searchQuery.getRealms()),
-                searchQuery.getPage(),
-                searchQuery.getSize(),
-                logic.searchCount(cond, searchQuery.getRealms()));
+    protected AbstractAnyLogic<GroupTO, GroupMod> getAnyLogic() {
+        return logic;
     }
 
     @Override
@@ -118,126 +43,4 @@ public class GroupServiceImpl extends AbstractServiceImpl implements GroupServic
         return logic.own();
     }
 
-    @Override
-    public Response update(final Long groupKey, final GroupMod groupMod) {
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        groupMod.setKey(groupKey);
-        GroupTO updated = logic.update(groupMod);
-        return modificationResponse(updated);
-    }
-
-    @Override
-    public Response bulkDeassociation(
-            final Long groupKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
-
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO updated;
-        switch (type) {
-            case UNLINK:
-                updated = logic.unlink(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case UNASSIGN:
-                updated = logic.unassign(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case DEPROVISION:
-                updated = logic.deprovision(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            default:
-                updated = logic.read(groupKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public Response bulkAssociation(
-            final Long groupKey, final ResourceAssociationActionType type, final List<ResourceKey> resourceNames) {
-
-        GroupTO group = logic.read(groupKey);
-
-        checkETag(group.getETagValue());
-
-        GroupTO updated;
-        switch (type) {
-            case LINK:
-                updated = logic.link(groupKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case ASSIGN:
-                updated = logic.assign(groupKey, CollectionWrapper.unwrap(resourceNames), false, null);
-                break;
-
-            case PROVISION:
-                updated = logic.provision(groupKey, CollectionWrapper.unwrap(resourceNames), false, null);
-                break;
-
-            default:
-                updated = logic.read(groupKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult result = new BulkActionResult();
-
-        if (bulkAction.getOperation() == BulkAction.Type.DELETE) {
-            for (String groupKey : bulkAction.getTargets()) {
-                try {
-                    result.getResults().put(
-                            String.valueOf(logic.delete(Long.valueOf(groupKey)).getKey()),
-                            BulkActionResult.Status.SUCCESS);
-                } catch (Exception e) {
-                    LOG.error("Error performing delete for group {}", groupKey, e);
-                    result.getResults().put(groupKey, BulkActionResult.Status.FAILURE);
-                }
-            }
-        } else {
-            LOG.warn("Unsupported bulk action: {}", bulkAction.getOperation());
-        }
-
-        return result;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 192b4e0..391aea8 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
@@ -18,44 +18,33 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
-import org.apache.syncope.common.lib.to.PropagationStatus;
 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.ResourceKey;
-import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
-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.AbstractAnyLogic;
 import org.apache.syncope.core.logic.UserLogic;
-import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
-public class UserServiceImpl extends AbstractServiceImpl implements UserService {
+public class UserServiceImpl extends AbstractAnyService<UserTO, UserMod> implements UserService {
 
     @Autowired
     private UserLogic logic;
 
     @Override
-    public Response getUsername(final Long userKey) {
+    protected AbstractAnyLogic<UserTO, UserMod> getAnyLogic() {
+        return logic;
+    }
+
+    @Override
+    public Response getUsername(final Long key) {
         return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
-                header(RESTHeaders.USERNAME, logic.getUsername(userKey)).
+                header(RESTHeaders.USERNAME, logic.getUsername(key)).
                 build();
     }
 
@@ -73,237 +62,13 @@ public class UserServiceImpl extends AbstractServiceImpl implements UserService
     }
 
     @Override
-    public Response delete(final Long userKey) {
-        UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO deleted = logic.delete(userKey);
-        return modificationResponse(deleted);
-    }
-
-    @Override
-    public PagedResult<UserTO> list(final AnyListQuery listQuery) {
-        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        return buildPagedResult(
-                logic.list(
-                        listQuery.getPage(),
-                        listQuery.getSize(),
-                        getOrderByClauses(listQuery.getOrderBy()),
-                        listQuery.getRealms()),
-                listQuery.getPage(),
-                listQuery.getSize(),
-                logic.count(listQuery.getRealms()));
-    }
-
-    @Override
-    public UserTO read(final Long userKey) {
-        return logic.read(userKey);
-    }
-
-    @Override
-    public PagedResult<UserTO> search(final AnySearchQuery searchQuery) {
-        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
-
-            @Override
-            public String transform(final String input) {
-                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
-            }
-        });
-
-        SearchCond cond = getSearchCond(searchQuery.getFiql());
-        return buildPagedResult(
-                logic.search(
-                        cond,
-                        searchQuery.getPage(),
-                        searchQuery.getSize(),
-                        getOrderByClauses(searchQuery.getOrderBy()),
-                        searchQuery.getRealms()),
-                searchQuery.getPage(),
-                searchQuery.getSize(),
-                logic.searchCount(cond, searchQuery.getRealms()));
-    }
-
-    @Override
-    public Response update(final Long userKey, final UserMod userMod) {
-        UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        userMod.setKey(userKey);
-        UserTO updated = logic.update(userMod);
-        return modificationResponse(updated);
-    }
-
-    @Override
-    public Response status(final Long userKey, final StatusMod statusMod) {
-        UserTO user = logic.read(userKey);
+    public Response status(final Long key, final StatusMod statusMod) {
+        UserTO user = logic.read(key);
 
         checkETag(user.getETagValue());
 
-        statusMod.setKey(userKey);
+        statusMod.setKey(key);
         UserTO updated = logic.status(statusMod);
         return modificationResponse(updated);
     }
-
-    @Override
-    public Response bulkDeassociation(
-            final Long userKey, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
-
-        final UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO updated;
-        switch (type) {
-            case UNLINK:
-                updated = logic.unlink(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case UNASSIGN:
-                updated = logic.unassign(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            case DEPROVISION:
-                updated = logic.deprovision(userKey, CollectionWrapper.unwrap(resourceNames));
-                break;
-
-            default:
-                updated = logic.read(userKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceDeassociationActionType.UNLINK) {
-            for (ResourceKey resourceName : resourceNames) {
-                result.getResults().put(
-                        resourceName.getElement(), updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public Response bulkAssociation(
-            final Long userKey, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
-
-        final UserTO user = logic.read(userKey);
-
-        checkETag(user.getETagValue());
-
-        UserTO updated;
-        switch (type) {
-            case LINK:
-                updated = logic.link(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()));
-                break;
-
-            case ASSIGN:
-                updated = logic.assign(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
-                        associationMod.isChangePwd(),
-                        associationMod.getPassword());
-                break;
-
-            case PROVISION:
-                updated = logic.provision(
-                        userKey,
-                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
-                        associationMod.isChangePwd(),
-                        associationMod.getPassword());
-                break;
-
-            default:
-                updated = logic.read(userKey);
-        }
-
-        BulkActionResult result = new BulkActionResult();
-
-        if (type == ResourceAssociationActionType.LINK) {
-            for (ResourceKey resourceName : associationMod.getTargetResources()) {
-                result.getResults().put(resourceName.getElement(),
-                        updated.getResources().contains(resourceName.getElement())
-                                ? BulkActionResult.Status.FAILURE
-                                : BulkActionResult.Status.SUCCESS);
-            }
-        } else {
-            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
-                result.getResults().put(propagationStatusTO.getResource(),
-                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
-            }
-        }
-
-        return modificationResponse(result);
-    }
-
-    @Override
-    public BulkActionResult bulk(final BulkAction bulkAction) {
-        BulkActionResult result = new BulkActionResult();
-
-        switch (bulkAction.getOperation()) {
-            case DELETE:
-                for (String key : bulkAction.getTargets()) {
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
-                                BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing delete for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case SUSPEND:
-                for (String key : bulkAction.getTargets()) {
-                    StatusMod statusMod = new StatusMod();
-                    statusMod.setKey(Long.valueOf(key));
-                    statusMod.setType(StatusMod.ModType.SUSPEND);
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing suspend for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            case REACTIVATE:
-                for (String key : bulkAction.getTargets()) {
-                    StatusMod statusMod = new StatusMod();
-                    statusMod.setKey(Long.valueOf(key));
-                    statusMod.setType(StatusMod.ModType.REACTIVATE);
-                    try {
-                        result.getResults().put(
-                                String.valueOf(logic.status(statusMod).getKey()), BulkActionResult.Status.SUCCESS);
-                    } catch (Exception e) {
-                        LOG.error("Error performing reactivate for user {}", key, e);
-                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
-                    }
-                }
-                break;
-
-            default:
-        }
-
-        return result;
-    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 3520a4a..4359e7b 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
@@ -56,6 +56,9 @@ public class CamelRouteLoader implements SyncopeLoader {
     @javax.annotation.Resource(name = "groupRoutes")
     private ResourceWithFallbackLoader groupRoutesLoader;
 
+    @javax.annotation.Resource(name = "anyObjectRoutes")
+    private ResourceWithFallbackLoader anyObjectRoutesLoader;
+
     @Autowired
     private DataSource dataSource;
 
@@ -76,6 +79,7 @@ public class CamelRouteLoader implements SyncopeLoader {
             if (!loaded) {
                 loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
                 loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
+                loadRoutes(anyObjectRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
                 loaded = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
new file mode 100644
index 0000000..ae29501
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelAnyObjectProvisioningManager.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.camel;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.PollingConsumer;
+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;
+import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
+
+public class CamelAnyObjectProvisioningManager
+        extends AbstractCamelProvisioningManager implements AnyObjectProvisioningManager {
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> create(final AnyObjectTO any) {
+        return create(any, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Pair<Long, List<PropagationStatus>> create(
+            final AnyObjectTO anyObjectTO, final Set<String> excludedResources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:createAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:createAnyObject", anyObjectTO, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Pair.class);
+    }
+
+    @Override
+    public Pair<Long, List<PropagationStatus>> update(final AnyObjectMod anyMod) {
+        return update(anyMod, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Pair<Long, List<PropagationStatus>> update(
+            final AnyObjectMod anyMod, final Set<String> excludedResources) {
+
+        PollingConsumer pollingConsumer = getConsumer("direct:updateAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:updateAnyObject", anyMod, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Pair.class);
+    }
+
+    @Override
+    public List<PropagationStatus> delete(final Long anyObjectObjectKey) {
+        return delete(anyObjectObjectKey, Collections.<String>emptySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> delete(final Long anyObjectKey, final Set<String> excludedResources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deleteAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:deleteAnyObject", anyObjectKey, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+    @Override
+    public Long unlink(final AnyObjectMod anyObjectMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:unlinkAnyObjectPort");
+
+        sendMessage("direct:unlinkAnyObject", anyObjectMod);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Long.class);
+    }
+
+    @Override
+    public Long link(final AnyObjectMod anyObjectMod) {
+        PollingConsumer pollingConsumer = getConsumer("direct:linkAnyObjectPort");
+
+        sendMessage("direct:linkAnyObject", anyObjectMod);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(Long.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public List<PropagationStatus> deprovision(final Long anyObjectKey, final Collection<String> resources) {
+        PollingConsumer pollingConsumer = getConsumer("direct:deprovisionAnyObjectPort");
+
+        Map<String, Object> props = new HashMap<>();
+        props.put("resources", resources);
+
+        sendMessage("direct:deprovisionAnyObject", anyObjectKey, props);
+
+        Exchange exchange = pollingConsumer.receive();
+
+        if (exchange.getProperty(Exchange.EXCEPTION_CAUGHT) != null) {
+            throw (RuntimeException) exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
+        }
+
+        return exchange.getIn().getBody(List.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.java
new file mode 100644
index 0000000..2f2e41e
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectCreateProcessor.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.core.provisioning.camel.processor;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectCreateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectCreateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> created = (WorkflowResult) exchange.getIn().getBody();
+        AnyObjectTO any = exchange.getProperty("any", AnyObjectTO.class);
+        Set<String> excludedResource = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks =
+                propagationManager.getAnyObjectCreateTasks(created, any.getVirAttrs(), excludedResource);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new ImmutablePair<>(created.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.java
new file mode 100644
index 0000000..d1c9243
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeleteProcessor.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.provisioning.camel.processor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectDeleteProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyObjectDeleteProcessor.class);
+
+    @Autowired
+    protected AnyObjectWorkflowAdapter gwfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Override
+    public void process(final Exchange exchange) throws Exception {
+        Long anyKey = exchange.getIn().getBody(Long.class);
+        AnyObject anyObject = anyObjectDAO.find(anyKey);
+        @SuppressWarnings("unchecked")
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks = new ArrayList<>();
+
+        if (anyObject != null) {
+            // Generate propagation tasks for deleting this anyObject from resources
+            tasks.addAll(propagationManager.getAnyObjectDeleteTasks(anyObject.getKey(), excludedResources));
+        }
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.setProperty("statuses", propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.java
new file mode 100644
index 0000000..c56ab90
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectDeprovisionProcessor.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.provisioning.camel.processor;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectDeprovisionProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserDeprovisionProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        Long anyObjectKey = exchange.getIn().getBody(Long.class);
+        List<String> resources = exchange.getProperty("resources", List.class);
+
+        AnyObject anyObject = anyObjectDAO.authFind(anyObjectKey);
+
+        Collection<String> noPropResourceNames = CollectionUtils.removeAll(anyObject.getResourceNames(), resources);
+
+        List<PropagationTask> tasks =
+                propagationManager.getAnyObjectDeleteTasks(anyObjectKey, new HashSet<>(resources), noPropResourceNames);
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(propagationReporter.getStatuses());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
new file mode 100644
index 0000000..2979e97
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/processor/AnyObjectUpdateProcessor.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.camel.processor;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyObjectUpdateProcessor implements Processor {
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserUpdateProcessor.class);
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void process(final Exchange exchange) {
+        WorkflowResult<Long> updated = (WorkflowResult) exchange.getIn().getBody();
+        AnyObjectMod anyObjectMod = exchange.getProperty("anyMod", AnyObjectMod.class);
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
+
+        List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated,
+                anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), excludedResources);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.GROUP,
+                    anyObjectMod.getVirAttrsToRemove(),
+                    anyObjectMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getAnyObjectUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
+        PropagationReporter propagationReporter =
+                ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        exchange.getOut().setBody(new ImmutablePair<>(updated.getResult(), propagationReporter.getStatuses()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
new file mode 100644
index 0000000..de4df0b
--- /dev/null
+++ b/ext/camel/provisioning-camel/src/main/resources/anyObjectRoutes.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<routes>
+     
+  <route id="createAnyObject">
+    <from uri="direct:createAnyObject"/>
+    <setProperty propertyName="any">
+      <simple>${body}</simple>
+    </setProperty>
+    <doTry>
+      <bean ref="awfAdapter" method="create(${body})"/>
+      <process ref="anyObjectCreateProcessor"/>
+      <to uri="direct:createAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:createAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+         
+  <route id="updateAnyObject">
+    <from uri="direct:updateAnyObject"/>
+    <setProperty propertyName="anyMod">
+      <simple>${body}</simple>
+    </setProperty>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <process ref="anyObjectUpdateProcessor"/>
+      <to uri="direct:updateAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:updateAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+
+  <route id="deleteAnyObject">
+    <from uri="direct:deleteAnyObject"/>
+    <doTry>
+      <process ref="anyObjectDeleteProcessor"/>
+      <bean ref="awfAdapter" method="delete(${body})"/>
+      <setBody>
+        <simple>${property.statuses}</simple>
+      </setBody>
+      <to uri="direct:deleteAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:deleteAnyObjectPort"/>
+      </doCatch>
+    </doTry>
+  </route>
+
+  <route id="unlinkAnyObject">
+    <from uri="direct:unlinkAnyObject"/>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <setBody>
+        <simple>${body.getResult}</simple>
+      </setBody>
+      <to uri="direct:unlinkAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:unlinkAnyObjectPort"/>
+      </doCatch>
+    </doTry>            
+  </route>
+        
+  <route id="linkAnyObject">
+    <from uri="direct:linkAnyObject"/>
+    <doTry>
+      <bean ref="awfAdapter" method="update(${body})"/>
+      <setBody>
+        <simple>${body.getResult}</simple>
+      </setBody>
+      <to uri="direct:linkAnyObjectPort"/>
+      <doCatch>        
+        <exception>java.lang.RuntimeException</exception>
+        <handled>
+          <constant>false</constant>
+        </handled>
+        <to uri="direct:linkAnyObjectPort"/>
+      </doCatch>
+    </doTry>            
+  </route>
+        
+  <route id="deprovisionAnyObject">
+    <from uri="direct:deprovisionAnyObject"/>            
+    <process ref="anyObjectDeprovisionProcessor"/>
+    <to uri="direct:deprovisionAnyObjectPort"/>              
+  </route>
+    
+</routes>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
index 5061502..aa843ca 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
@@ -17,5 +17,5 @@
 camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
-anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelAnObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
index 8eec14d..d334d75 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioningCamelContext.xml
@@ -33,7 +33,11 @@ under the License.
     <property name="primary" value="file:${camel.directory}/groupRoutes.xml"/>
     <property name="fallback" value="classpath:groupRoutes.xml"/>
   </bean>
-    
+  <bean id="anyObjectRoutes" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
+    <property name="primary" value="file:${camel.directory}/anyObjectRoutes.xml"/>
+    <property name="fallback" value="classpath:anyObjectRoutes.xml"/>
+  </bean>
+      
   <context:component-scan base-package="org.apache.syncope.core.provisioning.camel"/>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/pom.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index bfae2f4..679eee6 100644
--- a/fit/build-tools/pom.xml
+++ b/fit/build-tools/pom.xml
@@ -85,10 +85,16 @@ under the License.
     <dependency>
       <groupId>net.tirasa.connid.bundles.db</groupId>
       <artifactId>net.tirasa.connid.bundles.db.table</artifactId>
-      <version>${connid.db.table.version}</version>
+      <version>${connid.database.version}</version>
       <scope>runtime</scope>
     </dependency>
-    
+    <dependency>
+      <groupId>net.tirasa.connid.bundles.db</groupId>
+      <artifactId>net.tirasa.connid.bundles.db.scriptedsql</artifactId>
+      <version>${connid.database.version}</version>
+      <scope>runtime</scope>
+    </dependency>
+        
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
index 37adbd3..67567ec 100644
--- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
+++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java
@@ -49,7 +49,8 @@ public class ConnIdStartStopListener implements ServletContextListener {
 
         for (String bundleFile : new String[] {
             "testconnectorserver.soap.bundle",
-            "testconnectorserver.db.bundle",
+            "testconnectorserver.dbtable.bundle",
+            "testconnectorserver.scriptedsql.bundle",
             "testconnectorserver.csvdir.bundle",
             "testconnectorserver.ldap.bundle" }) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/buildToolsContext.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/buildToolsContext.xml b/fit/build-tools/src/main/resources/buildToolsContext.xml
index 2b63ed6..e0f5678 100644
--- a/fit/build-tools/src/main/resources/buildToolsContext.xml
+++ b/fit/build-tools/src/main/resources/buildToolsContext.xml
@@ -45,8 +45,11 @@ under the License.
   <bean id="testconnectorserver.soap.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.soap-${connid.soap.version}.jar"/>
   </bean>  
-  <bean id="testconnectorserver.db.bundle" class="java.lang.String">
-    <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.db.table.version}.jar"/>
+  <bean id="testconnectorserver.dbtable.bundle" class="java.lang.String">
+    <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.database.version}.jar"/>
+  </bean>  
+  <bean id="testconnectorserver.scriptedsql.bundle" class="java.lang.String">
+    <constructor-arg value="net.tirasa.connid.bundles.db.scriptedsql-${connid.database.version}.jar"/>
   </bean>  
   <bean id="testconnectorserver.csvdir.bundle" class="java.lang.String">
     <constructor-arg value="net.tirasa.connid.bundles.csvdir-${connid.csvdir.version}.jar"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/build-tools/src/main/resources/testdb.sql
----------------------------------------------------------------------
diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql
index ff4dd47..9202a87 100644
--- a/fit/build-tools/src/main/resources/testdb.sql
+++ b/fit/build-tools/src/main/resources/testdb.sql
@@ -37,10 +37,16 @@ INSERT INTO test2 VALUES ('verdi', 'password321', 'true');
 
 -- this table is for issueSYNCOPE230
 DROP TABLE testsync IF EXISTS;
-CREATE TABLE TESTSYNC (
+CREATE TABLE testsync (
 id NUMBER(10) PRIMARY KEY,
 username VARCHAR(80),
 surname VARCHAR(80),
 email VARCHAR(80));
 
 INSERT INTO testsync VALUES (965, 'issuesyncope230', 'Surname', 'syncope230@syncope.apache.org');
+
+DROP TABLE testPRINTER IF EXISTS;
+CREATE TABLE testPRINTER (
+id NUMBER(10) PRIMARY KEY,
+location VARCHAR(80),
+lastModification TIMESTAMP);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/connid.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/connid.properties b/fit/core-reference/src/main/resources/connid.properties
index a18252f..22ed0a8 100644
--- a/fit/core-reference/src/main/resources/connid.properties
+++ b/fit/core-reference/src/main/resources/connid.properties
@@ -20,5 +20,5 @@ connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}
 ## for test only
 testdb.url=${testdb.url}
 connid.soap.version=${connid.soap.version}
-connid.db.table.version=${connid.db.table.version}
+connid.database.version=${connid.database.version}
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
new file mode 100644
index 0000000..52c10f9
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/CreateScript.groovy
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends us the following:
+// connection : SQL connection
+// action: String correponding to the action ("CREATE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// id: The entry identifier (OpenICF "Name" atribute. (most often matches the uid)
+// attributes: an Attribute Map, containg the <String> attribute name as a key
+// and the <List> attribute value(s) as value.
+// password: password string, clear text
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+def sql = new Sql(connection);
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.execute("INSERT INTO TESTPRINTER (id, location, lastmodification) values (?,?,?)",
+    [
+      id,
+      attributes.get("location").get(0),
+      new Date()
+    ])
+  break
+
+default:
+  id;
+}
+
+return id;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
new file mode 100644
index 0000000..cdd7f5b
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/DeleteScript.groovy
@@ -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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("DELETE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// options: a handler to the OperationOptions Map
+// uid: String for the unique id that specifies the object to delete
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+assert uid != null
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.execute("DELETE FROM TESTPRINTER where id= ?",[uid])
+  break
+
+default:
+  uid;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
new file mode 100644
index 0000000..50f8a8a
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SchemaScript.groovy
@@ -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.
+ */
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+// This sample shows how to create 3 basic ObjectTypes: __ACCOUNT__, __GROUP__ and organization.
+// Each of them contains one required attribute and normal String attributes
+
+
+log.info("Entering " + action + " Script");
+
+idAIB = new AttributeInfoBuilder("id", String.class);
+idAIB.setRequired(true);
+
+orgAttrsInfo = new HashSet<AttributeInfo>();
+orgAttrsInfo.add(idAIB.build());
+orgAttrsInfo.add(AttributeInfoBuilder.build("location", String.class));
+// Create the organization Object class
+ObjectClassInfo ociOrg = new ObjectClassInfoBuilder().setType("__PRINTER__").addAllAttributeInfo(orgAttrsInfo).build();
+builder.defineObjectClass(ociOrg);
+
+log.info("Schema script done");
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
new file mode 100644
index 0000000..cc0dd65
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SearchScript.groovy
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+log.info("Entering " + action + " Script");
+
+def sql = new Sql(connection);
+def result = []
+def where = "";
+
+if (query != null)  {
+  // Need to handle the __UID__ in queries
+  if (query.get("left").equalsIgnoreCase("__UID__") && objectClass.equalsIgnoreCase("__PRINTER__")) {
+    query.put("left","id")
+  }
+  
+  // We can use Groovy template engine to generate our custom SQL queries
+  def engine = new groovy.text.SimpleTemplateEngine();
+
+  def whereTemplates = [
+    CONTAINS:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right%"',
+    ENDSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "%$right"',
+    STARTSWITH:' WHERE $left ${not ? "NOT " : ""}LIKE "$right%"',
+    EQUALS:' WHERE $left ${not ? "<>" : "="} \'$right\'',
+    GREATERTHAN:' WHERE $left ${not ? "<=" : ">"} "$right"',
+    GREATERTHANOREQUAL:' WHERE $left ${not ? "<" : ">="} "$right"',
+    LESSTHAN:' WHERE $left ${not ? ">=" : "<"} "$right"',
+    LESSTHANOREQUAL:' WHERE $left ${not ? ">" : "<="} "$right"'
+  ]
+
+  def wt = whereTemplates.get(query.get("operation"));
+  def binding = [left:query.get("left"),right:query.get("right"),not:query.get("not")];
+  def template = engine.createTemplate(wt).make(binding);
+  where = template.toString();
+  log.ok("Search WHERE clause is: "+ where)
+}
+
+switch ( objectClass ) {
+case "__PRINTER__":
+  sql.eachRow("SELECT * FROM TESTPRINTER " + where, 
+    {result.add([__UID__:it.id, __NAME__:it.id, location:it.location])} );
+  break
+
+default:
+  result;
+}
+
+return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
new file mode 100644
index 0000000..6060870
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/SyncScript.groovy
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN")
+// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN")
+//
+//
+// Returns:
+// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known
+// sync token for the corresponding ObjectClass
+// 
+// if action = "SYNC":
+// A list of Maps . Each map describing one update:
+// Map should look like the following:
+//
+// [
+// "token": <Object> token object (could be Integer, Date, String) , [!! could be null]
+// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE")  will always default to CREATE_OR_DELETE ,
+// "uid":<String> uid  (uid of the entry) ,
+// "previousUid":<String> prevuid (This is for rename ops) ,
+// "password":<String> password (optional... allows to pass clear text password if needed),
+// "attributes":Map<String,List> of attributes name/values
+// ]
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) {
+  switch (objectClass) {
+  case "__PRINTER__":
+    row = sql.firstRow("SELECT lastmodification FROM TESTPRINTER ORDER BY lastmodification DESC");
+    log.ok("Get Latest Sync Token script: last token is: " + row["lastmodification"])
+    break;
+    
+  default:
+    row = null;
+  }
+
+  return row == null ? null : row["lastmodification"].getTime();
+} else if (action.equalsIgnoreCase("SYNC")) {
+  def result = [];
+  def lastmodification = null;
+  if (token != null) {
+    lastmodification = new Date(token);
+  } else {
+    lastmodification = new Date(0);
+  }
+
+  switch (objectClass) {
+  case "__PRINTER__":    
+    sql.eachRow("SELECT * FROM TESTPRINTER WHERE lastmodification > ${lastmodification}",
+      {
+        result.add([
+            operation:"CREATE_OR_UPDATE", 
+            uid:it.id.toString(), 
+            token:it.lastmodification.getTime(), 
+            attributes:[
+              __UID__:it.id.toString(),
+              __NAME__:it.id.toString(),
+              id:it.id.toString(),
+              location:it.location
+            ]
+          ]);
+      }
+    )
+    break;
+  }
+  
+  log.ok("Sync script: found " + result.size() + " events to sync");
+  return result;
+} else {
+  log.error("Sync script: action '" + action + "' is not implemented in this script");
+  return null;
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
new file mode 100644
index 0000000..5b8f4b5
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/TestScript.groovy
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+sql.eachRow("select * from TESTPRINTER", { println it.uid} );
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
new file mode 100644
index 0000000..f3155cb
--- /dev/null
+++ b/fit/core-reference/src/main/resources/scriptedsql/UpdateScript.groovy
@@ -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.
+ */
+import groovy.sql.Sql;
+import groovy.sql.DataSet;
+
+// Parameters:
+// The connector sends us the following:
+// connection : SQL connection
+//
+// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES)
+//   - UPDATE : For each input attribute, replace all of the current values of that attribute
+//     in the target object with the values of that attribute.
+//   - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values
+//     of that attribute in the target object all of the values of that attribute in the input set.
+//   - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values
+//     of that attribute in the target object any value that matches one of the values of the attribute from the input set.
+
+// log: a handler to the Log facility
+//
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+//
+// uid: a String representing the entry uid
+//
+// attributes: an Attribute Map, containg the <String> attribute name as a key
+// and the <List> attribute value(s) as value.
+//
+// password: password string, clear text (only for UPDATE)
+//
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+def sql = new Sql(connection);
+
+
+switch (action) {
+case "UPDATE":
+  if (attributes.get("location").get(0) != null) {
+    sql.executeUpdate("UPDATE TESTPRINTER SET location = ?, lastmodification = ? where id = ?", 
+      [attributes.get("location").get(0), new Date(), attributes.get("__NAME__").get(0)])
+    
+    return attributes.get("__NAME__").get(0);
+  }
+  break
+
+case "ADD_ATTRIBUTE_VALUES":
+  break
+
+
+default:
+  sql
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 8cfec8b..efe1b16 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
@@ -35,11 +35,13 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
 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.AbstractPolicyTO;
 import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -48,6 +50,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
 import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
 import org.apache.syncope.common.rest.api.service.AnyTypeService;
 import org.apache.syncope.common.rest.api.service.CamelRouteService;
@@ -141,6 +144,8 @@ public abstract class AbstractITCase {
 
     protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
 
+    protected static final String RESOURCE_NAME_DBSCRIPTED = "resource-db-scripted";
+
     protected static String ANONYMOUS_UNAME;
 
     protected static String ANONYMOUS_KEY;
@@ -155,6 +160,8 @@ public abstract class AbstractITCase {
 
     protected static RealmService realmService;
 
+    protected static AnyObjectService anyObjectService;
+
     protected static RoleService roleService;
 
     protected static UserService userService;
@@ -226,6 +233,7 @@ public abstract class AbstractITCase {
         anyTypeClassService = adminClient.getService(AnyTypeClassService.class);
         anyTypeService = adminClient.getService(AnyTypeService.class);
         realmService = adminClient.getService(RealmService.class);
+        anyObjectService = adminClient.getService(AnyObjectService.class);
         roleService = adminClient.getService(RoleService.class);
         userService = adminClient.getService(UserService.class);
         userSelfService = adminClient.getService(UserSelfService.class);
@@ -287,8 +295,8 @@ public abstract class AbstractITCase {
         return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
     }
 
-    protected UserTO deleteUser(final Long id) {
-        return userService.delete(id).readEntity(UserTO.class);
+    protected UserTO deleteUser(final Long key) {
+        return userService.delete(key).readEntity(UserTO.class);
     }
 
     public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
@@ -322,6 +330,25 @@ public abstract class AbstractITCase {
         return getObject(response.getLocation(), RoleService.class, RoleTO.class);
     }
 
+    protected AnyObjectTO createAnyObject(final AnyObjectTO anyObjectTO) {
+        Response response = anyObjectService.create(anyObjectTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+            if (ex != null) {
+                throw (RuntimeException) ex;
+            }
+        }
+        return getObject(response.getLocation(), AnyObjectService.class, AnyObjectTO.class);
+    }
+
+    protected AnyObjectTO updateAnyObject(final AnyObjectMod anyObjectMod) {
+        return anyObjectService.update(anyObjectMod.getKey(), anyObjectMod).readEntity(AnyObjectTO.class);
+    }
+
+    protected AnyObjectTO deleteAnyObject(final Long key) {
+        return anyObjectService.delete(key).readEntity(AnyObjectTO.class);
+    }
+
     protected GroupTO createGroup(final GroupTO groupTO) {
         Response response = groupService.create(groupTO);
         if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
@@ -337,8 +364,8 @@ public abstract class AbstractITCase {
         return groupService.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class);
     }
 
-    protected GroupTO deleteGroup(final Long id) {
-        return groupService.delete(id).readEntity(GroupTO.class);
+    protected GroupTO deleteGroup(final Long key) {
+        return groupService.delete(key).readEntity(GroupTO.class);
     }
 
     @SuppressWarnings("unchecked")


[10/70] 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);
+
+}


[13/70] 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;
 


[37/70] syncope git commit: [SYNCOPE-673] Merge from master

Posted by il...@apache.org.
[SYNCOPE-673] Merge from master


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

Branch: refs/heads/master
Commit: c608b58540b1f6089e466096522042fd244b5368
Parents: 63108c8 8ea1e6a
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed May 27 12:20:38 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed May 27 12:20:38 2015 +0200

----------------------------------------------------------------------
 .../java/sync/GroupSyncResultHandlerImpl.java            |  5 +----
 .../java/sync/UserSyncResultHandlerImpl.java             | 11 ++++++-----
 pom.xml                                                  |  2 +-
 3 files changed, 8 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/c608b585/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/GroupSyncResultHandlerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/syncope/blob/c608b585/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --cc core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/UserSyncResultHandlerImpl.java
index 8487fa8,d111ac6..d5c41db
--- 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
@@@ -55,12 -55,24 +55,13 @@@ public class UserSyncResultHandlerImpl 
      }
  
      @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) {
 -
 -        UserTO userTO = UserTO.class.cast(subjectTO);
 +    protected AnyTO doCreate(final AnyTO anyTO, final SyncDelta delta, final ProvisioningResult result) {
 +        UserTO userTO = UserTO.class.cast(anyTO);
  
          Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
-         Map.Entry<Long, List<PropagationStatus>> created = userProvisioningManager.create(userTO, true, true, enabled,
-                 Collections.singleton(profile.getTask().getResource().getKey()));
+         Map.Entry<Long, List<PropagationStatus>> created =
+                 userProvisioningManager.create(userTO, true, true, enabled,
+                         Collections.singleton(profile.getTask().getResource().getKey()));
  
          result.setKey(created.getKey());
  
@@@ -92,8 -104,8 +93,8 @@@
              final SyncDelta delta,
              final ProvisioningResult result) {
  
-         final UserMod userMod = UserMod.class.cast(anyMod);
-         final Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
 -        UserMod userMod = UserMod.class.cast(subjectMod);
++        UserMod userMod = UserMod.class.cast(anyMod);
+         Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
  
          Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(userMod, before.getKey(),
                  result, enabled, Collections.singleton(profile.getTask().getResource().getKey()));

http://git-wip-us.apache.org/repos/asf/syncope/blob/c608b585/pom.xml
----------------------------------------------------------------------


[46/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.java
new file mode 100644
index 0000000..8747631
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeClassLogic.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.logic;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyTypeClassLogic extends AbstractTransactionalLogic<AnyTypeClassTO> {
+
+    @Autowired
+    private AnyTypeClassDataBinder binder;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeDAO;
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_READ + "')")
+    public AnyTypeClassTO read(final String key) {
+        AnyTypeClass anyType = anyTypeDAO.find(key);
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        return binder.getAnyTypeClassTO(anyType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_LIST + "')")
+    public List<AnyTypeClassTO> list() {
+        return CollectionUtils.collect(anyTypeDAO.findAll(), new Transformer<AnyTypeClass, AnyTypeClassTO>() {
+
+            @Override
+            public AnyTypeClassTO transform(final AnyTypeClass input) {
+                return binder.getAnyTypeClassTO(input);
+            }
+        }, new ArrayList<AnyTypeClassTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_CREATE + "')")
+    public AnyTypeClassTO create(final AnyTypeClassTO anyTypeTO) {
+        return binder.getAnyTypeClassTO(anyTypeDAO.save(binder.create(anyTypeTO)));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_UPDATE + "')")
+    public AnyTypeClassTO update(final AnyTypeClassTO anyTypeTO) {
+        AnyTypeClass anyType = anyTypeDAO.find(anyTypeTO.getKey());
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + anyTypeTO.getKey() + "'");
+            throw new NotFoundException(String.valueOf(anyTypeTO.getKey()));
+        }
+
+        binder.update(anyType, anyTypeTO);
+        anyType = anyTypeDAO.save(anyType);
+
+        return binder.getAnyTypeClassTO(anyType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPECLASS_DELETE + "')")
+    public AnyTypeClassTO delete(final String key) {
+        AnyTypeClass anyType = anyTypeDAO.find(key);
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        AnyTypeClassTO deleted = binder.getAnyTypeClassTO(anyType);
+        anyTypeDAO.delete(key);
+        return deleted;
+    }
+
+    @Override
+    protected AnyTypeClassTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
+        String key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof Long) {
+                    key = (String) args[i];
+                } else if (args[i] instanceof AnyTypeClassTO) {
+                    key = ((AnyTypeClassTO) args[i]).getKey();
+                }
+            }
+        }
+
+        if (StringUtils.isNotBlank(key)) {
+            try {
+                return binder.getAnyTypeClassTO(anyTypeDAO.find(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/dd88efbd/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
new file mode 100644
index 0000000..93af622
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.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.logic;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
+
+    @Autowired
+    private AnyTypeDataBinder binder;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_READ + "')")
+    public AnyTypeTO read(final String key) {
+        AnyType anyType = anyTypeDAO.find(key);
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        return binder.getAnyTypeTO(anyType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_LIST + "')")
+    public List<AnyTypeTO> list() {
+        return CollectionUtils.collect(anyTypeDAO.findAll(), new Transformer<AnyType, AnyTypeTO>() {
+
+            @Override
+            public AnyTypeTO transform(final AnyType input) {
+                return binder.getAnyTypeTO(input);
+            }
+        }, new ArrayList<AnyTypeTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_CREATE + "')")
+    public AnyTypeTO create(final AnyTypeTO anyTypeTO) {
+        return binder.getAnyTypeTO(anyTypeDAO.save(binder.create(anyTypeTO)));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_UPDATE + "')")
+    public AnyTypeTO update(final AnyTypeTO anyTypeTO) {
+        AnyType anyType = anyTypeDAO.find(anyTypeTO.getKey());
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + anyTypeTO.getKey() + "'");
+            throw new NotFoundException(String.valueOf(anyTypeTO.getKey()));
+        }
+
+        binder.update(anyType, anyTypeTO);
+        anyType = anyTypeDAO.save(anyType);
+
+        return binder.getAnyTypeTO(anyType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANYTYPE_DELETE + "')")
+    public AnyTypeTO delete(final String key) {
+        AnyType anyType = anyTypeDAO.find(key);
+        if (anyType == null) {
+            LOG.error("Could not find anyType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        AnyTypeTO deleted = binder.getAnyTypeTO(anyType);
+        anyTypeDAO.delete(key);
+        return deleted;
+    }
+
+    @Override
+    protected AnyTypeTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
+        String key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof Long) {
+                    key = (String) args[i];
+                } else if (args[i] instanceof AnyTypeTO) {
+                    key = ((AnyTypeTO) args[i]).getKey();
+                }
+            }
+        }
+
+        if (StringUtils.isNotBlank(key)) {
+            try {
+                return binder.getAnyTypeTO(anyTypeDAO.find(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/dd88efbd/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
index 968a34c..77ff7b5 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LogicInvocationHandler.java
@@ -34,9 +34,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 @Aspect
 public class LogicInvocationHandler {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(LogicInvocationHandler.class);
 
     @Autowired
@@ -47,16 +44,16 @@ public class LogicInvocationHandler {
 
     @Around("execution(* org.apache.syncope.core.logic.AbstractLogic+.*(..))")
     public Object around(final ProceedingJoinPoint joinPoint) throws Throwable {
-        final Class<?> clazz = joinPoint.getTarget().getClass();
+        Class<?> clazz = joinPoint.getTarget().getClass();
 
-        final Object[] input = joinPoint.getArgs();
+        Object[] input = joinPoint.getArgs();
 
-        final String category = clazz.getSimpleName();
+        String category = clazz.getSimpleName();
 
-        final MethodSignature ms = (MethodSignature) joinPoint.getSignature();
+        MethodSignature ms = (MethodSignature) joinPoint.getSignature();
         Method method = ms.getMethod();
 
-        final String event = joinPoint.getSignature().getName();
+        String event = joinPoint.getSignature().getName();
 
         AuditElements.Result result = null;
         Object output = null;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 073150b..863af12 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
@@ -217,7 +217,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
                 connector.getOperationOptions(attrUtils.getMappingItems(provision, MappingPurpose.BOTH)));
         if (connectorObject == null) {
             throw new NotFoundException("Object " + connObjectKeyValue + " with class " + provision.getObjectClass()
-                    + "not found on resource " + resourceKey);
+                    + " not found on resource " + resourceKey);
         }
 
         final Set<Attribute> attributes = connectorObject.getAttributes();

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 37acf19..4ecab47 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
@@ -50,12 +50,12 @@ 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;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-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.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -205,7 +205,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
 
         Map.Entry<Long, List<PropagationStatus>> created = provisioningManager.create(actual, storePassword);
 
-        final UserTO savedTO = binder.getUserTO(created.getKey());
+        UserTO savedTO = binder.getUserTO(created.getKey());
         savedTO.getPropagationStatusTOs().addAll(created.getValue());
         return savedTO;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
index 106ed36..6a8289a 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
@@ -57,6 +57,7 @@ import org.quartz.impl.JobDetailImpl;
 import org.quartz.impl.triggers.CronTriggerImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanCreationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@@ -126,6 +127,30 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         }
     }
 
+    private Job createSpringBean(final Class<?> jobClass) {
+        Job jobInstance = null;
+        for (int i = 0; i < 5 && jobInstance == null; i++) {
+            LOG.debug("{} attempt to create Spring bean for {}", i, jobClass);
+            try {
+                jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
+                        createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+                LOG.debug("{} attempt to create Spring bean for {} succeeded", i, jobClass);
+            } catch (BeanCreationException e) {
+                LOG.error("Could not create Spring bean for {}", jobClass, e);
+                try {
+                    Thread.sleep(1000);
+                } catch (final InterruptedException ex) {
+                    // ignore
+                }
+            }
+        }
+        if (jobInstance == null) {
+            throw new NotFoundException("Spring bean for " + jobClass);
+        }
+
+        return jobInstance;
+    }
+
     @SuppressWarnings("unchecked")
     @Override
     public void registerJob(final Task task, final String jobClassName, final String cronExpression)
@@ -137,8 +162,8 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
         } else if (PushJob.class.equals(jobClass)) {
             jobClass = PushJobImpl.class;
         }
-        Job jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
-                createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+
+        Job jobInstance = createSpringBean(jobClass);
         if (jobInstance instanceof TaskJob) {
             ((TaskJob) jobInstance).setTaskId(task.getKey());
         }
@@ -151,10 +176,8 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
                 try {
                     Class<?> actionsClass = Class.forName(className);
 
-                    final SyncActions syncActions =
-                            (SyncActions) ApplicationContextProvider.getBeanFactory().
+                    SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
                             createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
-
                     actions.add(syncActions);
                 } catch (Exception e) {
                     LOG.info("Class '{}' not found", className, e);
@@ -182,8 +205,7 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
 
     @Override
     public void registerJob(final Report report) throws SchedulerException, ParseException {
-        Job jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
-                createBean(ReportJob.class, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+        Job jobInstance = createSpringBean(ReportJob.class);
         ((ReportJob) jobInstance).setReportKey(report.getKey());
 
         registerJob(JobNamer.getJobName(report), jobInstance, report.getCronExpression());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 b4087a7..b05c4e6 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
@@ -29,6 +29,7 @@ import org.apache.syncope.common.lib.report.UserReportletConf.Feature;
 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.RelationshipTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
@@ -38,6 +39,8 @@ 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.persistence.api.entity.user.URelationship;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
 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;
@@ -62,6 +65,9 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
     @Autowired
     private GroupDataBinder groupDataBinder;
 
+    @Autowired
+    private AnyObjectDataBinder anyObjectDataBinder;
+
     private List<User> getPagedUsers(final int page) {
         List<User> result;
 
@@ -264,14 +270,39 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
 
             doExtractAttributes(handler, userTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
 
+            if (conf.getFeatures().contains(Feature.relationships)) {
+                handler.startElement("", "", "relationships", null);
+
+                for (RelationshipTO rel : userTO.getRelationships()) {
+                    atts.clear();
+
+                    atts.addAttribute("", "", "anyObjectKey",
+                            ReportXMLConst.XSD_LONG, String.valueOf(rel.getRightKey()));
+                    handler.startElement("", "", "relationship", atts);
+
+                    if (conf.getFeatures().contains(Feature.resources)) {
+                        URelationship actualRel = user.getRelationship(rel.getRightKey());
+                        if (actualRel == null) {
+                            LOG.warn("Unexpected: cannot find relationship for any object {} for user {}",
+                                    rel.getRightKey(), user);
+                        } else {
+                            doExtractResources(handler, anyObjectDataBinder.getAnyObjectTO(actualRel.getRightEnd()));
+                        }
+                    }
+
+                    handler.endElement("", "", "relationship");
+                }
+
+                handler.endElement("", "", "relationships");
+            }
             if (conf.getFeatures().contains(Feature.memberships)) {
                 handler.startElement("", "", "memberships", null);
 
                 for (MembershipTO memb : userTO.getMemberships()) {
                     atts.clear();
 
-                    atts.addAttribute("", "", "id", ReportXMLConst.XSD_LONG, String.valueOf(memb.getKey()));
-                    atts.addAttribute("", "", "groupId", ReportXMLConst.XSD_LONG, String.valueOf(memb.getRightKey()));
+                    atts.addAttribute("", "", "groupKey",
+                            ReportXMLConst.XSD_LONG, String.valueOf(memb.getRightKey()));
                     atts.addAttribute("", "", "groupName", ReportXMLConst.XSD_STRING, String.
                             valueOf(memb.getGroupName()));
                     handler.startElement("", "", "membership", atts);
@@ -279,8 +310,8 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     if (conf.getFeatures().contains(Feature.resources)) {
                         UMembership actualMemb = user.getMembership(memb.getRightKey());
                         if (actualMemb == null) {
-                            LOG.warn("Unexpected: cannot find membership for group {} for user {}", memb.getRightKey(),
-                                    user);
+                            LOG.warn("Unexpected: cannot find membership for group {} for user {}",
+                                    memb.getRightKey(), user);
                         } else {
                             doExtractResources(handler, groupDataBinder.getGroupTO(actualMemb.getRightEnd()));
                         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 279ef77..766c5cf 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
@@ -25,23 +25,21 @@ import java.util.ArrayList;
 import java.util.Collection;
 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.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
 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.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
@@ -54,24 +52,13 @@ 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.VirAttr;
 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;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
-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;
@@ -79,12 +66,9 @@ 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.OperationOptions;
-import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -100,9 +84,6 @@ public class ConnObjectUtils {
     private UserDAO userDAO;
 
     @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    @Autowired
     private GroupDAO groupDAO;
 
     @Autowired
@@ -114,18 +95,9 @@ public class ConnObjectUtils {
     @Autowired
     private PasswordGenerator pwdGen;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
     private final Encryptor encryptor = Encryptor.getInstance();
 
     /**
-     * Virtual attribute cache.
-     */
-    @Autowired
-    private VirAttrCache virAttrCache;
-
-    /**
      * Build a UserTO / GroupTO / AnyObjectTO out of connector object attributes and schema mapping.
      *
      * @param obj connector object
@@ -213,6 +185,8 @@ public class ConnObjectUtils {
             return (T) AnyOperations.diff(((UserTO) updated), ((UserTO) original), true);
         } else if (AnyTypeKind.GROUP == anyUtils.getAnyTypeKind()) {
             return (T) AnyOperations.diff(((GroupTO) updated), ((GroupTO) original), true);
+        } else if (AnyTypeKind.ANY_OBJECT == anyUtils.getAnyTypeKind()) {
+            return (T) AnyOperations.diff(((AnyObjectTO) updated), ((AnyObjectTO) original), true);
         }
 
         return null;
@@ -348,12 +322,14 @@ public class ConnObjectUtils {
         AnyTemplate anyTypeTemplate = syncTask.getTemplate(provision.getAnyType());
         if (anyTypeTemplate != null) {
             AnyTO template = anyTypeTemplate.get();
+            fillFromTemplate(anyTO, template);
 
-            if (template.getRealm() != null) {
-                anyTO.setRealm(template.getRealm());
-            }
-
-            if (template instanceof UserTO) {
+            if (template instanceof AnyObjectTO) {
+                fillRelationshipsFromTemplate(((AnyObjectTO) anyTO).getRelationshipMap(),
+                        ((AnyObjectTO) anyTO).getRelationships(), ((AnyObjectTO) template).getRelationships());
+                fillMembershipsFromTemplate(((AnyObjectTO) anyTO).getMembershipMap(),
+                        ((AnyObjectTO) anyTO).getMemberships(), ((AnyObjectTO) template).getMemberships());
+            } else if (template instanceof UserTO) {
                 if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
                     String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO);
                     if (StringUtils.isNotBlank(evaluated)) {
@@ -367,8 +343,12 @@ public class ConnObjectUtils {
                         ((UserTO) anyTO).setPassword(evaluated);
                     }
                 }
-            }
-            if (template instanceof GroupTO) {
+
+                fillRelationshipsFromTemplate(((UserTO) anyTO).getRelationshipMap(),
+                        ((UserTO) anyTO).getRelationships(), ((UserTO) template).getRelationships());
+                fillMembershipsFromTemplate(((UserTO) anyTO).getMembershipMap(),
+                        ((UserTO) anyTO).getMemberships(), ((UserTO) template).getMemberships());
+            } else if (template instanceof GroupTO) {
                 if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
                     String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO);
                     if (StringUtils.isNotBlank(evaluated)) {
@@ -389,12 +369,6 @@ public class ConnObjectUtils {
                     }
                 }
             }
-
-            fillFromTemplate(anyTO, template);
-
-            for (String resource : template.getResources()) {
-                anyTO.getResources().add(resource);
-            }
         }
 
         return anyTO;
@@ -467,171 +441,34 @@ public class ConnObjectUtils {
         return connObjectTO;
     }
 
-    /**
-     * Query connected external resources for values to populated virtual attributes associated with the given owner.
-     *
-     * @param any any object
-     */
-    public void retrieveVirAttrValues(final Any<?, ?, ?> any) {
-        ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
-        ConnectorFactory connFactory = context.getBean(ConnectorFactory.class);
-
-        IntMappingType type = any.getType().getKind() == AnyTypeKind.USER
-                ? IntMappingType.UserVirtualSchema
-                : any.getType().getKind() == AnyTypeKind.GROUP
-                        ? IntMappingType.GroupVirtualSchema
-                        : IntMappingType.AnyVirtualSchema;
-
-        Map<String, ConnectorObject> resources = new HashMap<>();
-
-        // -----------------------
-        // Retrieve virtual attribute values if and only if they have not been retrieved yet
-        // -----------------------
-        for (VirAttr<?> virAttr : any.getVirAttrs()) {
-            // reset value set
-            if (virAttr.getValues().isEmpty()) {
-                retrieveVirAttrValue(any, virAttr, type, resources, connFactory);
-            }
-        }
-        // -----------------------
-    }
-
-    private void retrieveVirAttrValue(
-            final Any<?, ?, ?> any,
-            final VirAttr<?> virAttr,
-            final IntMappingType type,
-            final Map<String, ConnectorObject> externalResources,
-            final ConnectorFactory connFactory) {
-
-        String schemaName = virAttr.getSchema().getKey();
-        VirAttrCacheValue virAttrCacheValue = virAttrCache.get(any.getType().getKey(), any.getKey(), schemaName);
-
-        LOG.debug("Retrieve values for virtual attribute {} ({})", schemaName, type);
-
-        if (virAttrCache.isValidEntry(virAttrCacheValue)) {
-            // cached ...
-            LOG.debug("Values found in cache {}", virAttrCacheValue);
-            virAttr.getValues().clear();
-            virAttr.getValues().addAll(new ArrayList<>(virAttrCacheValue.getValues()));
-        } else {
-            // not cached ...
-            LOG.debug("Need one or more remote connections");
-
-            VirAttrCacheValue toBeCached = new VirAttrCacheValue();
-
-            AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-            Collection<ExternalResource> targetResources = getTargetResources(virAttr, type, anyUtils, any.getType());
-
-            for (ExternalResource resource : targetResources) {
-                Provision provision = resource.getProvision(any.getType());
-                LOG.debug("Search values into {},{}", resource, provision);
-
-                if (provision != null) {
-                    try {
-                        List<MappingItem> mappings = anyUtils.getMappingItems(provision, MappingPurpose.BOTH);
-
-                        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);
-
-                            if (StringUtils.isBlank(connObjectKey)) {
-                                throw new IllegalArgumentException("No ConnObjectKey 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);
-
-                            // 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());
-                                        }
-                                    }
-                                }
-                            }
-
-                            toBeCached.setResourceValues(resource.getKey(), new HashSet<>(virAttr.getValues()));
+    private AttrTO evaluateAttrFromTemplate(final AnyTO anyTO, final AttrTO template) {
+        AttrTO result = new AttrTO();
+        result.setSchema(template.getSchema());
 
-                            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));
-                            }
-                        }
-                    }
+        if (template.getValues() != null && !template.getValues().isEmpty()) {
+            for (String value : template.getValues()) {
+                String evaluated = JexlUtils.evaluate(value, anyTO);
+                if (StringUtils.isNotBlank(evaluated)) {
+                    result.getValues().add(evaluated);
                 }
             }
-
-            virAttrCache.put(any.getType().getKey(), any.getKey(), schemaName, toBeCached);
         }
-    }
-
-    private Collection<ExternalResource> getTargetResources(
-            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 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 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 resource.getProvision(anyType) != null
-                        && !MappingUtils.getMatchingMappingItems(
-                                anyUtils.getMappingItems(resource.getProvision(anyType), MappingPurpose.BOTH),
-                                attr.getSchema().getKey(), type).isEmpty();
-            }
-        });
+        return result;
     }
 
     private void fillFromTemplate(final AnyTO anyTO, final AnyTO template) {
+        if (template.getRealm() != null) {
+            anyTO.setRealm(template.getRealm());
+        }
+
         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())) {
+        for (AttrTO templatePlainAttr : template.getPlainAttrs()) {
+            if (!templatePlainAttr.getValues().isEmpty()
+                    && (!currentAttrMap.containsKey(templatePlainAttr.getSchema())
+                    || currentAttrMap.get(templatePlainAttr.getSchema()).getValues().isEmpty())) {
 
-                anyTO.getPlainAttrs().add(evaluateAttrTemplate(anyTO, templateAttr));
+                anyTO.getPlainAttrs().add(evaluateAttrFromTemplate(anyTO, templatePlainAttr));
             }
         }
 
@@ -644,29 +481,39 @@ public class ConnObjectUtils {
 
         currentAttrMap = anyTO.getVirAttrMap();
         for (AttrTO templateVirAttr : template.getVirAttrs()) {
-            if (templateVirAttr.getValues() != null && !templateVirAttr.getValues().isEmpty()
+            if (!templateVirAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateVirAttr.getSchema())
                     || currentAttrMap.get(templateVirAttr.getSchema()).getValues().isEmpty())) {
 
-                anyTO.getVirAttrs().add(evaluateAttrTemplate(anyTO, templateVirAttr));
+                anyTO.getVirAttrs().add(evaluateAttrFromTemplate(anyTO, templateVirAttr));
             }
         }
+
+        for (String resource : template.getResources()) {
+            anyTO.getResources().add(resource);
+        }
+
+        anyTO.getAuxClasses().addAll(template.getAuxClasses());
     }
 
-    private AttrTO evaluateAttrTemplate(final AnyTO anyTO, final AttrTO template) {
-        AttrTO result = new AttrTO();
-        result.setSchema(template.getSchema());
+    private void fillRelationshipsFromTemplate(final Map<Long, RelationshipTO> anyRelMap,
+            final List<RelationshipTO> anyRels, final List<RelationshipTO> templateRels) {
 
-        if (template.getValues() != null && !template.getValues().isEmpty()) {
-            for (String value : template.getValues()) {
-                String evaluated = JexlUtils.evaluate(value, anyTO);
-                if (StringUtils.isNotBlank(evaluated)) {
-                    result.getValues().add(evaluated);
-                }
+        for (RelationshipTO memb : templateRels) {
+            if (!anyRelMap.containsKey(memb.getRightKey())) {
+                anyRels.add(memb);
             }
         }
+    }
 
-        return result;
+    private void fillMembershipsFromTemplate(final Map<Long, MembershipTO> anyMembMap,
+            final List<MembershipTO> anyMembs, final List<MembershipTO> templateMembs) {
+
+        for (MembershipTO memb : templateMembs) {
+            if (!anyMembMap.containsKey(memb.getRightKey())) {
+                anyMembs.add(memb);
+            }
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 a1931c1..2efae81 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
@@ -64,6 +64,7 @@ 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.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.identityconnectors.framework.common.FrameworkUtil;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeBuilder;
@@ -230,7 +231,7 @@ public final class MappingUtils {
 
         ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
         AnyUtilsFactory anyUtilsFactory = context.getBean(AnyUtilsFactory.class);
-        ConnObjectUtils connObjectUtils = context.getBean(ConnObjectUtils.class);
+        VirAttrHandler virAttrHandler = context.getBean(VirAttrHandler.class);
 
         switch (mapItem.getIntMappingType().getAnyTypeKind()) {
             case USER:
@@ -243,7 +244,7 @@ public final class MappingUtils {
                 if (any instanceof User) {
                     UserDAO userDAO = context.getBean(UserDAO.class);
                     for (Group group : userDAO.findAllGroups((User) any)) {
-                        connObjectUtils.retrieveVirAttrValues(group);
+                        virAttrHandler.retrieveVirAttrValues(group);
                         anys.add(group);
                     }
                 } else if (any instanceof Group) {
@@ -266,7 +267,7 @@ public final class MappingUtils {
         PlainSchema schema = null;
         boolean readOnlyVirSchema = false;
         AttrSchemaType schemaType;
-        final Pair<String, Attribute> result;
+        Pair<String, Attribute> result;
 
         switch (mapItem.getIntMappingType()) {
             case UserPlainSchema:
@@ -290,7 +291,7 @@ public final class MappingUtils {
                 schemaType = AttrSchemaType.String;
         }
 
-        final String extAttrName = mapItem.getExtAttrName();
+        String extAttrName = mapItem.getExtAttrName();
 
         LOG.debug("Define mapping for: "
                 + "\n* ExtAttrName " + extAttrName
@@ -389,7 +390,7 @@ public final class MappingUtils {
         if (StringUtils.isNotBlank(anyUtils.getConnObjectLink(provision))) {
             final JexlContext jexlContext = new MapContext();
             JexlUtils.addFieldsToContext(any, jexlContext);
-            JexlUtils.addAttrsToContext(any.getPlainAttrs(), jexlContext);
+            JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
             JexlUtils.addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
             evalConnObjectLink = JexlUtils.evaluate(anyUtils.getConnObjectLink(provision), jexlContext);
         }
@@ -443,6 +444,8 @@ public final class MappingUtils {
 
         EntityFactory entityFactory =
                 ApplicationContextProvider.getApplicationContext().getBean(EntityFactory.class);
+        AnyUtilsFactory anyUtilsFactory =
+                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
         List<PlainAttrValue> values = new ArrayList<>();
         PlainAttrValue attrValue;
         switch (mappingItem.getIntMappingType()) {
@@ -472,6 +475,7 @@ public final class MappingUtils {
             case GroupVirtualSchema:
             case AnyVirtualSchema:
                 for (Any<?, ?, ?> any : anys) {
+                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     VirAttr<?> virAttr = any.getVirAttr(mappingItem.getIntAttrName());
                     if (virAttr != null) {
                         if (vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
@@ -488,7 +492,7 @@ public final class MappingUtils {
                         }
                         if (virAttr.getValues() != null) {
                             for (String value : virAttr.getValues()) {
-                                attrValue = entityFactory.newEntity(UPlainAttrValue.class);
+                                attrValue = anyUtils.newPlainAttrValue();
                                 attrValue.setStringValue(value);
                                 values.add(attrValue);
                             }
@@ -508,11 +512,10 @@ public final class MappingUtils {
             case GroupDerivedSchema:
             case AnyDerivedSchema:
                 for (Any<?, ?, ?> any : anys) {
+                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     DerAttr<?> derAttr = any.getDerAttr(mappingItem.getIntAttrName());
                     if (derAttr != null) {
-                        attrValue = any instanceof Group
-                                ? entityFactory.newEntity(GPlainAttrValue.class)
-                                : entityFactory.newEntity(UPlainAttrValue.class);
+                        attrValue = anyUtils.newPlainAttrValue();
                         attrValue.setStringValue(derAttr.getValue(any.getPlainAttrs()));
                         values.add(attrValue);
                     }
@@ -529,7 +532,8 @@ public final class MappingUtils {
             case GroupId:
             case AnyId:
                 for (Any<?, ?, ?> any : anys) {
-                    attrValue = entityFactory.newEntity(UPlainAttrValue.class);
+                    AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+                    attrValue = anyUtils.newPlainAttrValue();
                     attrValue.setStringValue(any.getKey().toString());
                     values.add(attrValue);
                 }
@@ -600,7 +604,6 @@ public final class MappingUtils {
      * @return connObjectKey internal value
      */
     public static String getConnObjectKeyValue(final Any<?, ?, ?> any, final Provision provision) {
-
         List<PlainAttrValue> values = getIntValues(provision, provision.getMapping().getConnObjectKeyItem(),
                 Collections.<Any<?, ?, ?>>singletonList(any), null, null);
         return values == null || values.isEmpty()

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 83e98ec..9aad079 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
@@ -146,7 +146,7 @@ public final class JexlUtils {
         return context;
     }
 
-    public static JexlContext addAttrsToContext(final Collection<? extends PlainAttr<?>> attrs,
+    public static JexlContext addPlainAttrsToContext(final Collection<? extends PlainAttr<?>> attrs,
             final JexlContext jexlContext) {
 
         JexlContext context = jexlContext == null
@@ -215,11 +215,9 @@ public final class JexlUtils {
         return context;
     }
 
-    public static boolean evaluateMandatoryCondition(
-            final String mandatoryCondition, final Any<?, ?, ?> any) {
-
+    public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?, ?, ?> any) {
         JexlContext jexlContext = new MapContext();
-        addAttrsToContext(any.getPlainAttrs(), jexlContext);
+        addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
         addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
         addVirAttrsToContext(any.getVirAttrs(), jexlContext);
 
@@ -229,8 +227,8 @@ public final class JexlUtils {
     public static String evaluate(final String expression,
             final Any<?, ?, ?> any, final Collection<? extends PlainAttr<?>> attributes) {
 
-        final JexlContext jexlContext = new MapContext();
-        JexlUtils.addAttrsToContext(attributes, jexlContext);
+        JexlContext jexlContext = new MapContext();
+        JexlUtils.addPlainAttrsToContext(attributes, jexlContext);
         JexlUtils.addFieldsToContext(any, jexlContext);
 
         // Evaluate expression using the context prepared before

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UnallowedSchemaException.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UnallowedSchemaException.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UnallowedSchemaException.java
new file mode 100644
index 0000000..04f67dd
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UnallowedSchemaException.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.dao;
+
+public class UnallowedSchemaException extends RuntimeException {
+
+    private static final long serialVersionUID = -9206535191442808016L;
+
+    public UnallowedSchemaException(final String schemaName) {
+        super(schemaName + " not allowed");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
index ddb047e..19d0f6b 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
@@ -27,7 +27,7 @@ public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
 
     boolean remove(ARelationship relationship);
 
-    ARelationship getRelationship(AnyObject rightEnd);
+    ARelationship getRelationship(Long relationshipKey);
 
     List<? extends ARelationship> getRelationships();
 
@@ -35,7 +35,7 @@ public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
 
     boolean remove(AMembership membership);
 
-    AMembership getMembership(Long groupKey);
+    AMembership getMembership(Long membershipKey);
 
     List<? extends AMembership> getMemberships();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e1b9a5e..296de84 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
@@ -18,7 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity.task;
 
-import java.util.List;
+import java.util.Set;
 import org.apache.syncope.common.lib.types.MatchingRule;
 import org.apache.syncope.common.lib.types.UnmatchingRule;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
@@ -29,7 +29,7 @@ public interface ProvisioningTask extends SchedTask {
 
     void setResource(ExternalResource resource);
 
-    List<String> getActionsClassNames();
+    Set<String> getActionsClassNames();
 
     MatchingRule getMatchingRule();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 d896984..f02c555 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
@@ -23,7 +23,6 @@ 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.anyobject.AnyObject;
 
 public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> {
 
@@ -133,7 +132,7 @@ public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> {
 
     boolean remove(URelationship relationship);
 
-    URelationship getRelationship(AnyObject rightEnd);
+    URelationship getRelationship(Long anyObjectKey);
 
     List<? extends URelationship> getRelationships();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 3448737..ef2161e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -89,7 +89,8 @@ public abstract class AbstractAnyDAO<A extends Any<?, ?, ?>> extends AbstractDAO
 
         A any = find(key);
         if (any == null) {
-            throw new NotFoundException("Any " + key);
+            throw new NotFoundException(StringUtils.substringBefore(
+                    StringUtils.substringAfter(getClass().getSimpleName(), "JPA"), "DAO") + " " + key);
         }
 
         securityChecks(any);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 a849ef5..18b6636 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
@@ -102,7 +102,9 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
             resourceDAO.deleteMapping(key, anyUtils.derIntMappingType());
         }
 
-        schema.getAnyTypeClass().remove(schema);
+        if (schema.getAnyTypeClass() != null) {
+            schema.getAnyTypeClass().remove(schema);
+        }
 
         entityManager.remove(schema);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 50865c3..c3c94ce 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
@@ -102,7 +102,9 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             resourceDAO.deleteMapping(key, anyUtils.plainIntMappingType());
         }
 
-        schema.getAnyTypeClass().remove(schema);
+        if (schema.getAnyTypeClass() != null) {
+            schema.getAnyTypeClass().remove(schema);
+        }
 
         entityManager.remove(schema);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 cc4ffe4..dae6afc 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
@@ -102,7 +102,9 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
             resourceDAO.deleteMapping(key, anyUtils.virIntMappingType());
         }
 
-        schema.getAnyTypeClass().remove(schema);
+        if (schema.getAnyTypeClass() != null) {
+            schema.getAnyTypeClass().remove(schema);
+        }
 
         entityManager.remove(schema);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
index 914bd02..ec37649 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttr.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.Collections;
 import java.util.Set;
+import org.apache.syncope.core.persistence.api.dao.UnallowedSchemaException;
 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.DerSchema;
@@ -53,7 +54,7 @@ public abstract class AbstractAttr<S extends Schema, O extends Any<?, ?, ?>>
         }
 
         if (!getAllowedSchemas(getOwner()).contains(schema)) {
-            throw new IllegalArgumentException(schema + " not allowed for this instance");
+            throw new UnallowedSchemaException(schema.getKey());
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fba234d..4500a4e 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
@@ -21,9 +21,6 @@ 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;
@@ -38,20 +35,11 @@ public abstract class AbstractDerAttr<O extends Any<?, ?, ?>>
 
     private static final long serialVersionUID = 4740924251090424771L;
 
-    @Id
-    @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;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 946b09b..aebc8da 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
@@ -22,9 +22,6 @@ 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;
@@ -38,10 +35,6 @@ public abstract class AbstractVirAttr<O extends Any<?, ?, ?>>
 
     private static final long serialVersionUID = 5023204776925954907L;
 
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
     @Transient
     protected List<String> values = new ArrayList<>();
 
@@ -50,11 +43,6 @@ public abstract class AbstractVirAttr<O extends Any<?, ?, ?>>
     private JPAVirSchema schema;
 
     @Override
-    public Long getKey() {
-        return id;
-    }
-
-    @Override
     public List<String> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index abd6676..1525de9 100644
--- 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
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.entity.anyobject;
 
 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.ADerAttr;
@@ -33,10 +34,18 @@ public class JPAADerAttr extends AbstractDerAttr<AnyObject> implements ADerAttr
 
     public static final String TABLE = "ADerAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAAnyObject owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public AnyObject getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 7469799..62e2ea5 100644
--- 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
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.jpa.entity.anyobject;
 
 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.AVirAttr;
@@ -33,10 +34,18 @@ public class JPAAVirAttr extends AbstractVirAttr<AnyObject> implements AVirAttr
 
     public static final String TABLE = "AVirAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAAnyObject owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public AnyObject getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 6442c2d..a8e842b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -198,12 +198,12 @@ public class JPAAnyObject extends AbstractAny<APlainAttr, ADerAttr, AVirAttr> im
     }
 
     @Override
-    public ARelationship getRelationship(final AnyObject rightEnd) {
+    public ARelationship getRelationship(final Long anyObjectKey) {
         return CollectionUtils.find(getRelationships(), new Predicate<ARelationship>() {
 
             @Override
             public boolean evaluate(final ARelationship relationship) {
-                return rightEnd != null && rightEnd.equals(relationship.getRightEnd());
+                return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey());
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 46fc1cd..73911f8 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
@@ -19,6 +19,7 @@
 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.group.GDerAttr;
@@ -33,10 +34,18 @@ public class JPAGDerAttr extends AbstractDerAttr<Group> implements GDerAttr {
 
     public static final String TABLE = "GDerAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAGroup owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public Group getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 302e056..47b8886 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
@@ -19,6 +19,7 @@
 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.group.GVirAttr;
@@ -33,10 +34,18 @@ public class JPAGVirAttr extends AbstractVirAttr<Group> implements GVirAttr {
 
     public static final String TABLE = "GVirAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAGroup owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public Group getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index d90f605..7af8491 100644
--- 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
@@ -87,7 +87,9 @@ public class JPAAnyTemplate extends AbstractEntity<Long> implements AnyTemplate
                 ? anyType == null
                         ? null
                         : new JPAAnyUtilsFactory().getInstance(anyType.getKind()).newAnyTO()
-                : POJOHelper.deserialize(template, AnyTO.class);
+                : anyType == null
+                        ? null
+                        : POJOHelper.deserialize(template, anyType.getKind().getToClass());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 07e6f00..0592a9d 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
@@ -19,7 +19,9 @@
 package org.apache.syncope.core.persistence.jpa.entity.task;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.persistence.CascadeType;
 import javax.persistence.CollectionTable;
 import javax.persistence.Column;
@@ -48,7 +50,7 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     @CollectionTable(name = "PushTask_actionsClassNames",
             joinColumns =
             @JoinColumn(name = "pushTask_id", referencedColumnName = "id"))
-    private List<String> actionsClassNames = new ArrayList<>();
+    private Set<String> actionsClassNames = new HashSet<>();
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "pushTask")
     private List<JPAAnyFilter> filters = new ArrayList<>();
@@ -61,7 +63,7 @@ public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
     }
 
     @Override
-    public List<String> getActionsClassNames() {
+    public Set<String> getActionsClassNames() {
         return actionsClassNames;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 0106a65..41eb4ea 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
@@ -19,7 +19,9 @@
 package org.apache.syncope.core.persistence.jpa.entity.task;
 
 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;
@@ -57,7 +59,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     @CollectionTable(name = "SyncTask_actionsClassNames",
             joinColumns =
             @JoinColumn(name = "syncTask_id", referencedColumnName = "id"))
-    private List<String> actionsClassNames = new ArrayList<>();
+    private Set<String> actionsClassNames = new HashSet<>();
 
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "syncTask")
     private List<JPAAnyTemplate> templates = new ArrayList<>();
@@ -86,7 +88,7 @@ public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
     }
 
     @Override
-    public List<String> getActionsClassNames() {
+    public Set<String> getActionsClassNames() {
         return actionsClassNames;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 90bee1b..754fd59 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,6 +19,7 @@
 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.user.UDerAttr;
@@ -33,10 +34,18 @@ public class JPAUDerAttr extends AbstractDerAttr<User> implements UDerAttr {
 
     public static final String TABLE = "UDerAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAUser owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public User getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 56898d4..50ce967 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
@@ -45,9 +45,6 @@ public class JPAUPlainAttr extends AbstractPlainAttr<User> implements UPlainAttr
 
     public static final String TABLE = "UPlainAttr";
 
-    /**
-     * Auto-generated id for this table.
-     */
     @Id
     private Long id;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 52a168e..a6931ce 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,6 +19,7 @@
 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.user.UVirAttr;
@@ -33,10 +34,18 @@ public class JPAUVirAttr extends AbstractVirAttr<User> implements UVirAttr {
 
     public static final String TABLE = "UVirAttr";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPAUser owner;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public User getOwner() {
         return owner;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 f9c0c81..06d8f04 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
@@ -65,7 +65,6 @@ 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;
@@ -538,12 +537,12 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
     }
 
     @Override
-    public URelationship getRelationship(final AnyObject rightEnd) {
+    public URelationship getRelationship(final Long anyObjectKey) {
         return CollectionUtils.find(getRelationships(), new Predicate<URelationship>() {
 
             @Override
             public boolean evaluate(final URelationship relationship) {
-                return rightEnd != null && rightEnd.equals(relationship.getRightEnd());
+                return anyObjectKey != null && anyObjectKey.equals(relationship.getRightEnd().getKey());
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index c592c31..a75e4b6 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
@@ -312,6 +312,56 @@ under the License.
     </attributes>
   </entity>
 
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ADerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_ADerAttr" pk-column-value="SEQ_ADerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UDerAttr" pk-column-value="SEQ_UDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GDerAttr" pk-column-value="SEQ_GDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_AVirAttr" pk-column-value="SEQ_AVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UVirAttr" pk-column-value="SEQ_UVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GVirAttr" pk-column-value="SEQ_GVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
   <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
     <attributes>
       <id name="id">


[57/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 b61cb95..7b11faa 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -124,9 +124,9 @@ under the License.
   <AnyTypeClass name="minimal group"/>
   <AnyType_AnyTypeClass anyType_name="GROUP" anyTypeClass_name="minimal group"/>
   
-  <AnyType name="OTHER" kind="ANY_OBJECT"/>
-  <AnyTypeClass name="minimal other"/>
-  <AnyType_AnyTypeClass anyType_name="OTHER" anyTypeClass_name="minimal other"/>
+  <AnyType name="PRINTER" kind="ANY_OBJECT"/>
+  <AnyTypeClass name="minimal printer"/>
+  <AnyType_AnyTypeClass anyType_name="PRINTER" anyTypeClass_name="minimal printer"/>
       
   <AnyTypeClass name="csv"/>
 
@@ -135,10 +135,10 @@ under the License.
   <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"
+  <AnyObject id="1" realm_id="1" type_name="PRINTER"
              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"
+  <AnyObject id="2" realm_id="1" type_name="PRINTER"
              creator="admin" lastModifier="admin" 
              creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
@@ -286,7 +286,7 @@ under the License.
                conversionPattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ"/>
   <PlainSchema name="uselessReadonly" type="String" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="1"/>
-  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="minimal other" 
+  <PlainSchema name="cool" type="Boolean" anyTypeClass_name="other" 
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <PlainSchema name="gender" type="Enum" anyTypeClass_name="other"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
@@ -347,9 +347,21 @@ under the License.
 
   <VirSchema name="mvirtualdata"/>
         
-  <APlainAttr id="1" owner_id="2" schema_name="cool"/>
-  <APlainAttrValue id="1" attribute_id="1" booleanValue="1"/>
-  
+  <PlainSchema name="model" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <PlainSchema name="location" type="String" anyTypeClass_name="minimal printer"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+    
+  <APlainAttr id="1" owner_id="1" schema_name="model"/>
+  <APlainAttrValue id="1" attribute_id="1" stringValue="Canon MFC8030"/>
+  <APlainAttr id="2" owner_id="1" schema_name="location"/>
+  <APlainAttrValue id="2" attribute_id="2" stringValue="1st floor"/>
+    
+  <APlainAttr id="3" owner_id="2" schema_name="model"/>
+  <APlainAttrValue id="3" attribute_id="3" stringValue="HP Laserjet 1300n"/>
+  <APlainAttr id="4" owner_id="2" schema_name="location"/>
+  <APlainAttrValue id="4" attribute_id="4" stringValue="2nd floor"/>
+
   <UPlainAttr id="99" owner_id="1" schema_name="type"/>
   <UPlainAttrValue id="9" attribute_id="99" stringValue="G"/>
   <UPlainAttr id="100" owner_id="1" schema_name="fullname"/>
@@ -473,7 +485,7 @@ under the License.
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValu
 es":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required
 ":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityconnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="101" capability="AUTHENTICATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capability="ONE_PHASE_CREATE"/>
@@ -536,7 +548,7 @@ under the License.
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 bundleName="net.tirasa.connid.bundles.db.table"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector"
-                version="${connid.db.table.version}"
+                version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"disabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"keyColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"cipherAlgorithm","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["SHA1"]},{"schema":{"name":"enabledStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"
 defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"passwordColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["password"]},{"schema":{"name":"jdbcDriver","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"retrievePassword","displayName":null,"helpMessage":null,"type":"java.lang.Boolean","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"defaultStatusValue","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["true"]},{"schema":{"name":"password","displayName":null,"helpMessage":null,"type":"org.identityco
 nnectors.common.security.GuardedString","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"statusColumn","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["status"]},{"schema":{"name":"jdbcUrlTemplate","displayName":null,"helpMessage":null,"type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"table","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["test2"]}]'/>
   <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="106" capability="ONE_PHASE_UPDATE"/>
@@ -546,7 +558,7 @@ under the License.
   <ConnInstance id="107" bundleName="net.tirasa.connid.bundles.db.table" 
                 location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
                 connectorName="net.tirasa.connid.bundles.db.table.DatabaseTableConnector" 
-                displayName="H2-testsync" version="${connid.db.table.version}"
+                displayName="H2-testsync" version="${connid.database.version}"
                 jsonConf='[{"schema":{"name":"changeLogColumn","displayName":"Change Log Column (Sync)","helpMessage":"=&lt;b&gt;Change Log Column&lt;/b&gt;&lt;br&gt;The change log column store the latest change time. Providing this value the Sync capabilities are activated.","type":"java.lang.String","required":false,"order":21,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"nativeTimestamps","displayName":"Native Timestamps ","helpMessage":"&lt;b&gt;Native Timestamps&lt;/b&gt;&lt;br&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.","type":"boolean","required":false,"order":18,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"cipherAlgorithm","displayName":"Password cipher algorithm (defaults to CLEARTEXT)","helpMessage":"Cipher algorithm used to encode password before to store it onto the database table.\nSpecify one of th
 e values among CLEARTEXT,AES, MD5, SHA1, SHA256 or a custom implementation identified by its class name.","type":"java.lang.String","required":false,"order":24,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"enabledStatusValue","displayName":"Enabled Status Value","helpMessage":"&lt;b&gt;Enabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for enabled status.","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"retrievePassword","displayName":"Retrieve password","helpMessage":"Specify if password must be retrieved by default.","type":"boolean","required":true,"order":27,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"datasource","displayName":"Datasource Path","helpMessage":"&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br&gt;Enter the JDBC Data Source Name/Path to connect to the Or
 acle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;","type":"java.lang.String","required":false,"order":22,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"allNative","displayName":"All native","helpMessage":"&lt;b&gt;All native&lt;/b&gt;&lt;br&gt;Select to retrieve all data type of the columns in a native format from the database table.","type":"boolean","required":false,"order":19,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"user","displayName":"User","helpMessage":"&lt;b&gt;User&lt;/b&gt;&lt;br&gt;Enter the name of the mandatory Database user with permission to account table.","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name"
 :"pwdEncodeToLowerCase","displayName":"Force password encoding to lower case","helpMessage":"Force password encoding to lower case.","type":"boolean","required":false,"order":26,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"jdbcUrlTemplate","displayName":"JDBC Connection URL","helpMessage":"&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver Connection URL.&lt;br&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentation.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":null},"overridable":false,"values":["${testdb.url}"]},{"schema":{"name":"keyColumn","displayName":"Key Column","helpMessage":"&lt;b&gt;Key Column&lt;/b&gt;&lt;br&gt;This mandatory column value will be used as the unique identi
 fier for rows in the table.&lt;br&gt;","type":"java.lang.String","required":true,"order":8,"confidential":false,"defaultValues":null},"overridable":false,"values":["id"]},{"schema":{"name":"validConnectionQuery","displayName":"Validate Connection Query","helpMessage":"&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy table could be more efficient.","type":"java.lang.String","required":false,"order":20,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"rethrowAllSQLExceptions","displayName":"Rethrow all SQLExceptions","helpMessage":"If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.","type":"boolean","required":false,"order":17,"confid
 ential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"passwordColumn","displayName":"Password Column","helpMessage":"&lt;b&gt;Password Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the password values. If empty, no validation on resource and passwords are activated.","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jndiProperties","displayName":"Initial JNDI Properties","helpMessage":"&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.","type":"[Ljava.lang.String;","required":false,"order":23,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"password","displayName":"User Password","helpMessage":"&lt;b&gt;User Password&lt;/b&gt;&lt;br&gt;Enter a user account tha
 t has permission to access accounts table.","type":"org.identityconnectors.common.security.GuardedString","required":false,"order":5,"confidential":true,"defaultValues":null},"overridable":false,"values":["sa"]},{"schema":{"name":"host","displayName":"Host","helpMessage":"&lt;b&gt;Host&lt;/b&gt;&lt;br&gt;Enter the name of the host where the database is running.","type":"java.lang.String","required":false,"order":2,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"port","displayName":"Port","helpMessage":"&lt;b&gt;TCP Port&lt;/b&gt;&lt;br&gt;Enter the port number the database server is listening on.","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"statusColumn","displayName":"Status Column","helpMessage":"&lt;b&gt;Status Column&lt;/b&gt;&lt;br&gt;Enter the name of the column in the table that will hold the status values. If empty enabled and
  disabled operation wont be performed.","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"pwdEncodeToUpperCase","displayName":"Force password encoding to upper case","helpMessage":"Force password encoding to upper case.","type":"boolean","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":["false"]},{"schema":{"name":"enableEmptyString","displayName":"Enable writing empty string","helpMessage":"&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.","type":"boolean","required":false,"order":16,"confidential":false,"defaultValues":null},"overridable":false,"
 values":["false"]},{"schema":{"name":"database","displayName":"Database","helpMessage":"&lt;b&gt;Database&lt;/b&gt;&lt;br&gt;Enter the name of the database on the database server that contains the table.","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"defaultStatusValue","displayName":"Default Status Value","helpMessage":"&lt;b&gt;Default Status Value&lt;/b&gt;&lt;br&gt;Enter the value for status in case of status not specified.","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"table","displayName":"Table","helpMessage":"&lt;b&gt;Table&lt;/b&gt;&lt;br&gt;Enter the name of the table in the database that contains the accounts.","type":"java.lang.String","required":true,"order":7,"confidential":false,"defaultValues":null},"overridable":false,"values":["testsync"]},{"schema":{"name":"disab
 ledStatusValue","displayName":"Disabled Status Value","helpMessage":"&lt;b&gt;Disabled Status Value&lt;/b&gt;&lt;br&gt;Enter the value for disabled status.","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"jdbcDriver","displayName":"JDBC Driver","helpMessage":"&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br&gt;Could be empty if datasource is provided.","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":null},"overridable":false,"values":["org.h2.Driver"]},{"schema":{"name":"quoting","displayName":"Name Quoting","helpMessage":"&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selec
 tions (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.","type":"java.lang.String","required":false,"order":1,"confidential":false,"defaultValues":null},"overridable":false,"values":[]},{"schema":{"name":"cipherKey","displayName":"Password cipher key","helpMessage":"Specify key in case of reversible algorithm.","type":"java.lang.String","required":false,"order":25,"confidential":false,"defaultValues":null},"overridable":false,"values":[]}]'/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_CREATE"/>
@@ -556,6 +568,17 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="107" capability="TWO_PHASES_DELETE"/>
   <ConnInstance_capabilities ConnInstance_id="107" capability="SEARCH"/>
   
+  <ConnInstance id="108" bundleName="net.tirasa.connid.bundles.db.scriptedsql" 
+                location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}"
+                connectorName="net.tirasa.connid.bundles.db.scriptedsql.ScriptedSQLConnector"
+                displayName="Scripted SQL" version="${connid.database.version}"
+                jsonConf='[{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScriptFileName&quot;,&quot;displayName&quot;:&quot;updateScriptFileName&quot;,&quot;helpMessage&quot;:&quot;updateScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/UpdateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScript&quot;,&quot;displayName&quot;:&quot;testScript&quot;,&quot;helpMessage&quot;:&quot;testScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;host&quot;,&quot;displayName&quot;:&quot;Host&quot;,&quot;helpMessage&quot;:&quot;&lt;b
 &gt;Host&lt;/b&gt;&lt;br/&gt;Enter the name of the host where the database is running.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:2,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;localhost&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;port&quot;,&quot;displayName&quot;:&quot;Port&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;TCP Port&lt;/b&gt;&lt;br/&gt;Enter the port number the database server is listening on.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:3,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;3306&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;database&quot;,&quot;displayName&quot;:&quot;Database&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Database&lt;/b&gt;&lt;br/&gt;Enter the name of the database on the database server that contains the table.&quot;,&quot;type&
 quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:6,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false},{&quot;schema&quot;:{&quot;name&quot;:&quot;createScript&quot;,&quot;displayName&quot;:&quot;createScript&quot;,&quot;helpMessage&quot;:&quot;createScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcUrlTemplate&quot;,&quot;displayName&quot;:&quot;JDBC Connection URL&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Connection URL&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver Connection URL.&lt;br/&gt; Oracle template is jdbc:oracle:thin:@[host]:[port(1521)]:[DB].&lt;br/&gt;  MySQL template is jdbc:mysql://[host]:[port(3306)]/[db], for more info, read the JDBC driver documentati
 on.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:11,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;jdbc:mysql://%h:%p/%d&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.url}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jndiProperties&quot;,&quot;displayName&quot;:&quot;Initial JNDI Properties&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Initial JNDI Properties&lt;/b&gt;&lt;br/&gt;Could be empty or enter the JDBC JNDI Initial context factory, context provider in a format: key = value.&quot;,&quot;type&quot;:&quot;[Ljava.lang.String;&quot;,&quot;required&quot;:false,&quot;order&quot;:21,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;enableEmptyString&quot;,&quot;displayName&quot;:&quot;Enable writing empty string&quot;,&quot;
 helpMessage&quot;:&quot;&lt;b&gt;Enable writing empty string&lt;/b&gt;&lt;br/&gt;Select to enable support for writing an empty strings, instead of a NULL value, in character based columns defined as not-null in the table schema. This option does not influence the way strings are written for Oracle based tables. By default empty strings are written as a NULL value.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:12,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;allNative&quot;,&quot;displayName&quot;:&quot;All native&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;All native&lt;/b&gt;&lt;br/&gt;Select to retrieve all data type of the columns in a native format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:16,&quot;confidential&quot;:false,&quot;defaul
 tValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;password&quot;,&quot;displayName&quot;:&quot;User Password&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User Password&lt;/b&gt;&lt;br/&gt;Enter a user account that has permission to access accounts table.&quot;,&quot;type&quot;:&quot;org.identityconnectors.common.security.GuardedString&quot;,&quot;required&quot;:false,&quot;order&quot;:5,&quot;confidential&quot;:true,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.password}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;validConnectionQuery&quot;,&quot;displayName&quot;:&quot;Validate Connection Query&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Validate Connection Query&lt;/b&gt;&lt;br/&gt;There can be specified the check connection alive query. If empty, default implementation will test it using the switch on/off the autocommit. Some select 1 from dummy tab
 le could be more efficient.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:17,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;reloadScriptOnExecution&quot;,&quot;displayName&quot;:&quot;reloadScriptOnExecution&quot;,&quot;helpMessage&quot;:&quot;reloadScriptOnExecution&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;true&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;schemaScriptFileName&quot;,&quot;displayName&quot;:&quot;schemaScriptFileName&quot;,&quot;helpMessage&quot;:&quot;schemaScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&qu
 ot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SchemaScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;jdbcDriver&quot;,&quot;displayName&quot;:&quot;JDBC Driver&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Driver&lt;/b&gt;&lt;br/&gt;Specify the JDBC Driver class name. Oracle is oracle.jdbc.driver.OracleDriver. MySQL is org.gjt.mm.mysql.Driver.&lt;br/&gt;Could be empty if datasource is provided.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:10,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;com.mysql.jdbc.Driver&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.driver}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;testScriptFileName&quot;,&quot;displayName&quot;:&quot;testScriptFileName&quot;,&quot;helpMessage&quot;:&quot;testScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&qu
 ot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/TestScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;quoting&quot;,&quot;displayName&quot;:&quot;Name Quoting&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;Name Quoting&lt;/b&gt;&lt;br/&gt;Select whether database column names for this resource should be quoted, and the quoting characters. By default, database column names are not quoted (None). For other selections (Single, Double, Back, or Brackets), column names will appear between single quotes, double quotes, back quotes, or brackets in the SQL generated to access the database.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:-1,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quo
 t;createScriptFileName&quot;,&quot;displayName&quot;:&quot;createScriptFileName&quot;,&quot;helpMessage&quot;:&quot;createScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/CreateScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;clearTextPasswordToScript&quot;,&quot;displayName&quot;:&quot;clearTextPasswordToScript&quot;,&quot;helpMessage&quot;:&quot;clearTextPasswordToScript&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;false&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;nativeTimestamps&quot;,&quot;displayName&quot;:&quot;Native Timestamps&quot;,&quot;helpMessage&quot;:&quot;&lt;
 b&gt;Native Timestamps&lt;/b&gt;&lt;br/&gt;Select to retrieve Timestamp data type of the columns in java.sql.Timestamp format from the database table.&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:15,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[false]},&quot;overridable&quot;:false,&quot;values&quot;:[false]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScript&quot;,&quot;displayName&quot;:&quot;syncScript&quot;,&quot;helpMessage&quot;:&quot;syncScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;autoCommit&quot;,&quot;displayName&quot;:&quot;autoCommit&quot;,&quot;helpMessage&quot;:&quot;autoCommit&quot;,&quot;type&quot;:&quot;boolean&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential
 &quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;scriptingLanguage&quot;,&quot;displayName&quot;:&quot;scriptingLanguage&quot;,&quot;helpMessage&quot;:&quot;scriptingLanguage&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;GROOVY&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;GROOVY&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;datasource&quot;,&quot;displayName&quot;:&quot;Datasource Path&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;JDBC Data Source Name/Path&lt;/b&gt;&lt;br/&gt;Enter the JDBC Data Source Name/Path to connect to the Oracle server. If specified, connector will only try to connect using Datasource and ignore other resource parameters specified.&lt;br/&gt;the example value is: &lt;CODE&gt;jdbc/SampleDataSourceName&lt;/CODE&gt;&quot;,&q
 uot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:20,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScript&quot;,&quot;displayName&quot;:&quot;deleteScript&quot;,&quot;helpMessage&quot;:&quot;deleteScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;rethrowAllSQLExceptions&quot;,&quot;displayName&quot;:&quot;Rethrow all SQLExceptions&quot;,&quot;helpMessage&quot;:&quot;If this is not checked, SQL statements which throw SQLExceptions with a 0 ErrorCode will be have the exception caught and suppressed. Check it to have exceptions with 0 ErrorCodes rethrown.&quot;,&quot;type&quot;:&quot;boolean&quot;,
 &quot;required&quot;:false,&quot;order&quot;:14,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[true]},&quot;overridable&quot;:false,&quot;values&quot;:[true]},{&quot;schema&quot;:{&quot;name&quot;:&quot;syncScriptFileName&quot;,&quot;displayName&quot;:&quot;syncScriptFileName&quot;,&quot;helpMessage&quot;:&quot;syncScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SyncScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;updateScript&quot;,&quot;displayName&quot;:&quot;updateScript&quot;,&quot;helpMessage&quot;:&quot;updateScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&q
 uot;:[]},{&quot;schema&quot;:{&quot;name&quot;:&quot;user&quot;,&quot;displayName&quot;:&quot;User&quot;,&quot;helpMessage&quot;:&quot;&lt;b&gt;User&lt;/b&gt;&lt;br/&gt;Enter the name of the mandatory Database user with permission to account table.&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:4,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${testdb.username}&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;deleteScriptFileName&quot;,&quot;displayName&quot;:&quot;deleteScriptFileName&quot;,&quot;helpMessage&quot;:&quot;deleteScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:false,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/DeleteScript.groovy&quot;]},{&quot;schema&quot;:{&quot;n
 ame&quot;:&quot;searchScriptFileName&quot;,&quot;displayName&quot;:&quot;searchScriptFileName&quot;,&quot;helpMessage&quot;:&quot;searchScriptFileName&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[]},&quot;overridable&quot;:true,&quot;values&quot;:[&quot;${basedir}/src/main/resources/scriptedsql/SearchScript.groovy&quot;]},{&quot;schema&quot;:{&quot;name&quot;:&quot;searchScript&quot;,&quot;displayName&quot;:&quot;searchScript&quot;,&quot;helpMessage&quot;:&quot;searchScript&quot;,&quot;type&quot;:&quot;java.lang.String&quot;,&quot;required&quot;:false,&quot;order&quot;:0,&quot;confidential&quot;:false,&quot;defaultValues&quot;:[&quot;&quot;]},&quot;overridable&quot;:false,&quot;values&quot;:[]}]'/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_CREATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_UPDATE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="ONE_PHASE_DELETE"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SEARCH"/>
+  <ConnInstance_capabilities ConnInstance_id="108" capability="SYNC"/>
+  
   <ExternalResource name="ws-target-resource-1" connector_id="100"
                     randomPwdIfNotProvided="0" enforceMandatoryCondition="0" propagationMode="TWO_PHASES"
                     propagationPriority="0" propagationPrimary="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
@@ -657,6 +680,13 @@ under the License.
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
 
+  <ExternalResource name="resource-db-scripted" connector_id="108"
+                    randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" syncTraceLevel="ALL" updateTraceLevel="ALL"
+                    enforceMandatoryCondition="0"
+                    propagationMode="ONE_PHASE" propagationPrimary="0" propagationPriority="0"
+                    creator="admin" lastModifier="admin" 
+                    creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
+
   <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) -->
   <Policy_ExternalResource accountPolicy_id="5" resource_name="resource-testdb"/>
     
@@ -817,7 +847,7 @@ under the License.
                intAttrName="rderToBePropagated" intMappingType="GroupDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
   <MappingItem id="209" extAttrName="membership" mapping_id="9"
-               intAttrName="mderToBePropagated" intMappingType="AnyDerivedSchema" mandatoryCondition="false"
+               intAttrName="mderToBePropagated" intMappingType="AnyObjectDerivedSchema" mandatoryCondition="false"
                connObjectKey="0" password="0" purpose="PROPAGATION"/>
                          
   <Provision id="10" resource_name="ws-target-resource-update-resetsynctoken" anyType_name="USER" objectClass="__ACCOUNT__"
@@ -924,7 +954,16 @@ under the License.
   <MappingItem id="334" mapping_id="19" extAttrName="userId" 
                intMappingType="Username" mandatoryCondition="true"
                connObjectKey="1" password="0" purpose="PROPAGATION"/>
-  
+
+  <Provision id="21" resource_name="resource-db-scripted" anyType_name="PRINTER" objectClass="__PRINTER__"/>
+  <Mapping id="21" provision_id="21"/>
+  <MappingItem id="405" mapping_id="21" extAttrName="id" 
+               intMappingType="AnyObjectKey" mandatoryCondition="true"
+               connObjectKey="1" password="0" purpose="BOTH"/>
+  <MappingItem id="406" mapping_id="21" extAttrName="location" 
+               intAttrName="location" intMappingType="AnyObjectPlainSchema"
+               mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/>
+    
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="1" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
         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"]}]'/>
@@ -1055,6 +1094,9 @@ under the License.
   <Task DTYPE="PropagationTask" type="PROPAGATION" id="27" propagationMode="ONE_PHASE" propagationOperation="CREATE"
         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"]}]'/>
+  <Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="28" name="Scripted SQL" resource_name="resource-db-scripted"
+        destinationRealm_id="1" performCreate="1" performUpdate="1" performDelete="1" syncStatus="0" fullReconciliation="0"
+        jobClassName="org.apache.syncope.core.provisioning.api.job.SyncJob" unmatchingRule="PROVISION" matchingRule="UPDATE"/>
 
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" selfAsRecipient="1" 
                 sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 cc49d62..e23143a 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
@@ -67,9 +67,6 @@ import org.springframework.util.ClassUtils;
 
 public class ConnectorFacadeProxy implements Connector {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ConnectorFacadeProxy.class);
 
     /**
@@ -138,7 +135,7 @@ public class ConnectorFacadeProxy implements Connector {
         Uid result = null;
 
         if (activeConnInstance.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)) {
-            final Future<Uid> future = asyncFacade.authenticate(
+            Future<Uid> future = asyncFacade.authenticate(
                     connector, username, new GuardedString(password.toCharArray()), options);
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -173,7 +170,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("create");
 
-            final Future<Uid> future = asyncFacade.create(connector, objectClass, attrs, options);
+            Future<Uid> future = asyncFacade.create(connector, objectClass, attrs, options);
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
             } catch (java.util.concurrent.TimeoutException e) {
@@ -207,7 +204,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("update");
 
-            final Future<Uid> future = asyncFacade.update(connector, objectClass, uid, attrs, options);
+            Future<Uid> future = asyncFacade.update(connector, objectClass, uid, attrs, options);
 
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -241,7 +238,7 @@ public class ConnectorFacadeProxy implements Connector {
 
             propagationAttempted.add("delete");
 
-            final Future<Uid> future = asyncFacade.delete(connector, objectClass, uid, options);
+            Future<Uid> future = asyncFacade.delete(connector, objectClass, uid, options);
 
             try {
                 future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -279,7 +276,7 @@ public class ConnectorFacadeProxy implements Connector {
         SyncToken result = null;
 
         if (activeConnInstance.getCapabilities().contains(ConnectorCapability.SYNC)) {
-            final Future<SyncToken> future = asyncFacade.getLatestSyncToken(connector, objectClass);
+            Future<SyncToken> future = asyncFacade.getLatestSyncToken(connector, objectClass);
 
             try {
                 result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
@@ -350,7 +347,9 @@ public class ConnectorFacadeProxy implements Connector {
         try {
             return future == null ? null : future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
-            future.cancel(true);
+            if (future != null) {
+                future.cancel(true);
+            }
             throw new TimeoutException("Request timeout");
         } catch (Exception e) {
             LOG.error("Connector request execution failure", e);
@@ -363,8 +362,8 @@ public class ConnectorFacadeProxy implements Connector {
     }
 
     @Override
-    public List<ConnectorObject> search(final ObjectClass objectClass, final Filter filter,
-            final OperationOptions options) {
+    public List<ConnectorObject> search(
+            final ObjectClass objectClass, final Filter filter, final OperationOptions options) {
 
         final List<ConnectorObject> result = new ArrayList<>();
 
@@ -401,8 +400,8 @@ public class ConnectorFacadeProxy implements Connector {
     public Attribute getObjectAttribute(final ObjectClass objectClass, final Uid uid, final OperationOptions options,
             final String attributeName) {
 
-        final Future<Attribute> future = asyncFacade.getObjectAttribute(connector, objectClass, uid, options,
-                attributeName);
+        Future<Attribute> future = asyncFacade.getObjectAttribute(
+                connector, objectClass, uid, options, attributeName);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -422,7 +421,7 @@ public class ConnectorFacadeProxy implements Connector {
     public Set<Attribute> getObjectAttributes(final ObjectClass objectClass, final Uid uid,
             final OperationOptions options) {
 
-        final Future<Set<Attribute>> future = asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
+        Future<Set<Attribute>> future = asyncFacade.getObjectAttributes(connector, objectClass, uid, options);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -440,7 +439,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<String> getSchemaNames(final boolean includeSpecial) {
-        final Future<Set<String>> future = asyncFacade.getSchemaNames(connector, includeSpecial);
+        Future<Set<String>> future = asyncFacade.getSchemaNames(connector, includeSpecial);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -458,7 +457,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public Set<ObjectClass> getSupportedObjectClasses() {
-        final Future<Set<ObjectClass>> future = asyncFacade.getSupportedObjectClasses(connector);
+        Future<Set<ObjectClass>> future = asyncFacade.getSupportedObjectClasses(connector);
         try {
             return future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -476,7 +475,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void validate() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {
@@ -494,7 +493,7 @@ public class ConnectorFacadeProxy implements Connector {
 
     @Override
     public void test() {
-        final Future<String> future = asyncFacade.test(connector);
+        Future<String> future = asyncFacade.test(connector);
         try {
             future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
         } catch (java.util.concurrent.TimeoutException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index 888329c..b43e911 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -282,7 +282,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
                 ? IntMappingType.UserVirtualSchema
                 : any.getType().getKind() == AnyTypeKind.GROUP
                         ? IntMappingType.GroupVirtualSchema
-                        : IntMappingType.AnyVirtualSchema;
+                        : IntMappingType.AnyObjectVirtualSchema;
 
         Map<String, ConnectorObject> resources = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 90f5e91..92a9bd3 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -93,7 +93,7 @@ abstract class AbstractAnyDataBinder {
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class);
 
     private static final IntMappingType[] FOR_MANDATORY = new IntMappingType[] {
-        IntMappingType.AnyPlainSchema, IntMappingType.AnyDerivedSchema,
+        IntMappingType.AnyObjectPlainSchema, IntMappingType.AnyObjectDerivedSchema,
         IntMappingType.UserPlainSchema, IntMappingType.UserDerivedSchema,
         IntMappingType.GroupPlainSchema, IntMappingType.GroupDerivedSchema };
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index 462a488..237792b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -33,14 +33,18 @@ import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 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.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -53,6 +57,9 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
         "plainAttrs", "derAttrs", "virAttrs", "resources"
     };
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
     @Transactional(readOnly = true)
     @Override
     public AnyObjectTO getAnyObjectTO(final Long key) {
@@ -62,6 +69,7 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
     @Override
     public AnyObjectTO getAnyObjectTO(final AnyObject anyObject) {
         AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setType(anyObject.getType().getKey());
 
         BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES);
 
@@ -103,6 +111,14 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
 
     @Override
     public void create(final AnyObject anyObject, final AnyObjectTO anyObjectTO) {
+        AnyType type = anyTypeDAO.find(anyObjectTO.getType());
+        if (type == null) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add(anyObjectTO.getType());
+            throw sce;
+        }
+        anyObject.setType(type);
+
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
         // relationships

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 59f8994..a73f5b9 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
@@ -70,6 +70,7 @@ public class PropagationManagerImpl implements PropagationManager {
 
     protected static final Logger LOG = LoggerFactory.getLogger(PropagationManager.class);
 
+    @Autowired
     protected AnyObjectDAO anyObjectDAO;
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 479d342..c52c3cf 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
@@ -29,14 +29,12 @@ 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;
@@ -133,8 +131,8 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
             }
         }
 
-        try {
-            for (Provision provision : syncTask.getResource().getProvisions()) {
+        for (Provision provision : syncTask.getResource().getProvisions()) {
+            if (provision.getMapping() != null) {
                 SyncResultsHandler handler;
                 switch (provision.getAnyType().getKind()) {
                     case USER:
@@ -150,37 +148,32 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
                         handler = ahandler;
                 }
 
-                SyncToken latestSyncToken = null;
-                if (provision.getMapping() != null && !syncTask.isFullReconciliation()) {
-                    latestSyncToken = connector.getLatestSyncToken(ObjectClass.ACCOUNT);
-                }
+                try {
+                    SyncToken latestSyncToken = null;
+                    if (!syncTask.isFullReconciliation()) {
+                        latestSyncToken = connector.getLatestSyncToken(provision.getObjectClass());
+                    }
 
-                if (syncTask.isFullReconciliation()) {
-                    if (provision.getMapping() != null) {
+                    if (syncTask.isFullReconciliation()) {
                         connector.getAllObjects(provision.getObjectClass(), handler,
                                 connector.getOperationOptions(provision.getMapping().getItems()));
-                    }
-                } else {
-                    if (provision.getMapping() != null) {
+                    } else {
                         connector.sync(provision.getObjectClass(), provision.getSyncToken(), handler,
                                 connector.getOperationOptions(provision.getMapping().getItems()));
                     }
-                }
 
-                if (!dryRun && !syncTask.isFullReconciliation()) {
-                    try {
-                        ExternalResource resource = resourceDAO.find(syncTask.getResource().getKey());
-                        if (provision.getMapping() != null) {
+                    if (!dryRun && !syncTask.isFullReconciliation()) {
+                        try {
                             provision.setSyncToken(latestSyncToken);
+                            resourceDAO.save(provision.getResource());
+                        } 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) {
+                    throw new JobExecutionException("While syncing on connector", t);
                 }
             }
-        } catch (Throwable t) {
-            throw new JobExecutionException("While syncing on connector", t);
         }
 
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 14c94f70..c3d11a9 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
@@ -167,7 +167,7 @@ public class SyncUtils {
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 PlainAttrValue value = anyUtils.newPlainAttrValue();
 
                 PlainSchema schema = plainSchemaDAO.find(connObjectKeyItem.getIntAttrName());
@@ -191,7 +191,7 @@ public class SyncUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case AnyDerivedSchema:
+            case AnyObjectDerivedSchema:
                 anys = getAnyDAO(connObjectKeyItem).findByDerAttrValue(connObjectKeyItem.getIntAttrName(), uid);
                 for (Any<?, ?, ?> any : anys) {
                     result.add(any.getKey());
@@ -200,7 +200,7 @@ public class SyncUtils {
 
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 Any<?, ?, ?> any = getAnyDAO(connObjectKeyItem).find(Long.parseLong(uid));
                 if (any != null) {
                     result.add(any.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
new file mode 100644
index 0000000..7cf4a08
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.rest.cxf.service;
+
+import static org.apache.syncope.core.rest.cxf.service.AbstractServiceImpl.LOG;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+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.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+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.AnyService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+
+public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
+        extends AbstractServiceImpl
+        implements AnyService<TO, MOD> {
+
+    protected abstract AbstractAnyLogic<TO, MOD> getAnyLogic();
+
+    @Override
+    public TO read(final Long key) {
+        return getAnyLogic().read(key);
+    }
+
+    @Override
+    public PagedResult<TO> list(final AnyListQuery listQuery) {
+        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                getAnyLogic().list(
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+
+    @Override
+    public PagedResult<TO> search(final AnySearchQuery searchQuery) {
+        CollectionUtils.transform(searchQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        SearchCond cond = getSearchCond(searchQuery.getFiql());
+        return buildPagedResult(
+                getAnyLogic().search(
+                        cond,
+                        searchQuery.getPage(),
+                        searchQuery.getSize(),
+                        getOrderByClauses(searchQuery.getOrderBy()),
+                        searchQuery.getRealms()),
+                searchQuery.getPage(),
+                searchQuery.getSize(),
+                getAnyLogic().searchCount(cond, searchQuery.getRealms()));
+    }
+
+    @Override
+    public Response create(final TO anyTO) {
+        TO created = getAnyLogic().create(anyTO);
+        return createResponse(created.getKey(), created);
+    }
+
+    @Override
+    public Response update(final Long key, final MOD anyMod) {
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        anyMod.setKey(key);
+        TO updated = getAnyLogic().update(anyMod);
+        return modificationResponse(updated);
+    }
+
+    @Override
+    public Response delete(final Long key) {
+        TO group = getAnyLogic().read(key);
+
+        checkETag(group.getETagValue());
+
+        TO deleted = getAnyLogic().delete(key);
+        return modificationResponse(deleted);
+    }
+
+    @Override
+    public Response bulkDeassociation(
+            final Long key, final ResourceDeassociationActionType type, final List<ResourceKey> resourceNames) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case UNLINK:
+                updated = getAnyLogic().unlink(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case UNASSIGN:
+                updated = getAnyLogic().unassign(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            case DEPROVISION:
+                updated = getAnyLogic().deprovision(key, CollectionWrapper.unwrap(resourceNames));
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceDeassociationActionType.UNLINK) {
+            for (ResourceKey resourceName : resourceNames) {
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public Response bulkAssociation(
+            final Long key, final ResourceAssociationActionType type, final ResourceAssociationMod associationMod) {
+
+        TO any = getAnyLogic().read(key);
+
+        checkETag(any.getETagValue());
+
+        TO updated;
+        switch (type) {
+            case LINK:
+                updated = getAnyLogic().link(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()));
+                break;
+
+            case ASSIGN:
+                updated = getAnyLogic().assign(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            case PROVISION:
+                updated = getAnyLogic().provision(
+                        key,
+                        CollectionWrapper.unwrap(associationMod.getTargetResources()),
+                        associationMod.isChangePwd(),
+                        associationMod.getPassword());
+                break;
+
+            default:
+                updated = getAnyLogic().read(key);
+        }
+
+        BulkActionResult result = new BulkActionResult();
+
+        if (type == ResourceAssociationActionType.LINK) {
+            for (ResourceKey resourceName : associationMod.getTargetResources()) {
+                result.getResults().put(resourceName.getElement(),
+                        updated.getResources().contains(resourceName.getElement())
+                                ? BulkActionResult.Status.FAILURE
+                                : BulkActionResult.Status.SUCCESS);
+            }
+        } else {
+            for (PropagationStatus propagationStatusTO : updated.getPropagationStatusTOs()) {
+                result.getResults().put(propagationStatusTO.getResource(),
+                        BulkActionResult.Status.valueOf(propagationStatusTO.getStatus().toString()));
+            }
+        }
+
+        return modificationResponse(result);
+    }
+
+    @Override
+    public BulkActionResult bulk(final BulkAction bulkAction) {
+        AbstractAnyLogic<TO, MOD> logic = getAnyLogic();
+
+        BulkActionResult result = new BulkActionResult();
+
+        switch (bulkAction.getOperation()) {
+            case DELETE:
+                for (String key : bulkAction.getTargets()) {
+                    try {
+                        result.getResults().put(
+                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing delete for user {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            case SUSPEND:
+                if (logic instanceof UserLogic) {
+                    for (String key : bulkAction.getTargets()) {
+                        StatusMod statusMod = new StatusMod();
+                        statusMod.setKey(Long.valueOf(key));
+                        statusMod.setType(StatusMod.ModType.SUSPEND);
+                        try {
+                            result.getResults().put(
+                                    String.valueOf(((UserLogic) logic).status(statusMod).getKey()),
+                                    BulkActionResult.Status.SUCCESS);
+                        } catch (Exception e) {
+                            LOG.error("Error performing suspend for user {}", key, e);
+                            result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                        }
+                    }
+                }
+                break;
+
+            case REACTIVATE:
+                for (String key : bulkAction.getTargets()) {
+                    StatusMod statusMod = new StatusMod();
+                    statusMod.setKey(Long.valueOf(key));
+                    statusMod.setType(StatusMod.ModType.REACTIVATE);
+                    try {
+                        result.getResults().put(
+                                String.valueOf(((UserLogic) logic).status(statusMod).getKey()),
+                                BulkActionResult.Status.SUCCESS);
+                    } catch (Exception e) {
+                        LOG.error("Error performing reactivate for user {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
+                    }
+                }
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.java
new file mode 100644
index 0000000..ce6390a
--- /dev/null
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyObjectServiceImpl.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.core.rest.cxf.service;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.service.AnyObjectService;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.AnyObjectLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AnyObjectServiceImpl extends AbstractAnyService<AnyObjectTO, AnyObjectMod> implements AnyObjectService {
+
+    @Autowired
+    private AnyObjectLogic logic;
+
+    @Override
+    protected AbstractAnyLogic<AnyObjectTO, AnyObjectMod> getAnyLogic() {
+        return logic;
+    }
+
+    @Override
+    public PagedResult<AnyObjectTO> list(final String type, final AnyListQuery listQuery) {
+        if (StringUtils.isBlank(type)) {
+            return super.list(listQuery);
+        }
+
+        CollectionUtils.transform(listQuery.getRealms(), new Transformer<String, String>() {
+
+            @Override
+            public String transform(final String input) {
+                return StringUtils.prependIfMissing(input, SyncopeConstants.ROOT_REALM);
+            }
+        });
+
+        return buildPagedResult(
+                logic.list(
+                        type,
+                        listQuery.getPage(),
+                        listQuery.getSize(),
+                        getOrderByClauses(listQuery.getOrderBy()),
+                        listQuery.getRealms()),
+                listQuery.getPage(),
+                listQuery.getSize(),
+                getAnyLogic().count(listQuery.getRealms()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index bd24f22..d80caf9 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -27,11 +27,12 @@ import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.wrap.BooleanWrap;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.core.logic.ConnectorLogic;
@@ -87,17 +88,12 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final Long key,
+    public List<ConnIdObjectClass> getSupportedObjectClasses(final Long key,
             final ConnInstanceTO connInstanceTO) {
 
         connInstanceTO.setKey(key);
 
-        List<String> objectClasses = logic.getSupportedObjectClasses(connInstanceTO);
-        List<ConnIdObjectClassTO> result = new ArrayList<>(objectClasses.size());
-        for (String objectClass : objectClasses) {
-            result.add(new ConnIdObjectClassTO(objectClass));
-        }
-        return result;
+        return CollectionWrapper.wrap(logic.getSupportedObjectClasses(connInstanceTO), ConnIdObjectClass.class);
     }
 
     @Override


[70/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
[SYNCOPE-666] All done now


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

Branch: refs/heads/master
Commit: d8927ef4c3943a5a1dec1c17985a32fc9bfbae50
Parents: df60b3b
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Jun 11 16:04:23 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Jun 11 16:04:23 2015 +0200

----------------------------------------------------------------------
 .../syncope/common/lib/to/MembershipTO.java     |  16 +-
 .../syncope/common/lib/to/RelationshipTO.java   |  10 +
 .../common/lib/to/RelationshipTypeTO.java       |  53 ++
 .../common/lib/types/ClientExceptionType.java   |   1 +
 .../syncope/common/lib/types/Entitlement.java   |  10 +
 .../api/service/RelationshipTypeService.java    |  96 ++++
 .../core/logic/RelationshipTypeLogic.java       | 134 +++++
 .../api/dao/RelationshipTypeDAO.java            |  33 ++
 .../core/persistence/api/entity/Membership.java |   3 +
 .../persistence/api/entity/MembershipType.java  |  53 ++
 .../persistence/api/entity/Relationship.java    |   4 +
 .../api/entity/RelationshipType.java            |  28 +
 .../api/entity/anyobject/AnyObject.java         |   3 +
 .../api/entity/resource/ExternalResource.java   |   2 +-
 .../core/persistence/api/entity/user/User.java  |   3 +
 .../jpa/dao/JPARelationshipTypeDAO.java         |  95 ++++
 .../jpa/entity/JPAEntityFactory.java            |   3 +
 .../jpa/entity/JPARelationshipType.java         |  62 +++
 .../jpa/entity/anyobject/JPAAMembership.java    |  12 +
 .../jpa/entity/anyobject/JPAARelationship.java  |  25 +-
 .../jpa/entity/anyobject/JPAAnyObject.java      |  12 +
 .../jpa/entity/user/JPAUMembership.java         |  12 +
 .../jpa/entity/user/JPAURelationship.java       |  25 +-
 .../persistence/jpa/entity/user/JPAUser.java    |  12 +
 .../validation/entity/AbstractValidator.java    |   3 -
 .../entity/RelationshipTypeCheck.java           |  41 ++
 .../entity/RelationshipTypeValidator.java       |  41 ++
 .../persistence/jpa/entity/AnyObjectTest.java   |  85 ---
 .../persistence/jpa/entity/AnySearchTest.java   | 520 -------------------
 .../jpa/entity/AnyTypeClassTest.java            |  81 ---
 .../persistence/jpa/entity/AnyTypeTest.java     | 114 ----
 .../core/persistence/jpa/entity/ConfTest.java   | 119 -----
 .../jpa/entity/ConnInstanceTest.java            | 145 ------
 .../persistence/jpa/entity/DerAttrTest.java     | 220 --------
 .../persistence/jpa/entity/DerSchemaTest.java   | 100 ----
 .../core/persistence/jpa/entity/GroupTest.java  |  76 ---
 .../jpa/entity/NotificationTest.java            | 149 ------
 .../persistence/jpa/entity/PlainAttrTest.java   | 237 ---------
 .../persistence/jpa/entity/PlainSchemaTest.java | 152 ------
 .../core/persistence/jpa/entity/PolicyTest.java | 143 -----
 .../core/persistence/jpa/entity/RealmTest.java  | 178 -------
 .../core/persistence/jpa/entity/ReportTest.java |  83 ---
 .../persistence/jpa/entity/ResourceTest.java    | 372 -------------
 .../core/persistence/jpa/entity/RoleTest.java   |  89 ----
 .../jpa/entity/SecurityQuestionTest.java        |  68 ---
 .../persistence/jpa/entity/TaskExecTest.java    |  94 ----
 .../core/persistence/jpa/entity/TaskTest.java   | 117 -----
 .../core/persistence/jpa/entity/UserTest.java   | 241 ---------
 .../persistence/jpa/entity/VirAttrTest.java     | 118 -----
 .../persistence/jpa/entity/VirSchemaTest.java   |  99 ----
 .../persistence/jpa/inner/AnyObjectTest.java    |  85 +++
 .../persistence/jpa/inner/AnySearchTest.java    | 520 +++++++++++++++++++
 .../persistence/jpa/inner/AnyTypeClassTest.java |  81 +++
 .../core/persistence/jpa/inner/AnyTypeTest.java | 114 ++++
 .../core/persistence/jpa/inner/ConfTest.java    | 119 +++++
 .../persistence/jpa/inner/ConnInstanceTest.java | 145 ++++++
 .../core/persistence/jpa/inner/DerAttrTest.java | 220 ++++++++
 .../persistence/jpa/inner/DerSchemaTest.java    | 100 ++++
 .../core/persistence/jpa/inner/GroupTest.java   |  76 +++
 .../persistence/jpa/inner/NotificationTest.java | 149 ++++++
 .../persistence/jpa/inner/PlainAttrTest.java    | 237 +++++++++
 .../persistence/jpa/inner/PlainSchemaTest.java  | 152 ++++++
 .../core/persistence/jpa/inner/PolicyTest.java  | 143 +++++
 .../core/persistence/jpa/inner/RealmTest.java   | 178 +++++++
 .../jpa/inner/RelationshipTypeTest.java         | 104 ++++
 .../core/persistence/jpa/inner/ReportTest.java  |  83 +++
 .../persistence/jpa/inner/ResourceTest.java     | 372 +++++++++++++
 .../core/persistence/jpa/inner/RoleTest.java    |  89 ++++
 .../jpa/inner/SecurityQuestionTest.java         |  68 +++
 .../persistence/jpa/inner/TaskExecTest.java     |  94 ++++
 .../core/persistence/jpa/inner/TaskTest.java    | 117 +++++
 .../core/persistence/jpa/inner/UserTest.java    | 241 +++++++++
 .../core/persistence/jpa/inner/VirAttrTest.java | 118 +++++
 .../persistence/jpa/inner/VirSchemaTest.java    |  99 ++++
 .../persistence/jpa/outer/AnySearchTest.java    | 115 ++++
 .../persistence/jpa/outer/AnyTypeClassTest.java |  62 +++
 .../core/persistence/jpa/outer/AnyTypeTest.java |  61 +++
 .../persistence/jpa/outer/ConnInstanceTest.java | 103 ++++
 .../persistence/jpa/outer/DerSchemaTest.java    |  57 ++
 .../core/persistence/jpa/outer/GroupTest.java   | 328 ++++++++++++
 .../persistence/jpa/outer/PlainAttrTest.java    | 179 +++++++
 .../persistence/jpa/outer/PlainSchemaTest.java  | 170 ++++++
 .../core/persistence/jpa/outer/RealmTest.java   |  60 +++
 .../core/persistence/jpa/outer/ReportTest.java  | 120 +++++
 .../persistence/jpa/outer/ResourceTest.java     | 306 +++++++++++
 .../core/persistence/jpa/outer/RoleTest.java    | 167 ++++++
 .../jpa/outer/SecurityQuestionTest.java         |  61 +++
 .../core/persistence/jpa/outer/TaskTest.java    | 295 +++++++++++
 .../core/persistence/jpa/outer/UserTest.java    | 131 +++++
 .../jpa/relationship/AnySearchTest.java         | 115 ----
 .../jpa/relationship/AnyTypeClassTest.java      |  62 ---
 .../jpa/relationship/AnyTypeTest.java           |  61 ---
 .../jpa/relationship/ConnInstanceTest.java      | 103 ----
 .../jpa/relationship/DerSchemaTest.java         |  57 --
 .../persistence/jpa/relationship/GroupTest.java | 328 ------------
 .../jpa/relationship/PlainAttrTest.java         | 179 -------
 .../jpa/relationship/PlainSchemaTest.java       | 170 ------
 .../persistence/jpa/relationship/RealmTest.java |  60 ---
 .../jpa/relationship/ReportTest.java            | 120 -----
 .../jpa/relationship/ResourceTest.java          | 306 -----------
 .../persistence/jpa/relationship/RoleTest.java  | 167 ------
 .../jpa/relationship/SecurityQuestionTest.java  |  61 ---
 .../persistence/jpa/relationship/TaskTest.java  | 295 -----------
 .../persistence/jpa/relationship/UserTest.java  | 126 -----
 .../src/test/resources/content.xml              |   9 +-
 .../api/data/RelationshipTypeDataBinder.java    |  31 ++
 .../data/RelationshipTypeDataBinderImpl.java    |  64 +++
 .../service/RelationshipTypeServiceImpl.java    |  66 +++
 .../fit/core/reference/AbstractITCase.java      |   4 +
 .../core/reference/RelationshipTypeITCase.java  |  93 ++++
 110 files changed, 6966 insertions(+), 5822 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 ef70589..d535c34 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
@@ -30,9 +30,19 @@ public class MembershipTO extends RelationshipTO {
 
     private String groupName;
 
-    public MembershipTO() {
-        super();
-        super.setRightType(AnyTypeKind.GROUP.name());
+    @Override
+    public String getRelationshipType() {
+        return "Membership";
+    }
+
+    @Override
+    public void setRelationshipType(final String relationshipType) {
+        // ignore
+    }
+
+    @Override
+    public String getRightType() {
+        return AnyTypeKind.GROUP.name();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index d769719..6468dab 100644
--- 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
@@ -28,6 +28,8 @@ public class RelationshipTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 360672942026613929L;
 
+    private String relationshipType;
+
     private String leftType;
 
     private long leftKey;
@@ -36,6 +38,14 @@ public class RelationshipTO extends AbstractBaseBean {
 
     private long rightKey;
 
+    public String getRelationshipType() {
+        return relationshipType;
+    }
+
+    public void setRelationshipType(final String relationshipType) {
+        this.relationshipType = relationshipType;
+    }
+
     public String getLeftType() {
         return leftType;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
new file mode 100644
index 0000000..d1d72f7
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RelationshipTypeTO.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.ws.rs.Path;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "relationshipType")
+@XmlType
+public class RelationshipTypeTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -1884088415277925817L;
+
+    private String key;
+
+    private String description;
+
+    public String getKey() {
+        return key;
+    }
+
+    @Path("{key}")
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 8e96942..3fcef86 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -40,6 +40,7 @@ public enum ClientExceptionType {
     InvalidProvision(Response.Status.BAD_REQUEST),
     InvalidReport(Response.Status.BAD_REQUEST),
     InvalidReportExec(Response.Status.BAD_REQUEST),
+    InvalidRelationshipType(Response.Status.BAD_REQUEST),
     InvalidAnyType(Response.Status.BAD_REQUEST),
     InvalidAnyObject(Response.Status.BAD_REQUEST),
     InvalidGroup(Response.Status.BAD_REQUEST),

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 6ffe318..806aaa4 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
@@ -56,6 +56,16 @@ public final class Entitlement {
 
     public static final String ANYTYPE_DELETE = "ANYTYPE_DELETE";
 
+    public static final String RELATIONSHIPTYPE_LIST = "RELATIONSHIPTYPE_LIST";
+
+    public static final String RELATIONSHIPTYPE_CREATE = "RELATIONSHIPTYPE_CREATE";
+
+    public static final String RELATIONSHIPTYPE_READ = "RELATIONSHIPTYPE_READ";
+
+    public static final String RELATIONSHIPTYPE_UPDATE = "RELATIONSHIPTYPE_UPDATE";
+
+    public static final String RELATIONSHIPTYPE_DELETE = "RELATIONSHIPTYPE_DELETE";
+
     public static final String ROLE_LIST = "ROLE_LIST";
 
     public static final String ROLE_CREATE = "ROLE_CREATE";

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RelationshipTypeService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RelationshipTypeService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RelationshipTypeService.java
new file mode 100644
index 0000000..178bb6c
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RelationshipTypeService.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+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.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.RelationshipTypeTO;
+
+/**
+ * REST operations for relationship types.
+ */
+@Path("relationshipTypes")
+public interface RelationshipTypeService extends JAXRSService {
+
+    /**
+     * Returns a list of all relationshipTypes.
+     *
+     * @return list of all relationshipTypes.
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    List<RelationshipTypeTO> list();
+
+    /**
+     * Returns relationshipType with matching key.
+     *
+     * @param key relationshipType key to be read
+     * @return relationshipType with matching key
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    RelationshipTypeTO read(@NotNull @PathParam("key") String key);
+
+    /**
+     * Creates a new relationshipType.
+     *
+     * @param relationshipTypeTO relationshipType to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created relationshipType
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created relationshipType")
+    })
+    @POST
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull RelationshipTypeTO relationshipTypeTO);
+
+    /**
+     * Updates the relationshipType matching the provided key.
+     *
+     * @param relationshipTypeTO relationshipType to be stored
+     */
+    @PUT
+    @Path("{key}")
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    void update(@NotNull RelationshipTypeTO relationshipTypeTO);
+
+    /**
+     * Deletes the relationshipType matching the provided key.
+     *
+     * @param key relationshipType key to be deleted
+     */
+    @DELETE
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
new file mode 100644
index 0000000..7df2755
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/RelationshipTypeLogic.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF RELATIONSHIP
+ * 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.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.RelationshipTypeTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+import org.apache.syncope.core.provisioning.api.data.RelationshipTypeDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RelationshipTypeLogic extends AbstractTransactionalLogic<RelationshipTypeTO> {
+
+    @Autowired
+    private RelationshipTypeDataBinder binder;
+
+    @Autowired
+    private RelationshipTypeDAO relationshipTypeDAO;
+
+    @PreAuthorize("hasRole('" + Entitlement.RELATIONSHIPTYPE_READ + "')")
+    public RelationshipTypeTO read(final String key) {
+        RelationshipType relationshipType = relationshipTypeDAO.find(key);
+        if (relationshipType == null) {
+            LOG.error("Could not find relationshipType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        return binder.getRelationshipTypeTO(relationshipType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.RELATIONSHIPTYPE_LIST + "')")
+    public List<RelationshipTypeTO> list() {
+        return CollectionUtils.collect(relationshipTypeDAO.findAll(),
+                new Transformer<RelationshipType, RelationshipTypeTO>() {
+
+                    @Override
+                    public RelationshipTypeTO transform(final RelationshipType input) {
+                        return binder.getRelationshipTypeTO(input);
+                    }
+                }, new ArrayList<RelationshipTypeTO>());
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.RELATIONSHIPTYPE_CREATE + "')")
+    public RelationshipTypeTO create(final RelationshipTypeTO relationshipTypeTO) {
+        return binder.getRelationshipTypeTO(relationshipTypeDAO.save(binder.create(relationshipTypeTO)));
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.RELATIONSHIPTYPE_UPDATE + "')")
+    public RelationshipTypeTO update(final RelationshipTypeTO relationshipTypeTO) {
+        RelationshipType relationshipType = relationshipTypeDAO.find(relationshipTypeTO.getKey());
+        if (relationshipType == null) {
+            LOG.error("Could not find relationshipType '" + relationshipTypeTO.getKey() + "'");
+            throw new NotFoundException(String.valueOf(relationshipTypeTO.getKey()));
+        }
+
+        binder.update(relationshipType, relationshipTypeTO);
+        relationshipType = relationshipTypeDAO.save(relationshipType);
+
+        return binder.getRelationshipTypeTO(relationshipType);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.RELATIONSHIPTYPE_DELETE + "')")
+    public RelationshipTypeTO delete(final String key) {
+        RelationshipType relationshipType = relationshipTypeDAO.find(key);
+        if (relationshipType == null) {
+            LOG.error("Could not find relationshipType '" + key + "'");
+
+            throw new NotFoundException(String.valueOf(key));
+        }
+
+        RelationshipTypeTO deleted = binder.getRelationshipTypeTO(relationshipType);
+
+        relationshipTypeDAO.delete(key);
+
+        return deleted;
+    }
+
+    @Override
+    protected RelationshipTypeTO resolveReference(final Method method, final Object... args)
+            throws UnresolvedReferenceException {
+
+        String key = null;
+
+        if (ArrayUtils.isNotEmpty(args)) {
+            for (int i = 0; key == null && i < args.length; i++) {
+                if (args[i] instanceof Long) {
+                    key = (String) args[i];
+                } else if (args[i] instanceof RelationshipTypeTO) {
+                    key = ((RelationshipTypeTO) args[i]).getKey();
+                }
+            }
+        }
+
+        if (StringUtils.isNotBlank(key)) {
+            try {
+                return binder.getRelationshipTypeTO(relationshipTypeDAO.find(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/d8927ef4/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RelationshipTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RelationshipTypeDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RelationshipTypeDAO.java
new file mode 100644
index 0000000..e7d14b9
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RelationshipTypeDAO.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.RelationshipType;
+
+public interface RelationshipTypeDAO extends DAO<RelationshipType, String> {
+
+    RelationshipType find(String key);
+
+    List<RelationshipType> findAll();
+
+    RelationshipType save(RelationshipType anyType);
+
+    void delete(String key);
+}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MembershipType.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MembershipType.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MembershipType.java
new file mode 100644
index 0000000..d49b4dd
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/MembershipType.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 final class MembershipType implements RelationshipType {
+
+    private static final long serialVersionUID = -2767173479992170853L;
+
+    private static final MembershipType INSTANCE = new MembershipType();
+
+    public static MembershipType getInstance() {
+        return INSTANCE;
+    }
+
+    private MembershipType() {
+    }
+
+    @Override
+    public String getKey() {
+        return "Membership";
+    }
+
+    @Override
+    public void setKey(final String key) {
+        // cannot be changed
+    }
+
+    @Override
+    public String getDescription() {
+        return null;
+    }
+
+    @Override
+    public void setDescription(final String description) {
+        // cannot be changed
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
index df4d7ff..0549714 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Relationship.java
@@ -20,6 +20,10 @@ package org.apache.syncope.core.persistence.api.entity;
 
 public interface Relationship<L extends Any<?, ?, ?>, R extends Any<?, ?, ?>> extends Entity<Long> {
 
+    RelationshipType getType();
+
+    void setType(RelationshipType type);
+
     L getLeftEnd();
 
     void setLeftEnd(L leftEnd);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/RelationshipType.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/RelationshipType.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/RelationshipType.java
new file mode 100644
index 0000000..71f1155
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/RelationshipType.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;
+
+public interface RelationshipType extends Entity<String> {
+
+    void setKey(String key);
+
+    String getDescription();
+
+    void setDescription(String description);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
index 19d0f6b..ffb61a3 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/anyobject/AnyObject.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.entity.anyobject;
 
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 
 public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
 
@@ -27,6 +28,8 @@ public interface AnyObject extends Any<APlainAttr, ADerAttr, AVirAttr> {
 
     boolean remove(ARelationship relationship);
 
+    ARelationship getRelationship(RelationshipType relationshipType);
+
     ARelationship getRelationship(Long relationshipKey);
 
     List<? extends ARelationship> getRelationships();

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index da545e4..63047a1 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/resource/ExternalResource.java
@@ -33,7 +33,7 @@ import org.identityconnectors.framework.common.objects.ObjectClass;
 
 public interface ExternalResource extends AnnotatedEntity<String> {
 
-    void setKey(String name);
+    void setKey(String key);
 
     ConnInstance getConnector();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 f02c555..c3b0ca6 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
@@ -22,6 +22,7 @@ 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.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.Role;
 
 public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> {
@@ -134,6 +135,8 @@ public interface User extends Any<UPlainAttr, UDerAttr, UVirAttr> {
 
     URelationship getRelationship(Long anyObjectKey);
 
+    URelationship getRelationship(RelationshipType relationshipType);
+
     List<? extends URelationship> getRelationships();
 
     boolean add(UMembership membership);

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.java
new file mode 100644
index 0000000..37ce107
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARelationshipTypeDAO.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.dao;
+
+import java.util.Collection;
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.syncope.core.persistence.api.dao.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.Relationship;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
+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.JPARelationshipType;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPARelationshipTypeDAO extends AbstractDAO<RelationshipType, String> implements RelationshipTypeDAO {
+
+    @Override
+    public RelationshipType find(final String key) {
+        return entityManager.find(JPARelationshipType.class, key);
+    }
+
+    @Override
+    public List<RelationshipType> findAll() {
+        TypedQuery<RelationshipType> query = entityManager.createQuery(
+                "SELECT e FROM " + JPARelationshipType.class.getSimpleName() + " e ", RelationshipType.class);
+        return query.getResultList();
+    }
+
+    @Override
+    public RelationshipType save(final RelationshipType anyType) {
+        return entityManager.merge(anyType);
+    }
+
+    private Collection<? extends Relationship<?, ?>> findRelationshipsByType(final RelationshipType type) {
+        TypedQuery<ARelationship> aquery = entityManager.createQuery(
+                "SELECT e FROM " + JPAARelationship.class.getSimpleName() + " e WHERE e.type=:type",
+                ARelationship.class);
+        aquery.setParameter("type", type);
+        TypedQuery<URelationship> uquery = entityManager.createQuery(
+                "SELECT e FROM " + JPAURelationship.class.getSimpleName() + " e WHERE e.type=:type",
+                URelationship.class);
+        uquery.setParameter("type", type);
+
+        return CollectionUtils.union(aquery.getResultList(), uquery.getResultList());
+    }
+
+    @Override
+    public void delete(final String key) {
+        RelationshipType type = find(key);
+        if (type == null) {
+            return;
+        }
+
+        for (Relationship<?, ?> relationship : findRelationshipsByType(type)) {
+            if (relationship instanceof URelationship) {
+                ((URelationship) relationship).getLeftEnd().remove((URelationship) relationship);
+            } else if (relationship instanceof UMembership) {
+                ((UMembership) relationship).getLeftEnd().remove((UMembership) relationship);
+            } else if (relationship instanceof ARelationship) {
+                ((ARelationship) relationship).getLeftEnd().remove((ARelationship) relationship);
+            } else if (relationship instanceof AMembership) {
+                ((AMembership) relationship).getLeftEnd().remove((AMembership) relationship);
+            }
+
+            relationship.setLeftEnd(null);
+            entityManager.remove(relationship);
+        }
+
+        entityManager.remove(type);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 6a152b0..ad6304e 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
@@ -37,6 +37,7 @@ 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.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.Report;
 import org.apache.syncope.core.persistence.api.entity.ReportExec;
 import org.apache.syncope.core.persistence.api.entity.ReportletConfInstance;
@@ -150,6 +151,8 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAUser();
         } else if (reference.equals(Group.class)) {
             result = (T) new JPAGroup();
+        } else if (reference.equals(RelationshipType.class)) {
+            result = (T) new JPARelationshipType();
         } else if (reference.equals(ARelationship.class)) {
             result = (T) new JPAARelationship();
         } else if (reference.equals(URelationship.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARelationshipType.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARelationshipType.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARelationshipType.java
new file mode 100644
index 0000000..f3fc882
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARelationshipType.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+import org.apache.syncope.core.persistence.jpa.validation.entity.RelationshipTypeCheck;
+
+@Entity
+@Table(name = JPARelationshipType.TABLE)
+@RelationshipTypeCheck
+@Cacheable
+public class JPARelationshipType extends AbstractEntity<String> implements RelationshipType {
+
+    private static final long serialVersionUID = -753673974614737065L;
+
+    public static final String TABLE = "RelationshipType";
+
+    @Id
+    private String name;
+
+    private String description;
+
+    @Override
+    public String getKey() {
+        return name;
+    }
+
+    @Override
+    public void setKey(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index e770e33..28ee49b 100644
--- 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
@@ -23,6 +23,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.MembershipType;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -54,6 +56,16 @@ public class JPAAMembership extends AbstractEntity<Long> implements AMembership
     }
 
     @Override
+    public MembershipType getType() {
+        return MembershipType.getInstance();
+    }
+
+    @Override
+    public void setType(final RelationshipType type) {
+        // cannot be changed
+    }
+
+    @Override
     public AnyObject getLeftEnd() {
         return leftEnd;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index 93a7941..e12f8d8 100644
--- 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
@@ -20,15 +20,21 @@ package org.apache.syncope.core.persistence.jpa.entity.anyobject;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.MembershipType;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 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;
+import org.apache.syncope.core.persistence.jpa.entity.JPARelationshipType;
 
 @Entity
-@Table(name = JPAARelationship.TABLE)
+@Table(name = JPAARelationship.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "type_name", "left_anyObject_id", "right_anyObject_id" }))
 public class JPAARelationship extends AbstractEntity<Long> implements ARelationship {
 
     private static final long serialVersionUID = 6608821135023815357L;
@@ -38,6 +44,9 @@ public class JPAARelationship extends AbstractEntity<Long> implements ARelations
     @Id
     private Long id;
 
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPARelationshipType type;
+
     @ManyToOne
     @Column(name = "left_anyObject_id")
     private JPAAnyObject leftEnd;
@@ -52,6 +61,20 @@ public class JPAARelationship extends AbstractEntity<Long> implements ARelations
     }
 
     @Override
+    public RelationshipType getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(final RelationshipType type) {
+        if (MembershipType.getInstance().getKey().equalsIgnoreCase(type.getKey())) {
+            throw new IllegalArgumentException("This is not a membership");
+        }
+        checkType(type, JPARelationshipType.class);
+        this.type = (JPARelationshipType) type;
+    }
+
+    @Override
     public AnyObject getLeftEnd() {
         return leftEnd;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index a8e842b..d32ec02 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/anyobject/JPAAnyObject.java
@@ -36,6 +36,7 @@ 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.RelationshipType;
 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;
@@ -198,6 +199,17 @@ public class JPAAnyObject extends AbstractAny<APlainAttr, ADerAttr, AVirAttr> im
     }
 
     @Override
+    public ARelationship getRelationship(final RelationshipType relationshipType) {
+        return CollectionUtils.find(getRelationships(), new Predicate<ARelationship>() {
+
+            @Override
+            public boolean evaluate(final ARelationship relationship) {
+                return relationshipType != null && relationshipType.equals(relationship.getType());
+            }
+        });
+    }
+
+    @Override
     public ARelationship getRelationship(final Long anyObjectKey) {
         return CollectionUtils.find(getRelationships(), new Predicate<ARelationship>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index dd79434..879ee87 100644
--- 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
@@ -23,6 +23,8 @@ import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.MembershipType;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 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;
@@ -54,6 +56,16 @@ public class JPAUMembership extends AbstractEntity<Long> implements UMembership
     }
 
     @Override
+    public MembershipType getType() {
+        return MembershipType.getInstance();
+    }
+
+    @Override
+    public void setType(final RelationshipType type) {
+        // cannot be changed
+    }
+
+    @Override
     public JPAUser getLeftEnd() {
         return leftEnd;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
index d4c8bb3..25fd3a1 100644
--- 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
@@ -20,17 +20,23 @@ package org.apache.syncope.core.persistence.jpa.entity.user;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.MembershipType;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
 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.JPARelationshipType;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 
 @Entity
-@Table(name = JPAURelationship.TABLE)
+@Table(name = JPAURelationship.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "type_name", "user_id", "anyObject_id" }))
 public class JPAURelationship extends AbstractEntity<Long> implements URelationship {
 
     private static final long serialVersionUID = 2778494939240083204L;
@@ -40,6 +46,9 @@ public class JPAURelationship extends AbstractEntity<Long> implements URelations
     @Id
     private Long id;
 
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPARelationshipType type;
+
     @ManyToOne
     @Column(name = "user_id")
     private JPAUser leftEnd;
@@ -54,6 +63,20 @@ public class JPAURelationship extends AbstractEntity<Long> implements URelations
     }
 
     @Override
+    public RelationshipType getType() {
+        return type;
+    }
+
+    @Override
+    public void setType(final RelationshipType type) {
+        if (MembershipType.getInstance().getKey().equalsIgnoreCase(type.getKey())) {
+            throw new IllegalArgumentException("This is not a membership");
+        }
+        checkType(type, JPARelationshipType.class);
+        this.type = (JPARelationshipType) type;
+    }
+
+    @Override
     public JPAUser getLeftEnd() {
         return leftEnd;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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 06d8f04..88c86fb 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
@@ -64,6 +64,7 @@ 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.RelationshipType;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
 import org.apache.syncope.core.persistence.api.entity.user.URelationship;
@@ -537,6 +538,17 @@ public class JPAUser extends AbstractAny<UPlainAttr, UDerAttr, UVirAttr> impleme
     }
 
     @Override
+    public URelationship getRelationship(final RelationshipType relationshipType) {
+        return CollectionUtils.find(getRelationships(), new Predicate<URelationship>() {
+
+            @Override
+            public boolean evaluate(final URelationship relationship) {
+                return relationshipType != null && relationshipType.equals(relationship.getType());
+            }
+        });
+    }
+
+    @Override
     public URelationship getRelationship(final Long anyObjectKey) {
         return CollectionUtils.find(getRelationships(), new Predicate<URelationship>() {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
index 4308de6..f1a70dc 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AbstractValidator.java
@@ -27,9 +27,6 @@ import org.slf4j.LoggerFactory;
 
 public abstract class AbstractValidator<A extends Annotation, T> implements ConstraintValidator<A, T> {
 
-    /**
-     * Logger.
-     */
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractValidator.class);
 
     protected static final Pattern NAME_PATTERN =

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeCheck.java
new file mode 100644
index 0000000..9574e53
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeCheck.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.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = RelationshipTypeValidator.class)
+@Documented
+public @interface RelationshipTypeCheck {
+
+    String message() default "{org.apache.syncope.core.persistence.validation.relationshiptype}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeValidator.java
new file mode 100644
index 0000000..8051bda
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/RelationshipTypeValidator.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.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.MembershipType;
+import org.apache.syncope.core.persistence.api.entity.RelationshipType;
+
+public class RelationshipTypeValidator extends AbstractValidator<RelationshipTypeCheck, RelationshipType> {
+
+    @Override
+    public boolean isValid(final RelationshipType object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        if (MembershipType.getInstance().getKey().equalsIgnoreCase(object.getKey())) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Invalid RelationshipType name")).
+                    addPropertyNode("name").addConstraintViolation();
+            return false;
+        }
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
deleted file mode 100644
index e149969..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.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 static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.common.lib.SyncopeConstants;
-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.anyobject.AnyObject;
-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 AnyObjectTest extends AbstractTest {
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Test
-    public void findAll() {
-        List<AnyObject> list = anyObjectDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void findAllByType() {
-        List<AnyObject> list = anyObjectDAO.findAll("PRINTER", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertFalse(list.isEmpty());
-
-        list = anyObjectDAO.findAll("UNEXISTING", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertTrue(list.isEmpty());
-    }
-
-    @Test
-    public void find() {
-        AnyObject anyObject = anyObjectDAO.find(2L);
-        assertNotNull(anyObject);
-        assertNotNull(anyObject.getType());
-        assertFalse(anyObject.getType().getClasses().isEmpty());
-    }
-
-    @Test
-    public void save() {
-        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
-        anyObject.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
-
-        anyObject = anyObjectDAO.save(anyObject);
-        assertNotNull(anyObject);
-    }
-
-    @Test
-    public void delete() {
-        AnyObject anyObject = anyObjectDAO.find(2L);
-        anyObjectDAO.delete(anyObject.getKey());
-
-        AnyObject actual = anyObjectDAO.find(2L);
-        assertNull(actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 018f632..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnySearchTest.java
+++ /dev/null
@@ -1,520 +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.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.AnyTypeCond;
-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 searchByBooleanAnyCond() {
-        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 searchByType() {
-        AnyTypeCond tcond = new AnyTypeCond();
-        tcond.setAnyTypeName("PRINTER");
-
-        SearchCond searchCondition = SearchCond.getLeafCond(tcond);
-        assertTrue(searchCondition.isValid());
-
-        List<AnyObject> printers = searchDAO.search(
-                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
-        assertNotNull(printers);
-        assertEquals(2, printers.size());
-
-        tcond.setAnyTypeName("UNEXISTING");
-        printers = searchDAO.search(
-                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
-        assertNotNull(printers);
-        assertTrue(printers.isEmpty());
-    }
-
-    @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);
-    }
-}


[32/70] syncope git commit: [SYNCOPE-666] Fix naming

Posted by il...@apache.org.
[SYNCOPE-666] Fix naming


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

Branch: refs/heads/master
Commit: a78a6f1f7624bb834ada494cff969ed36ca4a85b
Parents: a5408c5
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue May 26 08:24:18 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue May 26 08:24:18 2015 +0200

----------------------------------------------------------------------
 .../commons/SortableAnyProviderComparator.java  | 122 +++++++++++++++++++
 .../SortableAttributableProviderComparator.java | 122 -------------------
 .../commons/status/ConnObjectWrapper.java       |   4 +-
 .../console/commons/status/StatusBean.java      |  10 +-
 .../console/commons/status/StatusUtils.java     |   6 +-
 .../resources/WorkflowDefGETResource.java       |   3 +-
 .../resources/WorkflowDefPUTResource.java       |   3 +-
 .../client/console/rest/GroupRestClient.java    |   8 +-
 .../client/console/rest/UserRestClient.java     |   8 +-
 .../syncope/client/lib/SyncopeClient.java       |   4 +-
 .../syncope/common/lib/to/MappingItemTO.java    |  10 +-
 .../apache/syncope/common/lib/to/MappingTO.java |   8 +-
 .../common/lib/types/PropagationByResource.java |  40 +++---
 .../syncope/core/logic/AbstractAnyLogic.java    |   2 +-
 .../syncope/core/logic/AnyObjectLogic.java      |   4 +-
 .../apache/syncope/core/logic/GroupLogic.java   |   4 +-
 .../apache/syncope/core/logic/UserLogic.java    |   4 +-
 core/logic/src/main/resources/logic.properties  |   2 +-
 core/logic/src/main/resources/logicContext.xml  |   2 +-
 .../syncope/core/misc/ConnObjectUtils.java      |   2 +-
 .../apache/syncope/core/misc/MappingUtils.java  |  40 +++---
 .../persistence/jpa/dao/JPAAnySearchDAO.java    |  50 ++++----
 .../entity/ExternalResourceValidator.java       |   4 +-
 .../persistence/jpa/entity/AnySearchTest.java   |   2 +-
 .../java/DefaultGroupProvisioningManager.java   |  34 +++---
 .../java/DefaultUserProvisioningManager.java    |  10 +-
 .../core/provisioning/java/VirAttrHandler.java  |   2 +-
 .../java/cache/MemoryVirAttrCache.java          |   6 +-
 .../java/data/AbstractAnyDataBinder.java        |   4 +-
 .../java/data/GroupDataBinderImpl.java          |   6 +-
 .../java/data/ResourceDataBinderImpl.java       |   2 +-
 .../java/data/UserDataBinderImpl.java           |  12 +-
 .../AbstractPropagationTaskExecutor.java        |  12 +-
 .../LDAPMembershipPropagationActions.java       |  16 +--
 .../propagation/PropagationManagerImpl.java     |   2 +-
 .../java/sync/AbstractSyncResultHandler.java    |   4 +-
 .../sync/AnyObjectPushResultHandlerImpl.java    |   2 +-
 .../java/sync/GroupPushResultHandlerImpl.java   |   4 +-
 .../java/sync/LDAPPasswordSyncActions.java      |  20 +--
 .../core/provisioning/java/sync/SyncUtils.java  |  10 +-
 .../java/sync/UserPushResultHandlerImpl.java    |   4 +-
 .../java/sync/UserSyncResultHandlerImpl.java    |   8 +-
 .../java/data/ResourceDataBinderTest.java       |   2 +-
 .../core/logic/init/CamelRouteLoader.java       |   4 +-
 .../camel/CamelGroupProvisioningManager.java    |  12 +-
 .../camel/CamelUserProvisioningManager.java     |   4 +-
 .../processor/GroupCreateInSyncProcessor.java   |   2 +-
 .../camel/processor/GroupCreateProcessor.java   |   4 +-
 .../camel/processor/GroupDeleteProcessor.java   |   4 +-
 .../camel/processor/GroupUpdateProcessor.java   |   4 +-
 .../src/main/resources/groupRoutes.xml          |   6 +-
 .../reference/DoubleValueAnyTransformer.java    |  75 ++++++++++++
 .../DoubleValueAttributableTransformer.java     |  75 ------------
 .../fit/core/reference/TestSyncActions.java     |  22 ++--
 .../src/main/resources/logic.properties         |   2 +-
 .../core/reference/AuthenticationITCase.java    |   4 +-
 .../fit/core/reference/ConnectorITCase.java     |   2 +-
 .../syncope/fit/core/reference/GroupITCase.java |   6 +-
 .../fit/core/reference/PushTaskITCase.java      |   2 +-
 .../fit/core/reference/ResourceITCase.java      |  22 ++--
 .../fit/core/reference/SearchITCase.java        |  34 +++---
 .../fit/core/reference/SyncTaskITCase.java      |  14 +--
 .../syncope/fit/core/reference/UserITCase.java  |   8 +-
 .../fit/core/reference/VirAttrITCase.java       |   2 +-
 src/site/xdoc/security.xml                      |   2 +-
 65 files changed, 464 insertions(+), 470 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java
new file mode 100644
index 0000000..99cfaf0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAnyProviderComparator.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.commons;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+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 SortableAnyProviderComparator 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 SortableAnyProviderComparator(final SortableDataProvider<AnyTO, String> provider) {
+        super(provider);
+    }
+
+    @Override
+    public int compare(final AnyTO any1, final AnyTO any2) {
+        if (INLINE_PROPS.contains(provider.getSort().getProperty())) {
+            return super.compare(any1, any2);
+        }
+
+        return super.compare(new AttrModel(any1), new AttrModel(any2));
+    }
+
+    @SuppressWarnings("rawtypes")
+    private class AttrModel extends AbstractReadOnlyModel<Comparable> {
+
+        private static final long serialVersionUID = -7856686374020091808L;
+
+        private final Map<String, AttrTO> attrs;
+
+        private final Map<String, AttrTO> derAttrs;
+
+        private final Map<String, AttrTO> virAttrs;
+
+        public AttrModel(final AnyTO anyTO) {
+            super();
+
+            this.attrs = anyTO.getPlainAttrMap();
+            this.derAttrs = anyTO.getDerAttrMap();
+            this.virAttrs = anyTO.getVirAttrMap();
+        }
+
+        /**
+         * @see UserAttrColumn constructor
+         */
+        @Override
+        public Comparable getObject() {
+            int hashPos = provider.getSort().getProperty().indexOf('#');
+
+            SchemaType schemaType = null;
+            final String schema;
+            if (hashPos == -1) {
+                schema = provider.getSort().getProperty();
+            } else {
+                String[] splitted = provider.getSort().getProperty().split("#");
+                try {
+                    schemaType = SchemaType.valueOf(splitted[0]);
+                } catch (IllegalArgumentException e) {
+                    // this should never happen
+                }
+                schema = provider.getSort().getProperty().substring(hashPos + 1);
+            }
+
+            final AttrTO attr;
+            if (schemaType == null) {
+                attr = this.attrs.get(schema);
+            } else {
+                switch (schemaType) {
+                    case PLAIN:
+                    default:
+                        attr = this.attrs.get(schema);
+                        break;
+
+                    case DERIVED:
+                        attr = this.derAttrs.get(schema);
+                        break;
+
+                    case VIRTUAL:
+                        attr = this.virAttrs.get(schema);
+                        break;
+                }
+            }
+
+            Comparable result = null;
+
+            List<String> values = attr == null ? null : attr.getValues();
+            if (values != null && !values.isEmpty()) {
+                result = values.iterator().next();
+            }
+
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
deleted file mode 100644
index 78b91ef..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/commons/SortableAttributableProviderComparator.java
+++ /dev/null
@@ -1,122 +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.commons;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-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<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<AnyTO, String> provider) {
-        super(provider);
-    }
-
-    @Override
-    public int compare(final AnyTO any1, final AnyTO any2) {
-        if (INLINE_PROPS.contains(provider.getSort().getProperty())) {
-            return super.compare(any1, any2);
-        }
-
-        return super.compare(new AttrModel(any1), new AttrModel(any2));
-    }
-
-    @SuppressWarnings("rawtypes")
-    private class AttrModel extends AbstractReadOnlyModel<Comparable> {
-
-        private static final long serialVersionUID = -7856686374020091808L;
-
-        private final Map<String, AttrTO> attrs;
-
-        private final Map<String, AttrTO> derAttrs;
-
-        private final Map<String, AttrTO> virAttrs;
-
-        public AttrModel(final AnyTO anyTO) {
-            super();
-
-            this.attrs = anyTO.getPlainAttrMap();
-            this.derAttrs = anyTO.getDerAttrMap();
-            this.virAttrs = anyTO.getVirAttrMap();
-        }
-
-        /**
-         * @see UserAttrColumn constructor
-         */
-        @Override
-        public Comparable getObject() {
-            int hashPos = provider.getSort().getProperty().indexOf('#');
-
-            SchemaType schemaType = null;
-            final String schema;
-            if (hashPos == -1) {
-                schema = provider.getSort().getProperty();
-            } else {
-                String[] splitted = provider.getSort().getProperty().split("#");
-                try {
-                    schemaType = SchemaType.valueOf(splitted[0]);
-                } catch (IllegalArgumentException e) {
-                    // this should never happen
-                }
-                schema = provider.getSort().getProperty().substring(hashPos + 1);
-            }
-
-            final AttrTO attr;
-            if (schemaType == null) {
-                attr = this.attrs.get(schema);
-            } else {
-                switch (schemaType) {
-                    case PLAIN:
-                    default:
-                        attr = this.attrs.get(schema);
-                        break;
-
-                    case DERIVED:
-                        attr = this.derAttrs.get(schema);
-                        break;
-
-                    case VIRTUAL:
-                        attr = this.virAttrs.get(schema);
-                        break;
-                }
-            }
-
-            Comparable result = null;
-
-            List<String> values = attr == null ? null : attr.getValues();
-            if (values != null && !values.isEmpty()) {
-                result = values.iterator().next();
-            }
-
-            return result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 c66a825..199b262 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
@@ -32,10 +32,10 @@ public class ConnObjectWrapper implements Serializable {
 
     private final ConnObjectTO connObjectTO;
 
-    public ConnObjectWrapper(final AnyTO attributable, final String resourceName,
+    public ConnObjectWrapper(final AnyTO any, final String resourceName,
             final ConnObjectTO connObjectTO) {
 
-        this.any = attributable;
+        this.any = any;
         this.resourceName = resourceName;
         this.connObjectTO = connObjectTO;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 af43c0a..adb6040 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
@@ -37,7 +37,7 @@ public class StatusBean implements Serializable {
 
     private final String resourceName;
 
-    private String accountLink = null;
+    private String connObjectLink = null;
 
     private Status status = Status.OBJECT_NOT_FOUND;
 
@@ -50,12 +50,12 @@ public class StatusBean implements Serializable {
         this.resourceName = resourceName;
     }
 
-    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 String getResourceName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 877a628..1a6f04f 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
@@ -108,10 +108,10 @@ public class StatusUtils implements Serializable {
                             ? Status.ACTIVE
                             : Status.SUSPENDED;
 
-            final String accountLink = getAccountLink(objectTO);
+            String connObjectLink = getConnObjectLink(objectTO);
 
             statusBean.setStatus(status);
-            statusBean.setAccountLink(accountLink);
+            statusBean.setConnObjectLink(connObjectLink);
         }
 
         return statusBean;
@@ -127,7 +127,7 @@ public class StatusUtils implements Serializable {
                 : null;
     }
 
-    private String getAccountLink(final ConnObjectTO objectTO) {
+    private String getConnObjectLink(final ConnObjectTO objectTO) {
         final Map<String, AttrTO> attributeTOs = objectTO == null
                 ? Collections.<String, AttrTO>emptyMap()
                 : objectTO.getPlainAttrMap();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
index faf3a57..62dfe30 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java
@@ -29,8 +29,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
 /**
  * Mirror REST resource for obtaining user workflow definition in JSON (used by Activiti Modeler).
  *
- * @see org.apache.syncope.common.rest.api.service.WorkflowService#exportDefinition(
- * org.apache.syncope.common.types.SubjectType)
+ * @see org.apache.syncope.common.rest.api.service.WorkflowService#exportDefinition
  */
 public class WorkflowDefGETResource extends AbstractResource {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
index e603ab2..b85dfd8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java
@@ -33,8 +33,7 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
 /**
  * Mirror REST resource for putting user workflow definition in JSON (used by Activiti Modeler).
  *
- * @see org.apache.syncope.common.rest.api.service.#importDefinition(
- * org.apache.syncope.common.types.SubjectType, java.lang.String)
+ * @see org.apache.syncope.common.rest.api.service.WorkflowService#importDefinition
  */
 public class WorkflowDefPUTResource extends AbstractResource {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 157de09..073e7c3 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
@@ -50,14 +50,14 @@ public class GroupRestClient extends AbstractAnyRestClient {
     @Override
     public int count(final String realm) {
         return getService(GroupService.class).
-                list(SyncopeClient.getSubjectListQueryBuilder().realm(realm).page(1).size(1).build()).
+                list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(1).size(1).build()).
                 getTotalCount();
     }
 
     @Override
     public List<GroupTO> list(final String realm, final int page, final int size, final SortParam<String> sort) {
         return getService(GroupService.class).
-                list(SyncopeClient.getSubjectListQueryBuilder().realm(realm).page(page).size(size).
+                list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(page).size(size).
                         orderBy(toOrderBy(sort)).build()).
                 getResult();
     }
@@ -65,7 +65,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
     @Override
     public int searchCount(final String realm, final String fiql) {
         return getService(GroupService.class).
-                search(SyncopeClient.getSubjectSearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
+                search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
                 getTotalCount();
     }
 
@@ -74,7 +74,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
             final String realm, final String fiql, final int page, final int size, final SortParam<String> sort) {
 
         return getService(GroupService.class).
-                search(SyncopeClient.getSubjectSearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
+                search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
                         orderBy(toOrderBy(sort)).build()).
                 getResult();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 9d30b78..45272c3 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
@@ -52,14 +52,14 @@ public class UserRestClient extends AbstractAnyRestClient {
     @Override
     public int count(final String realm) {
         return getService(UserService.class).
-                list(SyncopeClient.getSubjectListQueryBuilder().realm(realm).page(1).size(1).build()).
+                list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(1).size(1).build()).
                 getTotalCount();
     }
 
     @Override
     public List<UserTO> list(final String realm, final int page, final int size, final SortParam<String> sort) {
         return getService(UserService.class).
-                list(SyncopeClient.getSubjectListQueryBuilder().realm(realm).page(page).size(size).
+                list(SyncopeClient.getAnyListQueryBuilder().realm(realm).page(page).size(size).
                         orderBy(toOrderBy(sort)).build()).
                 getResult();
     }
@@ -103,7 +103,7 @@ public class UserRestClient extends AbstractAnyRestClient {
     @Override
     public int searchCount(final String realm, final String fiql) {
         return getService(UserService.class).
-                search(SyncopeClient.getSubjectSearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
+                search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(1).size(1).build()).
                 getTotalCount();
     }
 
@@ -112,7 +112,7 @@ public class UserRestClient extends AbstractAnyRestClient {
             final String realm, final String fiql, final int page, final int size, final SortParam<String> sort) {
 
         return getService(UserService.class).
-                search(SyncopeClient.getSubjectSearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
+                search(SyncopeClient.getAnySearchQueryBuilder().realm(realm).fiql(fiql).page(page).size(size).
                         orderBy(toOrderBy(sort)).build()).
                 getResult();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 4773150..c981739 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
@@ -113,7 +113,7 @@ public class SyncopeClient {
      *
      * @return default instance of {@link AnyListQueryBuilder}
      */
-    public static AnyListQueryBuilder getSubjectListQueryBuilder() {
+    public static AnyListQueryBuilder getAnyListQueryBuilder() {
         return new AnyListQueryBuilder();
     }
 
@@ -124,7 +124,7 @@ public class SyncopeClient {
      *
      * @return default instance of {@link AnySearchQueryBuilder}
      */
-    public static AnySearchQueryBuilder getSubjectSearchQueryBuilder() {
+    public static AnySearchQueryBuilder getAnySearchQueryBuilder() {
         return new AnySearchQueryBuilder();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
index 4df561c..f252fbb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingItemTO.java
@@ -51,7 +51,7 @@ public class MappingItemTO extends AbstractBaseBean {
     /**
      * Specify if the mapped target resource's field is the key.
      */
-    private boolean accountid;
+    private boolean connObjectKey;
 
     /**
      * Specify if the mapped target resource's field is the password.
@@ -68,12 +68,12 @@ public class MappingItemTO extends AbstractBaseBean {
      */
     private MappingPurpose purpose;
 
-    public boolean isAccountid() {
-        return accountid;
+    public boolean isConnObjectKey() {
+        return connObjectKey;
     }
 
-    public void setAccountid(final boolean accountid) {
-        this.accountid = accountid;
+    public void setConnObjectKey(final boolean connObjectKey) {
+        this.connObjectKey = connObjectKey;
     }
 
     public String getExtAttrName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 cf5dc71..92be8e1 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
@@ -53,7 +53,7 @@ public class MappingTO extends AbstractBaseBean {
 
             @Override
             public boolean evaluate(final MappingItemTO item) {
-                return item.isAccountid();
+                return item.isConnObjectKey();
             }
         });
     }
@@ -64,14 +64,14 @@ public class MappingTO extends AbstractBaseBean {
                 || IntMappingType.AnyVirtualSchema == connObjectItem.getIntMappingType()
                 || IntMappingType.Password == connObjectItem.getIntMappingType()) {
 
-            throw new IllegalArgumentException("Virtual attributes cannot be set as accountId");
+            throw new IllegalArgumentException("Virtual attributes cannot be set as connObjectKey");
         }
         if (IntMappingType.Password == connObjectItem.getIntMappingType()) {
-            throw new IllegalArgumentException("Password attributes cannot be set as accountId");
+            throw new IllegalArgumentException("Password attributes cannot be set as connObjectKey");
         }
 
         connObjectItem.setExtAttrName(connObjectItem.getExtAttrName());
-        connObjectItem.setAccountid(true);
+        connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
index 014f52d..bf35bb3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/PropagationByResource.java
@@ -49,9 +49,9 @@ public class PropagationByResource implements Serializable {
     private final Set<String> toBeDeleted;
 
     /**
-     * Mapping target resource names to old account ids (when applicable).
+     * Mapping target resource names to old ConnObjectKeys (when applicable).
      */
-    private final Map<String, String> oldAccountIds;
+    private final Map<String, String> oldConnObjectKeys;
 
     /**
      * Default constructor.
@@ -61,7 +61,7 @@ public class PropagationByResource implements Serializable {
         toBeUpdated = new HashSet<>();
         toBeDeleted = new HashSet<>();
 
-        oldAccountIds = new HashMap<>();
+        oldConnObjectKeys = new HashMap<>();
     }
 
     /**
@@ -301,7 +301,7 @@ public class PropagationByResource implements Serializable {
             toBeCreated.addAll(propByRes.get(ResourceOperation.CREATE));
             toBeUpdated.addAll(propByRes.get(ResourceOperation.UPDATE));
             toBeDeleted.addAll(propByRes.get(ResourceOperation.DELETE));
-            oldAccountIds.putAll(propByRes.getOldAccountIds());
+            oldConnObjectKeys.putAll(propByRes.getOldConnObjectKeys());
         }
     }
 
@@ -317,40 +317,40 @@ public class PropagationByResource implements Serializable {
     /**
      * Whether no operations are present.
      *
-     * @return true if no operations (create / update / delete) and no old account ids are present
+     * @return true if no operations (create / update / delete) and no old connObjectKeys are present
      */
     public final boolean isEmpty() {
-        return toBeCreated.isEmpty() && toBeUpdated.isEmpty() && toBeDeleted.isEmpty() && oldAccountIds.isEmpty();
+        return toBeCreated.isEmpty() && toBeUpdated.isEmpty() && toBeDeleted.isEmpty() && oldConnObjectKeys.isEmpty();
     }
 
     /**
-     * Fetch all old account ids.
+     * Fetch all old connObjectKeys.
      *
-     * @return old account ids; can be empty
+     * @return old connObjectKeys; can be empty
      */
-    public Map<String, String> getOldAccountIds() {
-        return oldAccountIds;
+    public Map<String, String> getOldConnObjectKeys() {
+        return oldConnObjectKeys;
     }
 
     /**
-     * Fetch old account id for given resource name.
+     * Fetch old connObjectKey for given resource name.
      *
      * @param resourceName resource name
-     * @return old account id; can be null
+     * @return old connObjectKey; can be null
      */
-    public String getOldAccountId(final String resourceName) {
-        return oldAccountIds.get(resourceName);
+    public String getOldConnObjectKey(final String resourceName) {
+        return oldConnObjectKeys.get(resourceName);
     }
 
     /**
-     * Add old account id for a given resource name.
+     * Add old ConnObjectKey for a given resource name.
      *
      * @param resourceName resourceName resource name
-     * @param oldAccountId old account id
+     * @param oldConnObjectKey old ConnObjectKey
      */
-    public void addOldAccountId(final String resourceName, final String oldAccountId) {
-        if (resourceName != null && oldAccountId != null) {
-            oldAccountIds.put(resourceName, oldAccountId);
+    public void addOldConnObjectKey(final String resourceName, final String oldConnObjectKey) {
+        if (resourceName != null && oldConnObjectKey != null) {
+            oldConnObjectKeys.put(resourceName, oldConnObjectKey);
         }
     }
 
@@ -359,6 +359,6 @@ public class PropagationByResource implements Serializable {
         return "To be Created: " + toBeCreated + ";\n"
                 + "To be Updated: " + toBeUpdated + ";\n"
                 + "To be Deleted: " + toBeDeleted + ";\n"
-                + "Old account Ids: " + oldAccountIds;
+                + "Old connObjectKeys: " + oldConnObjectKeys;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
index 7c998cf..83e90da 100644
--- 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
@@ -71,7 +71,7 @@ public abstract class AbstractAnyLogic<T extends AnyTO, V extends AnyMod>
 
     public abstract int count(List<String> realms);
 
-    public abstract T update(V attributableMod);
+    public abstract T update(V anyMod);
 
     public abstract T delete(Long key);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
index 5b186b5..31fda37 100644
--- 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
@@ -161,7 +161,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
             throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, null);
         }
 
-        // Attributable transformation (if configured)
+        // Any transformation (if configured)
         AnyObjectTO actual = attrTransformer.transform(anyObjectTO);
         LOG.debug("Transformed: {}", actual);
 
@@ -188,7 +188,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
             throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
         }
 
-        // Attribute value transformation (if configured)
+        // Any transformation (if configured)
         AnyObjectMod actual = attrTransformer.transform(anyObjectMod);
         LOG.debug("Transformed: {}", actual);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 7129b74..d9216da 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
@@ -178,7 +178,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
             throw new UnauthorizedException(AnyTypeKind.GROUP, null);
         }
 
-        // Attributable transformation (if configured)
+        // Any transformation (if configured)
         GroupTO actual = attrTransformer.transform(groupTO);
         LOG.debug("Transformed: {}", actual);
 
@@ -205,7 +205,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
             throw new UnauthorizedException(AnyTypeKind.GROUP, group.getKey());
         }
 
-        // Attribute value transformation (if configured)
+        // Any transformation (if configured)
         GroupMod actual = attrTransformer.transform(groupMod);
         LOG.debug("Transformed: {}", actual);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 2ec1175..37acf19 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
@@ -199,7 +199,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     protected UserTO doCreate(final UserTO userTO, final boolean storePassword) {
-        // Attributable transformation (if configured)
+        // Any transformation (if configured)
         UserTO actual = anyTransformer.transform(userTO);
         LOG.debug("Transformed: {}", actual);
 
@@ -224,7 +224,7 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     @PreAuthorize("hasRole('" + Entitlement.USER_UPDATE + "')")
     @Override
     public UserTO update(final UserMod userMod) {
-        // AttributableMod transformation (if configured)
+        // Any transformation (if configured)
         UserMod actual = anyTransformer.transform(userMod);
         LOG.debug("Transformed: {}", actual);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/core/logic/src/main/resources/logic.properties
----------------------------------------------------------------------
diff --git a/core/logic/src/main/resources/logic.properties b/core/logic/src/main/resources/logic.properties
index 72f5b06..d2f6b11 100644
--- a/core/logic/src/main/resources/logic.properties
+++ b/core/logic/src/main/resources/logic.properties
@@ -14,5 +14,5 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-attributableTransformer=org.apache.syncope.core.provisioning.java.DefaultAttributableTransformer
+anyTransformer=org.apache.syncope.core.provisioning.java.DefaultAnyTransformer
 logicInvocationHandler=org.apache.syncope.core.logic.LogicInvocationHandler

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/core/logic/src/main/resources/logicContext.xml
----------------------------------------------------------------------
diff --git a/core/logic/src/main/resources/logicContext.xml b/core/logic/src/main/resources/logicContext.xml
index 61eb724..b70f4cd 100644
--- a/core/logic/src/main/resources/logicContext.xml
+++ b/core/logic/src/main/resources/logicContext.xml
@@ -37,6 +37,6 @@ under the License.
   <context:component-scan base-package="org.apache.syncope.core.logic"/>
 
   <bean class="${logicInvocationHandler}"/>
-  <bean class="${attributableTransformer}"/>
+  <bean class="${anyTransformer}"/>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 30341bd..279ef77 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
@@ -540,7 +540,7 @@ public class ConnObjectUtils {
                                     : MappingUtils.getConnObjectKeyValue(any, provision);
 
                             if (StringUtils.isBlank(connObjectKey)) {
-                                throw new IllegalArgumentException("No AccountId found for " + resource.getKey());
+                                throw new IllegalArgumentException("No ConnObjectKey found for " + resource.getKey());
                             }
 
                             Connector connector = connFactory.getConnector(resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 87f2ea5..a1931c1 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
@@ -127,7 +127,7 @@ public final class MappingUtils {
      * @param vAttrsToBeUpdated virtual attributes to be added
      * @param enable whether any object must be enabled or not
      * @param provision provision information
-     * @return account link + prepared attributes
+     * @return connObjectLink + prepared attributes
      */
     public static Pair<String, Set<Attribute>> prepareAttributes(
             final AnyUtils anyUtils, final Any<?, ?, ?> any,
@@ -186,10 +186,10 @@ public final class MappingUtils {
             }
         }
 
-        final Attribute accountIdExtAttr =
+        Attribute connObjectKeyExtAttr =
                 AttributeUtil.find(anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), attributes);
-        if (accountIdExtAttr != null) {
-            attributes.remove(accountIdExtAttr);
+        if (connObjectKeyExtAttr != null) {
+            attributes.remove(connObjectKeyExtAttr);
             attributes.add(AttributeBuilder.build(
                     anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
         }
@@ -218,7 +218,7 @@ public final class MappingUtils {
      * @param passwordGenerator password generator
      * @param vAttrsToBeRemoved virtual attributes to be removed
      * @param vAttrsToBeUpdated virtual attributes to be added
-     * @return account link + prepared attribute
+     * @return connObjectLink + prepared attribute
      */
     @SuppressWarnings("unchecked")
     private static Pair<String, Attribute> prepareAttr(
@@ -294,7 +294,7 @@ public final class MappingUtils {
 
         LOG.debug("Define mapping for: "
                 + "\n* ExtAttrName " + extAttrName
-                + "\n* is accountId " + mapItem.isConnObjectKey()
+                + "\n* is connObjectKey " + mapItem.isConnObjectKey()
                 + "\n* is password " + (mapItem.isPassword() || mapItem.getIntMappingType() == IntMappingType.Password)
                 + "\n* mandatory condition " + mapItem.getMandatoryCondition()
                 + "\n* Schema " + mapItem.getIntAttrName()
@@ -364,8 +364,8 @@ 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.
+     * Build __NAME__ for propagation. First look if there ia a defined connObjectLink for the given resource (and in
+     * this case evaluate as JEXL); otherwise, take given connObjectKey.
      *
      * @param any given any object
      * @param provision external resource
@@ -384,29 +384,29 @@ public final class MappingUtils {
             LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
         }
 
-        // Evaluate AccountLink expression
-        String evalAccountLink = null;
+        // Evaluate connObjectKey expression
+        String evalConnObjectLink = null;
         if (StringUtils.isNotBlank(anyUtils.getConnObjectLink(provision))) {
             final JexlContext jexlContext = new MapContext();
             JexlUtils.addFieldsToContext(any, jexlContext);
             JexlUtils.addAttrsToContext(any.getPlainAttrs(), jexlContext);
             JexlUtils.addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
-            evalAccountLink = JexlUtils.evaluate(anyUtils.getConnObjectLink(provision), jexlContext);
+            evalConnObjectLink = JexlUtils.evaluate(anyUtils.getConnObjectLink(provision), jexlContext);
         }
 
-        // If AccountLink evaluates to an empty string, just use the provided AccountId as Name(),
-        // otherwise evaluated AccountLink expression is taken as Name().
+        // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
+        // otherwise evaluated connObjectLink expression is taken as Name().
         Name name;
-        if (StringUtils.isBlank(evalAccountLink)) {
-            // add AccountId as __NAME__ attribute ...
-            LOG.debug("Add AccountId [{}] as __NAME__", connObjectKey);
+        if (StringUtils.isBlank(evalConnObjectLink)) {
+            // add connObjectKey as __NAME__ attribute ...
+            LOG.debug("Add connObjectKey [{}] as __NAME__", connObjectKey);
             name = new Name(connObjectKey);
         } else {
-            LOG.debug("Add AccountLink [{}] as __NAME__", evalAccountLink);
-            name = new Name(evalAccountLink);
+            LOG.debug("Add connObjectLink [{}] as __NAME__", evalConnObjectLink);
+            name = new Name(evalConnObjectLink);
 
-            // AccountId not propagated: it will be used to set the value for __UID__ attribute
-            LOG.debug("AccountId will be used just as __UID__ attribute");
+            // connObjectKey not propagated: it will be used to set the value for __UID__ attribute
+            LOG.debug("connObjectKey will be used just as __UID__ attribute");
         }
 
         return name;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
index d91b948..6a14e58 100644
--- 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
@@ -61,8 +61,6 @@ 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;
@@ -70,8 +68,6 @@ 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
@@ -193,7 +189,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
 
     @Override
     public <T extends Any<?, ?, ?>> boolean matches(
-            final T subject, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+            final T any, final SearchCond searchCondition, final AnyTypeKind typeKind) {
 
         List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
 
@@ -208,7 +204,7 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         } 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()));
+            queryString.append(") u WHERE any_id=?").append(setParameter(parameters, any.getKey()));
 
             // 3. prepare the search query
             Query query = entityManager.createNativeQuery(queryString.toString());
@@ -305,8 +301,8 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
             // 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) {
+            Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), fieldName);
+            if (anyField == null) {
                 PlainSchema schema = schemaDAO.find(fieldName);
                 if (schema != null) {
                     if (schema.isUniqueConstraint()) {
@@ -389,25 +385,25 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         // 6. Prepare the result (avoiding duplicates)
         List<T> result = new ArrayList<>();
 
-        for (Object subjectKey : query.getResultList()) {
+        for (Object anyKey : query.getResultList()) {
             long actualKey;
-            if (subjectKey instanceof Object[]) {
-                actualKey = ((Number) ((Object[]) subjectKey)[0]).longValue();
+            if (anyKey instanceof Object[]) {
+                actualKey = ((Number) ((Object[]) anyKey)[0]).longValue();
             } else {
-                actualKey = ((Number) subjectKey).longValue();
+                actualKey = ((Number) anyKey).longValue();
             }
 
-            T subject = typeKind == AnyTypeKind.USER
+            T any = typeKind == AnyTypeKind.USER
                     ? (T) userDAO.find(actualKey)
                     : typeKind == AnyTypeKind.GROUP
                             ? (T) groupDAO.find(actualKey)
                             : (T) anyObjectDAO.find(actualKey);
-            if (subject == null) {
+            if (any == 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);
+                if (!result.contains(any)) {
+                    result.add(any);
                 }
             }
         }
@@ -736,26 +732,26 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
             cond.setSchema("id");
         }
 
-        Field subjectField = ReflectionUtils.findField(attrUtils.anyClass(), cond.getSchema());
-        if (subjectField == null) {
+        Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), cond.getSchema());
+        if (anyField == null) {
             LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
             return EMPTY_ATTR_QUERY;
         }
 
         PlainSchema schema = new JPAPlainSchema();
-        schema.setKey(subjectField.getName());
+        schema.setKey(anyField.getName());
         for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
-            if (subjectField.getType().isAssignableFrom(attrSchemaType.getType())) {
+            if (anyField.getType().isAssignableFrom(attrSchemaType.getType())) {
                 schema.setType(attrSchemaType);
             }
         }
 
-        // Deal with subject Integer fields logically mapping to boolean values
+        // Deal with any 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 (Integer.class.equals(anyField.getType())) {
+            for (Annotation annotation : anyField.getAnnotations()) {
                 if (Min.class.equals(annotation.annotationType())) {
                     foundBooleanMin = ((Min) annotation).value() == 0;
                 } else if (Max.class.equals(annotation.annotationType())) {
@@ -767,13 +763,13 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
             schema.setType(AttrSchemaType.Boolean);
         }
 
-        // Deal with subject fields representing relationships to other entities
-        if (subjectField.getType().getAnnotation(Entity.class) != null) {
+        // Deal with any fields representing relationships to other entities
+        if (anyField.getType().getAnnotation(Entity.class) != null) {
             Method relMethod = null;
             try {
-                relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
+                relMethod = ClassUtils.getPublicMethod(anyField.getType(), "getKey", new Class[0]);
             } catch (Exception e) {
-                LOG.error("Could not find {}#getKey", subjectField.getType(), e);
+                LOG.error("Could not find {}#getKey", anyField.getType(), e);
             }
 
             if (relMethod != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 77eea1c..f888374 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
@@ -82,8 +82,8 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
         MappingItem connObjectKey = mapping.getConnObjectKeyItem();
         if (connObjectKey.getIntMappingType().getAnyTypeKind() != anyType.getKind()) {
             context.buildConstraintViolationWithTemplate(
-                    getTemplate(EntityViolationType.InvalidMapping, "ConnObjectKey must be from the same AnyType")).
-                    addPropertyNode("attributableType").addConstraintViolation();
+                    getTemplate(EntityViolationType.InvalidMapping, "ConnObjectKey must be from the same AnyTypeKind")).
+                    addPropertyNode("anyTypeKind").addConstraintViolation();
             return false;
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
index 9d253da..fcc3982 100644
--- 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
@@ -272,7 +272,7 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
-    public void searchByBooleanSubjectCond() {
+    public void searchByBooleanAnyCond() {
         AttributeCond booleanCond = new AttributeCond(AnyCond.Type.EQ);
         booleanCond.setSchema("show");
         booleanCond.setExpression("true");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 f0344b4..8535dc2 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
@@ -66,16 +66,16 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     protected GroupDAO groupDAO;
 
     @Override
-    public Pair<Long, List<PropagationStatus>> create(final GroupTO subject) {
-        return create(subject, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO any) {
+        return create(any, Collections.<String>emptySet());
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> create(final GroupTO subject, final Set<String> excludedResources) {
-        WorkflowResult<Long> created = gwfAdapter.create(subject);
+    public Pair<Long, List<PropagationStatus>> create(final GroupTO any, final Set<String> excludedResources) {
+        WorkflowResult<Long> created = gwfAdapter.create(any);
 
         List<PropagationTask> tasks =
-                propagationManager.getGroupCreateTasks(created, subject.getVirAttrs(), excludedResources);
+                propagationManager.getGroupCreateTasks(created, any.getVirAttrs(), excludedResources);
         PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext().getBean(
                 PropagationReporter.class);
         try {
@@ -107,18 +107,18 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public Pair<Long, List<PropagationStatus>> update(final GroupMod subjectMod) {
-        return update(subjectMod, Collections.<String>emptySet());
+    public Pair<Long, List<PropagationStatus>> update(final GroupMod anyMod) {
+        return update(anyMod, Collections.<String>emptySet());
     }
 
     @Override
     public Pair<Long, List<PropagationStatus>> update(
-            final GroupMod subjectMod, final Set<String> excludedResources) {
+            final GroupMod anyMod, final Set<String> excludedResources) {
 
-        WorkflowResult<Long> updated = gwfAdapter.update(subjectMod);
+        WorkflowResult<Long> updated = gwfAdapter.update(anyMod);
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
-                subjectMod.getVirAttrsToRemove(), subjectMod.getVirAttrsToUpdate(), null);
+                anyMod.getVirAttrsToRemove(), anyMod.getVirAttrsToUpdate(), null);
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {
@@ -134,10 +134,10 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long subjectKey) {
+    public List<PropagationStatus> delete(final Long anyKey) {
         final List<PropagationTask> tasks = new ArrayList<>();
 
-        Group group = groupDAO.authFind(subjectKey);
+        Group group = groupDAO.authFind(anyKey);
         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)
@@ -163,7 +163,7 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
         }
 
         try {
-            gwfAdapter.delete(subjectKey);
+            gwfAdapter.delete(anyKey);
         } catch (RuntimeException e) {
             throw e;
         }
@@ -172,8 +172,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public Long unlink(final GroupMod subjectMod) {
-        WorkflowResult<Long> updated = gwfAdapter.update(subjectMod);
+    public Long unlink(final GroupMod anyMod) {
+        WorkflowResult<Long> updated = gwfAdapter.update(anyMod);
         return updated.getResult();
     }
 
@@ -197,8 +197,8 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     }
 
     @Override
-    public Long link(final GroupMod subjectMod) {
-        return gwfAdapter.update(subjectMod).getResult();
+    public Long link(final GroupMod anyMod) {
+        return gwfAdapter.update(anyMod).getResult();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 5826786..58ecb4a 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
@@ -143,13 +143,13 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public List<PropagationStatus> delete(final Long subjectId, final Set<String> excludedResources) {
+    public List<PropagationStatus> delete(final Long anyId, final Set<String> excludedResources) {
         // Note here that we can only notify about "delete", not any other
         // task defined in workflow process definition: this because this
         // information could only be available after uwfAdapter.delete(), which
         // will also effectively remove user from db, thus making virtually
         // impossible by NotificationManager to fetch required user information
-        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(subjectId, excludedResources);
+        List<PropagationTask> tasks = propagationManager.getUserDeleteTasks(anyId, excludedResources);
 
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
@@ -161,7 +161,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
         }
 
         try {
-            uwfAdapter.delete(subjectId);
+            uwfAdapter.delete(anyId);
         } catch (PropagationException e) {
             throw e;
         }
@@ -176,8 +176,8 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
     }
 
     @Override
-    public Long link(final UserMod subjectMod) {
-        return uwfAdapter.update(subjectMod).getResult().getKey().getKey();
+    public Long link(final UserMod anyMod) {
+        return uwfAdapter.update(anyMod).getResult().getKey().getKey();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 3ffc1c3..6c11f8a 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
@@ -138,7 +138,7 @@ public class VirAttrHandler {
 
                             // 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());
+                                propByRes.addOldConnObjectKey(resource.getKey(), virAttr.getValues().get(0).toString());
                             }
                         }
                     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 bac145e..21d2236 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
@@ -56,7 +56,7 @@ public class MemoryVirAttrCache implements VirAttrCache {
      * Cache virtual attribute values.
      *
      * @param type any object type
-     * @param key attributable key
+     * @param key any key
      * @param schemaName virtual attribute name
      * @param value virtual attribute values
      */
@@ -81,7 +81,7 @@ public class MemoryVirAttrCache implements VirAttrCache {
      * Retrieve cached value. Return null in case of virtual attribute not cached.
      *
      * @param type any object type
-     * @param key attributable key
+     * @param key any key
      * @param schemaName virtual attribute schema name.
      * @return cached values or null if virtual attribute is not cached.
      */
@@ -94,7 +94,7 @@ public class MemoryVirAttrCache implements VirAttrCache {
      * Force entry expiring.
      *
      * @param type any object type
-     * @param key attributable key
+     * @param key any key
      * @param schemaName virtual attribute schema name
      */
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 3551a80..f63a9b4 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -353,7 +353,7 @@ abstract class AbstractAnyDataBinder {
                             propByRes.add(ResourceOperation.UPDATE, resource.getKey());
 
                             if (mapItem.isConnObjectKey() && attr != null && !attr.getValuesAsStrings().isEmpty()) {
-                                propByRes.addOldAccountId(resource.getKey(), attr.getValuesAsStrings().get(0));
+                                propByRes.addOldConnObjectKey(resource.getKey(), attr.getValuesAsStrings().get(0));
                             }
                         }
                     }
@@ -451,7 +451,7 @@ abstract class AbstractAnyDataBinder {
                             if (mapItem.isConnObjectKey() && derAttr != null
                                     && !derAttr.getValue(any.getPlainAttrs()).isEmpty()) {
 
-                                propByRes.addOldAccountId(resource.getKey(),
+                                propByRes.addOldConnObjectKey(resource.getKey(),
                                         derAttr.getValue(any.getPlainAttrs()));
                             }
                         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 17370e6..6bce1b1 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
@@ -126,7 +126,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
 
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
-        // fetch account ids before update
+        // fetch connObjectKeys before update
         Map<String, String> oldConnObjectKeys = getConnObjectKeys(group);
 
         // realm
@@ -153,13 +153,13 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
         // attributes, derived attributes, virtual attributes and resources
         propByRes.merge(fill(group, groupMod, anyUtilsFactory.getInstance(AnyTypeKind.GROUP), scce));
 
-        // check if some account id was changed by the update above
+        // check if some connObjectKey was changed by the update above
         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.addOldConnObjectKey(entry.getKey(), entry.getValue());
                 propByRes.add(ResourceOperation.UPDATE, entry.getKey());
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 fae0f9f..4930764 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
@@ -246,7 +246,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             itemTO.setKey(item.getKey());
             BeanUtils.copyProperties(item, itemTO, MAPPINGITEM_IGNORE_PROPERTIES);
 
-            if (itemTO.isAccountid()) {
+            if (itemTO.isConnObjectKey()) {
                 mappingTO.setConnObjectKeyItem(itemTO);
             } else {
                 mappingTO.add(itemTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 e7ec3cd..e20e405 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
@@ -213,7 +213,7 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
 
         Collection<String> currentResources = userDAO.findAllResourceNames(user);
 
-        // fetch account ids before update
+        // fetch connObjectKeys before update
         Map<String, String> oldConnObjectKeys = getConnObjectKeys(user);
 
         // realm
@@ -336,13 +336,13 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             propByRes.addAll(ResourceOperation.UPDATE, currentResources);
         }
 
-        // check if some account id was changed by the update above
-        Map<String, String> newAccountIds = getConnObjectKeys(user);
+        // check if some connObjectKey was changed by the update above
+        Map<String, String> newcCnnObjectKeys = getConnObjectKeys(user);
         for (Map.Entry<String, String> entry : oldConnObjectKeys.entrySet()) {
-            if (newAccountIds.containsKey(entry.getKey())
-                    && !entry.getValue().equals(newAccountIds.get(entry.getKey()))) {
+            if (newcCnnObjectKeys.containsKey(entry.getKey())
+                    && !entry.getValue().equals(newcCnnObjectKeys.get(entry.getKey()))) {
 
-                propByRes.addOldAccountId(entry.getKey(), entry.getValue());
+                propByRes.addOldConnObjectKey(entry.getKey(), entry.getValue());
                 propByRes.add(ResourceOperation.UPDATE, entry.getKey());
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 5c89dbb..73a7896 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
@@ -296,11 +296,11 @@ 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).
              */
-            Any<?, ?, ?> subject = getAny(task);
-            Collection<String> resources = subject instanceof User
-                    ? userDAO.findAllResourceNames((User) subject)
-                    : subject instanceof Group
-                            ? ((Group) subject).getResourceNames()
+            Any<?, ?, ?> any = getAny(task);
+            Collection<String> resources = any instanceof User
+                    ? userDAO.findAllResourceNames((User) any)
+                    : any instanceof Group
+                            ? ((Group) any).getResourceNames()
                             : Collections.<String>emptySet();
             if (!resources.contains(task.getResource().getKey())) {
                 LOG.debug("Delete {} on {}", beforeObj.getUid(), task.getResource().getKey());
@@ -527,7 +527,7 @@ 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.
+     * @param latest 'FALSE' to retrieve object using old connObjectKey if not null.
      * @return remote connector object.
      */
     protected ConnectorObject getRemoteObject(final PropagationTask task, final Connector connector,

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 d01b5c5..6d795d8 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
@@ -76,31 +76,31 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
         if (AnyTypeKind.USER == task.getAnyTypeKind() && provision.getMapping() != null) {
             User user = userDAO.find(task.getAnyKey());
             if (user != null) {
-                List<String> groupAccountLinks = new ArrayList<>();
+                List<String> groupConnObjectLinks = new ArrayList<>();
                 for (Group group : userDAO.findAllGroups(user)) {
                     if (group.getResourceNames().contains(task.getResource().getKey())
                             && StringUtils.isNotBlank(provision.getMapping().getConnObjectLink())) {
 
-                        LOG.debug("Evaluating accountLink for {}", group);
+                        LOG.debug("Evaluating connObjectLink for {}", group);
 
                         JexlContext jexlContext = new MapContext();
                         JexlUtils.addFieldsToContext(group, jexlContext);
                         JexlUtils.addAttrsToContext(group.getPlainAttrs(), jexlContext);
                         JexlUtils.addDerAttrsToContext(group.getDerAttrs(), group.getPlainAttrs(), jexlContext);
 
-                        String groupAccountLink =
+                        String groupConnObjectLinkLink =
                                 JexlUtils.evaluate(provision.getMapping().getConnObjectLink(), jexlContext);
-                        LOG.debug("AccountLink for {} is '{}'", group, groupAccountLink);
-                        if (StringUtils.isNotBlank(groupAccountLink)) {
-                            groupAccountLinks.add(groupAccountLink);
+                        LOG.debug("ConnObjectLink for {} is '{}'", group, groupConnObjectLinkLink);
+                        if (StringUtils.isNotBlank(groupConnObjectLinkLink)) {
+                            groupConnObjectLinks.add(groupConnObjectLinkLink);
                         }
                     }
                 }
-                LOG.debug("Group accountLinks to propagate for membership: {}", groupAccountLinks);
+                LOG.debug("Group connObjectLinks to propagate for membership: {}", groupConnObjectLinks);
 
                 Set<Attribute> attributes = new HashSet<>(task.getAttributes());
 
-                Set<String> groups = new HashSet<>(groupAccountLinks);
+                Set<String> groups = new HashSet<>(groupConnObjectLinks);
                 Attribute ldapGroups = AttributeUtil.find(getGroupMembershipAttrName(), attributes);
 
                 if (ldapGroups != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 400b72e..952343b 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
@@ -467,7 +467,7 @@ public class PropagationManagerImpl implements PropagationManager {
                     }
                     task.setPropagationOperation(operation);
                     task.setPropagationMode(resource.getPropagationMode());
-                    task.setOldConnObjectKey(propByRes.getOldAccountId(resource.getKey()));
+                    task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
                     Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(anyUtils, any,
                             password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, enable, provision);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 b854921..1ead6a7 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
@@ -114,7 +114,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
         result.setAnyType(provision.getAnyType().getKey());
         result.setStatus(ProvisioningResult.Status.SUCCESS);
 
-        // Attributable transformation (if configured)
+        // Any transformation (if configured)
         AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 
@@ -145,7 +145,7 @@ public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHan
 
         AnyTO anyTO = connObjectUtils.getAnyTO(delta.getObject(), profile.getTask(), provision, anyUtils);
 
-        // Attributable transformation (if configured)
+        // Any transformation (if configured)
         AnyTO transformed = anyTransformer.transform(anyTO);
         LOG.debug("Transformed: {}", transformed);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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
index fcfb537..503ce0b 100644
--- 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
@@ -111,7 +111,7 @@ public class AnyObjectPushResultHandlerImpl extends AbstractPushResultHandler im
     }
 
     @Override
-    protected String getName(final Any<?, ?, ?> subject) {
+    protected String getName(final Any<?, ?, ?> any) {
         return StringUtils.EMPTY;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a78a6f1f/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 38ae900..78fffbf 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
@@ -110,8 +110,8 @@ public class GroupPushResultHandlerImpl extends AbstractPushResultHandler implem
     }
 
     @Override
-    protected String getName(final Any<?, ?, ?> subject) {
-        return Group.class.cast(subject).getName();
+    protected String getName(final Any<?, ?, ?> any) {
+        return Group.class.cast(any).getName();
     }
 
     @Override


[28/70] 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;
-    }
-
-}


[45/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index c592c31..a75e4b6 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
@@ -312,6 +312,56 @@ under the License.
     </attributes>
   </entity>
 
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ADerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_ADerAttr" pk-column-value="SEQ_ADerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UDerAttr" pk-column-value="SEQ_UDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GDerAttr" pk-column-value="SEQ_GDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_AVirAttr" pk-column-value="SEQ_AVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UVirAttr" pk-column-value="SEQ_UVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GVirAttr" pk-column-value="SEQ_GVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
   <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
     <attributes>
       <id name="id">

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 746314c..6f83543 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
@@ -360,6 +360,56 @@ under the License.
     </attributes>
   </entity>
 
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ADerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_ADerAttr" pk-column-value="SEQ_ADerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UDerAttr" pk-column-value="SEQ_UDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GDerAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GDerAttr" pk-column-value="SEQ_GDerAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_AVirAttr" pk-column-value="SEQ_AVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UVirAttr" pk-column-value="SEQ_UVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_GVirAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_GVirAttr" pk-column-value="SEQ_GVirAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.task.JPAAnyTemplate">
     <attributes>
       <id name="id">

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e1ffc11..02815b8 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
@@ -60,7 +60,7 @@ public class VirAttrTest extends AbstractTest {
 
     @Test
     public void findById() {
-        UVirAttr attribute = virAttrDAO.find(1000L, UVirAttr.class);
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
         assertNotNull("did not find expected attribute schema", attribute);
     }
 
@@ -104,7 +104,7 @@ public class VirAttrTest extends AbstractTest {
 
     @Test
     public void delete() {
-        UVirAttr attribute = virAttrDAO.find(1000L, UVirAttr.class);
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
         String attributeSchemaName = attribute.getSchema().getKey();
 
         virAttrDAO.delete(attribute.getKey(), UVirAttr.class);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
index e6a919d..60ff041 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
@@ -52,13 +52,8 @@ public class AnyTypeTest extends AbstractTest {
 
         anyTypeClassDAO.delete("other");
 
-        try {
         anyTypeDAO.flush();
-        } catch(Exception e) {
-            System.err.println("EEEEEEEEEEEE");
-            e.printStackTrace();
-        }
-        
+
         userType = anyTypeDAO.findUser();
         assertNotNull(userType);
         assertEquals(before, userType.getClasses().size() + 1);

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 8d2ef54..7c123a7 100644
--- a/core/persistence-jpa/src/test/resources/content.xml
+++ b/core/persistence-jpa/src/test/resources/content.xml
@@ -94,11 +94,11 @@ under the License.
   
   <!-- sample policies -->
   <Policy DTYPE="SyncPolicy" id="1" description="a sync policy" type="SYNC" 
-          specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"groupAltSearchSchemas":[]}'/>
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
   <Policy DTYPE="PasswordPolicy" id="2" description="a password policy" type="PASSWORD" 
           specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"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":true}'/>
   <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
-          specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"ALL","userAltSearchSchemas":["username","firstname"],"groupAltSearchSchemas":[]}'/>
+          specification='{"conflictResolutionAction":"ALL","items":[{"anyTypeKey":"USER","javaRule":null,"altSearchSchemas":["username","firstname"]}]}'/>
   <Policy DTYPE="PasswordPolicy" id="4" description="sample password policy" type="PASSWORD" 
           specification='{"historyLength":0,"maxLength":0,"minLength":10,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":true,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"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":true}'/>
   <Policy DTYPE="AccountPolicy" id="5" description="an account policy" type="ACCOUNT" 
@@ -106,11 +106,11 @@ under the License.
   <Policy DTYPE="AccountPolicy" id="6" description="sample account policy" type="ACCOUNT" 
           specification='{"maxLength":0,"minLength":4,"pattern":null,"allUpperCase":false,"allLowerCase":false,"propagateSuspension":false,"maxAuthenticationAttempts":3,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[]}'/>
   <Policy DTYPE="SyncPolicy" id="7" description="sync policy 1" type="SYNC" 
-          specification='{"userJavaRule":null,"groupJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"groupAltSearchSchemas":[]}'/>
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
   <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" 
           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":[]}'/>
+          specification='{"conflictResolutionAction":"IGNORE","items":[]}'/>
 
   <AnyTypeClass name="generic membership"/>
 
@@ -307,6 +307,7 @@ under the License.
   <DerSchema name="noschema" expression="surname + ', ' + notfound" anyTypeClass_name="other"/>
 
   <VirSchema name="virtualdata" anyTypeClass_name="minimal user"/>
+  <VirSchema name="virtualReadOnly" READONLY="1"  anyTypeClass_name="minimal user"/>
 
   <PlainSchema name="icon" type="String" anyTypeClass_name="minimal group"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>                
@@ -328,7 +329,7 @@ under the License.
 
   <VirSchema name="rvirtualdata" anyTypeClass_name="minimal group"/>
 
-  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"/>
+  <DerSchema name="rderivedschema" expression="rderived_sx + '-' + rderived_dx"  anyTypeClass_name="minimal group"/>
 
   <PlainSchema name="subscriptionDate" type="Date" anyTypeClass_name="generic membership"
                mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
@@ -412,9 +413,7 @@ under the License.
   <UPlainAttr id="126" owner_id="3" schema_name="type"/>
   <UPlainAttrValue id="37" attribute_id="126" stringValue="F"/>
     
-  <UVirAttr id="1000" schema_name="virtualdata" owner_id="3"/>
-
-  <VirSchema name="virtualReadOnly" READONLY="1"/>
+  <UVirAttr id="100" schema_name="virtualdata" owner_id="3"/>
   
   <UDerAttr id="100" schema_name="cn" owner_id="3"/>
   <UDerAttr id="101" schema_name="cn" owner_id="1"/>
@@ -446,13 +445,13 @@ under the License.
   <GPlainAttr id="995" owner_id="13" schema_name="title"/>
   <GPlainAttrValue attribute_id="995" id="95" stringValue="r13"/>
 
-  <GDerAttr id="1000" owner_id="1" schema_name="rderiveddata"/>
+  <GDerAttr id="100" owner_id="1" schema_name="rderiveddata"/>
     
-  <GDerAttr id="1001" owner_id="1" schema_name="displayProperty"/>
+  <GDerAttr id="101" owner_id="1" schema_name="displayProperty"/>
   
-  <GDerAttr id="1002" owner_id="4" schema_name="displayProperty"/>
+  <GDerAttr id="102" owner_id="4" schema_name="displayProperty"/>
 
-  <GDerAttr id="1003" owner_id="1" schema_name="rderToBePropagated"/>    
+  <GDerAttr id="103" owner_id="1" schema_name="rderToBePropagated"/>    
 
   <GVirAttr id="98" owner_id="4" schema_name="rvirtualdata"/>
 
@@ -816,10 +815,10 @@ under the License.
                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"/>
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
   <MappingItem id="209" extAttrName="membership" mapping_id="9"
                intAttrName="mderToBePropagated" intMappingType="AnyDerivedSchema" mandatoryCondition="false"
-               connObjectKey="0" password="0" purpose="BOTH"/>
+               connObjectKey="0" password="0" purpose="PROPAGATION"/>
                          
   <Provision id="10" resource_name="ws-target-resource-update-resetsynctoken" anyType_name="USER" objectClass="__ACCOUNT__"
              serializedSyncToken='{"value":null}'/>
@@ -853,7 +852,7 @@ under the License.
                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"
+               extAttrName="postalAddress" intAttrName="postalAddress" intMappingType="UserPlainSchema"
                mandatoryCondition="false" purpose="BOTH"/>
   <MappingItem id="318" connObjectKey="0" password="0" mapping_id="11"
                extAttrName="mail" intAttrName="userId" intMappingType="UserPlainSchema"
@@ -940,9 +939,9 @@ 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="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":[]}]}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":["csv"],"derAttrs":[{"schema":"cn","readonly":false,"values":[""]}],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"relationships":[],"memberships":[{"leftType":null,"leftKey":0,"rightType":"GROUP","rightKey":8,"groupName":null}],"dynGroups":[],"roles":[],"dynRoles":[],"plainAttrs":[{"schema":"type","readonly":false,"values":["email == &apos;test8@syncope.apache.org&apos;? &apos;TYPE_8&apos;: &apos;TYPE_OTHER&apos;"]}]}'/>
   <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": []}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <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" anyTypeKind="USER" anyKey="1"
@@ -951,10 +950,10 @@ under the License.
   <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"/>
-  <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": []}'/>
+  <AnyTemplate id="71" syncTask_id="7" anyType_name="USER"
+               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"relationships":[],"memberships":[],"dynGroups":[],"roles":[],"dynRoles":[],"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;"]}]}'/>
+  <AnyTemplate id="72" syncTask_id="7" anyType_name="GROUP"
+               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <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"
@@ -967,9 +966,9 @@ under the License.
         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"/>
   <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":[]}]}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[{"schema":"virtualReadOnly","readonly":true,"values":[""]}],"resources":["resource-ldap"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"plainAttrs":[]}'/>
   <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": []}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[{"schema":"show","readonly":false,"values":["true"]}]}'/>
   <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"
@@ -1044,9 +1043,9 @@ 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="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":[]}]}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.UserTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"USER","realm":null,"status":null,"password":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"securityQuestion":null,"securityAnswer":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":["resource-testdb"],"propagationStatuses":[],"roles":[],"dynRoles":[],"relationships":[],"memberships":[],"dynGroups":[],"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;"]}]}'/>
   <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": []}'/>
+               template='{"@class":"org.apache.syncope.common.lib.to.GroupTO","creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"type":"GROUP","realm":null,"status":null,"name":null,"userOwner":null,"groupOwner":null,"adynMembershipCond":null,"udynMembershipCond":null,"auxClasses":[],"derAttrs":[],"virAttrs":[],"resources":[],"propagationStatuses":[],"plainAttrs":[]}'/>
   <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"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
new file mode 100644
index 0000000..4cec074
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.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.core.provisioning.api;
+
+import java.util.Collection;
+import java.util.Set;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+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.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+
+public interface VirAttrHandler {
+
+    PropagationByResource fillVirtual(Any any, Set<String> vAttrsToBeRemoved, Set<AttrMod> vAttrsToBeUpdated);
+
+    /**
+     * Add virtual attributes and specify values to be propagated.
+     *
+     * @param any any.
+     * @param vAttrs virtual attributes to be added.
+     */
+    void fillVirtual(Any any, Collection<AttrTO> vAttrs);
+
+    /**
+     * SYNCOPE-459: build virtual attribute changes in case no other changes were made.
+     *
+     * @param key any key
+     * @param anyTypeKind type kind
+     * @param vAttrsToBeRemoved virtual attributes to be removed.
+     * @param vAttrsToBeUpdated virtual attributes to be updated.
+     * @return operations to be performed on external resources for virtual attributes changes
+     */
+    PropagationByResource fillVirtual(
+            Long key, AnyTypeKind anyTypeKind, Set<String> vAttrsToBeRemoved, Set<AttrMod> vAttrsToBeUpdated);
+
+    VirSchema getVirSchema(String virSchemaName);
+
+    /**
+     * Query connected external resources for values to populated virtual attributes associated with the given owner.
+     *
+     * @param any any object
+     */
+    void retrieveVirAttrValues(Any<?, ?, ?> any);
+
+    void updateOnResourcesIfMappingMatches(
+            Any<?, ?, ?> any, AnyUtils anyUtils, String schemaKey,
+            Iterable<? extends ExternalResource> resources, IntMappingType mappingType,
+            PropagationByResource propByRes);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeClassDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeClassDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeClassDataBinder.java
new file mode 100644
index 0000000..18187be
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeClassDataBinder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.to.AnyTypeClassTO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+
+public interface AnyTypeClassDataBinder {
+
+    AnyTypeClass create(AnyTypeClassTO anyTypeClassTO);
+
+    void update(AnyTypeClass anyTypeClass, AnyTypeClassTO anyTypeClassTO);
+
+    AnyTypeClassTO getAnyTypeClassTO(AnyTypeClass anyTypeClass);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
new file mode 100644
index 0000000..c29c2ac
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/AnyTypeDataBinder.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.to.AnyTypeTO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+
+public interface AnyTypeDataBinder {
+
+    AnyType create(AnyTypeTO anyTypeTO);
+
+    void update(AnyType anyType, AnyTypeTO anyTypeTO);
+
+    AnyTypeTO getAnyTypeTO(AnyType anyType);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
index 1bd2638..fd6bcf1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAnyObjectProvisioningManager.java
@@ -30,6 +30,8 @@ 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;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationByResource;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager;
@@ -40,6 +42,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -102,6 +105,18 @@ public class DefaultAnyObjectProvisioningManager implements AnyObjectProvisionin
 
         List<PropagationTask> tasks = propagationManager.getAnyObjectUpdateTasks(updated,
                 anyObjectMod.getVirAttrsToRemove(), anyObjectMod.getVirAttrsToUpdate(), null);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.ANY_OBJECT,
+                    anyObjectMod.getVirAttrsToRemove(),
+                    anyObjectMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getAnyObjectUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 c7bc1c4..5661df4 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
@@ -36,6 +36,7 @@ import org.apache.syncope.common.lib.mod.GroupMod;
 import org.apache.syncope.common.lib.to.AttrTO;
 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.PropagationByResource;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -47,6 +48,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
 
 public class DefaultGroupProvisioningManager implements GroupProvisioningManager {
@@ -65,6 +67,9 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
     @Autowired
     protected GroupDAO groupDAO;
 
+    @Autowired
+    protected VirAttrHandler virtAttrHandler;
+
     @Override
     public Pair<Long, List<PropagationStatus>> create(final GroupTO group) {
         return create(group, Collections.<String>emptySet());
@@ -119,6 +124,18 @@ public class DefaultGroupProvisioningManager implements GroupProvisioningManager
 
         List<PropagationTask> tasks = propagationManager.getGroupUpdateTasks(updated,
                 groupMod.getVirAttrsToRemove(), groupMod.getVirAttrsToUpdate(), excludedResources);
+        if (tasks.isEmpty()) {
+            // SYNCOPE-459: take care of user virtual attributes ...
+            PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
+                    updated.getResult(),
+                    AnyTypeKind.GROUP,
+                    groupMod.getVirAttrsToRemove(),
+                    groupMod.getVirAttrsToUpdate());
+            tasks.addAll(!propByResVirAttr.isEmpty()
+                    ? propagationManager.getGroupUpdateTasks(updated, null, null, null)
+                    : Collections.<PropagationTask>emptyList());
+        }
+
         PropagationReporter propagationReporter =
                 ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
         try {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 88d3094..656bc75 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
@@ -30,6 +30,7 @@ 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.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -42,6 +43,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.core.provisioning.api.sync.ProvisioningResult;
 import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.syncope.core.workflow.api.UserWorkflowAdapter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -120,6 +122,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
             // SYNCOPE-459: take care of user virtual attributes ...
             PropagationByResource propByResVirAttr = virtAttrHandler.fillVirtual(
                     updated.getResult().getKey().getKey(),
+                    AnyTypeKind.USER,
                     userMod.getVirAttrsToRemove(),
                     userMod.getVirAttrsToUpdate());
             tasks.addAll(!propByResVirAttr.isEmpty()

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
deleted file mode 100644
index 6c11f8a..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
+++ /dev/null
@@ -1,238 +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 java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-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.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.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.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.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-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 VirAttrHandler {
-
-    private static final Logger LOG = LoggerFactory.getLogger(VirAttrHandler.class);
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Autowired
-    private VirAttrDAO virAttrDAO;
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
-    public VirSchema getVirSchema(final String virSchemaName) {
-        VirSchema virtualSchema = null;
-        if (StringUtils.isNotBlank(virSchemaName)) {
-            virtualSchema = virSchemaDAO.find(virSchemaName);
-
-            if (virtualSchema == null) {
-                LOG.debug("Ignoring invalid virtual schema {}", virSchemaName);
-            }
-        }
-
-        return virtualSchema;
-    }
-
-    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 : anyUtils.getMappingItems(
-                    resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
-
-                if (schemaKey.equals(mapItem.getIntAttrName()) && mapItem.getIntMappingType() == mappingType) {
-                    propByRes.add(ResourceOperation.UPDATE, resource.getKey());
-                }
-            }
-        }
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    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 (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);
-            if (virSchema != null) {
-                VirAttr virAttr = any.getVirAttr(virSchema.getKey());
-                if (virAttr == null) {
-                    LOG.debug("No virtual attribute found for schema {}", virSchema.getKey());
-                } else {
-                    any.remove(virAttr);
-                    virAttrDAO.delete(virAttr);
-                }
-
-                for (ExternalResource resource : externalResources) {
-                    for (MappingItem mapItem : anyUtils.getMappingItems(
-                            resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
-
-                        if (virSchema.getKey().equals(mapItem.getIntAttrName())
-                                && mapItem.getIntMappingType() == anyUtils.virIntMappingType()) {
-
-                            propByRes.add(ResourceOperation.UPDATE, resource.getKey());
-
-                            // Using virtual attribute as ConnObjectKey must be avoided
-                            if (mapItem.isConnObjectKey() && virAttr != null && !virAttr.getValues().isEmpty()) {
-                                propByRes.addOldConnObjectKey(resource.getKey(), virAttr.getValues().get(0).toString());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        LOG.debug("Virtual attributes to be removed:\n{}", propByRes);
-
-        // 2. virtual attributes to be updated
-        for (AttrMod vAttrToBeUpdated : vAttrsToBeUpdated) {
-            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema());
-            VirAttr virAttr = null;
-            if (virSchema != null) {
-                virAttr = any.getVirAttr(virSchema.getKey());
-                if (virAttr == null) {
-                    virAttr = anyUtils.newVirAttr();
-                    virAttr.setSchema(virSchema);
-                    if (virAttr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema was found", vAttrToBeUpdated);
-                    } else {
-                        any.add(virAttr);
-                    }
-                }
-            }
-
-            if (virSchema != null && virAttr != null && virAttr.getSchema() != null) {
-                updateOnResourcesIfMappingMatches(any, anyUtils, virSchema.getKey(),
-                        externalResources, anyUtils.derIntMappingType(), propByRes);
-
-                List<String> values = new ArrayList<>(virAttr.getValues());
-                values.removeAll(vAttrToBeUpdated.getValuesToBeRemoved());
-                values.addAll(vAttrToBeUpdated.getValuesToBeAdded());
-
-                virAttr.getValues().clear();
-                virAttr.getValues().addAll(values);
-
-                // Owner cannot be specified before otherwise a virtual attribute remove will be invalidated.
-                virAttr.setOwner(any);
-            }
-        }
-
-        LOG.debug("Virtual attributes to be added:\n{}", propByRes);
-
-        return propByRes;
-    }
-
-    /**
-     * Add virtual attributes and specify values to be propagated.
-     *
-     * @param any any.
-     * @param vAttrs virtual attributes to be added.
-     * @param anyUtils utils
-     */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    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(attrTO.getSchema());
-                if (virSchema != null) {
-                    virAttr = anyUtils.newVirAttr();
-                    virAttr.setSchema(virSchema);
-                    if (virAttr.getSchema() == null) {
-                        LOG.debug("Ignoring {} because no valid schema was found", attrTO);
-                    } else {
-                        virAttr.setOwner(any);
-                        any.add(virAttr);
-                        virAttr.getValues().clear();
-                        virAttr.getValues().addAll(attrTO.getValues());
-                    }
-                }
-            } else {
-                virAttr.getValues().clear();
-                virAttr.getValues().addAll(attrTO.getValues());
-            }
-        }
-    }
-
-    /**
-     * SYNCOPE-459: build virtual attribute changes in case no other changes were made.
-     *
-     * @param key user id
-     * @param vAttrsToBeRemoved virtual attributes to be removed.
-     * @param vAttrsToBeUpdated virtual attributes to be updated.
-     * @return operations to be performed on external resources for virtual attributes changes
-     */
-    public PropagationByResource fillVirtual(
-            final Long key, final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated) {
-
-        return fillVirtual(
-                anyObjectDAO.authFind(key),
-                vAttrsToBeRemoved,
-                vAttrsToBeUpdated,
-                anyUtilsFactory.getInstance(AnyTypeKind.USER));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
new file mode 100644
index 0000000..21626f5
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.core.provisioning.api.VirAttrHandler;
+import java.util.ArrayList;
+import java.util.Collection;
+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.collections4.Predicate;
+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.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.misc.MappingUtils;
+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.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.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.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+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.Connector;
+import org.apache.syncope.core.provisioning.api.ConnectorFactory;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
+import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.framework.common.objects.Uid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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 VirAttrHandlerImpl implements VirAttrHandler {
+
+    private static final Logger LOG = LoggerFactory.getLogger(VirAttrHandler.class);
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private VirAttrDAO virAttrDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnyUtilsFactory anyUtilsFactory;
+
+    @Autowired
+    private ConnectorFactory connFactory;
+
+    /**
+     * Virtual attribute cache.
+     */
+    @Autowired
+    private VirAttrCache virAttrCache;
+
+    @Override
+    public VirSchema getVirSchema(final String virSchemaName) {
+        VirSchema virtualSchema = null;
+        if (StringUtils.isNotBlank(virSchemaName)) {
+            virtualSchema = virSchemaDAO.find(virSchemaName);
+
+            if (virtualSchema == null) {
+                LOG.debug("Ignoring invalid virtual schema {}", virSchemaName);
+            }
+        }
+
+        return virtualSchema;
+    }
+
+    @Override
+    public void updateOnResourcesIfMappingMatches(final Any<?, ?, ?> any, final AnyUtils anyUtils,
+            final String schemaKey, final Iterable<? extends ExternalResource> resources,
+            final IntMappingType mappingType, final PropagationByResource propByRes) {
+
+        for (ExternalResource resource : resources) {
+            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());
+                }
+            }
+        }
+    }
+
+    private Iterable<? extends ExternalResource> getAllResources(final Any<?, ?, ?> any) {
+        return any instanceof User
+                ? userDAO.findAllResources((User) any)
+                : any instanceof AnyObject
+                        ? anyObjectDAO.findAllResources((AnyObject) any)
+                        : any instanceof Group
+                                ? ((Group) any).getResources()
+                                : Collections.<ExternalResource>emptySet();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public PropagationByResource fillVirtual(final Any any,
+            final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated) {
+
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+
+        PropagationByResource propByRes = new PropagationByResource();
+
+        Iterable<? extends ExternalResource> externalResources = getAllResources(any);
+
+        // 1. virtual attributes to be removed
+        for (String vAttrToBeRemoved : vAttrsToBeRemoved) {
+            VirSchema virSchema = getVirSchema(vAttrToBeRemoved);
+            if (virSchema != null) {
+                VirAttr virAttr = any.getVirAttr(virSchema.getKey());
+                if (virAttr == null) {
+                    LOG.debug("No virtual attribute found for schema {}", virSchema.getKey());
+                } else {
+                    any.remove(virAttr);
+                    virAttrDAO.delete(virAttr);
+                }
+
+                for (ExternalResource resource : externalResources) {
+                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                            resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
+
+                        if (virSchema.getKey().equals(mapItem.getIntAttrName())
+                                && mapItem.getIntMappingType() == anyUtils.virIntMappingType()) {
+
+                            propByRes.add(ResourceOperation.UPDATE, resource.getKey());
+
+                            // Using virtual attribute as ConnObjectKey must be avoided
+                            if (mapItem.isConnObjectKey() && virAttr != null && !virAttr.getValues().isEmpty()) {
+                                propByRes.addOldConnObjectKey(resource.getKey(), virAttr.getValues().get(0).toString());
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        LOG.debug("Virtual attributes to be removed:\n{}", propByRes);
+
+        // 2. virtual attributes to be updated
+        for (AttrMod vAttrToBeUpdated : vAttrsToBeUpdated) {
+            VirSchema virSchema = getVirSchema(vAttrToBeUpdated.getSchema());
+            if (virSchema != null) {
+                VirAttr virAttr = any.getVirAttr(virSchema.getKey());
+                if (virAttr == null) {
+                    virAttr = anyUtils.newVirAttr();
+                    virAttr.setOwner(any);
+                    virAttr.setSchema(virSchema);
+
+                    any.add(virAttr);
+                }
+
+                updateOnResourcesIfMappingMatches(any, anyUtils, virSchema.getKey(),
+                        externalResources, anyUtils.derIntMappingType(), propByRes);
+
+                List<String> values = new ArrayList<>(virAttr.getValues());
+                values.removeAll(vAttrToBeUpdated.getValuesToBeRemoved());
+                values.addAll(vAttrToBeUpdated.getValuesToBeAdded());
+
+                virAttr.getValues().clear();
+                virAttr.getValues().addAll(values);
+            }
+        }
+
+        LOG.debug("Virtual attributes to be added:\n{}", propByRes);
+
+        return propByRes;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public void fillVirtual(final Any any, final Collection<AttrTO> vAttrs) {
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+
+        for (AttrTO attrTO : vAttrs) {
+            VirAttr virAttr = any.getVirAttr(attrTO.getSchema());
+            if (virAttr == null) {
+                VirSchema virSchema = getVirSchema(attrTO.getSchema());
+                if (virSchema != null) {
+                    virAttr = anyUtils.newVirAttr();
+                    virAttr.setSchema(virSchema);
+                    if (virAttr.getSchema() == null) {
+                        LOG.debug("Ignoring {} because no valid schema was found", attrTO);
+                    } else {
+                        virAttr.setOwner(any);
+                        any.add(virAttr);
+                        virAttr.getValues().clear();
+                        virAttr.getValues().addAll(attrTO.getValues());
+                    }
+                }
+            } else {
+                virAttr.getValues().clear();
+                virAttr.getValues().addAll(attrTO.getValues());
+            }
+        }
+    }
+
+    private Any<?, ?, ?> find(final Long key, final AnyTypeKind anyTypeKind) {
+        Any<?, ?, ?> result;
+
+        switch (anyTypeKind) {
+            case USER:
+                result = userDAO.authFind(key);
+                break;
+
+            case GROUP:
+                result = groupDAO.authFind(key);
+                break;
+
+            case ANY_OBJECT:
+            default:
+                result = anyObjectDAO.authFind(key);
+        }
+
+        return result;
+    }
+
+    @Transactional
+    @Override
+    public PropagationByResource fillVirtual(
+            final Long key, final AnyTypeKind anyTypeKind,
+            final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated) {
+
+        return fillVirtual(
+                find(key, anyTypeKind),
+                vAttrsToBeRemoved,
+                vAttrsToBeUpdated);
+    }
+
+    @Override
+    public void retrieveVirAttrValues(final Any<?, ?, ?> any) {
+        IntMappingType type = any.getType().getKind() == AnyTypeKind.USER
+                ? IntMappingType.UserVirtualSchema
+                : any.getType().getKind() == AnyTypeKind.GROUP
+                        ? IntMappingType.GroupVirtualSchema
+                        : IntMappingType.AnyVirtualSchema;
+
+        Map<String, ConnectorObject> resources = new HashMap<>();
+
+        // -----------------------
+        // Retrieve virtual attribute values if and only if they have not been retrieved yet
+        // -----------------------
+        for (VirAttr<?> virAttr : any.getVirAttrs()) {
+            // reset value set
+            if (virAttr.getValues().isEmpty()) {
+                retrieveVirAttrValue(any, virAttr, type, resources);
+            }
+        }
+        // -----------------------
+    }
+
+    private void retrieveVirAttrValue(
+            final Any<?, ?, ?> any,
+            final VirAttr<?> virAttr,
+            final IntMappingType type,
+            final Map<String, ConnectorObject> externalResources) {
+
+        String schemaName = virAttr.getSchema().getKey();
+        VirAttrCacheValue virAttrCacheValue = virAttrCache.get(any.getType().getKey(), any.getKey(), schemaName);
+
+        LOG.debug("Retrieve values for virtual attribute {} ({})", schemaName, type);
+
+        if (virAttrCache.isValidEntry(virAttrCacheValue)) {
+            // cached ...
+            LOG.debug("Values found in cache {}", virAttrCacheValue);
+            virAttr.getValues().clear();
+            virAttr.getValues().addAll(new ArrayList<>(virAttrCacheValue.getValues()));
+        } else {
+            // not cached ...
+            LOG.debug("Need one or more remote connections");
+
+            VirAttrCacheValue toBeCached = new VirAttrCacheValue();
+
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
+
+            for (ExternalResource resource : getTargetResources(virAttr, type, anyUtils, any.getType())) {
+                Provision provision = resource.getProvision(any.getType());
+                LOG.debug("Search values into {},{}", resource, provision);
+
+                try {
+                    List<MappingItem> mappings = anyUtils.getMappingItems(provision, MappingPurpose.BOTH);
+
+                    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);
+
+                        if (StringUtils.isBlank(connObjectKey)) {
+                            throw new IllegalArgumentException("No ConnObjectKey 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);
+
+                        // 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());
+                                    }
+                                }
+                            }
+                        }
+
+                        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));
+                        }
+                    }
+                }
+            }
+
+            virAttrCache.put(any.getType().getKey(), any.getKey(), schemaName, toBeCached);
+        }
+    }
+
+    private Collection<ExternalResource> getTargetResources(
+            final VirAttr<?> attr, final IntMappingType type, final AnyUtils anyUtils, final AnyType anyType) {
+
+        return CollectionUtils.select(getAllResources(attr.getOwner()), new Predicate<ExternalResource>() {
+
+            @Override
+            public boolean evaluate(final ExternalResource resource) {
+                return resource.getProvision(anyType) != null
+                        && !MappingUtils.getMatchingMappingItems(
+                                anyUtils.getMappingItems(resource.getProvision(anyType), MappingPurpose.BOTH),
+                                attr.getSchema().getKey(), type).isEmpty();
+            }
+        });
+    }
+}


[04/70] 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));
     }
 }


[55/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
new file mode 100644
index 0000000..e2b339a
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyObjectITCase.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+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.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyObjectITCase extends AbstractITCase {
+
+    public static AnyObjectTO getSampleTO(final String location) {
+        AnyObjectTO anyObjectTO = new AnyObjectTO();
+        anyObjectTO.setRealm(SyncopeConstants.ROOT_REALM);
+        anyObjectTO.setType("PRINTER");
+        anyObjectTO.getPlainAttrs().add(attrTO("location", location + getUUIDString()));
+
+        anyObjectTO.getResources().add(RESOURCE_NAME_DBSCRIPTED);
+        return anyObjectTO;
+    }
+
+    @Test
+    public void create() {
+        AnyObjectTO anyObjectTO = getSampleTO("create");
+
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        ConnObjectTO connObjectTO =
+                resourceService.readConnObject(RESOURCE_NAME_DBSCRIPTED, anyObjectTO.getType(), anyObjectTO.getKey());
+        assertNotNull(connObjectTO);
+        assertNotNull(connObjectTO.getPlainAttrMap().get("location"));
+        assertEquals(anyObjectTO.getPlainAttrMap().get("location"), connObjectTO.getPlainAttrMap().get("location"));
+    }
+
+    @Test
+    public void delete() {
+        try {
+            anyObjectService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        AnyObjectTO anyObjectTO = getSampleTO("deletable");
+        anyObjectTO.setRealm("/even");
+
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        AnyObjectTO deletedAnyObject = deleteAnyObject(anyObjectTO.getKey());
+        assertNotNull(deletedAnyObject);
+
+        try {
+            anyObjectService.read(deletedAnyObject.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        PagedResult<AnyObjectTO> anyObjectTOs = anyObjectService.list("PRINTER", SyncopeClient.getAnyListQueryBuilder().
+                realm(SyncopeConstants.ROOT_REALM).build());
+        assertNotNull(anyObjectTOs);
+        assertTrue(anyObjectTOs.getResult().size() >= 2);
+        for (AnyObjectTO anyObjectTO : anyObjectTOs.getResult()) {
+            assertNotNull(anyObjectTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        AnyObjectTO anyObjectTO = anyObjectService.read(1L);
+
+        assertNotNull(anyObjectTO);
+        assertNotNull(anyObjectTO.getPlainAttrs());
+        assertFalse(anyObjectTO.getPlainAttrs().isEmpty());
+    }
+
+    @Test
+    public void update() {
+        AnyObjectTO anyObjectTO = getSampleTO("update");
+        anyObjectTO = createAnyObject(anyObjectTO);
+
+        assertEquals(1, anyObjectTO.getPlainAttrs().size());
+
+        AnyObjectMod anyObjectMod = new AnyObjectMod();
+        anyObjectMod.setKey(anyObjectTO.getKey());
+        String newLocation = "new" + getUUIDString();
+        anyObjectMod.getPlainAttrsToUpdate().add(attrMod("location", newLocation));
+
+        anyObjectTO = updateAnyObject(anyObjectMod);
+
+        assertEquals(newLocation, anyObjectTO.getPlainAttrMap().get("location").getValues().get(0));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
new file mode 100644
index 0000000..4dbb796
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+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 static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeClassITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeClassTO minimalGroup = anyTypeClassService.read("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeClassTO> list = anyTypeClassService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add("firstname");
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        newClass.getDerSchemas().add("cn");
+        anyTypeClassService.update(newClass.getKey(), newClass);
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertFalse(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        try {
+            anyTypeClassService.read(newClass.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteSchema() {
+        PlainSchemaTO newSchema = new PlainSchemaTO();
+        newSchema.setKey("newSchema" + getUUIDString());
+        newSchema.setType(AttrSchemaType.Date);
+        createSchema(SchemaType.PLAIN, newSchema);
+
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getPlainSchemas().add(newSchema.getKey());
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+        assertTrue(newClass.getPlainSchemas().contains(newSchema.getKey()));
+
+        schemaService.delete(SchemaType.PLAIN, newSchema.getKey());
+
+        newClass = anyTypeClassService.read(newClass.getKey());
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().contains(newSchema.getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
new file mode 100644
index 0000000..01da6f8
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.apache.syncope.fit.core.reference.AbstractITCase.getUUIDString;
+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 static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AnyTypeITCase extends AbstractITCase {
+
+    @Test
+    public void read() {
+        AnyTypeTO userType = anyTypeService.read(AnyTypeKind.USER.name());
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyTypeTO groupType = anyTypeService.read(AnyTypeKind.GROUP.name());
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyTypeTO otherType = anyTypeService.read("PRINTER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("PRINTER", otherType.getKey());
+    }
+
+    @Test
+    public void list() {
+        List<AnyTypeTO> list = anyTypeService.list();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void crud() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.getClasses().add("generic membership");
+        newType.getClasses().add("csv");
+
+        Response response = anyTypeService.create(newType);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newType = getObject(response.getLocation(), AnyTypeService.class, AnyTypeTO.class);
+        assertNotNull(newType);
+        assertEquals(2, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("generic membership"));
+        assertTrue(newType.getClasses().contains("csv"));
+
+        newType.getClasses().remove("generic membership");
+        anyTypeService.update(newType.getKey(), newType);
+
+        newType = anyTypeService.read(newType.getKey());
+        assertNotNull(newType);
+        assertEquals(1, newType.getClasses().size());
+        assertTrue(newType.getClasses().contains("csv"));
+
+        anyTypeService.delete(newType.getKey());
+
+        try {
+            anyTypeService.read(newType.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidKind() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void createInvalidName() {
+        AnyTypeTO newType = new AnyTypeTO();
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        try {
+            anyTypeService.create(newType);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteInvalid() {
+        try {
+            anyTypeService.delete(AnyTypeKind.USER.name());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidAnyType, e.getType());
+        }
+    }
+
+    @Test
+    public void deleteTypeClass() {
+        AnyTypeClassTO newClass = new AnyTypeClassTO();
+        newClass.setKey("new class" + getUUIDString());
+        newClass.getDerSchemas().add("cn");
+
+        Response response = anyTypeClassService.create(newClass);
+        assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        newClass = getObject(response.getLocation(), AnyTypeClassService.class, AnyTypeClassTO.class);
+        assertNotNull(newClass);
+
+        AnyTypeTO other = anyTypeService.read("PRINTER");
+        assertNotNull(other);
+
+        other.getClasses().add(newClass.getKey());
+        anyTypeService.update(other.getKey(), other);
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertTrue(other.getClasses().contains(newClass.getKey()));
+
+        anyTypeClassService.delete(newClass.getKey());
+
+        other = anyTypeService.read(other.getKey());
+        assertNotNull(other);
+        assertFalse(other.getClasses().contains(newClass.getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 1136f02..2616d4a 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
@@ -40,7 +40,6 @@ import org.apache.commons.io.IOUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnPoolConfTO;
 import org.apache.syncope.common.lib.to.MappingItemTO;
@@ -53,6 +52,7 @@ import org.apache.syncope.common.lib.types.ConnConfPropSchema;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.types.ConnectorCapability;
 import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.identityconnectors.common.security.GuardedString;
@@ -88,7 +88,7 @@ public class ConnectorITCase extends AbstractITCase {
             }
 
             connidSoapVersion = props.getProperty("connid.soap.version");
-            connidDbTableVersion = props.getProperty("connid.db.table.version");
+            connidDbTableVersion = props.getProperty("connid.database.version");
 
             testJDBCURL = props.getProperty("testdb.url");
         } catch (Exception e) {
@@ -557,11 +557,13 @@ public class ConnectorITCase extends AbstractITCase {
         ConnInstanceTO ldap = connectorService.read(105L);
         assertNotNull(ldap);
 
-        List<ConnIdObjectClassTO> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
+        List<ConnIdObjectClass> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
         assertNotNull(objectClasses);
         assertEquals(2, objectClasses.size());
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.GROUP));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.ACCOUNT_NAME)));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.GROUP_NAME)));
 
         ConnInstanceTO csv = connectorService.read(104L);
         assertNotNull(csv);
@@ -569,7 +571,8 @@ public class ConnectorITCase extends AbstractITCase {
         objectClasses = connectorService.getSupportedObjectClasses(csv.getKey(), csv);
         assertNotNull(objectClasses);
         assertEquals(1, objectClasses.size());
-        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+        assertTrue(objectClasses.contains(
+                ConnIdObjectClass.getInstance(ConnIdObjectClass.class, ObjectClass.ACCOUNT_NAME)));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 017f802..f16ee21 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
@@ -44,6 +44,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.ReferenceMod;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.to.AnyTypeClassTO;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
 import org.apache.syncope.common.lib.to.BulkActionResult;
@@ -68,7 +69,6 @@ import org.apache.syncope.common.rest.api.Preference;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.service.GroupService;
 import org.junit.FixMethodOrder;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
 
@@ -92,7 +92,6 @@ public class GroupITCase extends AbstractITCase {
     }
 
     @Test
-    @Ignore
     public void create() {
         GroupTO groupTO = getSampleTO("lastGroup");
         groupTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
@@ -351,9 +350,9 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
-        assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.LINK,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
+        assertNotNull(groupService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.LINK, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -406,9 +405,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.ASSIGN,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+                ResourceAssociationActionType.ASSIGN, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -456,9 +456,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class)).
+                ResourceAssociationActionType.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());
@@ -482,9 +483,10 @@ public class GroupITCase extends AbstractITCase {
             assertNotNull(e);
         }
 
+        ResourceAssociationMod associationMod = new ResourceAssociationMod();
+        associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceKey.class));
         assertNotNull(groupService.bulkAssociation(actual.getKey(),
-                ResourceAssociationActionType.PROVISION,
-                CollectionWrapper.wrap("resource-ldap", ResourceKey.class)).
+                ResourceAssociationActionType.PROVISION, associationMod).
                 readEntity(BulkActionResult.class));
 
         actual = groupService.read(actual.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 3f1eb0a..6011c93 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
@@ -29,6 +29,7 @@ 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.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.RoleTO;
@@ -44,25 +45,25 @@ public class SearchITCase extends AbstractITCase {
     @Test
     public void searchUser() {
         // LIKE
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().
                         is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query()).build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        for (UserTO user : matchedUsers.getResult()) {
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
 
         // ISNULL
-        matchedUsers = userService.search(
+        matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query()).build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        Collection<UserTO> found = CollectionUtils.select(matchedUsers.getResult(), new Predicate<UserTO>() {
+        Collection<UserTO> found = CollectionUtils.select(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -98,14 +99,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByGroup() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(1L).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -121,14 +122,14 @@ public class SearchITCase extends AbstractITCase {
         group = createGroup(group);
         assertNotNull(group);
 
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inGroups(group.getKey()).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -139,14 +140,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchByRole() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(3L).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -163,14 +164,14 @@ public class SearchITCase extends AbstractITCase {
         role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
         assertNotNull(role);
 
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().inRoles(role.getKey()).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -181,14 +182,14 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void searchUserByResourceName() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query()).
                 build());
-        assertNotNull(matchedUsers);
-        assertFalse(matchedUsers.getResult().isEmpty());
+        assertNotNull(matchingUsers);
+        assertFalse(matchingUsers.getResult().isEmpty());
 
-        assertTrue(CollectionUtils.exists(matchedUsers.getResult(), new Predicate<UserTO>() {
+        assertTrue(CollectionUtils.exists(matchingUsers.getResult(), new Predicate<UserTO>() {
 
             @Override
             public boolean evaluate(final UserTO user) {
@@ -242,27 +243,47 @@ public class SearchITCase extends AbstractITCase {
 
     @Test
     public void nested() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql("((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)").page(1).size(2).build());
-        assertNotNull(matchedUsers);
+        assertNotNull(matchingUsers);
 
-        assertFalse(matchedUsers.getResult().isEmpty());
-        for (UserTO user : matchedUsers.getResult()) {
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
     }
 
     @Test
+    public void searchByType() {
+        PagedResult<AnyObjectTO> matching = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").query()).build());
+        assertNotNull(matching);
+
+        assertFalse(matching.getResult().isEmpty());
+        for (AnyObjectTO printer : matching.getResult()) {
+            assertNotNull(printer);
+        }
+
+        matching = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("UNEXISTING").query()).build());
+        assertNotNull(matching);
+
+        assertTrue(matching.getResult().isEmpty());
+    }
+
+    @Test
     public void orderBy() {
-        PagedResult<UserTO> matchedUsers = userService.search(
+        PagedResult<UserTO> matchingUsers = userService.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
                 fiql(SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query()).
                 orderBy(SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build()).build());
-        assertNotNull(matchedUsers);
+        assertNotNull(matchingUsers);
 
-        assertFalse(matchedUsers.getResult().isEmpty());
-        for (UserTO user : matchedUsers.getResult()) {
+        assertFalse(matchingUsers.getResult().isEmpty());
+        for (UserTO user : matchingUsers.getResult()) {
             assertNotNull(user);
         }
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 ee02b26..939919f 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
@@ -37,6 +37,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
 import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -44,6 +45,7 @@ import org.apache.syncope.common.lib.to.MembershipTO;
 import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.SyncPolicyTO;
 import org.apache.syncope.common.lib.to.SyncTaskTO;
 import org.apache.syncope.common.lib.to.TaskExecTO;
@@ -353,6 +355,49 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     }
 
     @Test
+    public void reconcileFromScriptedSQL() {
+        // 0. reset sync token
+        ResourceTO resource = resourceService.read(RESOURCE_NAME_DBSCRIPTED);
+        ProvisionTO provision = resource.getProvision("PRINTER");
+        assertNotNull(provision);
+
+        provision.setSyncToken(null);
+        resourceService.update(resource.getKey(), resource);
+
+        // 1. create printer on external resource
+        AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
+        anyObjectTO = createAnyObject(anyObjectTO);
+        assertNotNull(anyObjectTO);
+
+        // 2. unlink any existing printer and delete from Syncope (printer is now only on external resource)
+        PagedResult<AnyObjectTO> matchingPrinters = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                        is("location").equalTo("sync*").query()).build());
+        assertTrue(matchingPrinters.getSize() > 0);
+        for (AnyObjectTO printer : matchingPrinters.getResult()) {
+            anyObjectService.bulkDeassociation(printer.getKey(),
+                    ResourceDeassociationActionType.UNLINK,
+                    CollectionWrapper.wrap(RESOURCE_NAME_DBSCRIPTED, ResourceKey.class));
+            anyObjectService.delete(printer.getKey());
+        }
+
+        // 3. synchronize
+        execProvisioningTask(28L, 50, false);
+
+        // 4. verify that printer was re-created in Syncope
+        matchingPrinters = anyObjectService.search(
+                SyncopeClient.getAnySearchQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+                fiql(SyncopeClient.getAnyObjectSearchConditionBuilder().type("PRINTER").and().
+                        is("location").equalTo("sync*").query()).build());
+        assertTrue(matchingPrinters.getSize() > 0);
+
+        // 5. verify that synctoken was updated
+        assertNotNull(
+                resourceService.read(RESOURCE_NAME_DBSCRIPTED).getProvision(anyObjectTO.getType()).getSyncToken());
+    }
+
+    @Test
     public void issueSYNCOPE68() {
         //-----------------------------
         // Create a new user ... it should be updated applying sync policy

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 c0ab43d..bd6b4aa 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
@@ -1909,8 +1909,8 @@ public class UserITCase extends AbstractITCase {
         try {
             resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
             fail();
-        } catch (Exception e) {
-            assertNotNull(e);
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 9011e8d..f8506d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -321,12 +321,12 @@ under the License.
 
     <connid.version>1.4.1.0</connid.version>
     <connid.soap.version>1.3.0</connid.soap.version>
-    <connid.db.table.version>2.2.2</connid.db.table.version>
+    <connid.database.version>2.2.2</connid.database.version>
     <connid.csvdir.version>0.8.2</connid.csvdir.version>
     <connid.ldap.version>1.4.0</connid.ldap.version>
     <connid.ad.version>1.2.3</connid.ad.version>
 
-    <cxf.version>3.1.0</cxf.version>
+    <cxf.version>3.1.2-SNAPSHOT</cxf.version>
 
     <camel.version>2.15.2</camel.version>	
 
@@ -1126,8 +1126,13 @@ under the License.
               <dependency>
                 <groupId>net.tirasa.connid.bundles.db</groupId>
                 <artifactId>net.tirasa.connid.bundles.db.table</artifactId>
-                <version>${connid.db.table.version}</version>
+                <version>${connid.database.version}</version>
               </dependency>   
+              <dependency>
+                <groupId>net.tirasa.connid.bundles.db</groupId>
+                <artifactId>net.tirasa.connid.bundles.db.scriptedsql</artifactId>
+                <version>${connid.database.version}</version>
+              </dependency>  
               <artifactItem>
                 <groupId>net.tirasa.connid.bundles</groupId>
                 <artifactId>net.tirasa.connid.bundles.ldap</artifactId>


[69/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
deleted file mode 100644
index c77ea93..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.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 static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-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 AnyTypeClassTest extends AbstractTest {
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void find() {
-        AnyTypeClass minimalGroup = anyTypeClassDAO.find("minimal group");
-        assertNotNull(minimalGroup);
-
-        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
-        assertFalse(minimalGroup.getDerSchemas().isEmpty());
-        assertFalse(minimalGroup.getVirSchemas().isEmpty());
-    }
-
-    @Test
-    public void findAll() {
-        List<AnyTypeClass> list = anyTypeClassDAO.findAll();
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void save() {
-        AnyTypeClass newClass = entityFactory.newEntity(AnyTypeClass.class);
-        newClass.setKey("new class");
-        newClass.add(plainSchemaDAO.find("firstname"));
-
-        newClass = anyTypeClassDAO.save(newClass);
-        assertNotNull(newClass);
-        assertFalse(newClass.getPlainSchemas().isEmpty());
-        assertTrue(newClass.getDerSchemas().isEmpty());
-        assertTrue(newClass.getVirSchemas().isEmpty());
-    }
-
-    @Test
-    public void delete() {
-        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
-        assertNotNull(minimalUser);
-
-        anyTypeClassDAO.delete(minimalUser.getKey());
-        assertNull(anyTypeClassDAO.find("minimal user"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
deleted file mode 100644
index 13937cc..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
+++ /dev/null
@@ -1,114 +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.assertNull;
-
-import java.util.List;
-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.AnyTypeClassDAO;
-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.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class AnyTypeTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void find() {
-        AnyType userType = anyTypeDAO.findUser();
-        assertNotNull(userType);
-        assertEquals(AnyTypeKind.USER, userType.getKind());
-        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
-        assertFalse(userType.getClasses().isEmpty());
-
-        AnyType groupType = anyTypeDAO.findGroup();
-        assertNotNull(groupType);
-        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
-        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
-        assertFalse(groupType.getClasses().isEmpty());
-
-        AnyType otherType = anyTypeDAO.find("PRINTER");
-        assertNotNull(otherType);
-        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
-        assertEquals("PRINTER", otherType.getKey());
-    }
-
-    @Test
-    public void findAll() {
-        List<AnyType> list = anyTypeDAO.findAll();
-        assertFalse(list.isEmpty());
-    }
-
-    @Test
-    public void save() {
-        AnyType newType = entityFactory.newEntity(AnyType.class);
-        newType.setKey("new type");
-        newType.setKind(AnyTypeKind.ANY_OBJECT);
-        newType.add(anyTypeClassDAO.find("generic membership"));
-        newType.add(anyTypeClassDAO.find("csv"));
-
-        newType = anyTypeDAO.save(newType);
-        assertNotNull(newType);
-        assertFalse(newType.getClasses().isEmpty());
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidKind() {
-        AnyType newType = entityFactory.newEntity(AnyType.class);
-        newType.setKey("new type");
-        newType.setKind(AnyTypeKind.USER);
-        anyTypeDAO.save(newType);
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidName() {
-        AnyType newType = entityFactory.newEntity(AnyType.class);
-        newType.setKey("group");
-        newType.setKind(AnyTypeKind.ANY_OBJECT);
-        anyTypeDAO.save(newType);
-    }
-
-    @Test
-    public void delete() {
-        AnyType otherType = anyTypeDAO.find("PRINTER");
-        assertNotNull(otherType);
-
-        anyTypeDAO.delete(otherType.getKey());
-        assertNull(anyTypeDAO.find("PRINTER"));
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void deleteInvalid() {
-        anyTypeDAO.delete(anyTypeDAO.findUser().getKey());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 606c417..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConfTest.java
+++ /dev/null
@@ -1,119 +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 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.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.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;
-
-@Transactional
-public class ConfTest extends AbstractTest {
-
-    @Autowired
-    private ConfDAO confDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Test
-    public void read() {
-        CPlainAttr conf = confDAO.find("selfRegistration.allowed");
-        assertNotNull(conf);
-        assertTrue(conf.getValues().get(0).getBooleanValue());
-
-        conf = confDAO.find("authentication.statuses");
-        assertNotNull(conf);
-        assertEquals(2, conf.getValues().size());
-
-        conf = confDAO.find("non.existing");
-        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
-        PlainSchema useless = entityFactory.newEntity(PlainSchema.class);
-        useless.setKey("useless");
-        useless.setType(AttrSchemaType.Date);
-        useless.setConversionPattern("yyyy-MM-dd");
-        useless = plainSchemaDAO.save(useless);
-
-        // 2. create conf
-        CPlainAttr newConf = entityFactory.newEntity(CPlainAttr.class);
-        newConf.setSchema(useless);
-        add(newConf, "2014-06-20");
-        confDAO.save(newConf);
-
-        CPlainAttr actual = confDAO.find("useless");
-        assertEquals(actual.getValuesAsStrings(), newConf.getValuesAsStrings());
-
-        // 3. update conf
-        newConf.getValues().clear();
-        add(newConf, "2014-06-20");
-        confDAO.save(newConf);
-
-        actual = confDAO.find("useless");
-        assertEquals(actual.getValuesAsStrings(), newConf.getValuesAsStrings());
-
-        // 4. delete conf
-        confDAO.delete("useless");
-        assertNull(confDAO.find("useless"));
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        try {
-            PlainSchema failing = entityFactory.newEntity(PlainSchema.class);
-            failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-            failing.setType(AttrSchemaType.String);
-            plainSchemaDAO.save(failing);
-
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConnInstanceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConnInstanceTest.java
deleted file mode 100644
index 03b7c5d..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ConnInstanceTest.java
+++ /dev/null
@@ -1,145 +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.assertNull;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.syncope.common.lib.types.ConnConfPropSchema;
-import org.apache.syncope.common.lib.types.ConnConfProperty;
-import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
-import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-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 ConnInstanceTest extends AbstractTest {
-
-    @Autowired
-    private ConnInstanceDAO connInstanceDAO;
-
-    @Test
-    public void findAll() {
-        List<ConnInstance> connectors = connInstanceDAO.findAll();
-        assertNotNull(connectors);
-        assertFalse(connectors.isEmpty());
-    }
-
-    @Test
-    public void findById() {
-        ConnInstance connectorInstance = connInstanceDAO.find(100L);
-
-        assertNotNull("findById did not work", connectorInstance);
-
-        assertEquals("invalid connector name",
-                "net.tirasa.connid.bundles.soap.WebServiceConnector", connectorInstance.getConnectorName());
-
-        assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connectorInstance.getBundleName());
-    }
-
-    @Test
-    public void save() throws ClassNotFoundException {
-        ConnInstance connInstance = entityFactory.newEntity(ConnInstance.class);
-
-        connInstance.setLocation(new File(System.getProperty("java.io.tmpdir")).toURI().toString());
-
-        // set connector version
-        connInstance.setVersion("1.0");
-
-        // set connector name
-        connInstance.setConnectorName("WebService");
-
-        // set bundle name
-        connInstance.setBundleName("org.apache.syncope.core.persistence.test.util");
-
-        connInstance.setDisplayName("New");
-
-        connInstance.setConnRequestTimeout(60);
-
-        // set the connector configuration using PropertyTO
-        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
-
-        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
-        endpointSchema.setName("endpoint");
-        endpointSchema.setType(String.class.getName());
-        endpointSchema.setRequired(true);
-        ConnConfProperty endpoint = new ConnConfProperty();
-        endpoint.setSchema(endpointSchema);
-        endpoint.getValues().add("http://host.domain");
-
-        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
-        servicenameSchema.setName("servicename");
-        servicenameSchema.setType(String.class.getName());
-        servicenameSchema.setRequired(true);
-        ConnConfProperty servicename = new ConnConfProperty();
-        servicename.setSchema(servicenameSchema);
-        endpoint.getValues().add("Provisioning");
-
-        conf.add(endpoint);
-        conf.add(servicename);
-
-        // set connector configuration
-        connInstance.setConfiguration(conf);
-        assertFalse(connInstance.getConfiguration().isEmpty());
-
-        // perform save operation
-        ConnInstance actual = connInstanceDAO.save(connInstance);
-
-        assertNotNull("save did not work", actual.getKey());
-
-        assertTrue("save did not work", actual.getKey() > 100L);
-
-        assertEquals("save did not work for \"name\" attribute", "WebService", actual.getConnectorName());
-
-        assertEquals("save did not work for \"bundle name\" attribute", "org.apache.syncope.core.persistence.test.util",
-                actual.getBundleName());
-
-        assertEquals("save did not work for \"majorVersion\" attribute", "1.0", connInstance.getVersion());
-
-        assertEquals("New", actual.getDisplayName());
-
-        assertEquals(new Integer(60), actual.getConnRequestTimeout());
-
-        conf = connInstance.getConfiguration();
-        assertFalse(conf.isEmpty());
-
-        assertNotNull("configuration retrieving failed", conf);
-        assertTrue(conf.size() == 2);
-    }
-
-    @Test
-    public void delete() {
-        ConnInstance connectorInstance = connInstanceDAO.find(100L);
-        assertNotNull("find to delete did not work", connectorInstance);
-
-        connInstanceDAO.delete(connectorInstance.getKey());
-
-        ConnInstance actual = connInstanceDAO.find(100L);
-        assertNull("delete did not work", actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index f64e314..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerAttrTest.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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-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.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-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.group.GDerAttr;
-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.UPlainAttrValue;
-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 DerAttrTest extends AbstractTest {
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void findAll() {
-        List<UDerAttr> list = derAttrDAO.findAll(UDerAttr.class);
-        assertEquals("did not get expected number of derived attributes ", 2, list.size());
-    }
-
-    @Test
-    public void findById() {
-        UDerAttr attribute = derAttrDAO.find(100L, UDerAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-    }
-
-    @Test
-    public void saveUDerAttribute() {
-        DerSchema cnSchema = derSchemaDAO.find("cn");
-        assertNotNull(cnSchema);
-
-        User owner = userDAO.find(3L);
-        assertNotNull("did not get expected user", owner);
-
-        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(cnSchema);
-
-        derAttr = derAttrDAO.save(derAttr);
-
-        UDerAttr actual = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(derAttr, actual);
-
-        UPlainAttrValue firstname = owner.getPlainAttr("firstname").getValues().iterator().next();
-        UPlainAttrValue surname = owner.getPlainAttr("surname").getValues().iterator().next();
-
-        assertEquals(surname.getValue() + ", " + firstname.getValue(), derAttr.getValue(owner.getPlainAttrs()));
-    }
-
-    @Test
-    public void saveGDerAttribute() {
-        DerSchema schema = derSchemaDAO.find("rderiveddata");
-        assertNotNull(schema);
-
-        Group owner = groupDAO.find(1L);
-        assertNotNull("did not get expected user", owner);
-
-        GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(schema);
-
-        derAttr = derAttrDAO.save(derAttr);
-
-        GDerAttr actual = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(derAttr, actual);
-
-        GPlainAttrValue sx = owner.getPlainAttr("rderived_sx").getValues().iterator().next();
-        GPlainAttrValue dx = owner.getPlainAttr("rderived_dx").getValues().iterator().next();
-
-        assertEquals(sx.getValue() + "-" + dx.getValue(), derAttr.getValue(owner.getPlainAttrs()));
-    }
-
-    @Test
-    public void delete() {
-        UDerAttr attribute = derAttrDAO.find(100L, UDerAttr.class);
-        String schemaName = attribute.getSchema().getKey();
-
-        derAttrDAO.delete(attribute.getKey(), UDerAttr.class);
-
-        UDerAttr actual = derAttrDAO.find(100L, UDerAttr.class);
-        assertNull("delete did not work", actual);
-
-        DerSchema attributeSchema = derSchemaDAO.find(schemaName);
-        assertNotNull("user derived attribute schema deleted when deleting values", attributeSchema);
-    }
-
-    @Test
-    public void issueSYNCOPE134User() {
-        AnyTypeClass other = anyTypeClassDAO.find("other");
-
-        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
-        sderived.setKey("sderived");
-        sderived.setExpression("status + ' - ' + username + ' - ' + creationDate + '[' + failedLogins + ']'");
-
-        sderived = derSchemaDAO.save(sderived);
-
-        derSchemaDAO.flush();
-
-        other.add(sderived);
-        sderived.setAnyTypeClass(other);
-
-        derSchemaDAO.flush();
-
-        sderived = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", sderived);
-        assertEquals(other, sderived.getAnyTypeClass());
-
-        User owner = userDAO.find(3L);
-        assertNotNull("did not get expected user", owner);
-        owner.add(other);
-
-        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(sderived);
-
-        derAttr = derAttrDAO.save(derAttr);
-        derAttrDAO.flush();
-
-        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
-        assertNotNull("expected save to work", derAttr);
-
-        String value = derAttr.getValue(owner.getPlainAttrs());
-        assertNotNull(value);
-        assertFalse(value.isEmpty());
-        assertTrue(value.startsWith("active - vivaldi - 2010-10-20"));
-        assertTrue(value.endsWith("[0]"));
-    }
-
-    @Test
-    public void issueSYNCOPE134Group() {
-        AnyTypeClass genericMembership = anyTypeClassDAO.find("generic membership");
-
-        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
-        sderived.setKey("sderived");
-        sderived.setExpression("name");
-
-        sderived = derSchemaDAO.save(sderived);
-
-        derSchemaDAO.flush();
-
-        genericMembership.add(sderived);
-        sderived.setAnyTypeClass(genericMembership);
-
-        derSchemaDAO.flush();
-
-        sderived = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", sderived);
-        assertEquals(genericMembership, sderived.getAnyTypeClass());
-
-        Group owner = groupDAO.find(7L);
-        assertNotNull("did not get expected group", owner);
-        owner.add(genericMembership);
-
-        GDerAttr derAttr = entityFactory.newEntity(GDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(sderived);
-
-        derAttr = derAttrDAO.save(derAttr);
-        derAttrDAO.flush();
-
-        derAttr = derAttrDAO.find(derAttr.getKey(), GDerAttr.class);
-        assertNotNull("expected save to work", derAttr);
-
-        String value = derAttr.getValue(owner.getPlainAttrs());
-        assertNotNull(value);
-        assertFalse(value.isEmpty());
-        assertTrue(value.startsWith("managingDirector"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index b123513..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/DerSchemaTest.java
+++ /dev/null
@@ -1,100 +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 static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-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 DerSchemaTest extends AbstractTest {
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Test
-    public void findAll() {
-        List<DerSchema> list = derSchemaDAO.findAll();
-        assertEquals(9, list.size());
-    }
-
-    @Test
-    public void findByName() {
-        DerSchema attributeSchema = derSchemaDAO.find("cn");
-        assertNotNull("did not find expected derived attribute schema", attributeSchema);
-    }
-
-    @Test
-    public void save() {
-        DerSchema derivedAttributeSchema = entityFactory.newEntity(DerSchema.class);
-        derivedAttributeSchema.setKey("cn2");
-        derivedAttributeSchema.setExpression("firstname surname");
-
-        derSchemaDAO.save(derivedAttributeSchema);
-
-        DerSchema actual = derSchemaDAO.find("cn2");
-        assertNotNull("expected save to work", actual);
-        assertEquals(derivedAttributeSchema, actual);
-    }
-
-    @Test
-    public void delete() {
-        DerSchema cn = derSchemaDAO.find("cn");
-        assertNotNull(cn);
-
-        derSchemaDAO.delete(cn.getKey());
-
-        DerSchema actual = derSchemaDAO.find("cn");
-        assertNull("delete did not work", actual);
-
-        // ------------- //
-        DerSchema rderiveddata = derSchemaDAO.find("rderiveddata");
-        assertNotNull(rderiveddata);
-
-        derSchemaDAO.delete(rderiveddata.getKey());
-
-        actual = derSchemaDAO.find("rderiveddata");
-        assertNull("delete did not work", actual);
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        DerSchema schema = entityFactory.newEntity(DerSchema.class);
-        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-
-        try {
-            derSchemaDAO.save(schema);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/GroupTest.java
deleted file mode 100644
index 7593b06..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/GroupTest.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 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.common.lib.SyncopeConstants;
-import org.apache.syncope.core.persistence.api.dao.GroupDAO;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-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 GroupTest extends AbstractTest {
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Test
-    public void findAll() {
-        List<Group> list = groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertEquals("did not get expected number of groups ", 14, list.size());
-    }
-
-    @Test
-    public void find() {
-        Group group = groupDAO.find("root");
-        assertNotNull("did not find expected group", group);
-    }
-
-    @Test
-    public void save() {
-        Group group = entityFactory.newEntity(Group.class);
-        group.setName("secondChild");
-        group.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
-
-        group = groupDAO.save(group);
-
-        Group actual = groupDAO.find(group.getKey());
-        assertNotNull("expected save to work", actual);
-    }
-
-    @Test
-    public void delete() {
-        Group group = groupDAO.find(4L);
-        groupDAO.delete(group.getKey());
-
-        Group actual = groupDAO.find(4L);
-        assertNull("delete did not work", actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index df629ff..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/NotificationTest.java
+++ /dev/null
@@ -1,149 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-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;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class NotificationTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private NotificationDAO notificationDAO;
-
-    @Test
-    public void find() {
-        Notification notification = notificationDAO.find(10L);
-        assertNotNull(notification);
-        assertNotNull(notification.getEvents());
-        assertFalse(notification.getEvents().isEmpty());
-        assertNotNull(notification.getAbout(anyTypeDAO.findUser()));
-        assertNotNull(notification.getRecipients());
-
-    }
-
-    @Test
-    public void findAll() {
-        List<Notification> notifications = notificationDAO.findAll();
-        assertNotNull(notifications);
-        assertFalse(notifications.isEmpty());
-    }
-
-    @Test
-    public void save() {
-        Notification notification = entityFactory.newEntity(Notification.class);
-        notification.getEvents().add("save");
-
-        AnyAbout about = entityFactory.newEntity(AnyAbout.class);
-        about.setNotification(notification);
-        notification.add(about);
-        about.setAnyType(anyTypeDAO.findUser());
-        about.set("fake search condition");
-
-        notification.setRecipients("fake recipients");
-
-        notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
-
-        notification.setSender("syncope@syncope.apache.org");
-        notification.setSubject("Test notification");
-        notification.setTemplate("test");
-
-        Notification actual = notificationDAO.save(notification);
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-    }
-
-    @Test
-    public void delete() {
-        notificationDAO.delete(10L);
-        assertNull(notificationDAO.find(10L));
-    }
-
-    @Test
-    public void issueSYNCOPE445() {
-        Notification notification = entityFactory.newEntity(Notification.class);
-        notification.getEvents().add("save");
-
-        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.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
-
-        notification.getStaticRecipients().add("syncope445@syncope.apache.org");
-
-        notification.setSender("syncope@syncope.apache.org");
-        notification.setSubject("Test notification");
-        notification.setTemplate("test");
-
-        Notification actual = notificationDAO.save(notification);
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        assertNotNull(actual.getStaticRecipients());
-        assertFalse(actual.getStaticRecipients().isEmpty());
-    }
-
-    @Test
-    public void issueSYNCOPE446() {
-        Notification notification = entityFactory.newEntity(Notification.class);
-        notification.getEvents().add("[REST]:[GroupLogic]:[]:[create]:[SUCCESS]");
-
-        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);
-
-        notification.getStaticRecipients().add("syncope446@syncope.apache.org");
-
-        notification.setSender("syncope@syncope.apache.org");
-        notification.setSubject("Test notification");
-        notification.setTemplate("test");
-
-        Notification actual = notificationDAO.save(notification);
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-        assertNotNull(actual.getStaticRecipients());
-        assertFalse(actual.getStaticRecipients().isEmpty());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
deleted file mode 100644
index 014ee64..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainAttrTest.java
+++ /dev/null
@@ -1,237 +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 static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-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.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;
-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.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;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class PlainAttrTest extends AbstractTest {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Test
-    public void findById() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-        attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-    }
-
-    @Test
-    public void read() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull(attribute);
-        assertTrue(attribute.getValues().isEmpty());
-        assertNotNull(attribute.getUniqueValue());
-    }
-
-    @Test
-    public void save() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-
-        PlainSchema emailSchema = plainSchemaDAO.find("email");
-        assertNotNull(emailSchema);
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(emailSchema);
-
-        Exception thrown = null;
-        try {
-            attr.add("john.doe@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-            attr.add("mario.rossi@gmail.com", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNull("no validation exception expected here ", thrown);
-
-        try {
-            attr.add("http://www.apache.org", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-    }
-
-    @Test
-    public void saveWithEnum() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-        assertNotNull(user);
-
-        PlainSchema gender = plainSchemaDAO.find("gender");
-        assertNotNull(gender);
-        assertNotNull(gender.getType());
-        assertNotNull(gender.getEnumerationValues());
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setOwner(user);
-        attribute.setSchema(gender);
-        user.add(attribute);
-
-        Exception thrown = null;
-
-        try {
-            attribute.add("A", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-
-        attribute.add("M", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNull(iee);
-    }
-
-    @Test
-    public void validateAndSave() {
-        User user = userDAO.find(1L);
-
-        PlainSchema emailSchema = plainSchemaDAO.find("email");
-        assertNotNull(emailSchema);
-
-        PlainSchema fullnameSchema = plainSchemaDAO.find("fullname");
-        assertNotNull(fullnameSchema);
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(emailSchema);
-
-        UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
-        uauv.setAttr(attr);
-        uauv.setSchema(fullnameSchema);
-        uauv.setStringValue("a value");
-
-        attr.setUniqueValue(uauv);
-
-        user.add(attr);
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-            fail();
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNotNull(iee);
-        // for attribute
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
-        // for uauv
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidPlainSchema));
-    }
-
-    @Test
-    public void saveWithEncrypted() throws Exception {
-        User user = userDAO.find(1L);
-
-        PlainSchema obscureSchema = plainSchemaDAO.find("obscure");
-        assertNotNull(obscureSchema);
-        assertNotNull(obscureSchema.getSecretKey());
-        assertNotNull(obscureSchema.getCipherAlgorithm());
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(obscureSchema);
-        attr.add("testvalue", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("obscure");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
-                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
-    }
-
-    @Test
-    public void saveWithBinary() throws UnsupportedEncodingException {
-        User user = userDAO.find(1L);
-
-        PlainSchema photoSchema = plainSchemaDAO.find("photo");
-        assertNotNull(photoSchema);
-        assertNotNull(photoSchema.getMimeType());
-
-        final byte[] bytes = new byte[20];
-        new Random().nextBytes(bytes);
-        final String photoB64Value = new String(Base64.encode(bytes), SyncopeConstants.DEFAULT_ENCODING);
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(photoSchema);
-        attr.add(photoB64Value, anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("photo");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertTrue(Arrays.equals(bytes, obscure.getValues().get(0).getBinaryValue()));
-    }
-
-    @Test
-    public void delete() {
-        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        String attrSchemaName = attribute.getSchema().getKey();
-
-        plainAttrDAO.delete(attribute.getKey(), UPlainAttr.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/d8927ef4/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
deleted file mode 100644
index 7e86689..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PlainSchemaTest.java
+++ /dev/null
@@ -1,152 +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.assertNull;
-import static org.junit.Assert.assertTrue;
-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.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.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class PlainSchemaTest extends AbstractTest {
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Test
-    public void findAll() {
-        List<PlainSchema> schemas = plainSchemaDAO.findAll();
-        assertEquals(42, schemas.size());
-    }
-
-    @Test
-    public void findByName() {
-        PlainSchema schema = plainSchemaDAO.find("fullname");
-        assertNotNull("did not find expected attribute schema", schema);
-    }
-
-    @Test
-    public void findAttrs() {
-        PlainSchema schema = plainSchemaDAO.find("icon");
-        assertNotNull(schema);
-
-        List<GPlainAttr> attrs = plainSchemaDAO.findAttrs(schema, GPlainAttr.class);
-        assertNotNull(attrs);
-        assertFalse(attrs.isEmpty());
-    }
-
-    @Test
-    public void save() {
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setKey("secondaryEmail");
-        schema.setType(AttrSchemaType.String);
-        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
-        schema.setMandatoryCondition("false");
-        schema.setMultivalue(true);
-
-        plainSchemaDAO.save(schema);
-
-        PlainSchema actual = plainSchemaDAO.find("secondaryEmail");
-        assertNotNull("expected save to work", actual);
-        assertEquals(schema, actual);
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveNonValid() {
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setKey("secondaryEmail");
-        schema.setType(AttrSchemaType.String);
-        schema.setValidatorClass("org.apache.syncope.core.validation.EmailAddressValidator");
-        schema.setMandatoryCondition("false");
-        schema.setMultivalue(true);
-        schema.setUniqueConstraint(true);
-
-        plainSchemaDAO.save(schema);
-    }
-
-    @Test
-    public void checkForEnumType() {
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setType(AttrSchemaType.Enum);
-        schema.setKey("color");
-
-        Exception ex = null;
-        try {
-            plainSchemaDAO.save(schema);
-        } catch (Exception e) {
-            ex = e;
-        }
-        assertNotNull(ex);
-
-        schema.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
-        schema.setEnumerationKeys("1" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "2");
-
-        plainSchemaDAO.save(schema);
-
-        PlainSchema actual = plainSchemaDAO.find(schema.getKey());
-        assertNotNull(actual);
-        assertNotNull(actual.getEnumerationKeys());
-        assertFalse(actual.getEnumerationKeys().isEmpty());
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidSchema() {
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setKey("username");
-        plainSchemaDAO.save(schema);
-    }
-
-    @Test
-    public void delete() {
-        PlainSchema firstname = plainSchemaDAO.find("firstname");
-
-        plainSchemaDAO.delete(firstname.getKey());
-
-        PlainSchema actual = plainSchemaDAO.find("firstname");
-        assertNull("delete did not work", actual);
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
-        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-
-        try {
-            plainSchemaDAO.save(schema);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 764f0ac..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/PolicyTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.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.assertNull;
-
-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;
-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 PolicyTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private PolicyDAO policyDAO;
-
-    @Test
-    public void findAll() {
-        List<Policy> policies = policyDAO.findAll();
-        assertNotNull(policies);
-        assertFalse(policies.isEmpty());
-    }
-
-    @Test
-    public void findById() {
-        Policy policy = policyDAO.find(1L);
-        assertNotNull("findById did not work", policy);
-    }
-
-    @Test
-    public void findByType() {
-        List<? extends Policy> policies = policyDAO.find(PolicyType.SYNC);
-        assertNotNull("findById did not work", policies);
-        assertFalse(policies.isEmpty());
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidPolicy() {
-        PasswordPolicySpec passwordPolicy = new PasswordPolicySpec();
-        passwordPolicy.setMaxLength(8);
-        passwordPolicy.setMinLength(6);
-
-        SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
-        policy.setSpecification(passwordPolicy);
-        policy.setDescription("sync policy");
-
-        policyDAO.save(policy);
-    }
-
-    @Test
-    public void create() {
-        SyncPolicy policy = entityFactory.newEntity(SyncPolicy.class);
-
-        final String syncURuleName = "net.tirasa.sync.correlation.TirasaURule";
-        final String syncGRuleName = "net.tirasa.sync.correlation.TirasaGRule";
-
-        SyncPolicySpec syncPolicySpec = new SyncPolicySpec();
-
-        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");
-
-        policy = policyDAO.save(policy);
-
-        assertNotNull(policy);
-        assertEquals(PolicyType.SYNC, policy.getType());
-        assertEquals(syncURuleName,
-                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findUser().getKey()).getJavaRule());
-        assertEquals(syncGRuleName,
-                (policy.getSpecification(SyncPolicySpec.class)).getItem(anyTypeDAO.findGroup().getKey()).getJavaRule());
-    }
-
-    @Test
-    public void update() {
-        PasswordPolicySpec specification = new PasswordPolicySpec();
-        specification.setMaxLength(8);
-        specification.setMinLength(6);
-
-        Policy policy = policyDAO.find(2L);
-        assertNotNull(policy);
-        policy.setSpecification(specification);
-
-        policy = policyDAO.save(policy);
-
-        assertNotNull(policy);
-        assertEquals(PolicyType.PASSWORD, policy.getType());
-        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMaxLength(), 8);
-        assertEquals((policy.getSpecification(PasswordPolicySpec.class)).getMinLength(), 6);
-    }
-
-    @Test
-    public void delete() {
-        Policy policy = policyDAO.find(1L);
-        assertNotNull("find to delete did not work", policy);
-
-        policyDAO.delete(policy);
-
-        Policy actual = policyDAO.find(1L);
-        assertNull("delete did not work", actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RealmTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RealmTest.java
deleted file mode 100644
index e5e55fe..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RealmTest.java
+++ /dev/null
@@ -1,178 +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.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-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.MalformedPathException;
-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.PasswordPolicy;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-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 RealmTest extends AbstractTest {
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private PolicyDAO policyDAO;
-
-    @Test
-    public void getRoot() {
-        assertNotNull(realmDAO.getRoot());
-    }
-
-    @Test
-    public void find() {
-        Realm realm = realmDAO.find(1L);
-        assertNotNull(realm);
-        assertEquals(SyncopeConstants.ROOT_REALM, realm.getName());
-        assertEquals(SyncopeConstants.ROOT_REALM, realm.getFullPath());
-
-        realm = realmDAO.find(3L);
-        assertNotNull(realm);
-        assertEquals("even", realm.getName());
-        assertEquals("/even", realm.getFullPath());
-        assertEquals(1, realm.getParent().getKey(), 0);
-        assertEquals(realmDAO.getRoot(), realm.getParent());
-
-        realm = realmDAO.find("/even/two");
-        assertNotNull(realm);
-        assertEquals(4, realm.getKey(), 0);
-        assertEquals("two", realm.getName());
-        assertEquals("/even/two", realm.getFullPath());
-    }
-
-    @Test(expected = MalformedPathException.class)
-    public void findInvalidPath() {
-        realmDAO.find("even/two");
-    }
-
-    @Test
-    public void findChildren() {
-        List<Realm> children = realmDAO.findChildren(realmDAO.find(SyncopeConstants.ROOT_REALM));
-        assertEquals(2, children.size());
-        assertTrue(children.contains(realmDAO.find("/odd")));
-        assertTrue(children.contains(realmDAO.find("/even")));
-
-        children = realmDAO.findChildren(realmDAO.find("/odd"));
-        assertTrue(children.isEmpty());
-    }
-
-    @Test
-    public void findDescendants() {
-        assertTrue(CollectionUtils.disjunction(realmDAO.findAll(), realmDAO.findDescendants(realmDAO.getRoot())).
-                isEmpty());
-    }
-
-    @Test
-    public void findAll() {
-        List<Realm> list = realmDAO.findAll();
-        assertNotNull(list);
-        assertFalse(list.isEmpty());
-        for (Realm realm : list) {
-            assertNotNull(realm);
-        }
-    }
-
-    @Test
-    public void save() {
-        Realm realm = entityFactory.newEntity(Realm.class);
-        realm.setName("last");
-        realm.setParent(realmDAO.find("/even/two"));
-        assertNull(realm.getKey());
-
-        Realm actual = realmDAO.save(realm);
-        assertNotNull(actual.getKey());
-        assertEquals("last", actual.getName());
-        assertEquals("/even/two/last", actual.getFullPath());
-        assertEquals(realmDAO.find("/even/two"), actual.getParent());
-        assertEquals(5L, realm.getAccountPolicy().getKey(), 0);
-        assertEquals(2L, realm.getPasswordPolicy().getKey(), 0);
-
-        realm = actual;
-        realm.setAccountPolicy((AccountPolicy) policyDAO.find(6L));
-        realm.setPasswordPolicy((PasswordPolicy) policyDAO.find(4L));
-
-        actual = realmDAO.save(realm);
-        assertEquals(6L, actual.getAccountPolicy().getKey(), 0);
-        assertEquals(4L, actual.getPasswordPolicy().getKey(), 0);
-    }
-
-    @Test
-    public void saveInvalidName() {
-        Realm realm = entityFactory.newEntity(Realm.class);
-        realm.setName(" a name");
-        realm.setParent(realmDAO.getRoot());
-
-        try {
-            realmDAO.save(realm);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidRealm));
-        }
-    }
-
-    @Test
-    public void saveNullParent() {
-        Realm realm = entityFactory.newEntity(Realm.class);
-        realm.setName("name");
-        realm.setParent(null);
-
-        try {
-            realmDAO.save(realm);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidRealm));
-        }
-    }
-
-    @Test
-    public void delete() {
-        Realm realm = entityFactory.newEntity(Realm.class);
-        realm.setName("name");
-        realm.setParent(realmDAO.getRoot());
-
-        Realm actual = realmDAO.save(realm);
-        assertNotNull(actual);
-
-        Long key = actual.getKey();
-        assertNotNull(realmDAO.find(key));
-
-        realmDAO.delete(key);
-        assertNull(realmDAO.find(key));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ReportTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ReportTest.java
deleted file mode 100644
index 4521a48..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ReportTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-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.common.lib.report.UserReportletConf;
-import org.apache.syncope.core.persistence.api.dao.ReportDAO;
-import org.apache.syncope.core.persistence.api.entity.Report;
-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 ReportTest extends AbstractTest {
-
-    @Autowired
-    private ReportDAO reportDAO;
-
-    @Test
-    public void find() {
-        Report report = reportDAO.find(1L);
-        assertNotNull(report);
-
-        report = reportDAO.find(10L);
-        assertNull(report);
-    }
-
-    @Test
-    public void findAll() {
-        List<Report> reports = reportDAO.findAll();
-        assertNotNull(reports);
-        assertEquals(1, reports.size());
-    }
-
-    @Test
-    public void save() {
-        int beforeCount = reportDAO.count();
-
-        Report report = entityFactory.newEntity(Report.class);
-        report.setName("new report");
-        report.addReportletConf(new UserReportletConf("first"));
-        report.addReportletConf(new UserReportletConf("second"));
-
-        report = reportDAO.save(report);
-        assertNotNull(report);
-        assertNotNull(report.getKey());
-
-        int afterCount = reportDAO.count();
-        assertEquals(afterCount, beforeCount + 1);
-    }
-
-    @Test
-    public void delete() {
-        Report report = reportDAO.find(1L);
-        assertNotNull(report);
-
-        reportDAO.delete(1L);
-
-        report = reportDAO.find(1L);
-        assertNull(report);
-    }
-}


[41/70] syncope git commit: Merge from master

Posted by il...@apache.org.
Merge from master


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

Branch: refs/heads/master
Commit: d8c9479dd1f14d8af8f2d5bd6ded992c40e2cfe6
Parents: 79b1e80 6d120f7
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 5 16:53:03 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 5 16:53:03 2015 +0200

----------------------------------------------------------------------
 .../syncope/client/console/pages/Reports.java   |  12 ++
 .../syncope/client/console/pages/Tasks.java     |   9 ++
 .../console/panels/NotificationTasks.java       |   3 +
 .../client/console/panels/RuntimePanel.java     | 130 +++++++++++++++++++
 .../client/console/panels/SchedTasks.java       |   3 +
 .../client/console/panels/SyncTasksPanel.java   |   6 +-
 .../client/console/rest/JobRestClient.java      |  31 +++++
 .../client/console/rest/ReportRestClient.java   |  25 +++-
 .../client/console/rest/TaskRestClient.java     |  25 +++-
 .../html/repeater/data/table/JobColumn.java     |  66 ++++++++++
 .../syncope/client/console/pages/Reports.html   |  13 ++
 .../syncope/client/console/pages/Tasks.html     |  15 +++
 .../client/console/panels/RuntimePanel.html     |  49 +++++++
 .../syncope/core/logic/AbstractJobLogic.java    |  15 ++-
 .../api/notification/NotificationManager.java   |   4 +-
 .../notification/NotificationManagerImpl.java   |   8 +-
 pom.xml                                         |   6 +-
 17 files changed, 410 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/d8c9479d/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --cc core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 776b8db,900abc7..a0469a2
--- 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
@@@ -271,31 -266,29 +271,32 @@@ public class NotificationManagerImpl im
              final Object output,
              final Object... input) {
  
 -        SubjectType subjectType = null;
 -        Subject<?, ?, ?> subject = null;
 -        List<NotificationTask> notificationList = new ArrayList<NotificationTask>();
 +        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);
  
++        List<NotificationTask> notifications = new ArrayList<>();
          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);
@@@ -318,18 -314,23 +319,21 @@@
                      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, any, model));
 -                    NotificationTask notificationTask = getNotificationTask(notification, subject, model);
++                    NotificationTask notificationTask = getNotificationTask(notification, any, model);
+                     notificationTask = taskDAO.save(notificationTask);
 -                    notificationList.add(notificationTask);     
++                    notifications.add(notificationTask);
                  }
              } 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());
              }
          }
 -        return notificationList;
++        return notifications;
      }
  
      private String getRecipientEmail(

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8c9479d/pom.xml
----------------------------------------------------------------------


[47/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
[SYNCOPE-666] All tests are green, time to add more


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

Branch: refs/heads/master
Commit: dd88efbd0ec6fabb98728a84a6fe103f285433d7
Parents: d8c9479
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 5 17:11:22 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 5 17:11:22 2015 +0200

----------------------------------------------------------------------
 .travis.yml                                     |   3 +-
 .../console/rest/ConnectorRestClient.java       |   2 +-
 .../syncope/common/lib/AnyOperations.java       |  91 ++++
 .../lib/SyncopeClientCompositeException.java    |  14 +-
 .../common/lib/SyncopeClientException.java      |   8 +-
 .../common/lib/jaxb/GenericMapEntryType.java    |  59 +++
 .../syncope/common/lib/jaxb/GenericMapType.java |  49 +++
 .../common/lib/jaxb/XmlGenericMapAdapter.java   |  52 +++
 .../apache/syncope/common/lib/mod/AnyMod.java   |  18 +
 .../common/lib/report/UserReportletConf.java    |   1 +
 .../common/lib/search/SearchableFields.java     |   9 +-
 .../lib/to/AbstractProvisioningTaskTO.java      |   8 +-
 .../syncope/common/lib/to/AnyObjectTO.java      |  57 +++
 .../org/apache/syncope/common/lib/to/AnyTO.java |  59 +--
 .../syncope/common/lib/to/AnyTypeClassTO.java   |  73 ++++
 .../apache/syncope/common/lib/to/AnyTypeTO.java |  66 +++
 .../apache/syncope/common/lib/to/AttrTO.java    |  13 +-
 .../syncope/common/lib/to/BulkActionResult.java |  88 +---
 .../apache/syncope/common/lib/to/GroupTO.java   |  43 +-
 .../syncope/common/lib/to/MembershipTO.java     |  10 +-
 .../syncope/common/lib/to/NotificationTO.java   |   9 +
 .../syncope/common/lib/to/PushTaskTO.java       |  11 +-
 .../syncope/common/lib/to/RelationshipTO.java   |  10 -
 .../syncope/common/lib/to/ResourceTO.java       |  14 +-
 .../syncope/common/lib/to/SyncTaskTO.java       |  10 +
 .../apache/syncope/common/lib/to/UserTO.java    |  64 +++
 .../common/lib/to/WorkflowFormPropertyTO.java   |   7 +
 .../syncope/common/lib/types/AnyTypeKind.java   |  20 +-
 .../common/lib/types/ClientExceptionType.java   |   4 +-
 .../syncope/common/lib/types/Entitlement.java   |  20 +
 .../rest/api/service/AnyTypeClassService.java   |  97 +++++
 .../common/rest/api/service/AnyTypeService.java |  97 +++++
 .../common/rest/api/service/RoleService.java    |  26 +-
 .../common/rest/api/service/SchemaService.java  |   2 +-
 .../common/rest/api/service/UserService.java    |   2 +-
 .../rest/api/service/WorkflowService.java       |   2 +-
 .../syncope/core/logic/AnyTypeClassLogic.java   | 131 ++++++
 .../apache/syncope/core/logic/AnyTypeLogic.java | 131 ++++++
 .../core/logic/LogicInvocationHandler.java      |  13 +-
 .../syncope/core/logic/ResourceLogic.java       |   2 +-
 .../apache/syncope/core/logic/UserLogic.java    |   4 +-
 .../core/logic/init/JobInstanceLoaderImpl.java  |  36 +-
 .../core/logic/report/UserReportlet.java        |  39 +-
 .../syncope/core/misc/ConnObjectUtils.java      | 269 +++---------
 .../apache/syncope/core/misc/MappingUtils.java  |  25 +-
 .../syncope/core/misc/jexl/JexlUtils.java       |  12 +-
 .../api/dao/UnallowedSchemaException.java       |  29 ++
 .../api/entity/anyobject/AnyObject.java         |   4 +-
 .../api/entity/task/ProvisioningTask.java       |   4 +-
 .../core/persistence/api/entity/user/User.java  |   3 +-
 .../persistence/jpa/dao/AbstractAnyDAO.java     |   3 +-
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |   4 +-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |   4 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |   4 +-
 .../persistence/jpa/entity/AbstractAttr.java    |   3 +-
 .../persistence/jpa/entity/AbstractDerAttr.java |  12 -
 .../persistence/jpa/entity/AbstractVirAttr.java |  12 -
 .../jpa/entity/anyobject/JPAADerAttr.java       |   9 +
 .../jpa/entity/anyobject/JPAAVirAttr.java       |   9 +
 .../jpa/entity/anyobject/JPAAnyObject.java      |   4 +-
 .../jpa/entity/group/JPAGDerAttr.java           |   9 +
 .../jpa/entity/group/JPAGVirAttr.java           |   9 +
 .../jpa/entity/task/JPAAnyTemplate.java         |   4 +-
 .../jpa/entity/task/JPAPushTask.java            |   6 +-
 .../jpa/entity/task/JPASyncTask.java            |   6 +-
 .../jpa/entity/user/JPAUDerAttr.java            |   9 +
 .../jpa/entity/user/JPAUPlainAttr.java          |   3 -
 .../jpa/entity/user/JPAUVirAttr.java            |   9 +
 .../persistence/jpa/entity/user/JPAUser.java    |   5 +-
 .../resources/META-INF/spring-orm-oracle.xml    |  50 +++
 .../resources/META-INF/spring-orm-sqlserver.xml |  50 +++
 .../src/main/resources/META-INF/spring-orm.xml  |  50 +++
 .../persistence/jpa/entity/VirAttrTest.java     |   4 +-
 .../jpa/relationship/AnyTypeTest.java           |   7 +-
 .../src/test/resources/content.xml              |  49 ++-
 .../core/provisioning/api/VirAttrHandler.java   |  71 ++++
 .../api/data/AnyTypeClassDataBinder.java        |  31 ++
 .../api/data/AnyTypeDataBinder.java             |  31 ++
 .../DefaultAnyObjectProvisioningManager.java    |  15 +
 .../java/DefaultGroupProvisioningManager.java   |  17 +
 .../java/DefaultUserProvisioningManager.java    |   3 +
 .../core/provisioning/java/VirAttrHandler.java  | 238 -----------
 .../provisioning/java/VirAttrHandlerImpl.java   | 411 +++++++++++++++++++
 .../java/data/AbstractAnyDataBinder.java        | 262 +++++++-----
 .../java/data/AnyObjectDataBinderImpl.java      |  99 ++++-
 .../java/data/AnyTypeClassDataBinderImpl.java   | 115 ++++++
 .../java/data/AnyTypeDataBinderImpl.java        |  90 ++++
 .../java/data/ConfigurationDataBinderImpl.java  |   4 +-
 .../java/data/GroupDataBinderImpl.java          |   6 +-
 .../java/data/NotificationDataBinderImpl.java   |  30 +-
 .../java/data/ResourceDataBinderImpl.java       |  40 +-
 .../java/data/RoleDataBinderImpl.java           |   2 +-
 .../java/data/SchemaDataBinderImpl.java         |   2 +-
 .../java/data/TaskDataBinderImpl.java           | 177 ++++----
 .../java/data/UserDataBinderImpl.java           | 122 ++++--
 .../notification/NotificationManagerImpl.java   |  18 +-
 .../AbstractPropagationTaskExecutor.java        |  20 +-
 .../LDAPMembershipPropagationActions.java       |   4 +-
 .../propagation/PropagationManagerImpl.java     |  24 +-
 .../java/sync/AbstractProvisioningJob.java      |   3 +-
 .../java/sync/AbstractPushResultHandler.java    |   6 +-
 .../java/sync/AbstractSyncResultHandler.java    |  29 +-
 .../java/sync/AbstractSyncopeResultHandler.java |   5 +-
 .../java/sync/GroupSyncResultHandlerImpl.java   |   6 +-
 .../java/sync/LDAPMembershipSyncActions.java    |   8 +-
 .../provisioning/java/sync/PushJobImpl.java     |  36 +-
 .../provisioning/java/sync/SyncJobImpl.java     |  12 +-
 .../core/provisioning/java/sync/SyncUtils.java  |  62 ++-
 .../java/data/ResourceDataBinderTest.java       |   2 +-
 .../rest/cxf/RestServiceExceptionMapper.java    |   3 +
 .../cxf/service/AnyTypeClassServiceImpl.java    |  67 +++
 .../rest/cxf/service/AnyTypeServiceImpl.java    |  67 +++
 .../rest/cxf/service/ConnectorServiceImpl.java  |   9 +-
 .../core/rest/cxf/service/GroupServiceImpl.java |  34 +-
 .../rest/cxf/service/ResourceServiceImpl.java   |  12 +-
 .../core/rest/cxf/service/TaskServiceImpl.java  |  14 +-
 .../core/rest/cxf/service/UserServiceImpl.java  |  46 ++-
 .../activiti/ActivitiUserWorkflowAdapter.java   |  12 +-
 .../core/workflow/activiti/ActivitiUtils.java   |  39 ++
 .../workflow/activiti/SyncopeUserManager.java   |   4 +-
 .../main/resources/workflowActivitiContext.xml  |   2 +
 .../camel/processor/GroupUpdateProcessor.java   |  23 +-
 .../camel/processor/UserUpdateProcessor.java    |  12 +-
 .../main/resources/all/provisioning.properties  |   2 +-
 .../src/main/resources/userWorkflow.bpmn20.xml  |  12 +-
 .../fit/core/reference/AbstractITCase.java      |  12 +-
 .../fit/core/reference/AbstractTaskITCase.java  |  16 +-
 .../fit/core/reference/CamelRouteITCase.java    |   8 +
 .../fit/core/reference/ConfigurationITCase.java |  92 -----
 .../fit/core/reference/ConnectorITCase.java     |   6 +-
 .../core/reference/ExceptionMapperITCase.java   |   9 +
 .../syncope/fit/core/reference/GroupITCase.java |  51 ++-
 .../fit/core/reference/PlainSchemaITCase.java   |  30 +-
 .../fit/core/reference/PushTaskITCase.java      |  70 ++--
 .../fit/core/reference/ResourceITCase.java      |  20 +-
 .../fit/core/reference/SyncTaskITCase.java      |  55 ++-
 .../syncope/fit/core/reference/UserITCase.java  |  51 ++-
 .../fit/core/reference/UserWorkflowITCase.java  |  29 +-
 .../fit/core/reference/VirAttrITCase.java       |   7 +-
 139 files changed, 3540 insertions(+), 1429 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index e17fd2c..0e6f5c4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,7 +19,6 @@ 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 -PskipTests -Dinvoker.streamLogs=true
+script: mvn --show-version --quiet clean install -Dinvoker.streamLogs=true
 notifications:
   webhooks: http://rovere.tirasa.net/cgi-bin/travis.cgi

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index a093dbd..e6f8488 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -172,7 +172,7 @@ public class ConnectorRestClient extends BaseRestClient {
         try {
             check = getService(ResourceService.class).check(resourceTO);
         } catch (Exception e) {
-            LOG.error("Connector not found {}", resourceTO.getConnectorId(), e);
+            LOG.error("Connector not found {}", resourceTO.getConnector(), e);
         }
 
         return check;

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
index cab3239..e8bcedb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AnyOperations.java
@@ -29,13 +29,17 @@ 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.AnyObjectMod;
 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.AnyObjectTO;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.AttrTO;
 import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.to.UserTO;
 
 /**
@@ -193,6 +197,63 @@ public final class AnyOperations {
     /**
      * Calculate modifications needed by first in order to be equal to second.
      *
+     * @param updated updated AnyObjectTO
+     * @param original original AnyObjectTO
+     * @return AnyObjectMod containing differences
+     */
+    public static AnyObjectMod diff(final AnyObjectTO updated, final AnyObjectTO original) {
+        return diff(updated, original, false);
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
+     * @param updated updated AnyObjectTO
+     * @param original original AnyObjectTO
+     * @param incremental perform incremental diff (without removing existing info)
+     * @return AnyObjectMod containing differences
+     */
+    public static AnyObjectMod diff(final AnyObjectTO updated, final AnyObjectTO original, final boolean incremental) {
+        AnyObjectMod result = new AnyObjectMod();
+
+        diff(updated, original, result, incremental);
+
+        // 1. relationships
+        Map<Long, RelationshipTO> updatedRels = updated.getRelationshipMap();
+        Map<Long, RelationshipTO> originalRels = original.getRelationshipMap();
+
+        for (Map.Entry<Long, RelationshipTO> entry : updatedRels.entrySet()) {
+            if (!originalRels.containsKey(entry.getKey())) {
+                result.getRelationshipsToAdd().add(entry.getKey());
+            }
+        }
+        if (!incremental) {
+            Set<Long> originalGroups = new HashSet<>(originalRels.keySet());
+            originalGroups.removeAll(updatedRels.keySet());
+            result.getRelationshipsToRemove().addAll(originalGroups);
+        }
+
+        // 2. memberships
+        Map<Long, MembershipTO> updatedMembs = updated.getMembershipMap();
+        Map<Long, MembershipTO> originalMembs = original.getMembershipMap();
+
+        for (Map.Entry<Long, MembershipTO> entry : updatedMembs.entrySet()) {
+            if (!originalMembs.containsKey(entry.getKey())) {
+                result.getMembershipsToAdd().add(entry.getKey());
+            }
+        }
+        if (!incremental) {
+            Set<Long> originalGroups = new HashSet<>(originalMembs.keySet());
+            originalGroups.removeAll(updatedMembs.keySet());
+            result.getMembershipsToRemove().addAll(originalGroups);
+        }
+
+        return result;
+    }
+
+    /**
+     * Calculate modifications needed by first in order to be equal to second.
+     *
      * @param updated updated UserTO
      * @param original original UserTO
      * @return UserMod containing differences
@@ -248,6 +309,36 @@ public final class AnyOperations {
         result.getRolesToRemove().addAll(CollectionUtils.subtract(original.getRoles(), updated.getRoles()));
         result.getRolesToAdd().addAll(CollectionUtils.subtract(updated.getRoles(), original.getRoles()));
 
+        // 5. relationships
+        Map<Long, RelationshipTO> updatedRels = updated.getRelationshipMap();
+        Map<Long, RelationshipTO> originalRels = original.getRelationshipMap();
+
+        for (Map.Entry<Long, RelationshipTO> entry : updatedRels.entrySet()) {
+            if (!originalRels.containsKey(entry.getKey())) {
+                result.getRelationshipsToAdd().add(entry.getKey());
+            }
+        }
+        if (!incremental) {
+            Set<Long> originalGroups = new HashSet<>(originalRels.keySet());
+            originalGroups.removeAll(updatedRels.keySet());
+            result.getRelationshipsToRemove().addAll(originalGroups);
+        }
+
+        // 6. memberships
+        Map<Long, MembershipTO> updatedMembs = updated.getMembershipMap();
+        Map<Long, MembershipTO> originalMembs = original.getMembershipMap();
+
+        for (Map.Entry<Long, MembershipTO> entry : updatedMembs.entrySet()) {
+            if (!originalMembs.containsKey(entry.getKey())) {
+                result.getMembershipsToAdd().add(entry.getKey());
+            }
+        }
+        if (!incremental) {
+            Set<Long> originalGroups = new HashSet<>(originalMembs.keySet());
+            originalGroups.removeAll(updatedMembs.keySet());
+            result.getMembershipsToRemove().addAll(originalGroups);
+        }
+
         return result;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
index d139bda..ebdc5ae 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
@@ -21,6 +21,8 @@ package org.apache.syncope.common.lib;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 
 public class SyncopeClientCompositeException extends SyncopeClientException {
@@ -66,7 +68,17 @@ public class SyncopeClientCompositeException extends SyncopeClientException {
                     + ClientExceptionType.class.getName() + " set");
         }
 
-        return exceptions.add(exception);
+        SyncopeClientException alreadyAdded = CollectionUtils.find(exceptions, new Predicate<SyncopeClientException>() {
+
+            @Override
+            public boolean evaluate(final SyncopeClientException ex) {
+                return ex.getType() == exception.getType();
+            }
+        });
+
+        return alreadyAdded == null
+                ? exceptions.add(exception)
+                : alreadyAdded.getElements().addAll(exception.getElements());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
index 8d015f2..f17d5e5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
@@ -18,8 +18,8 @@
  */
 package org.apache.syncope.common.lib;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 
 public class SyncopeClientException extends RuntimeException {
@@ -28,7 +28,7 @@ public class SyncopeClientException extends RuntimeException {
 
     private ClientExceptionType type;
 
-    private final List<String> elements = new ArrayList<>();
+    private final Set<String> elements = new HashSet<>();
 
     public static SyncopeClientException build(final ClientExceptionType type) {
         if (type == ClientExceptionType.Composite) {
@@ -66,7 +66,7 @@ public class SyncopeClientException extends RuntimeException {
         this.type = type;
     }
 
-    public List<String> getElements() {
+    public Set<String> getElements() {
         return elements;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapEntryType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapEntryType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapEntryType.java
new file mode 100644
index 0000000..2d30612
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapEntryType.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011 John Yeary <jy...@bluelotussoftware.com>.
+ * Copyright 2011 Bluelotus Software, LLC.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: MapEntryType.java 399 2011-12-03 04:22:50Z jyeary $
+ */
+package org.apache.syncope.common.lib.jaxb;
+
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class GenericMapEntryType<K, V> {
+
+    private K key;
+
+    private V value;
+
+    public GenericMapEntryType() {
+    }
+
+    public GenericMapEntryType(final Map.Entry<K, V> e) {
+        key = e.getKey();
+        value = e.getValue();
+    }
+
+    @XmlElement
+    public K getKey() {
+        return key;
+    }
+
+    public void setKey(final K key) {
+        this.key = key;
+    }
+
+    @XmlElement
+    public V getValue() {
+        return value;
+    }
+
+    public void setValue(final V value) {
+        this.value = value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapType.java
new file mode 100644
index 0000000..491a860
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/GenericMapType.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 John Yeary <jy...@bluelotussoftware.com>.
+ * Copyright 2011 Bluelotus Software, LLC.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: MapType.java 399 2011-12-03 04:22:50Z jyeary $
+ */
+package org.apache.syncope.common.lib.jaxb;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class GenericMapType<K, V> {
+
+    private final List<GenericMapEntryType<K, V>> entry = new ArrayList<>();
+
+    public GenericMapType() {
+    }
+
+    public GenericMapType(final Map<K, V> map) {
+        for (Map.Entry<K, V> e : map.entrySet()) {
+            entry.add(new GenericMapEntryType<>(e));
+        }
+    }
+
+    public List<GenericMapEntryType<K, V>> getEntry() {
+        return entry;
+    }
+
+    public void setEntry(final List<GenericMapEntryType<K, V>> entry) {
+        this.entry.clear();
+        if (entry != null) {
+            this.entry.addAll(entry);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/XmlGenericMapAdapter.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/XmlGenericMapAdapter.java b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/XmlGenericMapAdapter.java
new file mode 100644
index 0000000..1b10d5f
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/jaxb/XmlGenericMapAdapter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011 John Yeary <jy...@bluelotussoftware.com>.
+ * Copyright 2011 Bluelotus Software, LLC.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * $Id: XmlGenericMapAdapter.java 399 2011-12-03 04:22:50Z jyeary $
+ */
+package org.apache.syncope.common.lib.jaxb;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class XmlGenericMapAdapter<K, V> extends XmlAdapter<GenericMapType<K, V>, Map<K, V>> {
+
+    @Override
+    public Map<K, V> unmarshal(final GenericMapType<K, V> v) throws Exception {
+        Map<K, V> map = new HashMap<>();
+
+        for (GenericMapEntryType<K, V> mapEntryType : v.getEntry()) {
+            map.put(mapEntryType.getKey(), mapEntryType.getValue());
+        }
+
+        return map;
+    }
+
+    @Override
+    public GenericMapType<K, V> marshal(final Map<K, V> v) throws Exception {
+        GenericMapType<K, V> mapType = new GenericMapType<>();
+
+        for (Map.Entry<K, V> entry : v.entrySet()) {
+            GenericMapEntryType<K, V> mapEntryType = new GenericMapEntryType<>();
+            mapEntryType.setKey(entry.getKey());
+            mapEntryType.setValue(entry.getValue());
+            mapType.getEntry().add(mapEntryType);
+        }
+
+        return mapType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index ec508c9..e5fcb85 100644
--- 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
@@ -35,6 +35,10 @@ public abstract class AnyMod extends AbstractBaseBean {
 
     private String realm;
 
+    protected final Set<String> auxClassesToAdd = new HashSet<>();
+
+    protected final Set<String> auxClassesToRemove = new HashSet<>();
+
     protected final Set<AttrMod> plainAttrsToUpdate = new HashSet<>();
 
     protected final Set<String> plainAttrsToRemove = new HashSet<>();
@@ -67,6 +71,20 @@ public abstract class AnyMod extends AbstractBaseBean {
         this.realm = realm;
     }
 
+    @XmlElementWrapper(name = "auxClassesToAdd")
+    @XmlElement(name = "class")
+    @JsonProperty("auxClassesToAdd")
+    public Set<String> getAuxClassesToAdd() {
+        return auxClassesToAdd;
+    }
+
+    @XmlElementWrapper(name = "auxClassesToRemove")
+    @XmlElement(name = "class")
+    @JsonProperty("auxClassesToRemove")
+    public Set<String> getAuxClassesToRemove() {
+        return auxClassesToRemove;
+    }
+
     @XmlElementWrapper(name = "plainAttrsToRemove")
     @XmlElement(name = "attribute")
     @JsonProperty("plainAttrsToRemove")

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 72daf7b..afc459e 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
@@ -44,6 +44,7 @@ public class UserReportletConf extends AbstractAnyReportletConf {
         changePwdDate,
         passwordHistorySize,
         failedLoginCount,
+        relationships,
         memberships,
         resources
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 9a68a8d..6443eea 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,7 @@ 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.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;
 
 public final class SearchableFields {
@@ -38,11 +35,7 @@ public final class SearchableFields {
     };
 
     public static List<String> get(final AnyTypeKind anyTypeKind) {
-        return get(anyTypeKind == AnyTypeKind.USER
-                ? UserTO.class
-                : anyTypeKind == AnyTypeKind.GROUP
-                        ? GroupTO.class
-                        : AnyObjectTO.class);
+        return get(anyTypeKind.getToClass());
     }
 
     public static List<String> get(final Class<? extends AnyTO> anyRef) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
index c1dcf1c..cd63bcd 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
@@ -19,8 +19,8 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.ArrayList;
-import java.util.List;
+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.XmlRootElement;
@@ -50,7 +50,7 @@ public class AbstractProvisioningTaskTO extends SchedTaskTO {
 
     private MatchingRule matchingRule;
 
-    private final List<String> actionsClassNames = new ArrayList<>();
+    private final Set<String> actionsClassNames = new HashSet<>();
 
     public String getResource() {
         return resource;
@@ -95,7 +95,7 @@ public class AbstractProvisioningTaskTO extends SchedTaskTO {
     @XmlElementWrapper(name = "actionsClassNames")
     @XmlElement(name = "actionsClassName")
     @JsonProperty("actionsClassNames")
-    public List<String> getActionsClassNames() {
+    public Set<String> getActionsClassNames() {
         return actionsClassNames;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 6d2eb1b..f5599de 100644
--- 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
@@ -18,6 +18,15 @@
  */
 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.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
@@ -27,4 +36,52 @@ public class AnyObjectTO extends AnyTO {
 
     private static final long serialVersionUID = 8841697496476959639L;
 
+    private final List<RelationshipTO> relationships = new ArrayList<>();
+
+    private final List<MembershipTO> memberships = new ArrayList<>();
+
+    private final List<Long> dynGroups = new ArrayList<>();
+
+    @XmlElementWrapper(name = "relationships")
+    @XmlElement(name = "relationship")
+    @JsonProperty("relationships")
+    public List<RelationshipTO> getRelationships() {
+        return relationships;
+    }
+
+    @JsonIgnore
+    public Map<Long, RelationshipTO> getRelationshipMap() {
+        Map<Long, RelationshipTO> result = new HashMap<>(getRelationships().size());
+        for (RelationshipTO membership : getRelationships()) {
+            result.put(membership.getRightKey(), membership);
+        }
+        result = Collections.unmodifiableMap(result);
+
+        return result;
+    }
+
+    @XmlElementWrapper(name = "memberships")
+    @XmlElement(name = "membership")
+    @JsonProperty("memberships")
+    public List<MembershipTO> getMemberships() {
+        return memberships;
+    }
+
+    @JsonIgnore
+    public Map<Long, MembershipTO> getMembershipMap() {
+        Map<Long, MembershipTO> 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/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index bac9947..56b1c44 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -30,9 +31,14 @@ 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.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
+@XmlRootElement(name = "any")
 @XmlType
+@XmlSeeAlso({ UserTO.class, GroupTO.class, AnyObjectTO.class })
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
 public abstract class AnyTO extends ConnObjectTO {
 
     private static final long serialVersionUID = -754311920679872084L;
@@ -45,6 +51,8 @@ public abstract class AnyTO extends ConnObjectTO {
 
     private String status;
 
+    private final List<String> auxClasses = new ArrayList<>();
+
     private final Set<AttrTO> derAttrs = new LinkedHashSet<>();
 
     private final Set<AttrTO> virAttrs = new LinkedHashSet<>();
@@ -53,12 +61,6 @@ public abstract class AnyTO extends ConnObjectTO {
 
     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;
     }
@@ -91,6 +93,13 @@ public abstract class AnyTO extends ConnObjectTO {
         this.status = status;
     }
 
+    @XmlElementWrapper(name = "auxClasses")
+    @XmlElement(name = "class")
+    @JsonProperty("auxClasses")
+    public List<String> getAuxClasses() {
+        return auxClasses;
+    }
+
     @XmlElementWrapper(name = "derAttrs")
     @XmlElement(name = "attribute")
     @JsonProperty("derAttrs")
@@ -139,42 +148,4 @@ public abstract class AnyTO extends ConnObjectTO {
         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/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
new file mode 100644
index 0000000..1afbe4d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "anyTypeClass")
+@XmlType
+public class AnyTypeClassTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = -591757688607551266L;
+
+    private String name;
+
+    private final List<String> plainSchemas = new ArrayList<>();
+
+    private final List<String> derSchemas = new ArrayList<>();
+
+    private final List<String> virSchemas = new ArrayList<>();
+
+    public String getKey() {
+        return name;
+    }
+
+    public void setKey(final String key) {
+        this.name = key;
+    }
+
+    @XmlElementWrapper(name = "plainSchemas")
+    @XmlElement(name = "schema")
+    @JsonProperty("plainSchemas")
+    public List<String> getPlainSchemas() {
+        return plainSchemas;
+    }
+
+    @XmlElementWrapper(name = "derSchemas")
+    @XmlElement(name = "schema")
+    @JsonProperty("derSchemas")
+    public List<String> getDerSchemas() {
+        return derSchemas;
+    }
+
+    @XmlElementWrapper(name = "virSchemas")
+    @XmlElement(name = "schema")
+    @JsonProperty("virSchemas")
+    public List<String> getVirSchemas() {
+        return virSchemas;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
new file mode 100644
index 0000000..9618bf5
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.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.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+@XmlRootElement(name = "anyType")
+@XmlType
+public class AnyTypeTO extends AbstractBaseBean {
+
+    private static final long serialVersionUID = 6771657557616874373L;
+
+    private String name;
+
+    private AnyTypeKind kind;
+
+    private final List<String> classes = new ArrayList<>();
+
+    public String getKey() {
+        return name;
+    }
+
+    public void setKey(final String key) {
+        this.name = key;
+    }
+
+    public AnyTypeKind getKind() {
+        return kind;
+    }
+
+    public void setKind(final AnyTypeKind kind) {
+        this.kind = kind;
+    }
+
+    @XmlElementWrapper(name = "classes")
+    @XmlElement(name = "class")
+    @JsonProperty("classes")
+    public List<String> getClasses() {
+        return classes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
index 829f309..cf385b4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
@@ -41,21 +41,12 @@ public class AttrTO extends AbstractBaseBean {
     /**
      * Set of (string) values of this attribute.
      */
-    private final List<String> values;
+    private final List<String> values = new ArrayList<>();
 
     /**
      * Whether this attribute is read-only or not.
      */
-    private boolean readonly;
-
-    /**
-     * Default constructor.
-     */
-    public AttrTO() {
-        super();
-        values = new ArrayList<String>();
-        readonly = false;
-    }
+    private boolean readonly = false;
 
     /**
      * @return the name of the schema that this attribute is referring to

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
index 9726a25..9b44b3f 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/BulkActionResult.java
@@ -25,15 +25,18 @@ import java.util.Collections;
 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.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 
 @XmlRootElement(name = "bulkActionResult")
 @XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
 public class BulkActionResult extends AbstractBaseBean {
 
     private static final long serialVersionUID = 2868894178821778133L;
@@ -52,86 +55,25 @@ public class BulkActionResult extends AbstractBaseBean {
 
     }
 
-    private final List<Result> results = new ArrayList<>();
-
-    @XmlElementWrapper(name = "result")
-    @XmlElement(name = "item")
-    @JsonProperty("result")
-    public List<Result> getResult() {
-        return results;
-    }
-
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
     @JsonIgnore
-    public void add(final Object id, final Status status) {
-        if (id != null) {
-            results.add(new Result(id.toString(), status));
-        }
-    }
+    private final Map<String, Status> results = new HashMap<>();
 
-    @JsonIgnore
-    public void add(final Object id, final String status) {
-        if (id != null) {
-            results.add(new Result(id.toString(), Status.valueOf(status.toUpperCase())));
-        }
-    }
-
-    @JsonIgnore
-    public Map<String, Status> getResultMap() {
-        final Map<String, Status> res = new HashMap<>();
-
-        for (Result result : results) {
-            res.put(result.getKey(), result.getValue());
-        }
-
-        return Collections.unmodifiableMap(res);
+    @JsonProperty
+    public Map<String, Status> getResults() {
+        return results;
     }
 
     @JsonIgnore
     public List<String> getResultByStatus(final Status status) {
-        final List<String> res = new ArrayList<>();
+        final List<String> result = new ArrayList<>();
 
-        for (Result result : results) {
-            if (result.getValue() == status) {
-                res.add(result.getKey());
+        for (Map.Entry<String, Status> entry : results.entrySet()) {
+            if (entry.getValue() == status) {
+                result.add(entry.getKey());
             }
         }
 
-        return Collections.unmodifiableList(res);
-    }
-
-    public static class Result extends AbstractBaseBean {
-
-        private static final long serialVersionUID = -1149681964161193232L;
-
-        private String key;
-
-        private Status value;
-
-        public Result() {
-            super();
-        }
-
-        public Result(final String key, final Status value) {
-            super();
-
-            this.key = key;
-            this.value = value;
-        }
-
-        public String getKey() {
-            return key;
-        }
-
-        public Status getValue() {
-            return value;
-        }
-
-        public void setKey(final String key) {
-            this.key = key;
-        }
-
-        public void setValue(final Status value) {
-            this.value = value;
-        }
+        return Collections.unmodifiableList(result);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 873b15d..a5a33ca 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
@@ -18,13 +18,13 @@
  */
 package org.apache.syncope.common.lib.to;
 
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "group")
 @XmlType
-@JsonIgnoreProperties({ "displayName" })
 public class GroupTO extends AnyTO {
 
     private static final long serialVersionUID = -7785920258290147542L;
@@ -35,9 +35,19 @@ public class GroupTO extends AnyTO {
 
     private Long groupOwner;
 
-    private String aDynMembershipCond;
+    private String adynMembershipCond;
 
-    private String uDynMembershipCond;
+    private String udynMembershipCond;
+
+    @Override
+    public String getType() {
+        return AnyTypeKind.GROUP.name();
+    }
+
+    @Override
+    public void setType(final String type) {
+        // fixed
+    }
 
     public String getName() {
         return name;
@@ -64,19 +74,36 @@ public class GroupTO extends AnyTO {
     }
 
     public String getADynMembershipCond() {
-        return aDynMembershipCond;
+        return adynMembershipCond;
     }
 
     public void setADynMembershipCond(final String aDynMembershipCond) {
-        this.aDynMembershipCond = aDynMembershipCond;
+        this.adynMembershipCond = aDynMembershipCond;
     }
 
     public String getUDynMembershipCond() {
-        return uDynMembershipCond;
+        return udynMembershipCond;
     }
 
     public void setUDynMembershipCond(final String uDynMembershipCond) {
-        this.uDynMembershipCond = uDynMembershipCond;
+        this.udynMembershipCond = uDynMembershipCond;
     }
 
+    @JsonIgnore
+    public String getDisplayName() {
+        return getKey() + " " + getName();
+    }
+
+    public static long fromDisplayName(final String displayName) {
+        long result = 0;
+        if (displayName != null && !displayName.isEmpty() && displayName.indexOf(' ') != -1) {
+            try {
+                result = Long.valueOf(displayName.split(" ")[0]);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 5c435e4..ef70589 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
@@ -20,6 +20,7 @@ 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;
 
 @XmlRootElement(name = "membership")
 @XmlType
@@ -29,9 +30,14 @@ public class MembershipTO extends RelationshipTO {
 
     private String groupName;
 
+    public MembershipTO() {
+        super();
+        super.setRightType(AnyTypeKind.GROUP.name());
+    }
+
     @Override
-    public String getRightType() {
-        return "group";
+    public void setRightType(final String rightType) {
+        // ignore
     }
 
     public String getGroupName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 662a465..7cb6556 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
@@ -18,21 +18,27 @@
  */
 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.HashMap;
 import java.util.List;
 import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 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 javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.TraceLevel;
 
 @XmlRootElement(name = "notification")
 @XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
 public class NotificationTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = -6145117115632592612L;
@@ -41,6 +47,8 @@ public class NotificationTO extends AbstractBaseBean {
 
     private final List<String> events = new ArrayList<>();
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
     private final Map<String, String> abouts = new HashMap<>();
 
     private String recipients;
@@ -63,6 +71,7 @@ public class NotificationTO extends AbstractBaseBean {
 
     private boolean active;
 
+    @JsonProperty
     public Map<String, String> getAbouts() {
         return abouts;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e1839af..dd3347a 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,21 +18,30 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashMap;
 import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 
 @XmlRootElement(name = "pushTask")
 @XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
 public class PushTaskTO extends AbstractProvisioningTaskTO {
 
     private static final long serialVersionUID = -2143537546915809018L;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
     private final Map<String, String> filters = new HashMap<>();
 
+    @JsonProperty
     public Map<String, String> getFilters() {
         return filters;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index 2585b2b..d769719 100644
--- 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
@@ -28,8 +28,6 @@ public class RelationshipTO extends AbstractBaseBean {
 
     private static final long serialVersionUID = 360672942026613929L;
 
-    private long key;
-
     private String leftType;
 
     private long leftKey;
@@ -38,14 +36,6 @@ public class RelationshipTO extends AbstractBaseBean {
 
     private long rightKey;
 
-    public long getKey() {
-        return key;
-    }
-
-    public void setKey(final long key) {
-        this.key = key;
-    }
-
     public String getLeftType() {
         return leftType;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fb97113..dcec457 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
@@ -48,7 +48,7 @@ public class ResourceTO extends AbstractAnnotatedBean {
     /**
      * The resource type is identified by the associated connector.
      */
-    private Long connectorId;
+    private Long connector;
 
     /**
      * Convenience information: display name for the connector id.
@@ -83,10 +83,6 @@ public class ResourceTO extends AbstractAnnotatedBean {
 
     private final Set<ConnConfProperty> connConfProperties = new HashSet<>();
 
-    private String usyncToken;
-
-    private String rsyncToken;
-
     private final List<String> propagationActionsClassNames = new ArrayList<>();
 
     public ResourceTO() {
@@ -117,12 +113,12 @@ public class ResourceTO extends AbstractAnnotatedBean {
         this.enforceMandatoryCondition = enforceMandatoryCondition;
     }
 
-    public Long getConnectorId() {
-        return connectorId;
+    public Long getConnector() {
+        return connector;
     }
 
-    public void setConnectorId(final Long connectorId) {
-        this.connectorId = connectorId;
+    public void setConnector(final Long connector) {
+        this.connector = connector;
     }
 
     public String getConnectorDisplayName() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 4974505..a6a7a8a 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,19 +18,28 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashMap;
 import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 
 @XmlRootElement(name = "syncTask")
 @XmlType
+@XmlAccessorType(XmlAccessType.FIELD)
 public class SyncTaskTO extends AbstractProvisioningTaskTO {
 
     private static final long serialVersionUID = -2143537546915809017L;
 
     private String destinationRealm;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
     private final Map<String, AnyTO> templates = new HashMap<>();
 
     private boolean fullReconciliation;
@@ -43,6 +52,7 @@ public class SyncTaskTO extends AbstractProvisioningTaskTO {
         this.destinationRealm = destinationRealm;
     }
 
+    @JsonProperty
     public Map<String, AnyTO> getTemplates() {
         return templates;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 5de7b01..dd5ebee 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,17 +18,22 @@
  */
 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;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
 @XmlRootElement(name = "user")
 @XmlType
@@ -58,6 +63,22 @@ public class UserTO extends AnyTO {
 
     private String securityAnswer;
 
+    private final List<RelationshipTO> relationships = new ArrayList<>();
+
+    private final List<MembershipTO> memberships = new ArrayList<>();
+
+    private final List<Long> dynGroups = new ArrayList<>();
+
+    @Override
+    public String getType() {
+        return AnyTypeKind.USER.name();
+    }
+
+    @Override
+    public void setType(final String type) {
+        // fixed
+    }
+
     public String getPassword() {
         return password;
     }
@@ -148,6 +169,49 @@ public class UserTO extends AnyTO {
         this.securityAnswer = securityAnswer;
     }
 
+    @XmlElementWrapper(name = "relationships")
+    @XmlElement(name = "relationship")
+    @JsonProperty("relationships")
+    public List<RelationshipTO> getRelationships() {
+        return relationships;
+    }
+
+    @JsonIgnore
+    public Map<Long, RelationshipTO> getRelationshipMap() {
+        Map<Long, RelationshipTO> result = new HashMap<>(getRelationships().size());
+        for (RelationshipTO membership : getRelationships()) {
+            result.put(membership.getRightKey(), membership);
+        }
+        result = Collections.unmodifiableMap(result);
+
+        return result;
+    }
+
+    @XmlElementWrapper(name = "memberships")
+    @XmlElement(name = "membership")
+    @JsonProperty("memberships")
+    public List<MembershipTO> getMemberships() {
+        return memberships;
+    }
+
+    @JsonIgnore
+    public Map<Long, MembershipTO> getMembershipMap() {
+        Map<Long, MembershipTO> 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;
+    }
+
     @Override
     public String toString() {
         return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
index 5b67c92..9fa5928 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormPropertyTO.java
@@ -18,11 +18,15 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashMap;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 import org.apache.syncope.common.lib.types.WorkflowFormPropertyType;
 
 @XmlRootElement(name = "workflowFormProperty")
@@ -47,6 +51,8 @@ public class WorkflowFormPropertyTO extends AbstractBaseBean {
 
     private String datePattern;
 
+    @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
+    @JsonIgnore
     private final Map<String, String> enumValues = new HashMap<>();
 
     public String getId() {
@@ -113,6 +119,7 @@ public class WorkflowFormPropertyTO extends AbstractBaseBean {
         this.datePattern = datePattern;
     }
 
+    @JsonProperty
     public Map<String, String> getEnumValues() {
         return enumValues;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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
index c7b4e47..ee35e28 100644
--- 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
@@ -19,12 +19,26 @@
 package org.apache.syncope.common.lib.types;
 
 import javax.xml.bind.annotation.XmlEnum;
+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;
 
 @XmlEnum
 public enum AnyTypeKind {
 
-    USER,
-    GROUP,
-    ANY_OBJECT;
+    USER(UserTO.class),
+    GROUP(GroupTO.class),
+    ANY_OBJECT(AnyObjectTO.class);
+
+    private final Class<? extends AnyTO> toClass;
+
+    private AnyTypeKind(final Class<? extends AnyTO> toClass) {
+        this.toClass = toClass;
+    }
+
+    public Class<? extends AnyTO> getToClass() {
+        return toClass;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 498f603..8e96942 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -40,6 +40,7 @@ public enum ClientExceptionType {
     InvalidProvision(Response.Status.BAD_REQUEST),
     InvalidReport(Response.Status.BAD_REQUEST),
     InvalidReportExec(Response.Status.BAD_REQUEST),
+    InvalidAnyType(Response.Status.BAD_REQUEST),
     InvalidAnyObject(Response.Status.BAD_REQUEST),
     InvalidGroup(Response.Status.BAD_REQUEST),
     InvalidSchemaDefinition(Response.Status.BAD_REQUEST),
@@ -49,7 +50,7 @@ public enum ClientExceptionType {
     InvalidPlainSchema(Response.Status.BAD_REQUEST),
     InvalidDerSchema(Response.Status.BAD_REQUEST),
     InvalidVirSchema(Response.Status.BAD_REQUEST),
-    InvalidSchemaMapping(Response.Status.BAD_REQUEST),
+    InvalidMapping(Response.Status.BAD_REQUEST),
     InvalidRealm(Response.Status.BAD_REQUEST),
     InvalidUser(Response.Status.BAD_REQUEST),
     InvalidExternalResource(Response.Status.BAD_REQUEST),
@@ -65,6 +66,7 @@ public enum ClientExceptionType {
     GroupOwnership(Response.Status.BAD_REQUEST),
     Scheduling(Response.Status.BAD_REQUEST),
     Unauthorized(Response.Status.UNAUTHORIZED),
+    UnallowedSchemas(Response.Status.BAD_REQUEST),
     Unknown(Response.Status.BAD_REQUEST),
     Workflow(Response.Status.BAD_REQUEST);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 81caa77..6ffe318 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
@@ -36,6 +36,26 @@ public final class Entitlement {
 
     public static final String REALM_DELETE = "REALM_DELETE";
 
+    public static final String ANYTYPECLASS_LIST = "ANYTYPECLASS_LIST";
+
+    public static final String ANYTYPECLASS_CREATE = "ANYTYPECLASS_CREATE";
+
+    public static final String ANYTYPECLASS_READ = "ANYTYPECLASS_READ";
+
+    public static final String ANYTYPECLASS_UPDATE = "ANYTYPECLASS_UPDATE";
+
+    public static final String ANYTYPECLASS_DELETE = "ANYTYPECLASS_DELETE";
+
+    public static final String ANYTYPE_LIST = "ANYTYPE_LIST";
+
+    public static final String ANYTYPE_CREATE = "ANYTYPE_CREATE";
+
+    public static final String ANYTYPE_READ = "ANYTYPE_READ";
+
+    public static final String ANYTYPE_UPDATE = "ANYTYPE_UPDATE";
+
+    public static final String ANYTYPE_DELETE = "ANYTYPE_DELETE";
+
     public static final String ROLE_LIST = "ROLE_LIST";
 
     public static final String ROLE_CREATE = "ROLE_CREATE";

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
new file mode 100644
index 0000000..21831cf
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.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.common.rest.api.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+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.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.AnyTypeClassTO;
+
+/**
+ * REST operations for any type classes.
+ */
+@Path("anyTypeClassClasses")
+public interface AnyTypeClassService extends JAXRSService {
+
+    /**
+     * Returns a list of all anyTypeClasss.
+     *
+     * @return list of all anyTypeClasss.
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    List<AnyTypeClassTO> list();
+
+    /**
+     * Returns anyTypeClass with matching key.
+     *
+     * @param key anyTypeClass key to be read
+     * @return anyTypeClass with matching key
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    AnyTypeClassTO read(@NotNull @PathParam("key") String key);
+
+    /**
+     * Creates a new anyTypeClass.
+     *
+     * @param anyTypeClassTO anyTypeClass to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created anyTypeClass
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created anyTypeClass")
+    })
+    @POST
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull AnyTypeClassTO anyTypeClassTO);
+
+    /**
+     * Updates the anyTypeClass matching the provided key.
+     *
+     * @param key anyTypeClass key to be updated
+     * @param anyTypeClassTO anyTypeClass to be stored
+     */
+    @PUT
+    @Path("{key}")
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    void update(@NotNull @PathParam("key") String key, @NotNull AnyTypeClassTO anyTypeClassTO);
+
+    /**
+     * Deletes the anyTypeClass matching the provided key.
+     *
+     * @param key anyTypeClass key to be deleted
+     */
+    @DELETE
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
new file mode 100644
index 0000000..ddedd25
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.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.common.rest.api.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+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.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.AnyTypeTO;
+
+/**
+ * REST operations for any types.
+ */
+@Path("anyTypes")
+public interface AnyTypeService extends JAXRSService {
+
+    /**
+     * Returns a list of all anyTypes.
+     *
+     * @return list of all anyTypes.
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    List<AnyTypeTO> list();
+
+    /**
+     * Returns anyType with matching key.
+     *
+     * @param key anyType key to be read
+     * @return anyType with matching key
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    AnyTypeTO read(@NotNull @PathParam("key") String key);
+
+    /**
+     * Creates a new anyType.
+     *
+     * @param anyTypeTO anyType to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created anyType
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created anyType")
+    })
+    @POST
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull AnyTypeTO anyTypeTO);
+
+    /**
+     * Updates the anyType matching the provided key.
+     *
+     * @param key anyType key to be updated
+     * @param anyTypeTO anyType to be stored
+     */
+    @PUT
+    @Path("{key}")
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    void update(@NotNull @PathParam("key") String key, @NotNull AnyTypeTO anyTypeTO);
+
+    /**
+     * Deletes the anyType matching the provided key.
+     *
+     * @param key anyType key to be deleted
+     */
+    @DELETE
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
index 172af5f..881e1bc 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
@@ -51,15 +51,15 @@ public interface RoleService extends JAXRSService {
     List<RoleTO> list();
 
     /**
-     * Returns role with matching id.
+     * Returns role with matching key.
      *
-     * @param roleKey role id to be read
-     * @return role with matching id
+     * @param key role key to be read
+     * @return role with matching key
      */
     @GET
-    @Path("{roleKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    RoleTO read(@NotNull @PathParam("roleKey") Long roleKey);
+    RoleTO read(@NotNull @PathParam("key") Long key);
 
     /**
      * Creates a new role.
@@ -76,22 +76,22 @@ public interface RoleService extends JAXRSService {
     Response create(@NotNull RoleTO roleTO);
 
     /**
-     * Updates the role matching the provided id.
+     * Updates the role matching the provided key.
      *
-     * @param roleKey role id to be updated
+     * @param key role key to be updated
      * @param roleTO role to be stored
      */
     @PUT
-    @Path("{roleKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("roleKey") Long roleKey, @NotNull RoleTO roleTO);
+    void update(@NotNull @PathParam("key") Long key, @NotNull RoleTO roleTO);
 
     /**
-     * Deletes the role matching the provided id.
+     * Deletes the role matching the provided key.
      *
-     * @param roleKey role id to be deleted
+     * @param key role key to be deleted
      */
     @DELETE
-    @Path("{roleKey}")
-    void delete(@NotNull @PathParam("roleKey") Long roleKey);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 4ffb3f6..352e310 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
@@ -39,7 +39,7 @@ import org.apache.syncope.common.lib.types.SchemaType;
 /**
  * REST operations for attribute schemas.
  */
-@Path("schemas/{kind}/{type}")
+@Path("schemas/{type}")
 public interface SchemaService extends JAXRSService {
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 9e280a5..8f9363cb 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
@@ -81,7 +81,7 @@ public interface UserService extends JAXRSService {
     })
     @OPTIONS
     @Path("{username}/userKey")
-    Response getUserId(@NotNull @PathParam("username") String username);
+    Response getUserKey(@NotNull @PathParam("username") String username);
 
     /**
      * Reads the user matching the provided userKey.

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fc48429..68858c7 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
@@ -33,7 +33,7 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
 /**
  * REST operations for workflow definition management.
  */
-@Path("workflows/{kind}")
+@Path("workflows/{anyTypeKind}")
 public interface WorkflowService extends JAXRSService {
 
     /**


[62/70] syncope git commit: Improving REST update methods signature thanks to CXF-6447

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 2616d4a..60842b9 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
@@ -172,8 +172,8 @@ public class ConnectorITCase extends AbstractITCase {
         assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
         assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
         assertNotNull(actual.getPoolConf());
-        assertEquals(1534, actual.getPoolConf().getMaxObjects().intValue());
-        assertEquals(10, actual.getPoolConf().getMaxIdle().intValue());
+        assertEquals(1534, actual.getPoolConf().getMaxObjects(), 0);
+        assertEquals(10, actual.getPoolConf().getMaxIdle(), 0);
 
         Throwable t = null;
 
@@ -182,7 +182,7 @@ public class ConnectorITCase extends AbstractITCase {
         actual.getPoolConf().setMaxObjects(null);
 
         try {
-            connectorService.update(actual.getKey(), actual);
+            connectorService.update(actual);
             actual = connectorService.read(actual.getKey());
         } catch (SyncopeClientException e) {
             LOG.error("update failed", e);
@@ -255,7 +255,7 @@ public class ConnectorITCase extends AbstractITCase {
         // set connector configuration
         connectorTO.getConfiguration().addAll(conf);
 
-        connectorService.update(connectorTO.getKey(), connectorTO);
+        connectorService.update(connectorTO);
         ConnInstanceTO actual = connectorService.read(connectorTO.getKey());
 
         assertNotNull(actual);
@@ -348,7 +348,7 @@ public class ConnectorITCase extends AbstractITCase {
         // ----------------------------------
         connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
 
-        connectorService.update(connInstanceTO.getKey(), connInstanceTO);
+        connectorService.update(connInstanceTO);
         ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey());
         assertNotNull(actual);
         assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
@@ -732,7 +732,7 @@ public class ConnectorITCase extends AbstractITCase {
         assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
 
         connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
-        connectorService.update(connectorInstanceTO.getKey(), connectorInstanceTO);
+        connectorService.update(connectorInstanceTO);
 
         ConnInstanceTO updatedCapabilities = connectorService.read(connectorInstanceTO.getKey());
         assertNotNull(updatedCapabilities.getCapabilities());

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 d06ca77..210b515 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
@@ -94,8 +94,7 @@ public class DerSchemaITCase extends AbstractITCase {
         try {
             schema.setExpression("mderived_sx + '.' + mderived_dx");
 
-            schemaService.update(SchemaType.DERIVED,
-                    schema.getKey(), schema);
+            schemaService.update(SchemaType.DERIVED, schema);
 
             schema = schemaService.read(SchemaType.DERIVED, "mderiveddata");
             assertNotNull(schema);
@@ -103,8 +102,7 @@ public class DerSchemaITCase extends AbstractITCase {
         } finally {
             // Set updated back to make test re-runnable
             schema.setExpression("mderived_sx + '-' + mderived_dx");
-            schemaService.update(SchemaType.DERIVED,
-                    schema.getKey(), schema);
+            schemaService.update(SchemaType.DERIVED, schema);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 f16ee21..855f25b 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
@@ -272,7 +272,7 @@ public class GroupITCase extends AbstractITCase {
         GroupService groupService2 = clientFactory.create("verdi", ADMIN_PWD).getService(GroupService.class);
 
         try {
-            groupService2.update(groupMod.getKey(), groupMod);
+            groupService2.update(groupMod);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
@@ -283,7 +283,7 @@ public class GroupITCase extends AbstractITCase {
         // 4. update as puccini, owner of group 6 - success
         GroupService groupService3 = clientFactory.create("puccini", ADMIN_PWD).getService(GroupService.class);
 
-        groupTO = groupService3.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class);
+        groupTO = groupService3.update(groupMod).readEntity(GroupTO.class);
         assertEquals("Director", groupTO.getName());
 
         // issue SYNCOPE-15
@@ -531,7 +531,7 @@ public class GroupITCase extends AbstractITCase {
         String typeClassName = type.getClasses().get(0);
         AnyTypeClassTO typeClass = anyTypeClassService.read(typeClassName);
         typeClass.getPlainSchemas().add(badge.getKey());
-        anyTypeClassService.update(typeClassName, typeClass);
+        anyTypeClassService.update(typeClass);
         typeClass = anyTypeClassService.read(typeClassName);
         assertTrue(typeClass.getPlainSchemas().contains(badge.getKey()));
 
@@ -556,7 +556,7 @@ public class GroupITCase extends AbstractITCase {
         } finally {
             // restore the original group class
             typeClass.getPlainSchemas().remove(badge.getKey());
-            anyTypeClassService.update(typeClassName, typeClass);
+            anyTypeClassService.update(typeClass);
             typeClass = anyTypeClassService.read(typeClassName);
             assertFalse(typeClass.getPlainSchemas().contains(badge.getKey()));
         }
@@ -595,9 +595,10 @@ public class GroupITCase extends AbstractITCase {
         assertNotNull(group);
 
         GroupMod groupMod = new GroupMod();
+        groupMod.setKey(group.getKey());
         groupMod.getPlainAttrsToUpdate().add(attrMod("badge", "xxxxxxxxxx"));
 
-        response = noContentService.update(group.getKey(), groupMod);
+        response = noContentService.update(groupMod);
         assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
         assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
         assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
@@ -705,7 +706,7 @@ public class GroupITCase extends AbstractITCase {
         GroupMod mod = new GroupMod();
         mod.setKey(group.getKey());
         mod.setUDynMembershipCond("cool==false");
-        groupService.update(mod.getKey(), mod);
+        groupService.update(mod);
 
         assertTrue(userService.read(4L).getDynGroups().isEmpty());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 c58b7b7..09f40f9 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
@@ -93,7 +93,7 @@ public class NotificationITCase extends AbstractITCase {
         NotificationTO notificationTO = notificationService.read(10L);
         notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().inGroups(7L).query());
 
-        notificationService.update(notificationTO.getKey(), notificationTO);
+        notificationService.update(notificationTO);
         NotificationTO actual = notificationService.read(notificationTO.getKey());
         assertNotNull(actual);
         assertEquals(actual, notificationTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 e6e450c..feb041a 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
@@ -184,13 +184,13 @@ public class PlainSchemaITCase extends AbstractITCase {
         PlainSchemaTO schemaTO = schemaService.read(SchemaType.PLAIN, "icon");
         assertNotNull(schemaTO);
 
-        schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+        schemaService.update(SchemaType.PLAIN, schemaTO);
         PlainSchemaTO updatedTO = schemaService.read(SchemaType.PLAIN, "icon");
         assertEquals(schemaTO, updatedTO);
 
         updatedTO.setType(AttrSchemaType.Date);
         try {
-            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), updatedTO);
+            schemaService.update(SchemaType.PLAIN, updatedTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -220,7 +220,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         schemaTO.setType(AttrSchemaType.Long);
         try {
-            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            schemaService.update(SchemaType.PLAIN, schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
@@ -253,7 +253,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         UserMod userMod = AnyOperations.diff(newUserTO, userTO);
 
-        userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+        userTO = userService.update(userMod).readEntity(UserTO.class);
         assertNotNull(userTO);
     }
 
@@ -278,7 +278,7 @@ public class PlainSchemaITCase extends AbstractITCase {
 
         schemaTO.setUniqueConstraint(false);
         try {
-            schemaService.update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+            schemaService.update(SchemaType.PLAIN, schemaTO);
             fail("This should not be reacheable");
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 df36ac4..3684f35 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
@@ -141,7 +141,7 @@ public class PolicyITCase extends AbstractITCase {
         policy.setSpecification(policySpec);
 
         // update new password policy
-        policyService.update(policy.getKey(), policy);
+        policyService.update(policy);
         policy = policyService.read(policy.getKey());
 
         assertNotNull(policy);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
index edb2366..fe2c0a5 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RealmITCase.java
@@ -91,7 +91,7 @@ public class RealmITCase extends AbstractITCase {
         // 2. update setting policies
         actual.setAccountPolicy(6L);
         actual.setPasswordPolicy(4L);
-        realmService.update(actual.getFullPath(), actual);
+        realmService.update(actual);
 
         actual = getRealm(actual.getFullPath());
         assertNotNull(actual.getAccountPolicy());
@@ -99,7 +99,7 @@ public class RealmITCase extends AbstractITCase {
 
         // 3. update changing parent
         actual.setParent(getRealm("/odd").getKey());
-        realmService.update(actual.getFullPath(), actual);
+        realmService.update(actual);
 
         actual = getRealm("/odd/last");
         assertNotNull(actual);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
index 2199bc8..d02b726 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ReportITCase.java
@@ -116,7 +116,7 @@ public class ReportITCase extends AbstractITCase {
 
         report.getReportletConfs().add(new UserReportletConf("last"));
 
-        reportService.update(report.getKey(), report);
+        reportService.update(report);
         ReportTO updated = reportService.read(report.getKey());
         assertNotNull(updated);
         assertEquals(3, updated.getReportletConfs().size());

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 a6dd805..c0e1790 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
@@ -329,7 +329,7 @@ public class ResourceITCase extends AbstractITCase {
         try {
             ResourceTO resourceTO = new ResourceTO();
             resourceTO.setKey("resourcenotfound");
-            resourceService.update(resourceTO.getKey(), resourceTO);
+            resourceService.update(resourceTO);
 
             fail();
         } catch (SyncopeClientException e) {
@@ -378,7 +378,7 @@ public class ResourceITCase extends AbstractITCase {
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setConnObjectKeyItem(item);
 
-        resourceService.update(resourceTO.getKey(), resourceTO);
+        resourceService.update(resourceTO);
         ResourceTO actual = resourceService.read(resourceTO.getKey());
         assertNotNull(actual);
 
@@ -408,7 +408,7 @@ public class ResourceITCase extends AbstractITCase {
         resourceService.create(pre);
 
         pre.getProvision(AnyTypeKind.USER.name()).setSyncToken(null);
-        resourceService.update(pre.getKey(), pre);
+        resourceService.update(pre);
         ResourceTO actual = resourceService.read(pre.getKey());
         // check that the synctoken has been reset
         assertNull(actual.getProvision(AnyTypeKind.USER.name()).getSyncToken());
@@ -511,7 +511,7 @@ public class ResourceITCase extends AbstractITCase {
         assertNotNull(resource.getProvision(AnyTypeKind.USER.name()).getMapping());
 
         resource.getProvision(AnyTypeKind.USER.name()).setMapping(null);
-        resourceService.update(name, resource);
+        resourceService.update(resource);
 
         resource = resourceService.read(name);
         assertNotNull(resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
index 4d61644..81b0796 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/RoleITCase.java
@@ -95,7 +95,7 @@ public class RoleITCase extends AbstractITCase {
         role.getEntitlements().add(Entitlement.WORKFLOW_TASK_LIST);
         role.getRealms().add("/even/two");
 
-        roleService.update(role.getKey(), role);
+        roleService.update(role);
 
         actual = roleService.read(role.getKey());
         assertTrue(actual.getEntitlements().contains(Entitlement.WORKFLOW_TASK_LIST));
@@ -133,7 +133,7 @@ public class RoleITCase extends AbstractITCase {
         assertTrue(userService.read(4L).getDynRoles().contains(role.getKey()));
 
         role.setDynMembershipCond("cool==false");
-        roleService.update(role.getKey(), role);
+        roleService.update(role);
 
         assertTrue(userService.read(4L).getDynGroups().isEmpty());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
index e31190f..b65aa72 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SchedTaskITCase.java
@@ -74,7 +74,7 @@ public class SchedTaskITCase extends AbstractTaskITCase {
         taskMod.setKey(5);
         taskMod.setCronExpression(null);
 
-        taskService.update(taskMod.getKey(), taskMod);
+        taskService.update(taskMod);
         SchedTaskTO actual = taskService.read(taskMod.getKey());
         assertNotNull(actual);
         assertEquals(task.getKey(), actual.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
index 95a1988..36214c9 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/SecurityQuestionITCase.java
@@ -72,7 +72,7 @@ public class SecurityQuestionITCase extends AbstractITCase {
         SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
         securityQuestionTO.setContent("What is your favorite color?");
 
-        securityQuestionService.update(securityQuestionTO.getKey(), securityQuestionTO);
+        securityQuestionService.update(securityQuestionTO);
         SecurityQuestionTO actual = securityQuestionService.read(securityQuestionTO.getKey());
         assertNotNull(actual);
         assertEquals(actual, securityQuestionTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 939919f..f6d2e57 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
@@ -78,7 +78,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
     public static void testSyncActionsSetup() {
         SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID);
         syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
-        taskService.update(SYNC_TASK_ID, syncTask);
+        taskService.update(syncTask);
     }
 
     @Test
@@ -362,7 +362,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         assertNotNull(provision);
 
         provision.setSyncToken(null);
-        resourceService.update(resource.getKey(), resource);
+        resourceService.update(resource);
 
         // 1. create printer on external resource
         AnyObjectTO anyObjectTO = AnyObjectITCase.getSampleTO("sync");
@@ -449,7 +449,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
             task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
-            taskService.update(task.getKey(), task);
+            taskService.update(task);
             SyncTaskTO actual = taskService.read(task.getKey());
             assertNotNull(actual);
             assertEquals(task.getKey(), actual.getKey());
@@ -514,7 +514,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         }
         item.setJavaRule(TestSyncRule.class.getName());
 
-        policyService.update(policyTO.getKey(), policyTO);
+        policyService.update(policyTO);
         // -----------------------------
 
         SyncTaskTO task = new SyncTaskTO();
@@ -548,7 +548,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         userMod.getPlainAttrsToRemove().add("email");
         userMod.getPlainAttrsToUpdate().add(attrMod("email", "s258@apache.org"));
 
-        userService.update(userMod.getKey(), userMod);
+        userService.update(userMod);
 
         execProvisioningTask(actual.getKey(), 50, false);
 
@@ -622,7 +622,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
 
         task.getTemplates().put(AnyTypeKind.USER.name(), template);
 
-        taskService.update(task.getKey(), task);
+        taskService.update(task);
         execProvisioningTask(task.getKey(), 50, false);
 
         // check for sync policy
@@ -736,7 +736,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         ConnConfProperty property = resourceConnector.getConfigurationMap().get("retrievePasswordsWithSearch");
         property.getValues().clear();
         property.getValues().add(Boolean.TRUE);
-        connectorService.update(ldapResource.getConnector(), resourceConnector);
+        connectorService.update(resourceConnector);
 
         // 6. Sync the user from the resource
         SyncTaskTO syncTask = new SyncTaskTO();
@@ -771,7 +771,7 @@ public class SyncTaskITCase extends AbstractTaskITCase {
         taskService.delete(syncTask.getKey());
         property.getValues().clear();
         property.getValues().add(Boolean.FALSE);
-        connectorService.update(ldapResource.getConnector(), resourceConnector);
+        connectorService.update(resourceConnector);
         deleteUser(updatedUser.getKey());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 bd6b4aa..10b07bf 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
@@ -617,7 +617,7 @@ public class UserITCase extends AbstractITCase {
         userMod.setKey(userTO.getKey());
         userMod.setPassword("pass");
 
-        userService.update(userMod.getKey(), userMod);
+        userService.update(userMod);
     }
 
     @Test(expected = SyncopeClientException.class)
@@ -632,7 +632,7 @@ public class UserITCase extends AbstractITCase {
         userMod.setKey(userTO.getKey());
         userMod.setPassword("password123");
 
-        userService.update(userMod.getKey(), userMod);
+        userService.update(userMod);
     }
 
     @Test
@@ -1145,9 +1145,10 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(user);
 
         UserMod userMod = new UserMod();
+        userMod.setKey(user.getKey());
         userMod.setPassword("password321");
 
-        response = noContentService.update(user.getKey(), userMod);
+        response = noContentService.update(userMod);
         assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
         assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
         assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
@@ -1577,7 +1578,7 @@ public class UserITCase extends AbstractITCase {
                 item.setExtAttrName("uniqueMember");
             }
         }
-        resourceService.update(ldap.getKey(), ldap);
+        resourceService.update(ldap);
 
         // 1. create group with LDAP resource
         GroupTO groupTO = new GroupTO();
@@ -1625,7 +1626,7 @@ public class UserITCase extends AbstractITCase {
                 item.setExtAttrName("description");
             }
         }
-        resourceService.update(ldap.getKey(), ldap);
+        resourceService.update(ldap);
     }
 
     @Test
@@ -2026,8 +2027,9 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(userTO);
 
         UserMod userMod = new UserMod();
+        userMod.setKey(userTO.getKey());
         userMod.setPassword("anotherPassword123");
-        userTO = userService.update(userTO.getKey(), userMod).readEntity(UserTO.class);
+        userTO = userService.update(userMod).readEntity(UserTO.class);
         assertNotNull(userTO);
     }
 
@@ -2041,9 +2043,10 @@ public class UserITCase extends AbstractITCase {
 
         // 2. try to update user by subscribing a resource - works but propagation is not even attempted
         UserMod userMod = new UserMod();
+        userMod.setKey(userTO.getKey());
         userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
 
-        userTO = userService.update(userTO.getKey(), userMod).readEntity(UserTO.class);
+        userTO = userService.update(userMod).readEntity(UserTO.class);
         assertEquals(Collections.singleton(RESOURCE_NAME_WS1), userTO.getResources());
         assertFalse(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
         assertTrue(userTO.getPropagationStatusTOs().get(0).getFailureReason().
@@ -2064,7 +2067,7 @@ public class UserITCase extends AbstractITCase {
         UserMod userMod = new UserMod();
         userMod.setKey(userTO.getKey());
         userMod.setUsername(userTO.getUsername() + "XX");
-        userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+        userTO = userService.update(userMod).readEntity(UserTO.class);
         assertTrue(userTO.getUsername().endsWith("XX"));
         EntityTag etag1 = adminClient.getLatestEntityTag(userService);
         assertFalse(etag.getValue().equals(etag1.getValue()));
@@ -2072,7 +2075,7 @@ public class UserITCase extends AbstractITCase {
         UserService ifMatchService = adminClient.ifMatch(UserService.class, etag);
         userMod.setUsername(userTO.getUsername() + "YY");
         try {
-            ifMatchService.update(userMod.getKey(), userMod);
+            ifMatchService.update(userMod);
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.ConcurrentModification, e.getType());
@@ -2106,7 +2109,7 @@ public class UserITCase extends AbstractITCase {
         userMod.setPwdPropRequest(new StatusMod());
         userMod.getPlainAttrsToUpdate().add(attrMod("surname", "surname2"));
 
-        userService.update(userTO.getKey(), userMod);
+        userService.update(userMod);
 
         // 5. try (and succeed again) to perform simple LDAP binding: password has not changed
         assertNotNull(getLdapRemoteObject(
@@ -2145,7 +2148,7 @@ public class UserITCase extends AbstractITCase {
 
         ws1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
 
-        resourceService.update(RESOURCE_NAME_WS1, ws1);
+        resourceService.update(ws1);
         ResourceTO newWs1 = resourceService.read(ws1.getKey());
         assertNotNull(newWs1);
 
@@ -2182,7 +2185,7 @@ public class UserITCase extends AbstractITCase {
 
         newWs1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
 
-        resourceService.update(RESOURCE_NAME_WS1, newWs1);
+        resourceService.update(newWs1);
     }
 
     @Test
@@ -2198,7 +2201,7 @@ public class UserITCase extends AbstractITCase {
         ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_TESTDB);
         assertNotNull(resourceTO);
         resourceTO.getPropagationActionsClassNames().add(DBPasswordPropagationActions.class.getName());
-        resourceService.update(RESOURCE_NAME_TESTDB, resourceTO);
+        resourceService.update(resourceTO);
 
         // 3. Add a db resource to the User
         UserMod userMod = new UserMod();
@@ -2224,7 +2227,7 @@ public class UserITCase extends AbstractITCase {
         resourceTO = resourceService.read(RESOURCE_NAME_TESTDB);
         assertNotNull(resourceTO);
         resourceTO.getPropagationActionsClassNames().remove(DBPasswordPropagationActions.class.getName());
-        resourceService.update(RESOURCE_NAME_TESTDB, resourceTO);
+        resourceService.update(resourceTO);
     }
 
     @Test
@@ -2241,7 +2244,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(resourceTO);
         resourceTO.getPropagationActionsClassNames().add(LDAPPasswordPropagationActions.class.getName());
         resourceTO.setRandomPwdIfNotProvided(false);
-        resourceService.update(RESOURCE_NAME_LDAP, resourceTO);
+        resourceService.update(resourceTO);
 
         // 3. Add a resource to the User
         UserMod userMod = new UserMod();
@@ -2271,7 +2274,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(resourceTO);
         resourceTO.getPropagationActionsClassNames().remove(LDAPPasswordPropagationActions.class.getName());
         resourceTO.setRandomPwdIfNotProvided(true);
-        resourceService.update(RESOURCE_NAME_LDAP, resourceTO);
+        resourceService.update(resourceTO);
     }
 
     @Test
@@ -2360,7 +2363,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(csv);
         try {
             csv.setPasswordPolicy(8L);
-            resourceService.update(RESOURCE_NAME_CSV, csv);
+            resourceService.update(csv);
             csv = resourceService.read(RESOURCE_NAME_CSV);
 
             userTO = getUniqueSampleTO("syncope391@syncope.apache.org");
@@ -2379,7 +2382,7 @@ public class UserITCase extends AbstractITCase {
         } finally {
             // resource csv with null password policy
             csv.setPasswordPolicy(null);
-            resourceService.update(RESOURCE_NAME_CSV, csv);
+            resourceService.update(csv);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 fdd25bd..2944cdc 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
@@ -148,10 +148,11 @@ public class UserSelfITCase extends AbstractITCase {
 
         // 2. self-update (username) - works
         UserMod userMod = new UserMod();
+        userMod.setKey(created.getKey());
         userMod.setUsername(created.getUsername() + "XX");
 
         SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
-        UserTO updated = authClient.getService(UserSelfService.class).update(created.getKey(), userMod).
+        UserTO updated = authClient.getService(UserSelfService.class).update(userMod).
                 readEntity(UserTO.class);
         assertNotNull(updated);
         assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
@@ -170,6 +171,7 @@ public class UserSelfITCase extends AbstractITCase {
 
         // 2. self-update (username + memberships + resource) - works but needs approval
         UserMod userMod = new UserMod();
+        userMod.setKey(created.getKey());
         userMod.setUsername(created.getUsername() + "XX");
         userMod.getMembershipsToAdd().add(7L);
         userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
@@ -180,7 +182,7 @@ public class UserSelfITCase extends AbstractITCase {
         userMod.setPwdPropRequest(statusMod);
 
         SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
-        UserTO updated = authClient.getService(UserSelfService.class).update(created.getKey(), userMod).
+        UserTO updated = authClient.getService(UserSelfService.class).update(userMod).
                 readEntity(UserTO.class);
         assertNotNull(updated);
         assertEquals("updateApproval", updated.getStatus());

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 2c2065f..3fc1b98 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
@@ -281,7 +281,7 @@ public class VirAttrITCase extends AbstractITCase {
                 }
             }
 
-            resourceService.update(csv.getKey(), csv);
+            resourceService.update(csv);
             csv = resourceService.read(RESOURCE_NAME_CSV);
             assertNotNull(csv.getProvisions().get(0).getMapping());
 
@@ -337,7 +337,7 @@ public class VirAttrITCase extends AbstractITCase {
         } finally {
             // restore mapping of resource-csv
             csv.getProvisions().get(0).setMapping(origMapping);
-            resourceService.update(csv.getKey(), csv);
+            resourceService.update(csv);
         }
     }
 
@@ -376,7 +376,7 @@ public class VirAttrITCase extends AbstractITCase {
             }
         }
 
-        connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+        connectorService.update(connInstanceBean);
 
         UserMod userMod = new UserMod();
         userMod.setKey(actual.getKey());
@@ -421,7 +421,7 @@ public class VirAttrITCase extends AbstractITCase {
             }
         }
 
-        connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+        connectorService.update(connInstanceBean);
         // ----------------------------------------
 
         actual = userService.read(actual.getKey());


[21/70] 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();
+            }
+        });
+    }
+
+}


[40/70] syncope git commit: [SYNCOPE-666] Integration tests can run, with 10 failures and 151 errors

Posted by il...@apache.org.
[SYNCOPE-666] Integration tests can run, with 10 failures and 151 errors


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

Branch: refs/heads/master
Commit: 79b1e80aa1f3b72fabb7427eecb1e9e967739b44
Parents: 705bfb8
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed May 27 16:40:51 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed May 27 16:40:51 2015 +0200

----------------------------------------------------------------------
 core/workflow-activiti/src/main/resources/workflow.properties    | 1 +
 .../org/apache/syncope/core/logic/init/CamelRouteLoader.java     | 2 +-
 .../src/main/resources/provisioning.properties                   | 1 +
 .../src/main/resources/all/provisioning.properties               | 1 +
 fit/core-reference/src/main/resources/all/workflow.properties    | 1 +
 fit/core-reference/src/main/resources/provisioning.properties    | 1 +
 fit/core-reference/src/main/resources/workflow.properties        | 1 +
 .../org/apache/syncope/fit/core/reference/ActivitiDetector.java  | 4 ++++
 .../org/apache/syncope/fit/core/reference/CamelDetector.java     | 4 ++++
 9 files changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/core/workflow-activiti/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/core/workflow-activiti/src/main/resources/workflow.properties b/core/workflow-activiti/src/main/resources/workflow.properties
index 5a975cf..61f1a3e 100644
--- a/core/workflow-activiti/src/main/resources/workflow.properties
+++ b/core/workflow-activiti/src/main/resources/workflow.properties
@@ -18,3 +18,4 @@ wf.directory=${conf.directory}
 jobExecutorActivate=true
 uwfAdapter=org.apache.syncope.core.workflow.activiti.ActivitiUserWorkflowAdapter
 gwfAdapter=org.apache.syncope.core.workflow.java.DefaultGroupWorkflowAdapter
+awfAdapter=org.apache.syncope.core.workflow.java.DefaultAnyObjectWorkflowAdapter

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/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 e2ddbc9..3520a4a 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
@@ -70,12 +70,12 @@ public class CamelRouteLoader implements SyncopeLoader {
     }
 
     @Transactional
+    @Override
     public void load() {
         synchronized (this) {
             if (!loaded) {
                 loadRoutes(userRoutesLoader.getResource(), AnyTypeKind.USER);
                 loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.GROUP);
-                loadRoutes(groupRoutesLoader.getResource(), AnyTypeKind.ANY_OBJECT);
                 loaded = true;
             }
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
index 32fa5af..5061502 100644
--- a/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
+++ b/ext/camel/provisioning-camel/src/main/resources/provisioning.properties
@@ -17,4 +17,5 @@
 camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/main/resources/all/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/provisioning.properties b/fit/core-reference/src/main/resources/all/provisioning.properties
index 32fa5af..5061502 100644
--- a/fit/core-reference/src/main/resources/all/provisioning.properties
+++ b/fit/core-reference/src/main/resources/all/provisioning.properties
@@ -17,4 +17,5 @@
 camel.directory=${conf.directory}
 userProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.camel.CamelGroupProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/main/resources/all/workflow.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/all/workflow.properties b/fit/core-reference/src/main/resources/all/workflow.properties
index 5a975cf..61f1a3e 100644
--- a/fit/core-reference/src/main/resources/all/workflow.properties
+++ b/fit/core-reference/src/main/resources/all/workflow.properties
@@ -18,3 +18,4 @@ wf.directory=${conf.directory}
 jobExecutorActivate=true
 uwfAdapter=org.apache.syncope.core.workflow.activiti.ActivitiUserWorkflowAdapter
 gwfAdapter=org.apache.syncope.core.workflow.java.DefaultGroupWorkflowAdapter
+awfAdapter=org.apache.syncope.core.workflow.java.DefaultAnyObjectWorkflowAdapter

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/provisioning.properties b/fit/core-reference/src/main/resources/provisioning.properties
index 9c0abff..af1dd4b 100644
--- a/fit/core-reference/src/main/resources/provisioning.properties
+++ b/fit/core-reference/src/main/resources/provisioning.properties
@@ -16,4 +16,5 @@
 # under the License.
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/resources/workflow.properties b/fit/core-reference/src/main/resources/workflow.properties
index 7167164..f05a464 100644
--- a/fit/core-reference/src/main/resources/workflow.properties
+++ b/fit/core-reference/src/main/resources/workflow.properties
@@ -18,3 +18,4 @@ wf.directory=${conf.directory}
 jobExecutorActivate=false
 uwfAdapter=org.apache.syncope.core.workflow.java.DefaultUserWorkflowAdapter
 gwfAdapter=org.apache.syncope.core.workflow.java.DefaultGroupWorkflowAdapter
+awfAdapter=org.apache.syncope.core.workflow.java.DefaultAnyObjectWorkflowAdapter

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
index 798a313..6182e2a 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ActivitiDetector.java
@@ -29,4 +29,8 @@ public class ActivitiDetector {
     public static boolean isActivitiEnabledForGroups(final SyncopeService syncopeService) {
         return syncopeService.info().getGroupWorkflowAdapter().indexOf("Activiti") != -1;
     }
+
+    public static boolean isActivitiEnabledForAnyObjects(final SyncopeService syncopeService) {
+        return syncopeService.info().getAnyObjectWorkflowAdapter().indexOf("Activiti") != -1;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/79b1e80a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
index a061005..0021922 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
@@ -29,4 +29,8 @@ public class CamelDetector {
     public static boolean isCamelEnabledForGroups(final SyncopeService syncopeService) {
         return syncopeService.info().getGroupProvisioningManager().indexOf("Camel") != -1;
     }
+
+    public static boolean isCamelEnabledForAnyObjects(final SyncopeService syncopeService) {
+        return syncopeService.info().getAnyObjectProvisioningManager().indexOf("Camel") != -1;
+    }
 }


[27/70] 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.


[63/70] syncope git commit: Improving REST update methods signature thanks to CXF-6447

Posted by il...@apache.org.
Improving REST update methods signature thanks to CXF-6447


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

Branch: refs/heads/master
Commit: df60b3b4166cfb924dac08c6f81a7f49bd2a5f8c
Parents: 6239afa
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jun 10 16:03:09 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jun 10 16:03:09 2015 +0200

----------------------------------------------------------------------
 .../console/rest/ConnectorRestClient.java       |  2 +-
 .../client/console/rest/GroupRestClient.java    |  2 +-
 .../console/rest/NotificationRestClient.java    |  2 +-
 .../client/console/rest/PolicyRestClient.java   |  2 +-
 .../client/console/rest/ReportRestClient.java   |  2 +-
 .../client/console/rest/ResourceRestClient.java |  2 +-
 .../client/console/rest/SchemaRestClient.java   |  6 +--
 .../rest/SecurityQuestionRestClient.java        |  6 +--
 .../client/console/rest/TaskRestClient.java     |  4 +-
 .../client/console/rest/UserRestClient.java     |  2 +-
 .../client/console/rest/UserSelfRestClient.java |  2 +-
 .../apache/syncope/common/lib/mod/AnyMod.java   |  2 +
 .../syncope/common/lib/to/AbstractPolicyTO.java |  2 +
 .../syncope/common/lib/to/AbstractSchemaTO.java |  2 +
 .../syncope/common/lib/to/AbstractTaskTO.java   |  2 +
 .../syncope/common/lib/to/AnyTypeClassTO.java   |  2 +
 .../apache/syncope/common/lib/to/AnyTypeTO.java |  2 +
 .../syncope/common/lib/to/ConnInstanceTO.java   |  2 +
 .../syncope/common/lib/to/NotificationTO.java   |  2 +
 .../apache/syncope/common/lib/to/RealmTO.java   |  2 +
 .../apache/syncope/common/lib/to/ReportTO.java  |  2 +
 .../syncope/common/lib/to/ResourceTO.java       |  2 +
 .../apache/syncope/common/lib/to/RoleTO.java    |  2 +
 .../common/lib/to/SecurityQuestionTO.java       |  2 +
 .../common/rest/api/service/AnyService.java     |  3 +-
 .../rest/api/service/AnyTypeClassService.java   |  3 +-
 .../common/rest/api/service/AnyTypeService.java |  3 +-
 .../rest/api/service/ConnectorService.java      |  3 +-
 .../rest/api/service/NotificationService.java   | 17 ++++---
 .../common/rest/api/service/PolicyService.java  | 17 ++++---
 .../common/rest/api/service/RealmService.java   |  3 +-
 .../common/rest/api/service/ReportService.java  | 29 ++++++------
 .../rest/api/service/ResourceService.java       |  3 +-
 .../common/rest/api/service/RoleService.java    |  3 +-
 .../common/rest/api/service/SchemaService.java  | 27 +++++------
 .../api/service/SecurityQuestionService.java    | 26 +++++------
 .../common/rest/api/service/TaskService.java    | 29 ++++++------
 .../rest/api/service/UserSelfService.java       |  8 ++--
 .../rest/cxf/service/AbstractAnyService.java    |  5 +--
 .../cxf/service/AnyTypeClassServiceImpl.java    |  3 +-
 .../rest/cxf/service/AnyTypeServiceImpl.java    |  3 +-
 .../rest/cxf/service/ConnectorServiceImpl.java  |  3 +-
 .../cxf/service/NotificationServiceImpl.java    | 11 +++--
 .../rest/cxf/service/PolicyServiceImpl.java     | 12 +++--
 .../core/rest/cxf/service/RealmServiceImpl.java |  4 +-
 .../rest/cxf/service/ReportServiceImpl.java     | 19 ++++----
 .../rest/cxf/service/ResourceServiceImpl.java   |  3 +-
 .../core/rest/cxf/service/RoleServiceImpl.java  |  3 +-
 .../rest/cxf/service/SchemaServiceImpl.java     | 13 +++---
 .../service/SecurityQuestionServiceImpl.java    | 11 +++--
 .../core/rest/cxf/service/TaskServiceImpl.java  | 47 ++++++++++----------
 .../rest/cxf/service/UserSelfServiceImpl.java   |  3 +-
 .../fit/core/reference/AbstractITCase.java      |  6 +--
 .../fit/core/reference/AnyTypeClassITCase.java  |  2 +-
 .../fit/core/reference/AnyTypeITCase.java       |  4 +-
 .../core/reference/AuthenticationITCase.java    |  2 +-
 .../fit/core/reference/ConnectorITCase.java     | 12 ++---
 .../fit/core/reference/DerSchemaITCase.java     |  6 +--
 .../syncope/fit/core/reference/GroupITCase.java | 13 +++---
 .../fit/core/reference/NotificationITCase.java  |  2 +-
 .../fit/core/reference/PlainSchemaITCase.java   | 10 ++---
 .../fit/core/reference/PolicyITCase.java        |  2 +-
 .../syncope/fit/core/reference/RealmITCase.java |  4 +-
 .../fit/core/reference/ReportITCase.java        |  2 +-
 .../fit/core/reference/ResourceITCase.java      |  8 ++--
 .../syncope/fit/core/reference/RoleITCase.java  |  4 +-
 .../fit/core/reference/SchedTaskITCase.java     |  2 +-
 .../core/reference/SecurityQuestionITCase.java  |  2 +-
 .../fit/core/reference/SyncTaskITCase.java      | 16 +++----
 .../syncope/fit/core/reference/UserITCase.java  | 39 ++++++++--------
 .../fit/core/reference/UserSelfITCase.java      |  6 ++-
 .../fit/core/reference/VirAttrITCase.java       |  8 ++--
 72 files changed, 258 insertions(+), 264 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index 3298d3f..8dab310 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -85,7 +85,7 @@ public class ConnectorRestClient extends BaseRestClient {
         Set<ConnConfProperty> filteredConf = filterProperties(connectorTO.getConfiguration());
         connectorTO.getConfiguration().clear();
         connectorTO.getConfiguration().addAll(filteredConf);
-        getService(ConnectorService.class).update(connectorTO.getKey(), connectorTO);
+        getService(ConnectorService.class).update(connectorTO);
     }
 
     public ConnInstanceTO delete(final Long id) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 a146857..b4b848c 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
@@ -98,7 +98,7 @@ public class GroupRestClient extends AbstractAnyRestClient {
         GroupTO result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class);
+            result = service.update(groupMod).readEntity(GroupTO.class);
             resetClient(GroupService.class);
         }
         return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java
index b33e4dc..ac2eb03 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java
@@ -41,7 +41,7 @@ public class NotificationRestClient extends BaseRestClient {
     }
 
     public void update(final NotificationTO notificationTO) {
-        getService(NotificationService.class).update(notificationTO.getKey(), notificationTO);
+        getService(NotificationService.class).update(notificationTO);
     }
 
     public void delete(final Long key) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
index c1f019f..e58f734 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java
@@ -62,7 +62,7 @@ public class PolicyRestClient extends BaseRestClient {
     }
 
     public <T extends AbstractPolicyTO> void updatePolicy(final T policy) {
-        getService(PolicyService.class).update(policy.getKey(), policy);
+        getService(PolicyService.class).update(policy);
     }
 
     public void delete(final Long id, final Class<? extends AbstractPolicyTO> policyClass) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
index 617a2c7..05af975 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
@@ -77,7 +77,7 @@ public class ReportRestClient extends BaseRestClient implements ExecutionRestCli
     }
 
     public void update(final ReportTO reportTO) {
-        getService(ReportService.class).update(reportTO.getKey(), reportTO);
+        getService(ReportService.class).update(reportTO);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 f5431db..15bf7aa 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
@@ -69,7 +69,7 @@ public class ResourceRestClient extends BaseRestClient {
     }
 
     public void update(final ResourceTO resourceTO) {
-        getService(ResourceService.class).update(resourceTO.getKey(), resourceTO);
+        getService(ResourceService.class).update(resourceTO);
     }
 
     public void delete(final String name) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 8a145dc..6b9f244 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
@@ -153,7 +153,7 @@ public class SchemaRestClient extends BaseRestClient {
     }
 
     public void updatePlainSchema(final PlainSchemaTO schemaTO) {
-        getService(SchemaService.class).update(SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+        getService(SchemaService.class).update(SchemaType.PLAIN, schemaTO);
     }
 
     public PlainSchemaTO deletePlainSchema(final String name) {
@@ -177,7 +177,7 @@ public class SchemaRestClient extends BaseRestClient {
     }
 
     public void updateVirSchema(final VirSchemaTO schemaTO) {
-        getService(SchemaService.class).update(SchemaType.VIRTUAL, schemaTO.getKey(), schemaTO);
+        getService(SchemaService.class).update(SchemaType.VIRTUAL, schemaTO);
     }
 
     public DerSchemaTO deleteDerSchema(final String name) {
@@ -191,7 +191,7 @@ public class SchemaRestClient extends BaseRestClient {
     }
 
     public void updateDerSchema(final DerSchemaTO schemaTO) {
-        getService(SchemaService.class).update(SchemaType.DERIVED, schemaTO.getKey(), schemaTO);
+        getService(SchemaService.class).update(SchemaType.DERIVED, schemaTO);
     }
 
     public VirSchemaTO deleteVirSchema(final String name) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/SecurityQuestionRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SecurityQuestionRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SecurityQuestionRestClient.java
index 119b3b5..2fd07e0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SecurityQuestionRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SecurityQuestionRestClient.java
@@ -37,11 +37,11 @@ public class SecurityQuestionRestClient extends BaseRestClient {
     }
 
     public void update(final SecurityQuestionTO securityQuestionTO) {
-        getService(SecurityQuestionService.class).update(securityQuestionTO.getKey(), securityQuestionTO);
+        getService(SecurityQuestionService.class).update(securityQuestionTO);
     }
 
-    public void delete(final Long securityQuestionId) {
-        getService(SecurityQuestionService.class).delete(securityQuestionId);
+    public void delete(final Long securityQuestionKey) {
+        getService(SecurityQuestionService.class).delete(securityQuestionKey);
     }
 
     public SecurityQuestionTO readByUser(final String username) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
index cea466e..32236a9 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/TaskRestClient.java
@@ -131,11 +131,11 @@ public class TaskRestClient extends BaseRestClient implements ExecutionRestClien
     }
 
     public void updateSchedTask(final SchedTaskTO taskTO) {
-        getService(TaskService.class).update(taskTO.getKey(), taskTO);
+        getService(TaskService.class).update(taskTO);
     }
 
     public void updateSyncTask(final SyncTaskTO taskTO) {
-        getService(TaskService.class).update(taskTO.getKey(), taskTO);
+        getService(TaskService.class).update(taskTO);
     }
 
     public BulkActionResult bulkAction(final BulkAction action) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 bfe6385..f517c4c 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
@@ -73,7 +73,7 @@ public class UserRestClient extends AbstractAnyRestClient {
         UserTO result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+            result = service.update(userMod).readEntity(UserTO.class);
             resetClient(UserService.class);
         }
         return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/client/console/src/main/java/org/apache/syncope/client/console/rest/UserSelfRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserSelfRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserSelfRestClient.java
index 13e1555..9668672 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserSelfRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserSelfRestClient.java
@@ -52,7 +52,7 @@ public class UserSelfRestClient extends BaseRestClient {
     }
 
     public void update(final UserMod userMod) {
-        getService(UserSelfService.class).update(userMod.getKey(), userMod);
+        getService(UserSelfService.class).update(userMod);
     }
 
     public void delete() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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
index f84e65a..0fbd6aa 100644
--- 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
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashSet;
 import java.util.Set;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlType;
@@ -60,6 +61,7 @@ public abstract class AnyMod extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractPolicyTO.java
index 9202fba..2c5fcb4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractPolicyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractPolicyTO.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -62,6 +63,7 @@ public abstract class AbstractPolicyTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
index b3a37a8..afd6e6b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
@@ -38,6 +39,7 @@ public abstract class AbstractSchemaTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
index 21e1cb0..21e665b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
 
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -47,6 +48,7 @@ public abstract class AbstractTaskTO extends AbstractStartEndBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
index 9b696f8..508d2cb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeClassTO.java
@@ -21,6 +21,7 @@ package org.apache.syncope.common.lib.to;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -45,6 +46,7 @@ public class AnyTypeClassTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
index 3722b81..a5a7104 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTypeTO.java
@@ -21,6 +21,7 @@ package org.apache.syncope.common.lib.to;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -44,6 +45,7 @@ public class AnyTypeTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
index 5c25783..2111570 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnInstanceTO.java
@@ -26,6 +26,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -71,6 +72,7 @@ public class ConnInstanceTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 5487410..01f70d0 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
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -91,6 +92,7 @@ public class NotificationTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final Long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
index 9a25be2..faef389 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RealmTO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
@@ -68,6 +69,7 @@ public class RealmTO extends AbstractBaseBean {
         return fullPath;
     }
 
+    @PathParam("fullPath")
     public void setFullPath(final String fullPath) {
         this.fullPath = fullPath;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
index 80f74f3..533f8d1 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ReportTO.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -54,6 +55,7 @@ public class ReportTO extends AbstractStartEndBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 7fbac89..79d33a1 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
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -98,6 +99,7 @@ public class ResourceTO extends AbstractAnnotatedBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final String key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
index 1a12fdb..fab8a06 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -49,6 +50,7 @@ public class RoleTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
index dd73f2c..83a8c55 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SecurityQuestionTO.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
@@ -36,6 +37,7 @@ public class SecurityQuestionTO extends AbstractBaseBean {
         return key;
     }
 
+    @PathParam("key")
     public void setKey(final long key) {
         this.key = key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
index 90fbf7d..93167cb 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -100,7 +100,6 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     /**
      * Updates any object matching the provided key.
      *
-     * @param key key of any object to be updated
      * @param anyMod modification to be applied to any object matching the provided key
      * @return <tt>Response</tt> object featuring the updated any object enriched with propagation status information
      * - {@link AnyTO} as <tt>Entity</tt>
@@ -114,7 +113,7 @@ public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSS
     @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("key") Long key, @NotNull MOD anyMod);
+    Response update(@NotNull MOD anyMod);
 
     /**
      * Deletes any object matching provided key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
index 21831cf..18bf1c4 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeClassService.java
@@ -78,13 +78,12 @@ public interface AnyTypeClassService extends JAXRSService {
     /**
      * Updates the anyTypeClass matching the provided key.
      *
-     * @param key anyTypeClass key to be updated
      * @param anyTypeClassTO anyTypeClass to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("key") String key, @NotNull AnyTypeClassTO anyTypeClassTO);
+    void update(@NotNull AnyTypeClassTO anyTypeClassTO);
 
     /**
      * Deletes the anyTypeClass matching the provided key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
index ddedd25..c4a8c02 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyTypeService.java
@@ -78,13 +78,12 @@ public interface AnyTypeService extends JAXRSService {
     /**
      * Updates the anyType matching the provided key.
      *
-     * @param key anyType key to be updated
      * @param anyTypeTO anyType to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("key") String key, @NotNull AnyTypeTO anyTypeTO);
+    void update(@NotNull AnyTypeTO anyTypeTO);
 
     /**
      * Deletes the anyType matching the provided key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index e0c240f..2518a74 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -154,13 +154,12 @@ public interface ConnectorService extends JAXRSService {
     /**
      * Updates the connector instance matching the provided key.
      *
-     * @param key connector instance key to be updated
      * @param connInstanceTO connector instance to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("key") Long key, @NotNull ConnInstanceTO connInstanceTO);
+    void update(@NotNull ConnInstanceTO connInstanceTO);
 
     /**
      * Deletes the connector instance matching the provided key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
index a210014..ae33d5a 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/NotificationService.java
@@ -44,13 +44,13 @@ public interface NotificationService extends JAXRSService {
     /**
      * Returns notification with matching id.
      *
-     * @param notificationKey key of notification to be read
+     * @param key key of notification to be read
      * @return notification with matching key
      */
     @GET
-    @Path("{notificationKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    NotificationTO read(@NotNull @PathParam("notificationKey") Long notificationKey);
+    NotificationTO read(@NotNull @PathParam("key") Long key);
 
     /**
      * Returns a list of all notifications.
@@ -78,20 +78,19 @@ public interface NotificationService extends JAXRSService {
     /**
      * Updates the notification matching the given key.
      *
-     * @param notificationKey key of notification to be updated
      * @param notificationTO notification to be stored
      */
     @PUT
-    @Path("{notificationKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("notificationKey") Long notificationKey, @NotNull NotificationTO notificationTO);
+    void update(@NotNull NotificationTO notificationTO);
 
     /**
      * Deletes the notification matching the given key.
      *
-     * @param notificationKey key for notification to be deleted
+     * @param key key for notification to be deleted
      */
     @DELETE
-    @Path("{notificationKey}")
-    void delete(@NotNull @PathParam("notificationKey") Long notificationKey);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
index c098ace..980da9f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/PolicyService.java
@@ -46,14 +46,14 @@ public interface PolicyService extends JAXRSService {
     /**
      * Returns the policy matching the given key.
      *
-     * @param policyKey key of requested policy
+     * @param key key of requested policy
      * @param <T> response type (extending PolicyTO)
      * @return policy with matching id
      */
     @GET
-    @Path("{policyKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractPolicyTO> T read(@NotNull @PathParam("policyKey") Long policyKey);
+    <T extends AbstractPolicyTO> T read(@NotNull @PathParam("key") Long key);
 
     /**
      * Returns a list of policies of the matching type.
@@ -83,23 +83,22 @@ public interface PolicyService extends JAXRSService {
     /**
      * Updates policy matching the given key.
      *
-     * @param policyKey key of policy to be updated
      * @param policyTO Policy to replace existing policy
      * @param <T> response type (extending PolicyTO)
      */
     @PUT
-    @Path("{policyKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractPolicyTO> void update(@NotNull @PathParam("policyKey") Long policyKey, @NotNull T policyTO);
+    <T extends AbstractPolicyTO> void update(@NotNull T policyTO);
 
     /**
      * Delete policy matching the given key.
      *
-     * @param policyKey key of policy to be deleted
+     * @param key key of policy to be deleted
      * @param <T> response type (extending PolicyTO)
      */
     @DELETE
-    @Path("{policyKey}")
-    <T extends AbstractPolicyTO> void delete(@NotNull @PathParam("policyKey") Long policyKey);
+    @Path("{key}")
+    <T extends AbstractPolicyTO> void delete(@NotNull @PathParam("key") Long key);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RealmService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RealmService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RealmService.java
index c8343ae..74b2333 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RealmService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RealmService.java
@@ -80,13 +80,12 @@ public interface RealmService extends JAXRSService {
     /**
      * Updates the realm under the given path.
      *
-     * @param fullPath full path of the realm
      * @param realmTO realm to be stored
      */
     @PUT
     @Path("{fullPath:.*}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("fullPath") String fullPath, @NotNull RealmTO realmTO);
+    void update(@NotNull RealmTO realmTO);
 
     /**
      * Deletes the notification matching the given key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
index 996f784..b5ce7ec 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
@@ -64,13 +64,13 @@ public interface ReportService extends JAXRSService {
     /**
      * Returns report with matching key.
      *
-     * @param reportKey key of report to be read
+     * @param key key of report to be read
      * @return report with matching key
      */
     @GET
-    @Path("{reportKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ReportTO read(@NotNull @PathParam("reportKey") Long reportKey);
+    ReportTO read(@NotNull @PathParam("key") Long key);
 
     /**
      * Returns report execution with matching key.
@@ -109,22 +109,21 @@ public interface ReportService extends JAXRSService {
     /**
      * Updates report with matching key.
      *
-     * @param reportKey id for report to be updated
      * @param reportTO report to be stored
      */
     @PUT
-    @Path("{reportKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("reportKey") Long reportKey, ReportTO reportTO);
+    void update(@NotNull ReportTO reportTO);
 
     /**
      * Deletes report with matching key.
      *
-     * @param reportKey Deletes report with matching key
+     * @param key Deletes report with matching key
      */
     @DELETE
-    @Path("{reportKey}")
-    void delete(@NotNull @PathParam("reportKey") Long reportKey);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 
     /**
      * Deletes report execution with matching key.
@@ -138,13 +137,13 @@ public interface ReportService extends JAXRSService {
     /**
      * Executes the report with matching key.
      *
-     * @param reportKey key of report to be executed
+     * @param key key of report to be executed
      * @return report execution result
      */
     @POST
-    @Path("{reportKey}/execute")
+    @Path("{key}/execute")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    ReportExecTO execute(@NotNull @PathParam("reportKey") Long reportKey);
+    ReportExecTO execute(@NotNull @PathParam("key") Long key);
 
     /**
      * Exports the report execution with matching key in the requested format.
@@ -173,10 +172,10 @@ public interface ReportService extends JAXRSService {
     /**
      * Executes an action on an existing report's job.
      *
-     * @param reportKey report key
+     * @param key report key
      * @param action
      */
     @POST
-    @Path("{reportKey}")
-    void actionJob(@PathParam("reportKey") Long reportKey, @QueryParam("action") JobAction action);
+    @Path("{key}")
+    void actionJob(@PathParam("key") Long key, @QueryParam("action") JobAction action);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 41204a0..cac9132 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
@@ -98,13 +98,12 @@ public interface ResourceService extends JAXRSService {
     /**
      * Updates the resource matching the given name.
      *
-     * @param key name of resource to be updated
      * @param resourceTO resource to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("key") String key, @NotNull ResourceTO resourceTO);
+    void update(@NotNull ResourceTO resourceTO);
 
     /**
      * Deletes the resource matching the given name.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
index 881e1bc..d6afa1f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
@@ -78,13 +78,12 @@ public interface RoleService extends JAXRSService {
     /**
      * Updates the role matching the provided key.
      *
-     * @param key role key to be updated
      * @param roleTO role to be stored
      */
     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("key") Long key, @NotNull RoleTO roleTO);
+    void update(@NotNull RoleTO roleTO);
 
     /**
      * Deletes the role matching the provided key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 352e310..68f0f43 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
@@ -23,6 +23,7 @@ import javax.validation.constraints.NotNull;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.MatrixParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
@@ -43,18 +44,18 @@ import org.apache.syncope.common.lib.types.SchemaType;
 public interface SchemaService extends JAXRSService {
 
     /**
-     * Returns schema matching the given kind, type and name.
+     * Returns schema matching the given type and key.
      *
      * @param <T> actual SchemaTO
      * @param type type for schemas to be read
-     * @param schemaKey name of schema to be read
+     * @param key 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("type") SchemaType type, @NotNull @PathParam("key") String schemaKey);
+            @NotNull @PathParam("type") SchemaType type, @NotNull @PathParam("key") String key);
 
     /**
      * Returns a list of schemas with matching kind and type.
@@ -65,7 +66,7 @@ public interface SchemaService extends JAXRSService {
      */
     @GET
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> List<T> list(@NotNull @PathParam("type") SchemaType type);
+    <T extends AbstractSchemaTO> List<T> list(@NotNull @MatrixParam("type") SchemaType type);
 
     /**
      * Creates a new schema.
@@ -80,33 +81,27 @@ public interface SchemaService extends JAXRSService {
     })
     @POST
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractSchemaTO> Response create(
-            @NotNull @PathParam("type") SchemaType type, @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.
+     * Updates the schema matching the given type and key.
      *
      * @param <T> actual SchemaTO
      * @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("type") SchemaType type,
-            @NotNull @PathParam("key") String schemaKey, @NotNull T schemaTO);
+    <T extends AbstractSchemaTO> void update(@NotNull @PathParam("type") SchemaType type, @NotNull T schemaTO);
 
     /**
-     * Deletes the schema matching the given kind, type and name.
+     * Deletes the schema matching the given type and key.
      *
      * @param type type for schema to be deleted
-     * @param schemaKey name of schema to be deleted
+     * @param key name of schema to be deleted
      */
     @DELETE
     @Path("{key}")
-    void delete(
-            @NotNull @PathParam("type") SchemaType type,
-            @NotNull @PathParam("key") String schemaKey);
+    void delete(@NotNull @PathParam("type") SchemaType type, @NotNull @PathParam("key") String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SecurityQuestionService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SecurityQuestionService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SecurityQuestionService.java
index 12a73cf..f0dcf27 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SecurityQuestionService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SecurityQuestionService.java
@@ -51,15 +51,15 @@ public interface SecurityQuestionService extends JAXRSService {
     List<SecurityQuestionTO> list();
 
     /**
-     * Returns security question with matching id.
+     * Returns security question with matching key.
      *
-     * @param securityQuestionId security question id to be read
-     * @return security question with matching id
+     * @param key security question key to be read
+     * @return security question with matching key
      */
     @GET
-    @Path("{securityQuestionId}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    SecurityQuestionTO read(@NotNull @PathParam("securityQuestionId") Long securityQuestionId);
+    SecurityQuestionTO read(@NotNull @PathParam("key") Long key);
 
     /**
      * Creates a new security question.
@@ -76,25 +76,23 @@ public interface SecurityQuestionService extends JAXRSService {
     Response create(@NotNull SecurityQuestionTO securityQuestionTO);
 
     /**
-     * Updates the security question matching the provided id.
+     * Updates the security question matching the provided key.
      *
-     * @param securityQuestionId security question id to be updated
      * @param securityQuestionTO security question to be stored
      */
     @PUT
-    @Path("{securityQuestionId}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("securityQuestionId") Long securityQuestionId,
-            @NotNull SecurityQuestionTO securityQuestionTO);
+    void update(@NotNull SecurityQuestionTO securityQuestionTO);
 
     /**
-     * Deletes the security question matching the provided id.
+     * Deletes the security question matching the provided key.
      *
-     * @param securityQuestionId security question id to be deleted
+     * @param key security question key to be deleted
      */
     @DELETE
-    @Path("{securityQuestionId}")
-    void delete(@NotNull @PathParam("securityQuestionId") Long securityQuestionId);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 
     /**
      * Ask for security question configured for the user matching the given username, if any.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
index 84b7cbf..5e39b2a 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/TaskService.java
@@ -58,14 +58,14 @@ public interface TaskService extends JAXRSService {
     /**
      * Returns the task matching the given key.
      *
-     * @param taskKey key of task to be read
+     * @param key key of task to be read
      * @param <T> type of taskTO
      * @return task with matching id
      */
     @GET
-    @Path("{taskKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    <T extends AbstractTaskTO> T read(@NotNull @PathParam("taskKey") Long taskKey);
+    <T extends AbstractTaskTO> T read(@NotNull @PathParam("key") Long key);
 
     /**
      * Returns the task execution with the given id.
@@ -109,22 +109,21 @@ public interface TaskService extends JAXRSService {
     /**
      * Updates the task matching the provided key.
      *
-     * @param taskKey key of task to be updated
      * @param taskTO updated task to be stored
      */
     @PUT
-    @Path("{taskKey}")
+    @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    void update(@NotNull @PathParam("taskKey") Long taskKey, @NotNull AbstractTaskTO taskTO);
+    void update(@NotNull AbstractTaskTO taskTO);
 
     /**
      * Deletes the task matching the provided key.
      *
-     * @param taskKey key of task to be deleted
+     * @param key key of task to be deleted
      */
     @DELETE
-    @Path("{taskKey}")
-    void delete(@NotNull @PathParam("taskKey") Long taskKey);
+    @Path("{key}")
+    void delete(@NotNull @PathParam("key") Long key);
 
     /**
      * Deletes the task execution matching the provided key.
@@ -138,14 +137,14 @@ public interface TaskService extends JAXRSService {
     /**
      * Executes the task matching the given id.
      *
-     * @param taskKey key of task to be executed
+     * @param key key of task to be executed
      * @param dryRun if true, task will only be simulated
      * @return execution report for the task matching the given id
      */
     @POST
-    @Path("{taskKey}/execute")
+    @Path("{key}/execute")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    TaskExecTO execute(@NotNull @PathParam("taskKey") Long taskKey,
+    TaskExecTO execute(@NotNull @PathParam("key") Long key,
             @QueryParam("dryRun") @DefaultValue("false") boolean dryRun);
 
     /**
@@ -185,10 +184,10 @@ public interface TaskService extends JAXRSService {
     /**
      * Executes an action on an existing task's job.
      *
-     * @param taskKey task key
+     * @param key task key
      * @param action
      */
     @POST
-    @Path("{taskKey}")
-    void actionJob(@PathParam("taskKey") Long taskKey, @QueryParam("action") JobAction action);
+    @Path("{key}")
+    void actionJob(@PathParam("key") Long key, @QueryParam("action") JobAction action);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
index f57f2cf..dd2fe7e 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
@@ -25,7 +25,6 @@ import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
@@ -74,8 +73,7 @@ public interface UserSelfService extends JAXRSService {
     /**
      * Self-updates user.
      *
-     * @param userKey id of user to be updated
-     * @param userMod modification to be applied to user matching the provided userKey
+     * @param userMod modification to be applied to user matching the provided key
      * @return <tt>Response</tt> object featuring the updated user - {@link UserTO} as <tt>Entity</tt>
      */
     @Descriptions({
@@ -83,10 +81,10 @@ public interface UserSelfService extends JAXRSService {
                 value = "Featuring the updated user - <tt>UserTO</tt> as <tt>Entity</tt>")
     })
     @POST
-    @Path("{userKey}")
+    @Path("{key}")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("userKey") Long userKey, @NotNull UserMod userMod);
+    Response update(@NotNull UserMod userMod);
 
     /**
      * Self-deletes user.

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 7cf4a08..93afe01 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -107,12 +107,11 @@ public abstract class AbstractAnyService<TO extends AnyTO, MOD extends AnyMod>
     }
 
     @Override
-    public Response update(final Long key, final MOD anyMod) {
-        TO any = getAnyLogic().read(key);
+    public Response update(final MOD anyMod) {
+        TO any = getAnyLogic().read(anyMod.getKey());
 
         checkETag(any.getETagValue());
 
-        anyMod.setKey(key);
         TO updated = getAnyLogic().update(anyMod);
         return modificationResponse(updated);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
index 3683e61..54a546a 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeClassServiceImpl.java
@@ -54,8 +54,7 @@ public class AnyTypeClassServiceImpl extends AbstractServiceImpl implements AnyT
     }
 
     @Override
-    public void update(final String key, final AnyTypeClassTO anyTypeTO) {
-        anyTypeTO.setKey(key);
+    public void update(final AnyTypeClassTO anyTypeTO) {
         logic.update(anyTypeTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
index bb3c699..5f0e8ec 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AnyTypeServiceImpl.java
@@ -54,8 +54,7 @@ public class AnyTypeServiceImpl extends AbstractServiceImpl implements AnyTypeSe
     }
 
     @Override
-    public void update(final String key, final AnyTypeTO anyTypeTO) {
-        anyTypeTO.setKey(key);
+    public void update(final AnyTypeTO anyTypeTO) {
         logic.update(anyTypeTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
index d80caf9..6725bf9 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ConnectorServiceImpl.java
@@ -112,8 +112,7 @@ public class ConnectorServiceImpl extends AbstractServiceImpl implements Connect
     }
 
     @Override
-    public void update(final Long key, final ConnInstanceTO connInstanceTO) {
-        connInstanceTO.setKey(key);
+    public void update(final ConnInstanceTO connInstanceTO) {
         logic.update(connInstanceTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
index 017b0b3..dbd3461 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/NotificationServiceImpl.java
@@ -44,8 +44,8 @@ public class NotificationServiceImpl extends AbstractServiceImpl implements Noti
     }
 
     @Override
-    public NotificationTO read(final Long notificationKey) {
-        return logic.read(notificationKey);
+    public NotificationTO read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
@@ -54,13 +54,12 @@ public class NotificationServiceImpl extends AbstractServiceImpl implements Noti
     }
 
     @Override
-    public void update(final Long notificationKey, final NotificationTO notificationTO) {
-        notificationTO.setKey(notificationKey);
+    public void update(final NotificationTO notificationTO) {
         logic.update(notificationTO);
     }
 
     @Override
-    public void delete(final Long notificationKey) {
-        logic.delete(notificationKey);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
index a61e776..ecec019 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/PolicyServiceImpl.java
@@ -48,8 +48,8 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
     }
 
     @Override
-    public void delete(final Long policyKey) {
-        logic.delete(policyKey);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 
     @Override
@@ -58,14 +58,12 @@ public class PolicyServiceImpl extends AbstractServiceImpl implements PolicyServ
     }
 
     @Override
-    public <T extends AbstractPolicyTO> T read(final Long policyKey) {
-        return logic.read(policyKey);
+    public <T extends AbstractPolicyTO> T read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
-    public <T extends AbstractPolicyTO> void update(final Long policyKey, final T policyTO) {
-        policyTO.setKey(policyKey);
-
+    public <T extends AbstractPolicyTO> void update(final T policyTO) {
         switch (policyTO.getType()) {
             case ACCOUNT:
                 logic.update((AccountPolicyTO) policyTO);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
index ecf372d..0485c1d 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RealmServiceImpl.java
@@ -56,8 +56,8 @@ public class RealmServiceImpl extends AbstractServiceImpl implements RealmServic
     }
 
     @Override
-    public void update(final String fullPath, final RealmTO realmTO) {
-        realmTO.setFullPath(StringUtils.prependIfMissing(fullPath, SyncopeConstants.ROOT_REALM));
+    public void update(final RealmTO realmTO) {
+        realmTO.setFullPath(StringUtils.prependIfMissing(realmTO.getFullPath(), SyncopeConstants.ROOT_REALM));
         logic.update(realmTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
index 405e105..9fa3d99 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/ReportServiceImpl.java
@@ -57,8 +57,7 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
     }
 
     @Override
-    public void update(final Long reportKey, final ReportTO reportTO) {
-        reportTO.setKey(reportKey);
+    public void update(final ReportTO reportTO) {
         logic.update(reportTO);
     }
 
@@ -80,8 +79,8 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
     }
 
     @Override
-    public ReportTO read(final Long reportKey) {
-        return logic.read(reportKey);
+    public ReportTO read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
@@ -108,13 +107,13 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
     }
 
     @Override
-    public ReportExecTO execute(final Long reportKey) {
-        return logic.execute(reportKey);
+    public ReportExecTO execute(final Long key) {
+        return logic.execute(key);
     }
 
     @Override
-    public void delete(final Long reportKey) {
-        logic.delete(reportKey);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 
     @Override
@@ -128,7 +127,7 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
     }
 
     @Override
-    public void actionJob(final Long reportKey, final JobAction action) {
-        logic.actionJob(reportKey, action);
+    public void actionJob(final Long key, final JobAction action) {
+        logic.actionJob(key, action);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 b6c3f50..ae7c426 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
@@ -67,8 +67,7 @@ public class ResourceServiceImpl extends AbstractServiceImpl implements Resource
     }
 
     @Override
-    public void update(final String key, final ResourceTO resourceTO) {
-        resourceTO.setKey(key);
+    public void update(final ResourceTO resourceTO) {
         logic.update(resourceTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
index d2efb3f..006767c 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RoleServiceImpl.java
@@ -54,8 +54,7 @@ public class RoleServiceImpl extends AbstractServiceImpl implements RoleService
     }
 
     @Override
-    public void update(final Long roleKey, final RoleTO roleTO) {
-        roleTO.setKey(roleKey);
+    public void update(final RoleTO roleTO) {
         logic.update(roleTO);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 aa99255..e846a95 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
@@ -46,8 +46,8 @@ public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaServ
     }
 
     @Override
-    public void delete(final SchemaType schemaType, final String schemaKey) {
-        logic.delete(schemaType, schemaKey);
+    public void delete(final SchemaType schemaType, final String key) {
+        logic.delete(schemaType, key);
     }
 
     @Override
@@ -56,15 +56,12 @@ public class SchemaServiceImpl extends AbstractServiceImpl implements SchemaServ
     }
 
     @Override
-    public <T extends AbstractSchemaTO> T read(final SchemaType schemaType, final String schemaKey) {
-        return logic.read(schemaType, schemaKey);
+    public <T extends AbstractSchemaTO> T read(final SchemaType schemaType, final String key) {
+        return logic.read(schemaType, key);
     }
 
     @Override
-    public <T extends AbstractSchemaTO> void update(
-            final SchemaType schemaType, final String schemaKey, final T schemaTO) {
-
-        schemaTO.setKey(schemaKey);
+    public <T extends AbstractSchemaTO> void update(final SchemaType schemaType, final T schemaTO) {
         logic.update(schemaType, schemaTO);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
index b094adc..37cc4552 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SecurityQuestionServiceImpl.java
@@ -40,8 +40,8 @@ public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements
     }
 
     @Override
-    public SecurityQuestionTO read(final Long securityQuestionId) {
-        return logic.read(securityQuestionId);
+    public SecurityQuestionTO read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
@@ -55,14 +55,13 @@ public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements
     }
 
     @Override
-    public void update(final Long securityQuestionId, final SecurityQuestionTO securityQuestionTO) {
-        securityQuestionTO.setKey(securityQuestionId);
+    public void update(final SecurityQuestionTO securityQuestionTO) {
         logic.update(securityQuestionTO);
     }
 
     @Override
-    public void delete(final Long securityQuestionId) {
-        logic.delete(securityQuestionId);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
index 29d4a0c..5fb19e2 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/TaskServiceImpl.java
@@ -64,8 +64,8 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public void delete(final Long taskKey) {
-        logic.delete(taskKey);
+    public void delete(final Long key) {
+        logic.delete(key);
     }
 
     @Override
@@ -74,8 +74,8 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public TaskExecTO execute(final Long taskKey, final boolean dryRun) {
-        return logic.execute(taskKey, dryRun);
+    public TaskExecTO execute(final Long key, final boolean dryRun) {
+        return logic.execute(key, dryRun);
     }
 
     @SuppressWarnings("unchecked")
@@ -93,8 +93,8 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public <T extends AbstractTaskTO> T read(final Long taskKey) {
-        return logic.read(taskKey);
+    public <T extends AbstractTaskTO> T read(final Long key) {
+        return logic.read(key);
     }
 
     @Override
@@ -110,8 +110,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public void update(final Long taskKey, final AbstractTaskTO taskTO) {
-        taskTO.setKey(taskKey);
+    public void update(final AbstractTaskTO taskTO) {
         if (taskTO instanceof SyncTaskTO) {
             logic.updateSync((SyncTaskTO) taskTO);
         } else if (taskTO instanceof SchedTaskTO) {
@@ -127,38 +126,38 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
 
         switch (bulkAction.getOperation()) {
             case DELETE:
-                for (String taskKey : bulkAction.getTargets()) {
+                for (String key : bulkAction.getTargets()) {
                     try {
                         result.getResults().put(
-                                String.valueOf(logic.delete(Long.valueOf(taskKey)).getKey()),
+                                String.valueOf(logic.delete(Long.valueOf(key)).getKey()),
                                 BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
-                        LOG.error("Error performing delete for task {}", taskKey, e);
-                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
+                        LOG.error("Error performing delete for task {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
 
             case DRYRUN:
-                for (String taskKey : bulkAction.getTargets()) {
+                for (String key : bulkAction.getTargets()) {
                     try {
-                        logic.execute(Long.valueOf(taskKey), true);
-                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
+                        logic.execute(Long.valueOf(key), true);
+                        result.getResults().put(key, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
-                        LOG.error("Error performing dryrun for task {}", taskKey, e);
-                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
+                        LOG.error("Error performing dryrun for task {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
 
             case EXECUTE:
-                for (String taskKey : bulkAction.getTargets()) {
+                for (String key : bulkAction.getTargets()) {
                     try {
-                        logic.execute(Long.valueOf(taskKey), false);
-                        result.getResults().put(taskKey, BulkActionResult.Status.SUCCESS);
+                        logic.execute(Long.valueOf(key), false);
+                        result.getResults().put(key, BulkActionResult.Status.SUCCESS);
                     } catch (Exception e) {
-                        LOG.error("Error performing execute for task {}", taskKey, e);
-                        result.getResults().put(taskKey, BulkActionResult.Status.FAILURE);
+                        LOG.error("Error performing execute for task {}", key, e);
+                        result.getResults().put(key, BulkActionResult.Status.FAILURE);
                     }
                 }
                 break;
@@ -175,7 +174,7 @@ public class TaskServiceImpl extends AbstractServiceImpl implements TaskService
     }
 
     @Override
-    public void actionJob(final Long taskKey, final JobAction action) {
-        logic.actionJob(taskKey, action);
+    public void actionJob(final Long key, final JobAction action) {
+        logic.actionJob(key, action);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
----------------------------------------------------------------------
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
index 74d58d1..18013d2 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserSelfServiceImpl.java
@@ -63,8 +63,7 @@ public class UserSelfServiceImpl extends AbstractServiceImpl implements UserSelf
     }
 
     @Override
-    public Response update(final Long userKey, final UserMod userMod) {
-        userMod.setKey(userKey);
+    public Response update(final UserMod userMod) {
         UserTO updated = logic.updateSelf(userMod);
         return modificationResponse(updated);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 efe1b16..77e4c50 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
@@ -292,7 +292,7 @@ public abstract class AbstractITCase {
     }
 
     protected UserTO updateUser(final UserMod userMod) {
-        return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+        return userService.update(userMod).readEntity(UserTO.class);
     }
 
     protected UserTO deleteUser(final Long key) {
@@ -342,7 +342,7 @@ public abstract class AbstractITCase {
     }
 
     protected AnyObjectTO updateAnyObject(final AnyObjectMod anyObjectMod) {
-        return anyObjectService.update(anyObjectMod.getKey(), anyObjectMod).readEntity(AnyObjectTO.class);
+        return anyObjectService.update(anyObjectMod).readEntity(AnyObjectTO.class);
     }
 
     protected AnyObjectTO deleteAnyObject(final Long key) {
@@ -361,7 +361,7 @@ public abstract class AbstractITCase {
     }
 
     protected GroupTO updateGroup(final GroupMod groupMod) {
-        return groupService.update(groupMod.getKey(), groupMod).readEntity(GroupTO.class);
+        return groupService.update(groupMod).readEntity(GroupTO.class);
     }
 
     protected GroupTO deleteGroup(final Long key) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
index 4dbb796..557f4b3 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeClassITCase.java
@@ -72,7 +72,7 @@ public class AnyTypeClassITCase extends AbstractITCase {
         assertTrue(newClass.getVirSchemas().isEmpty());
 
         newClass.getDerSchemas().add("cn");
-        anyTypeClassService.update(newClass.getKey(), newClass);
+        anyTypeClassService.update(newClass);
 
         newClass = anyTypeClassService.read(newClass.getKey());
         assertNotNull(newClass);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
index 01da6f8..9fdc1e4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AnyTypeITCase.java
@@ -85,7 +85,7 @@ public class AnyTypeITCase extends AbstractITCase {
         assertTrue(newType.getClasses().contains("csv"));
 
         newType.getClasses().remove("generic membership");
-        anyTypeService.update(newType.getKey(), newType);
+        anyTypeService.update(newType);
 
         newType = anyTypeService.read(newType.getKey());
         assertNotNull(newType);
@@ -154,7 +154,7 @@ public class AnyTypeITCase extends AbstractITCase {
         assertNotNull(other);
 
         other.getClasses().add(newClass.getKey());
-        anyTypeService.update(other.getKey(), other);
+        anyTypeService.update(other);
 
         other = anyTypeService.read(other.getKey());
         assertNotNull(other);

http://git-wip-us.apache.org/repos/asf/syncope/blob/df60b3b4/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 5102e9b..a756401 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
@@ -152,7 +152,7 @@ public class AuthenticationITCase extends AbstractITCase {
 
         // 5. update the schema create above (as user) - failure
         try {
-            schemaService2.update(SchemaType.PLAIN, schemaName, schemaTO);
+            schemaService2.update(SchemaType.PLAIN, schemaTO);
             fail("Schemaupdate as user should not work");
         } catch (AccessControlException e) {
             // CXF Service will throw this exception


[59/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
deleted file mode 100644
index 755b2d1..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/Resources.java
+++ /dev/null
@@ -1,485 +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.panels;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.PreferenceManager;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.pages.BasePage;
-import org.apache.syncope.client.console.pages.ConnectorModalPage;
-import org.apache.syncope.client.console.pages.ProvisioningModalPage;
-import org.apache.syncope.client.console.pages.ResourceModalPage;
-import org.apache.syncope.client.console.rest.ConnectorRestClient;
-import org.apache.syncope.client.console.rest.ResourceRestClient;
-import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.LinkPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-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.Entitlement;
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.Page;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.form.DropDownChoice;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.markup.repeater.Item;
-import org.apache.wicket.model.AbstractReadOnlyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.apache.wicket.model.StringResourceModel;
-import org.apache.wicket.spring.injection.annot.SpringBean;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Resources WebPage.
- */
-public class Resources extends Panel {
-
-    private static final long serialVersionUID = -3789252860990261728L;
-
-    protected static final Logger LOG = LoggerFactory.getLogger(Resources.class);
-
-    private static final int WIN_HEIGHT = 600;
-
-    private static final int WIN_WIDTH = 1100;
-
-    @SpringBean
-    private PreferenceManager prefMan;
-
-    @SpringBean
-    private ResourceRestClient resourceRestClient;
-
-    private final ModalWindow createResourceWin;
-
-    private final ModalWindow editResourceWin;
-
-    private final int resourcePaginatorRows;
-
-    private WebMarkupContainer resourceContainer;
-
-    private final ModalWindow editConnectorWin;
-
-    /**
-     * Modal window to be used for user status management.
-     */
-    protected final ModalWindow statusmodal = new ModalWindow("statusModal");
-
-    /**
-     * Schemas to be shown modal window height.
-     */
-    private static final int STATUS_MODAL_WIN_HEIGHT = 500;
-
-    /**
-     * Schemas to be shown modal window width.
-     */
-    private static final int STATUS_MODAL_WIN_WIDTH = 700;
-
-    @SpringBean
-    private ConnectorRestClient connectorRestClient;
-
-    private final PageReference pageRef;
-
-    public Resources(final String id, final PageReference pageRef) {
-        super(id);
-        this.pageRef = pageRef;
-
-        createResourceWin = new ModalWindow("createResourceWin");
-        add(createResourceWin);
-
-        editResourceWin = new ModalWindow("editResourceWin");
-        add(editResourceWin);
-
-        editConnectorWin = new ModalWindow("editConnectorWin");
-        add(editConnectorWin);
-
-        statusmodal.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        statusmodal.setInitialHeight(STATUS_MODAL_WIN_HEIGHT);
-        statusmodal.setInitialWidth(STATUS_MODAL_WIN_WIDTH);
-        statusmodal.setCookieName("status-modal");
-        add(statusmodal);
-
-        resourcePaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_RESOURCES_PAGINATOR_ROWS);
-
-        setupResources();
-    }
-
-    private void setupResources() {
-        List<IColumn<ResourceTO, String>> columns = new ArrayList<>();
-
-        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel("key", this, null), "key", "key"));
-
-        columns.add(new AbstractColumn<ResourceTO, String>(
-                new StringResourceModel("connector", this, null, "connector")) {
-
-                    private static final long serialVersionUID = 8263694778917279290L;
-
-                    @Override
-                    public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
-                            final IModel<ResourceTO> rowModel) {
-
-                        final AjaxLink<String> editLink = new ClearIndicatingAjaxLink<String>("link", pageRef) {
-
-                            private static final long serialVersionUID = -7978723352517770644L;
-
-                            @Override
-                            protected void onClickInternal(final AjaxRequestTarget target) {
-
-                                editConnectorWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                                    private static final long serialVersionUID = -7834632442532690940L;
-
-                                    @Override
-                                    public Page createPage() {
-                                        return new ConnectorModalPage(Resources.this.pageRef,
-                                                editConnectorWin,
-                                                connectorRestClient.read(rowModel.getObject().getConnectorId()));
-                                    }
-                                });
-
-                                editConnectorWin.show(target);
-                            }
-                        };
-                        editLink.add(new Label("linkTitle", rowModel.getObject().getConnectorDisplayName()));
-
-                        LinkPanel editConnPanel = new LinkPanel(componentId);
-                        editConnPanel.add(editLink);
-
-                        cellItem.add(editConnPanel);
-
-                        MetaDataRoleAuthorizationStrategy.authorize(editConnPanel, ENABLE, Entitlement.CONNECTOR_READ);
-                    }
-                });
-
-        columns.add(new AbstractColumn<ResourceTO, String>(
-                new StringResourceModel("propagationPrimary", this, null)) {
-
-                    private static final long serialVersionUID = -3503023501954863131L;
-
-                    @Override
-                    public void populateItem(final Item<ICellPopulator<ResourceTO>> item,
-                            final String componentId, final IModel<ResourceTO> model) {
-
-                        item.add(new Label(componentId, ""));
-                        item.add(new AttributeModifier("class", new Model<>(
-                                                Boolean.toString(model.getObject().isPropagationPrimary()))));
-                    }
-
-                    @Override
-                    public String getCssClass() {
-                        return "narrowcolumn";
-                    }
-                });
-
-        columns.add(new PropertyColumn<ResourceTO, String>(new StringResourceModel(
-                "propagationPriority", this, null), "propagationPriority", "propagationPriority") {
-
-                    private static final long serialVersionUID = 1L;
-
-                    @Override
-                    public String getCssClass() {
-                        return "narrowcolumn";
-                    }
-                });
-
-        columns.add(new AbstractColumn<ResourceTO, String>(new StringResourceModel("actions", this, null, "")) {
-
-            private static final long serialVersionUID = 2054811145491901166L;
-
-            @Override
-            public String getCssClass() {
-                return "action";
-            }
-
-            @Override
-            public void populateItem(final Item<ICellPopulator<ResourceTO>> cellItem, final String componentId,
-                    final IModel<ResourceTO> model) {
-
-                final ResourceTO resourceTO = model.getObject();
-
-                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) {
-                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ProvisioningModalPage<>(
-                                        pageRef, statusmodal, model.getObject(), UserTO.class);
-                            }
-                        });
-
-                        statusmodal.show(target);
-                    }
-                }, ActionLink.ActionType.MANAGE_USERS, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-
-                        statusmodal.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ProvisioningModalPage<>(
-                                        pageRef, statusmodal, model.getObject(), GroupTO.class);
-                            }
-                        });
-
-                        statusmodal.show(target);
-                    }
-                }, ActionLink.ActionType.MANAGE_GROUPS, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        resourceTO.setUsyncToken(null);
-                        resourceTO.setRsyncToken(null);
-                        try {
-                            resourceRestClient.update(resourceTO);
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException e) {
-                            error(getString(Constants.ERROR) + ":" + e.getMessage());
-
-                            LOG.error("While resetting sync token from " + resourceTO.getKey(), e);
-                        }
-
-                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                        target.add(resourceContainer);
-                    }
-                }, ActionLink.ActionType.RESET, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        editResourceWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                return new ResourceModalPage(pageRef, editResourceWin, resourceTO, false);
-                            }
-                        });
-
-                        editResourceWin.show(target);
-                    }
-                }, ActionLink.ActionType.EDIT, "Resources");
-
-                panel.add(new ActionLink() {
-
-                    private static final long serialVersionUID = -3722207913631435501L;
-
-                    @Override
-                    public void onClick(final AjaxRequestTarget target) {
-                        try {
-                            resourceRestClient.delete(resourceTO.getKey());
-                            info(getString(Constants.OPERATION_SUCCEEDED));
-                        } catch (SyncopeClientException e) {
-                            error(getString(Constants.ERROR) + ": " + e.getMessage());
-
-                            LOG.error("While deleting resource " + resourceTO.getKey(), e);
-                        }
-
-                        ((BasePage) pageRef.getPage()).getFeedbackPanel().refresh(target);
-                        target.add(resourceContainer);
-                    }
-                }, ActionLink.ActionType.DELETE, "Resources");
-
-                cellItem.add(panel);
-            }
-        });
-
-        final AjaxDataTablePanel<ResourceTO, String> table = new AjaxDataTablePanel<>(
-                "resourceDatatable",
-                columns,
-                (ISortableDataProvider<ResourceTO, String>) new ResourcesProvider(),
-                resourcePaginatorRows,
-                Arrays.asList(new ActionLink.ActionType[] { ActionLink.ActionType.DELETE }),
-                resourceRestClient,
-                "key",
-                "Resources",
-                pageRef);
-
-        resourceContainer = new WebMarkupContainer("resourceContainer");
-        resourceContainer.add(table);
-        resourceContainer.setOutputMarkupId(true);
-
-        add(resourceContainer);
-
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(createResourceWin, resourceContainer);
-        ((BasePage) pageRef.getPage()).setWindowClosedCallback(editResourceWin, resourceContainer);
-
-        createResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        createResourceWin.setInitialHeight(WIN_HEIGHT);
-        createResourceWin.setInitialWidth(WIN_WIDTH);
-        createResourceWin.setCookieName("create-res-modal");
-
-        editResourceWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editResourceWin.setInitialHeight(WIN_HEIGHT);
-        editResourceWin.setInitialWidth(WIN_WIDTH);
-        editResourceWin.setCookieName("edit-res-modal");
-
-        editConnectorWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
-        editConnectorWin.setInitialHeight(WIN_HEIGHT);
-        editConnectorWin.setInitialWidth(WIN_WIDTH);
-        editConnectorWin.setCookieName("edit-conn-modal");
-
-        AjaxLink<Void> createResourceLink
-                = new ClearIndicatingAjaxLink<Void>("createResourceLink", pageRef) {
-
-                    private static final long serialVersionUID = -7978723352517770644L;
-
-                    @Override
-                    protected void onClickInternal(final AjaxRequestTarget target) {
-                        createResourceWin.setPageCreator(new ModalWindow.PageCreator() {
-
-                            private static final long serialVersionUID = -7834632442532690940L;
-
-                            @Override
-                            public Page createPage() {
-                                final ResourceModalPage windows = new ResourceModalPage(Resources.this.pageRef,
-                                        editResourceWin, new ResourceTO(), true);
-                                return windows;
-                            }
-                        });
-
-                        createResourceWin.show(target);
-                    }
-                };
-
-        MetaDataRoleAuthorizationStrategy.authorize(createResourceLink, ENABLE, Entitlement.RESOURCE_CREATE);
-
-        add(createResourceLink);
-
-        @SuppressWarnings("rawtypes")
-        final Form paginatorForm = new Form("resourcePaginatorForm");
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", new PropertyModel(this,
-                "resourcePaginatorRows"), prefMan.getPaginatorChoices());
-
-        rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
-
-            private static final long serialVersionUID = -1107858522700306810L;
-
-            @Override
-            protected void onUpdate(final AjaxRequestTarget target) {
-                prefMan.set(getRequest(), getResponse(), Constants.PREF_RESOURCES_PAGINATOR_ROWS,
-                        String.valueOf(resourcePaginatorRows));
-
-                table.setItemsPerPage(resourcePaginatorRows);
-                target.add(resourceContainer);
-            }
-        });
-
-        paginatorForm.add(rowsChooser);
-        add(paginatorForm);
-    }
-
-    class ResourcesProvider extends SortableDataProvider<ResourceTO, String> {
-
-        private static final long serialVersionUID = -9055916672926643975L;
-
-        private final SortableDataProviderComparator<ResourceTO> comparator;
-
-        public ResourcesProvider() {
-            super();
-            //Default sorting
-            setSort("key", SortOrder.ASCENDING);
-            comparator = new SortableDataProviderComparator<>(this);
-        }
-
-        @Override
-        public Iterator<ResourceTO> iterator(final long first, final long count) {
-            List<ResourceTO> list = resourceRestClient.getAll();
-
-            Collections.sort(list, comparator);
-
-            return list.subList((int) first, (int) first + (int) count).iterator();
-        }
-
-        @Override
-        public long size() {
-            return resourceRestClient.getAll().size();
-        }
-
-        @Override
-        public IModel<ResourceTO> model(final ResourceTO resource) {
-            return new AbstractReadOnlyModel<ResourceTO>() {
-
-                private static final long serialVersionUID = 8952474152465381634L;
-
-                @Override
-                public ResourceTO getObject() {
-                    return resource;
-                }
-            };
-        }
-    }
-
-    @Override
-    public void onEvent(final IEvent<?> event) {
-        if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) {
-            ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(resourceContainer);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index 5535c7b..3298d3f 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -28,11 +28,11 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.springframework.beans.BeanUtils;
@@ -196,8 +196,8 @@ public class ConnectorRestClient extends BaseRestClient {
         return schemaNames;
     }
 
-    public List<ConnIdObjectClassTO> getSupportedObjectClasses(final ConnInstanceTO connectorTO) {
-        List<ConnIdObjectClassTO> result = Collections.emptyList();
+    public List<ConnIdObjectClass> getSupportedObjectClasses(final ConnInstanceTO connectorTO) {
+        List<ConnIdObjectClass> result = Collections.emptyList();
         try {
             result = getService(ConnectorService.class).getSupportedObjectClasses(connectorTO.getKey(), connectorTO);
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 ef490e2..a146857 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
@@ -25,6 +25,7 @@ import org.apache.syncope.client.console.commons.status.StatusBean;
 import org.apache.syncope.client.console.commons.status.StatusUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnObjectTO;
@@ -119,31 +120,34 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return getService(GroupService.class).bulk(action);
     }
 
-    public void unlink(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public void unlink(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNLINK,
+            service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(GroupService.class);
         }
     }
 
-    public void link(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public void link(final String etag, final long groupKey, final List<StatusBean> statuses) {
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            service.bulkAssociation(groupId, ResourceAssociationActionType.LINK,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class));
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+            service.bulkAssociation(groupKey, ResourceAssociationActionType.LINK, associationMod);
+
             resetClient(GroupService.class);
         }
     }
 
-    public BulkActionResult deprovision(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult deprovision(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.DEPROVISION,
+            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -152,24 +156,27 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult provision(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult provision(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkAssociation(groupId, ResourceAssociationActionType.PROVISION,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class)).
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(GroupService.class);
         }
         return result;
     }
 
-    public BulkActionResult unassign(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult unassign(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkDeassociation(groupId, ResourceDeassociationActionType.UNASSIGN,
+            result = service.bulkDeassociation(groupKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -178,14 +185,18 @@ public class GroupRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult assign(final String etag, final long groupId, final List<StatusBean> statuses) {
+    public BulkActionResult assign(final String etag, final long groupKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             GroupService service = getService(etag, GroupService.class);
-            result = service.bulkAssociation(groupId, ResourceAssociationActionType.ASSIGN,
-                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class)).
+
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
+
+            result = service.bulkAssociation(groupKey, ResourceAssociationActionType.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
+
             resetClient(GroupService.class);
         }
         return result;

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 64daf50..bfe6385 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
@@ -122,22 +122,22 @@ public class UserRestClient extends AbstractAnyRestClient {
         return getService(ResourceService.class).readConnObject(resourceName, AnyTypeKind.USER.name(), id);
     }
 
-    public void suspend(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void suspend(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, false);
         statusMod.setType(StatusMod.ModType.SUSPEND);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userId, statusMod);
+            service.status(userKey, statusMod);
             resetClient(UserService.class);
         }
     }
 
-    public void reactivate(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void reactivate(final String etag, final long userKey, final List<StatusBean> statuses) {
         StatusMod statusMod = StatusUtils.buildStatusMod(statuses, true);
         statusMod.setType(StatusMod.ModType.REACTIVATE);
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.status(userId, statusMod);
+            service.status(userKey, statusMod);
             resetClient(UserService.class);
         }
     }
@@ -147,34 +147,34 @@ public class UserRestClient extends AbstractAnyRestClient {
         return getService(UserService.class).bulk(action);
     }
 
-    public void unlink(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void unlink(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            service.bulkDeassociation(userId, ResourceDeassociationActionType.UNLINK,
+            service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNLINK,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class));
             resetClient(UserService.class);
         }
     }
 
-    public void link(final String etag, final long userId, final List<StatusBean> statuses) {
+    public void link(final String etag, final long userKey, final List<StatusBean> statuses) {
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
             associationMod.getTargetResources().addAll(
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
-            service.bulkAssociation(userId, ResourceAssociationActionType.LINK, associationMod);
+            service.bulkAssociation(userKey, ResourceAssociationActionType.LINK, associationMod);
 
             resetClient(UserService.class);
         }
     }
 
-    public BulkActionResult deprovision(final String etag, final long userId, final List<StatusBean> statuses) {
+    public BulkActionResult deprovision(final String etag, final long userKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userId, ResourceDeassociationActionType.DEPROVISION,
+            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.DEPROVISION,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -183,32 +183,31 @@ public class UserRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult provision(final String etag, final long userId,
+    public BulkActionResult provision(final String etag, final long userKey,
             final List<StatusBean> statuses, final boolean changepwd, final String password) {
 
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
-                    getResourceNames(),
-                    ResourceKey.class));
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userId, ResourceAssociationActionType.PROVISION, associationMod).
+            result = service.bulkAssociation(userKey, ResourceAssociationActionType.PROVISION, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }
         return result;
     }
 
-    public BulkActionResult unassign(final String etag, final long userId, final List<StatusBean> statuses) {
+    public BulkActionResult unassign(final String etag, final long userKey, final List<StatusBean> statuses) {
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
-            result = service.bulkDeassociation(userId, ResourceDeassociationActionType.UNASSIGN,
+            result = service.bulkDeassociation(userKey, ResourceDeassociationActionType.UNASSIGN,
                     CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
                             ResourceKey.class)).
                     readEntity(BulkActionResult.class);
@@ -217,21 +216,20 @@ public class UserRestClient extends AbstractAnyRestClient {
         return result;
     }
 
-    public BulkActionResult assign(final String etag, final long userId,
+    public BulkActionResult assign(final String etag, final long userKey,
             final List<StatusBean> statuses, final boolean changepwd, final String password) {
 
         BulkActionResult result;
         synchronized (this) {
             UserService service = getService(etag, UserService.class);
 
-            final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
-                    getResourceNames(),
-                    ResourceKey.class));
+            ResourceAssociationMod associationMod = new ResourceAssociationMod();
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
-            result = service.bulkAssociation(userId, ResourceAssociationActionType.ASSIGN, associationMod).
+            result = service.bulkAssociation(userKey, ResourceAssociationActionType.ASSIGN, associationMod).
                     readEntity(BulkActionResult.class);
             resetClient(UserService.class);
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
index 013fa3a..8f6cc5c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/extensions/markup/html/repeater/data/table/ActionResultColumn.java
@@ -37,19 +37,16 @@ public class ActionResultColumn<T, S> extends AbstractColumn<T, S> {
 
     private static final long serialVersionUID = 7955560320949560716L;
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(ActionResultColumn.class);
 
     private final BulkActionResult results;
 
-    private final String idFieldName;
+    private final String keyFieldName;
 
-    public ActionResultColumn(final BulkActionResult results, final String idFieldName) {
+    public ActionResultColumn(final BulkActionResult results, final String keyFieldName) {
         super(new Model<String>());
         this.results = results;
-        this.idFieldName = idFieldName;
+        this.keyFieldName = keyFieldName;
     }
 
     @Override
@@ -65,10 +62,10 @@ public class ActionResultColumn<T, S> extends AbstractColumn<T, S> {
     @Override
     public void populateItem(final Item<ICellPopulator<T>> item, final String componentId, final IModel<T> rowModel) {
         try {
-            final PropertyDescriptor propDesc = BeanUtils.getPropertyDescriptor(rowModel.getObject().getClass(),
-                    idFieldName);
-            final Object id = propDesc.getReadMethod().invoke(rowModel.getObject(), new Object[0]);
-            final Status status = id == null ? null : results.getResultMap().get(id.toString());
+            PropertyDescriptor propDesc =
+                    BeanUtils.getPropertyDescriptor(rowModel.getObject().getClass(), keyFieldName);
+            Object id = propDesc.getReadMethod().invoke(rowModel.getObject(), new Object[0]);
+            Status status = id == null ? null : results.getResults().get(id.toString());
             item.add(new Label(componentId, status == null ? Status.SUCCESS : status.toString()));
         } catch (Exception e) {
             LOG.error("Errore retrieving target id value", e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
index 8a8eb3f..789919b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage.properties
@@ -28,7 +28,7 @@ extAttrNames=External attributes
 intMappingTypes=Internal mapping types
 entity=Entity
 groupSchema=Group Schema
-accountId=AccountId
+connObjectKey=ConnObjectKey
 mandatoryCondition=Mandatory
 password=Password
 purpose=Purpose
@@ -39,9 +39,9 @@ intAttrNames=Internal attributes
 enforceMandatoryCondition=Enforce mandatory condition
 fieldName=Field name
 
-accountIdValidation=There must be exactly one AccountId
+connObjectKeyValidation=There must be exactly one ConnObjectKey
 propagationMode=Propagation mode
-accountLink=Account link
+connObjectLink=ConnObjectLink
 enable=Enable
 
 createTraceLevel=Create trace level

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
index b98b3ae..54179a5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_it.properties
@@ -28,7 +28,7 @@ extAttrNames=Attributi esterni
 intMappingTypes=Tipo mapping interno
 entity=Entit&agrave;
 groupSchema=Schema Gruppo
-accountId=AccountId
+connObjectKey=ConnObjectKey
 mandatoryCondition=Obbligatorio
 password=Password
 purpose=Scopo
@@ -39,9 +39,9 @@ intAttrNames=Attributi interni
 enforceMandatoryCondition=Abilita mandatory condition
 fieldName=Nome campo
 
-accountIdValidation=Deve essere definito esattamente un AccountId
+connObjectKeyValidation=Deve essere definito esattamente un ConnObjectKey
 propagationMode=Modalit\u00e0 di propagazione
-accountLink=Account link
+connObjectLink=ConnObjectLink
 enable=Abilita
 
 createTraceLevel=Livello di tracciamento delle creazioni

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
index a91df81..45c3616 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/ResourceModalPage_pt_BR.properties
@@ -28,7 +28,7 @@ extAttrNames=Atributos Externos
 intMappingTypes=Tipos internos de mapeamentos
 entity=Entidade
 groupSchema=Esquema de Grupo
-accountId=Identificador da Conta
+connObjectKey=ConnObjectKey
 mandatoryCondition=Obrigat\u00f3rio
 password=Senha
 purpose=Prop\u00f3sito
@@ -39,9 +39,9 @@ intAttrNames=Atributos internos
 enforceMandatoryCondition=Aplicar condi\u00e7\u00e3o obrigat\u00f3ria
 fieldName=Nome do Campo
 
-accountIdValidation=Precisa ser exatamente um Identificador de Conta
+connObjectKeyValidation=Precisa ser exatamente um ConnObjectKey
 propagationMode=Modo de propaga\u00e7\u00e3o
-accountLink=Link de Conta
+connObjectLink=ConnObjectLink
 enable=Habilitado
 
 createTraceLevel=Criar n\u00edvel de trace

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
index 0e145bb..fe6c4ef 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ResourceMappingPanel.html
@@ -43,7 +43,7 @@ under the License.
                 </span>
               </a>
             </th>
-            <th><wicket:message key="accountId"/></th>
+            <th><wicket:message key="connObjectKey"/></th>
             <th><label wicket:id="passwordLabel"/></th>
             <th><wicket:message key="purpose"/></th>
           </tr>
@@ -67,7 +67,7 @@ under the License.
               <span wicket:id="mandatoryCondition">[mandatoryCondition]</span>
             </td>
             <td>
-              <span wicket:id="accountId">[accountId]</span>
+              <span wicket:id="connObjectKey">[connObjectKey]</span>
             </td>
             <td>
               <span wicket:id="password">[password]</span>
@@ -90,21 +90,21 @@ under the License.
         </tfoot>
       </table>
 
-      <table id="accountLinkTable"
+      <table id="connObjectLinkTable"
              class="table"
              style="font-size: 1em;margin-top:2px;"
-             wicket:id="accountLinkContainer">
+             wicket:id="connObjectLinkContainer">
         <tbody>
           <tr>
             <th width="10%" align="left"><wicket:message key="enable"/></th>
-            <th align="left"><wicket:message key="accountLink"/></th>
+            <th align="left"><wicket:message key="connObjectLink"/></th>
           </tr>
           <tr>
             <td width="10%">
-              <span wicket:id="accountLinkCheckbox">[accountLinkCheckbox]</span>
+              <span wicket:id="connObjectLinkCheckbox">[connObjectLinkCheckbox]</span>
             </td>
             <td>
-              <span wicket:id="accountLink">[accountLink]</span>
+              <span wicket:id="connObjectLink">[connObjectLink]</span>
             </td>
           </tr>
         </tbody>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
deleted file mode 100644
index 3d02b33..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.html
+++ /dev/null
@@ -1,52 +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.
--->
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://xmlns.jcp.org/jsf/composite">
-  <body>
-    <wicket:panel>
-
-      <div>
-        <div id="users-contain" class="ui-widget" style="width:inherit">
-          <span wicket:id="resourceContainer">
-            <span wicket:id="resourceDatatable">[resources]</span>
-          </span>
-
-          <span style="float:right">
-            <form wicket:id="resourcePaginatorForm" style="display:inline">
-              <label><wicket:message key="displayRows"/></label>
-              <select class="text ui-widget-content ui-corner-all" wicket:id="rowsChooser"/>
-            </form>
-          </span>
-        </div>
-
-        <div wicket:id="statusModal">[Show modal window for provisioning status]</div>
-        <div wicket:id="createResourceWin">[Show modal window for creating resource]</div>
-        <div wicket:id="editResourceWin">[Show modal window for editing resource]</div>
-        <div wicket:id="editConnectorWin">[Show modal window for editing connector]</div>
-
-        <a class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="createResourceLink">
-          <wicket:message key="create-resource"/>
-        </a>
-      </div>
-
-    </wicket:panel>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
deleted file mode 100644
index fb6b8a1..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources.properties
+++ /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.
-tab1=Resources
-edit=Edit
-delete=Delete
-create-resource=Create
-propagationPriority=Propagation priority
-propagationPrimary=Propagation primary
-
-tab2=Connectors
-displayName=Display name
-version=Version
-bundleName=Bundle name
-edit=Edit
-delete=Delete
-create-connector=Create
-delete_error=Operation forbidden:the connector you're trying to delete is connected to a Resource
-connector=Connector
-reloadConnectors=Reload connectors
-confirmReloadConnectors=This request is potentially dangerous for running operations, continue?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
deleted file mode 100644
index 80a5185..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_it.properties
+++ /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.
-tab1=Risorse
-edit=Modifica
-delete=Rimuovi
-create-resource=Crea
-propagationPriority=Priorit\u00e0 in propagazione
-propagationPrimary=Primaria in propagazione
-
-tab2=Connettori
-create-connector=Crea
-version=Versione
-bundleName=Bundle name
-edit=Modifica
-delete=Elimina
-delete_error=Operazione vietata: il connettore che si desidera rimuovere \u00e8 correlato ad una risorsa
-displayName=Nome visualizzato
-connector=Connettore
-reloadConnectors=Ricarica connettori
-confirmReloadConnectors=Questa richiesta \u00e8 potenzialmente dannosa per le operazioni in corso, proseguire?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
deleted file mode 100644
index a631352..0000000
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/Resources_pt_BR.properties
+++ /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.
-tab1=Recursos
-edit=Alterar
-delete=Excluir
-create-resource=Criar
-propagationPriority=Prioridade de propaga\u00e7\u00e3o
-propagationPrimary=Propaga\u00e7\u00e3o prim\u00e1ria
-
-tab2=Conectores
-displayName=Mostar
-version=Vers\u00e3o
-bundleName=Nome do Pacote
-create-connector=Criar
-delete_error=Opera\u00e7\u00e3o n\u00e3o permitida\: o conector que voc\u00ea est\u00e1 tentando excluir est\u00e1 conectado a um recurso
-connector=Conector
-reloadConnectors=Carregar Conector
-confirmReloadConnectors=Esta requis\u00e7\u00e3o \u00e9 potencialmente perigosa para opera\u00e7\u00f5es em execu\u00e7\u00e3o, prosseguir?

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 c981739..b744dc1 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
@@ -33,6 +33,7 @@ import org.apache.cxf.jaxrs.client.WebClient;
 import org.apache.syncope.client.lib.builders.ListQueryBuilder;
 import org.apache.syncope.client.lib.builders.AnyListQueryBuilder;
 import org.apache.syncope.client.lib.builders.AnySearchQueryBuilder;
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.OrderByClauseBuilder;
 import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
 import org.apache.syncope.common.lib.search.UserFiqlSearchConditionBuilder;
@@ -89,6 +90,15 @@ public class SyncopeClient {
     }
 
     /**
+     * Returns a new instance of {@link AnyObjectFiqlSearchConditionBuilder}, for assisted building of FIQL queries.
+     *
+     * @return default instance of {@link AnyObjectFiqlSearchConditionBuilder}
+     */
+    public static AnyObjectFiqlSearchConditionBuilder getAnyObjectSearchConditionBuilder() {
+        return new AnyObjectFiqlSearchConditionBuilder();
+    }
+
+    /**
      * Returns a new instance of {@link OrderByClauseBuilder}, for assisted building of {@link orderby} clauses.
      *
      * @return default instance of {@link OrderByClauseBuilder}
@@ -119,8 +129,7 @@ public class SyncopeClient {
 
     /**
      * Returns a new instance of {@link AnySearchQueryBuilder}, for assisted building of some service's
-     * {@code search()}
-     * arguments.
+     * {@code search()} arguments.
      *
      * @return default instance of {@link AnySearchQueryBuilder}
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index 62e4bbe..afd29e9 100644
--- 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
@@ -45,6 +45,7 @@ public class AnyListQueryBuilder extends ListQueryBuilder {
         if (instance.getRealms() == null) {
             instance.setRealms(new ArrayList<String>());
         }
+        instance.getRealms().add(realm);
 
         return this;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index e5fcb85..f84e65a 100644
--- 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
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.mod;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.HashSet;
 import java.util.Set;
@@ -144,6 +145,7 @@ public abstract class AnyMod extends AbstractBaseBean {
     /**
      * @return true is all backing collections are empty.
      */
+    @JsonIgnore
     public boolean isEmpty() {
         return plainAttrsToUpdate.isEmpty() && plainAttrsToRemove.isEmpty()
                 && derAttrsToAdd.isEmpty() && derAttrsToRemove.isEmpty()

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
index 9279e72..0ace0b5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AbstractFiqlSearchConditionBuilder.java
@@ -49,6 +49,7 @@ public abstract class AbstractFiqlSearchConditionBuilder extends FiqlSearchCondi
         return new Builder(properties);
     }
 
+    @Override
     public SyncopeProperty is(final String property) {
         return newBuilderInstance().is(property);
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.java
new file mode 100644
index 0000000..67e7e15
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectFiqlSearchConditionBuilder.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.search;
+
+import java.util.Map;
+import org.apache.cxf.jaxrs.ext.search.client.CompleteCondition;
+
+/**
+ * Extends {@link AbstractFiqlSearchConditionBuilder} by providing some additional facilities for searching
+ * any objects in Syncope.
+ */
+public class AnyObjectFiqlSearchConditionBuilder extends AbstractFiqlSearchConditionBuilder {
+
+    public AnyObjectFiqlSearchConditionBuilder() {
+        super();
+    }
+
+    public AnyObjectFiqlSearchConditionBuilder(final Map<String, String> properties) {
+        super(properties);
+    }
+
+    @Override
+    protected Builder newBuilderInstance() {
+        return new Builder(properties);
+    }
+
+    @Override
+    public AnyObjectProperty is(final String property) {
+        return newBuilderInstance().is(property);
+    }
+
+    public CompleteCondition type(final String type) {
+        return newBuilderInstance().is(SpecialAttr.TYPE.toString()).equalTo(type);
+    }
+
+    protected static class Builder extends AbstractFiqlSearchConditionBuilder.Builder
+            implements AnyObjectProperty, CompleteCondition {
+
+        public Builder(final Map<String, String> properties) {
+            super(properties);
+        }
+
+        public Builder(final Builder parent) {
+            super(parent);
+        }
+
+        @Override
+        public AnyObjectProperty is(final String property) {
+            Builder b = new Builder(this);
+            b.result = property;
+            return b;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.java
new file mode 100644
index 0000000..c675712
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/AnyObjectProperty.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.common.lib.search;
+
+public interface AnyObjectProperty extends SyncopeProperty {
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
index 9877267..551a0ad 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/search/SpecialAttr.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections4.Predicate;
 public enum SpecialAttr {
 
     NULL("$null"),
+    TYPE("$type"),
     RESOURCES("$resources"),
     GROUPS("$groups"),
     ROLES("$roles");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
deleted file mode 100644
index c562b69..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnIdObjectClassTO.java
+++ /dev/null
@@ -1,74 +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 javax.xml.bind.annotation.XmlEnum;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-/**
- * Mimic ConnId's ObjectClass information.
- */
-@XmlRootElement(name = "connIdObjectClass")
-@XmlType
-public class ConnIdObjectClassTO extends AbstractBaseBean {
-
-    private static final long serialVersionUID = 5802458031138859994L;
-
-    @XmlEnum
-    public enum DefaultType {
-
-        ACCOUNT("__ACCOUNT__"),
-        GROUP("__GROUP__");
-
-        private final String specialName;
-
-        private DefaultType(final String specialName) {
-            this.specialName = specialName;
-        }
-
-        public String getSpecialName() {
-            return specialName;
-        }
-    }
-
-    public static final ConnIdObjectClassTO ACCOUNT = new ConnIdObjectClassTO(DefaultType.ACCOUNT.getSpecialName());
-
-    public static final ConnIdObjectClassTO GROUP = new ConnIdObjectClassTO(DefaultType.GROUP.getSpecialName());
-
-    private String type;
-
-    public ConnIdObjectClassTO() {
-        super();
-    }
-
-    public ConnIdObjectClassTO(final String type) {
-        super();
-        this.type = type;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(final String type) {
-        this.type = type;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 92be8e1..c573278 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
@@ -61,7 +61,7 @@ public class MappingTO extends AbstractBaseBean {
     protected boolean addConnObjectKeyItem(final MappingItemTO connObjectItem) {
         if (IntMappingType.UserVirtualSchema == connObjectItem.getIntMappingType()
                 || IntMappingType.GroupVirtualSchema == connObjectItem.getIntMappingType()
-                || IntMappingType.AnyVirtualSchema == connObjectItem.getIntMappingType()
+                || IntMappingType.AnyObjectVirtualSchema == connObjectItem.getIntMappingType()
                 || IntMappingType.Password == connObjectItem.getIntMappingType()) {
 
             throw new IllegalArgumentException("Virtual attributes cannot be set as connObjectKey");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 3537bc5..4588a36 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
@@ -53,10 +53,10 @@ public enum IntMappingType {
     // -------------------------
     // Any attribute types (the same in AnyMappingType)
     // -------------------------
-    AnyPlainSchema(AnyTypeKind.ANY_OBJECT),
-    AnyDerivedSchema(AnyTypeKind.ANY_OBJECT),
-    AnyVirtualSchema(AnyTypeKind.ANY_OBJECT),
-    AnyKey(AnyTypeKind.ANY_OBJECT);
+    AnyObjectPlainSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectDerivedSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectVirtualSchema(AnyTypeKind.ANY_OBJECT),
+    AnyObjectKey(AnyTypeKind.ANY_OBJECT);
 
     private final AnyTypeKind anyTypeKind;
 
@@ -119,7 +119,7 @@ public enum IntMappingType {
     public static Set<IntMappingType> getEmbedded() {
         return EnumSet.of(IntMappingType.UserKey, IntMappingType.Username, IntMappingType.Password,
                 IntMappingType.GroupKey, IntMappingType.GroupName, IntMappingType.GroupOwnerSchema,
-                IntMappingType.AnyKey);
+                IntMappingType.AnyObjectKey);
     }
 
     /**
@@ -192,10 +192,10 @@ public enum IntMappingType {
      */
     private enum AnyMappingType {
 
-        AnyPlainSchema,
-        AnyDerivedSchema,
-        AnyVirtualSchema,
-        AnyKey;
+        AnyObjectPlainSchema,
+        AnyObjectDerivedSchema,
+        AnyObjectVirtualSchema,
+        AnyObjectKey;
 
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.java
new file mode 100644
index 0000000..868b3f1
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/wrap/ConnIdObjectClass.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.wrap;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "connIdObjectClass")
+@XmlType
+public class ConnIdObjectClass extends AbstractWrappable<String> {
+
+    private static final long serialVersionUID = 613925852330408531L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.java
new file mode 100644
index 0000000..b460b54
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyObjectService.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.common.rest.api.service;
+
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.MatrixParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+
+/**
+ * REST operations for anyObjects.
+ */
+@Path("anyObjects")
+public interface AnyObjectService extends AnyService<AnyObjectTO, AnyObjectMod> {
+
+    /**
+     * Returns a paged list of existing any objects matching the given query, for the given type.
+     *
+     * @param type any type
+     * @param listQuery query conditions
+     * @return paged list of existing any objects matching the given query, for the given type
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<AnyObjectTO> list(@MatrixParam("type") String type, @BeanParam AnyListQuery listQuery);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
new file mode 100644
index 0000000..90fbf7d
--- /dev/null
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/AnyService.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.service;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.BeanParam;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+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.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.mod.AnyMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+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.PagedResult;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.beans.AnyListQuery;
+import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
+
+public interface AnyService<TO extends AnyTO, MOD extends AnyMod> extends JAXRSService {
+
+    /**
+     * Reads the any object matching the provided key.
+     *
+     * @param key key of any object to be read
+     * @return any object with matching id
+     */
+    @GET
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    TO read(@NotNull @PathParam("key") Long key);
+
+    /**
+     * Returns a paged list of existing any objects matching the given query.
+     *
+     * @param listQuery query conditions
+     * @return paged list of existing any objects matching the given query
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<TO> list(@BeanParam AnyListQuery listQuery);
+
+    /**
+     * Returns a paged list of any objects matching the given query.
+     *
+     * @param searchQuery query conditions
+     * @return paged list of any objects matching the given query
+     */
+    @GET
+    @Path("search")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    PagedResult<TO> search(@BeanParam AnySearchQuery searchQuery);
+
+    /**
+     * Creates a new any object.
+     *
+     * @param anyTO any object to be created
+     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created any object as well as the any
+     * object itself enriched with propagation status information - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>Location</tt> header of created any object as well as the "
+                + "any object itself enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response create(@NotNull TO anyTO);
+
+    /**
+     * Updates any object matching the provided key.
+     *
+     * @param key key of any object to be updated
+     * @param anyMod modification to be applied to any object matching the provided key
+     * @return <tt>Response</tt> object featuring the updated any object enriched with propagation status information
+     * - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring the updated any object enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response update(@NotNull @PathParam("key") Long key, @NotNull MOD anyMod);
+
+    /**
+     * Deletes any object matching provided key.
+     *
+     * @param key key of any object to be deleted
+     * @return <tt>Response</tt> object featuring the deleted any object enriched with propagation status information
+     * - {@link AnyTO} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring the deleted any object enriched with propagation status information - "
+                + "<tt>AnyTO</tt> as <tt>Entity</tt>")
+    })
+    @DELETE
+    @Path("{key}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response delete(@NotNull @PathParam("key") Long key);
+
+    /**
+     * Executes resource-related operations on given any object.
+     *
+     * @param key any object id.
+     * @param type resource association action type
+     * @param resourceNames external resources to be used for propagation-related operations
+     * @return <tt>Response</tt> object featuring
+     * {@link BulkActionResult} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}/deassociate/{type}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response bulkDeassociation(
+            @NotNull @PathParam("key") Long key,
+            @NotNull @PathParam("type") ResourceDeassociationActionType type,
+            @NotNull List<ResourceKey> resourceNames);
+
+    /**
+     * Executes resource-related operations on given any object.
+     *
+     * @param key any object id.
+     * @param type resource association action type
+     * @param associationMod external resources to be used for propagation-related operations
+     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
+     */
+    @Descriptions({
+        @Description(target = DocTarget.RESPONSE,
+                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
+    })
+    @POST
+    @Path("{key}/associate/{type}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    Response bulkAssociation(
+            @NotNull @PathParam("key") Long key,
+            @NotNull @PathParam("type") ResourceAssociationActionType type,
+            @NotNull ResourceAssociationMod associationMod);
+
+    /**
+     * Executes the provided bulk action.
+     *
+     * @param bulkAction list of any object ids against which the bulk action will be performed.
+     * @return Bulk action result
+     */
+    @POST
+    @Path("bulk")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    BulkActionResult bulk(@NotNull BulkAction bulkAction);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
----------------------------------------------------------------------
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
index 07fc6a4..e0c240f 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ConnectorService.java
@@ -38,11 +38,11 @@ import org.apache.cxf.jaxrs.model.wadl.DocTarget;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
 import org.apache.syncope.common.lib.to.ConnBundleTO;
-import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.lib.wrap.BooleanWrap;
+import org.apache.syncope.common.lib.wrap.ConnIdObjectClass;
 
 /**
  * REST operations for connector bundles and instances.
@@ -100,7 +100,7 @@ public interface ConnectorService extends JAXRSService {
     @Path("{key}/supportedObjectClasses")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    List<ConnIdObjectClassTO> getSupportedObjectClasses(
+    List<ConnIdObjectClass> getSupportedObjectClasses(
             @NotNull @PathParam("key") Long key,
             @NotNull ConnInstanceTO connInstanceTO);
 


[65/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
new file mode 100644
index 0000000..d092f3d
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ResourceTest.java
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+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.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class ResourceTest extends AbstractTest {
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private ConnInstanceDAO connInstanceDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Test
+    public void createWithPasswordPolicy() {
+        final String resourceName = "resourceWithPasswordPolicy";
+
+        PasswordPolicy policy = (PasswordPolicy) policyDAO.find(4L);
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey(resourceName);
+        resource.setPasswordPolicy(policy);
+
+        ConnInstance connector = connInstanceDAO.find(100L);
+        assertNotNull("connector not found", connector);
+        resource.setConnector(connector);
+
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+
+        actual = resourceDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getPasswordPolicy());
+
+        resourceDAO.delete(resourceName);
+        assertNull(resourceDAO.find(resourceName));
+
+        assertNotNull(policyDAO.find(4L));
+    }
+
+    @Test
+    public void save() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("ws-target-resource-save");
+
+        // specify the connector
+        ConnInstance connector = connInstanceDAO.find(100L);
+        assertNotNull("connector not found", connector);
+
+        resource.setConnector(connector);
+
+        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++) {
+            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.add(item);
+            item.setMapping(mapping);
+        }
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("username");
+        connObjectKey.setIntMappingType(IntMappingType.UserKey);
+        connObjectKey.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.setConnObjectKeyItem(connObjectKey);
+        connObjectKey.setMapping(mapping);
+
+        // map a derived attribute
+        MappingItem derived = entityFactory.newEntity(MappingItem.class);
+        derived.setConnObjectKey(false);
+        derived.setExtAttrName("fullname");
+        derived.setIntAttrName("cn");
+        derived.setIntMappingType(IntMappingType.UserDerivedSchema);
+        derived.setPurpose(MappingPurpose.PROPAGATION);
+        mapping.add(derived);
+        derived.setMapping(mapping);
+
+        // save the resource
+        ExternalResource actual = resourceDAO.save(resource);
+        assertNotNull(actual);
+        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
+
+        resourceDAO.flush();
+        resourceDAO.detach(actual);
+        connInstanceDAO.detach(connector);
+
+        // assign the new resource to an user
+        User user = userDAO.find(1L);
+        assertNotNull("user not found", user);
+
+        user.add(actual);
+
+        resourceDAO.flush();
+
+        // retrieve resource
+        resource = resourceDAO.find(actual.getKey());
+        assertNotNull(resource);
+        resourceDAO.refresh(resource);
+
+        // check connector
+        connector = connInstanceDAO.find(100L);
+        assertNotNull(connector);
+        assertNotNull(connector.getResources());
+
+        assertNotNull(resource.getConnector());
+        assertTrue(resource.getConnector().equals(connector));
+
+        // check mappings
+        List<? extends MappingItem> items = resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems();
+        assertNotNull(items);
+        assertEquals(5, items.size());
+
+        // check user
+        user = userDAO.find(1L);
+        assertNotNull(user);
+        assertNotNull(user.getResources());
+        assertTrue(user.getResources().contains(actual));
+    }
+
+    @Test
+    public void delete() {
+        ExternalResource resource = resourceDAO.find("resource-testdb");
+        assertNotNull("find to delete did not work", resource);
+
+        // -------------------------------------
+        // Get originally associated connector
+        // -------------------------------------
+        ConnInstance connector = resource.getConnector();
+        assertNotNull(connector);
+        // -------------------------------------
+
+        // -------------------------------------
+        // Get originally associated users
+        // -------------------------------------
+        List<User> users = userDAO.findByResource(resource);
+        assertNotNull(users);
+
+        Set<Long> userIds = new HashSet<>();
+        for (User user : users) {
+            userIds.add(user.getKey());
+        }
+        // -------------------------------------
+
+        // Get tasks
+        List<PropagationTask> propagationTasks = taskDAO.findAll(resource, TaskType.PROPAGATION);
+        assertFalse(propagationTasks.isEmpty());
+
+        // delete resource
+        resourceDAO.delete(resource.getKey());
+
+        // close the transaction
+        resourceDAO.flush();
+
+        // resource must be removed
+        ExternalResource actual = resourceDAO.find("resource-testdb");
+        assertNull("delete did not work", actual);
+
+        // resource must be not referenced any more from users
+        for (Long id : userIds) {
+            User actualUser = userDAO.find(id);
+            assertNotNull(actualUser);
+            for (ExternalResource res : userDAO.findAllResources(actualUser)) {
+                assertFalse(res.getKey().equalsIgnoreCase(resource.getKey()));
+            }
+        }
+
+        // resource must be not referenced any more from the connector
+        ConnInstance actualConnector = connInstanceDAO.find(connector.getKey());
+        assertNotNull(actualConnector);
+        for (ExternalResource res : actualConnector.getResources()) {
+            assertFalse(res.getKey().equalsIgnoreCase(resource.getKey()));
+        }
+
+        // there must be no tasks
+        for (PropagationTask task : propagationTasks) {
+            assertNull(taskDAO.find(task.getKey()));
+        }
+    }
+
+    @Test
+    public void emptyMapping() {
+        ExternalResource ldap = resourceDAO.find("resource-ldap");
+        assertNotNull(ldap);
+        assertNotNull(ldap.getProvision(anyTypeDAO.findUser()).getMapping());
+        assertNotNull(ldap.getProvision(anyTypeDAO.findGroup()).getMapping());
+
+        List<? extends MappingItem> items = ldap.getProvision(anyTypeDAO.findGroup()).getMapping().getItems();
+        assertNotNull(items);
+        assertFalse(items.isEmpty());
+        List<Long> itemKeys = new ArrayList<>(items.size());
+        for (MappingItem item : items) {
+            itemKeys.add(item.getKey());
+        }
+
+        ldap.remove(ldap.getProvision(anyTypeDAO.findGroup()));
+
+        // need to avoid any class not defined in this Maven module
+        ldap.getPropagationActionsClassNames().clear();
+
+        resourceDAO.save(ldap);
+        resourceDAO.flush();
+
+        for (Long itemId : itemKeys) {
+            assertNull(entityManager.find(JPAMappingItem.class, itemId));
+        }
+    }
+
+    @Test
+    public void issue243() {
+        ExternalResource csv = resourceDAO.find("resource-csv");
+        assertNotNull(csv);
+
+        int origMapItems = csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size();
+
+        MappingItem newMapItem = entityFactory.newEntity(MappingItem.class);
+        newMapItem.setIntMappingType(IntMappingType.Username);
+        newMapItem.setExtAttrName("TEST");
+        newMapItem.setPurpose(MappingPurpose.PROPAGATION);
+        csv.getProvision(anyTypeDAO.findUser()).getMapping().add(newMapItem);
+
+        resourceDAO.save(csv);
+        resourceDAO.flush();
+
+        csv = resourceDAO.find("resource-csv");
+        assertNotNull(csv);
+        assertEquals(origMapItems + 1, csv.getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
new file mode 100644
index 0000000..11b572c
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RoleTest.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+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.AnyTypeKind;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+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.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.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+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;
+
+@Transactional
+public class RoleTest extends AbstractTest {
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    /**
+     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
+     * required for avoiding creating new transaction - good for general use case but bad for the way how
+     * this test class is architected.
+     */
+    private Collection<Role> findDynRoleMemberships(final User user) {
+        TypedQuery<Role> query = entityManager.createQuery(
+                "SELECT e.role FROM " + JPADynRoleMembership.class.getSimpleName()
+                + " e WHERE :user MEMBER OF e.users", Role.class);
+        query.setParameter("user", user);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void dynMembership() {
+        // 0. create user matching the condition below
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.add(anyTypeClassDAO.find("other"));
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        user = userDAO.save(user);
+        Long newUserKey = user.getKey();
+        assertNotNull(newUserKey);
+
+        // 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 actual = roleDAO.save(role);
+        assertNotNull(actual);
+
+        roleDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = roleDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getDynMembership());
+        assertNotNull(actual.getDynMembership().getKey());
+        assertEquals(actual, actual.getDynMembership().getRole());
+
+        // 3. verify that expected users have the created role dynamically assigned
+        assertEquals(2, actual.getDynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
+                CollectionUtils.collect(actual.getDynMembership().getMembers(), new Transformer<User, Long>() {
+
+                    @Override
+                    public Long transform(final User input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        user = userDAO.find(4L);
+        assertNotNull(user);
+        Collection<Role> dynRoleMemberships = findDynRoleMemberships(user);
+        assertEquals(1, dynRoleMemberships.size());
+        assertTrue(dynRoleMemberships.contains(actual.getDynMembership().getRole()));
+
+        // 4. delete the new user and verify that dynamic membership was updated
+        userDAO.delete(newUserKey);
+
+        userDAO.flush();
+
+        actual = roleDAO.find(actual.getKey());
+        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();
+
+        roleDAO.delete(actual);
+
+        roleDAO.flush();
+
+        assertNull(entityManager.find(JPADynRoleMembership.class, dynMembershipKey));
+
+        dynRoleMemberships = findDynRoleMemberships(user);
+        assertTrue(dynRoleMemberships.isEmpty());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/SecurityQuestionTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/SecurityQuestionTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/SecurityQuestionTest.java
new file mode 100644
index 0000000..0a966da
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/SecurityQuestionTest.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.outer;
+
+import static org.junit.Assert.assertNull;
+
+import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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 SecurityQuestionTest extends AbstractTest {
+
+    @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void test() {
+        User user = userDAO.find(4L);
+        assertNull(user.getSecurityQuestion());
+        assertNull(user.getSecurityAnswer());
+
+        user.setSecurityQuestion(securityQuestionDAO.find(1L));
+        user.setSecurityAnswer("Rossi");
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        securityQuestionDAO.delete(1L);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+
+        assertNull(user.getSecurityQuestion());
+        assertNull(user.getSecurityAnswer());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
new file mode 100644
index 0000000..f281fb4
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/TaskTest.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+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.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;
+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.core.persistence.api.attrvalue.validation.InvalidEntityException;
+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.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;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskTest extends AbstractTest {
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private TaskExecDAO taskExecDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void read() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        assertNotNull(task.getExecs());
+        assertFalse(task.getExecs().isEmpty());
+        assertEquals(1, task.getExecs().size());
+    }
+
+    @Test
+    public void save() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+
+        User user = userDAO.find(2L);
+        assertNotNull(user);
+
+        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
+        task.setResource(resource);
+        task.setAnyTypeKind(AnyTypeKind.USER);
+        task.setPropagationMode(PropagationMode.TWO_PHASES);
+        task.setPropagationOperation(ResourceOperation.CREATE);
+        task.setConnObjectKey("one@two.com");
+
+        Set<Attribute> attributes = new HashSet<>();
+        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
+        attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
+        task.setAttributes(attributes);
+
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        PropagationTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+
+        taskDAO.flush();
+
+        resource = resourceDAO.find("ws-target-resource-1");
+        assertTrue(taskDAO.findAll(resource, TaskType.PROPAGATION).contains(task));
+    }
+
+    @Test
+    public void addPropagationTaskExecution() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        int executionNumber = task.getExecs().size();
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setTask(task);
+        execution.setStatus(PropagationTaskExecStatus.CREATED.name());
+        task.addExec(execution);
+        execution.setStartDate(new Date());
+
+        taskDAO.save(task);
+        taskDAO.flush();
+
+        task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        assertEquals(executionNumber + 1, task.getExecs().size());
+    }
+
+    @Test
+    public void addSyncTaskExecution() {
+        SyncTask task = taskDAO.find(4L);
+        assertNotNull(task);
+
+        int executionNumber = task.getExecs().size();
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setStatus("Text-free status");
+        execution.setTask(task);
+        task.addExec(execution);
+        execution.setMessage("A message");
+
+        taskDAO.save(task);
+        taskDAO.flush();
+
+        task = taskDAO.find(4L);
+        assertNotNull(task);
+
+        assertEquals(executionNumber + 1, task.getExecs().size());
+    }
+
+    @Test
+    public void addPushTaskExecution() {
+        PushTask task = taskDAO.find(13L);
+        assertNotNull(task);
+
+        int executionNumber = task.getExecs().size();
+
+        TaskExec execution = entityFactory.newEntity(TaskExec.class);
+        execution.setStatus("Text-free status");
+        execution.setTask(task);
+        task.addExec(execution);
+        execution.setMessage("A message");
+
+        taskDAO.save(task);
+        taskDAO.flush();
+
+        task = taskDAO.find(13L);
+        assertNotNull(task);
+
+        assertEquals(executionNumber + 1, task.getExecs().size());
+    }
+
+    @Test
+    public void deleteTask() {
+        taskDAO.delete(1L);
+
+        taskDAO.flush();
+
+        assertNull(taskDAO.find(1L));
+        assertNull(taskExecDAO.find(1L));
+    }
+
+    @Test
+    public void deleteTaskExecution() {
+        TaskExec execution = taskExecDAO.find(1L);
+        int executionNumber = execution.getTask().getExecs().size();
+
+        taskExecDAO.delete(1L);
+
+        taskExecDAO.flush();
+
+        assertNull(taskExecDAO.find(1L));
+
+        PropagationTask task = taskDAO.find(1L);
+        assertEquals(task.getExecs().size(), executionNumber - 1);
+    }
+
+    @Test
+    public void saveSyncTask() {
+        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.add(template);
+        task.setCronExpression("BLA BLA");
+        task.setMatchingRule(MatchingRule.UPDATE);
+        task.setUnmatchingRule(UnmatchingRule.PROVISION);
+
+        // this save() fails because of an invalid Cron Expression
+        InvalidEntityException exception = null;
+        try {
+            taskDAO.save(task);
+        } catch (InvalidEntityException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        task.setCronExpression(null);
+        // this save() fails because a SyncTask requires a target resource
+        exception = null;
+        try {
+            taskDAO.save(task);
+        } catch (InvalidEntityException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        task.setResource(resource);
+        task.getActionsClassNames().add(getClass().getName());
+
+        // this save() fails because jobActionsClassName does not implement 
+        // the right interface
+        exception = null;
+        try {
+            taskDAO.save(task);
+        } catch (InvalidEntityException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        task.getActionsClassNames().clear();
+        task.getActionsClassNames().add(SyncActions.class.getName());
+        // this save() finally works
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        SyncTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+    }
+
+    @Test
+    public void issueSYNCOPE144() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+
+        SyncTask task = entityFactory.newEntity(SyncTask.class);
+
+        task.setResource(resource);
+        task.setName("issueSYNCOPE144");
+        task.setDescription("issueSYNCOPE144 Description");
+        task.getActionsClassNames().add(SyncActions.class.getName());
+        task.setMatchingRule(MatchingRule.UPDATE);
+        task.setUnmatchingRule(UnmatchingRule.PROVISION);
+
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        SyncTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+        assertEquals("issueSYNCOPE144", actual.getName());
+        assertEquals("issueSYNCOPE144 Description", actual.getDescription());
+
+        actual.setName("issueSYNCOPE144_2");
+        actual.setDescription("issueSYNCOPE144 Description_2");
+
+        actual = taskDAO.save(actual);
+        assertNotNull(actual);
+        assertEquals("issueSYNCOPE144_2", actual.getName());
+        assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.java
new file mode 100644
index 0000000..b921cdc
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/UserTest.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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+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.RelationshipTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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.URelationship;
+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 UserTest extends AbstractTest {
+
+    @Autowired
+    private RelationshipTypeDAO relationshipTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Test
+    public void delete() {
+        List<UMembership> memberships = groupDAO.findUMemberships(groupDAO.find(7L));
+        assertFalse(memberships.isEmpty());
+        List<URelationship> relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
+        assertFalse(relationships.isEmpty());
+
+        userDAO.delete(4L);
+
+        userDAO.flush();
+
+        assertNull(userDAO.find(4L));
+        assertNull(plainAttrDAO.find(550L, UPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(22L, UPlainAttrValue.class));
+        assertNotNull(plainSchemaDAO.find("loginDate"));
+
+        memberships = groupDAO.findUMemberships(groupDAO.find(7L));
+        assertTrue(memberships.isEmpty());
+        relationships = anyObjectDAO.findURelationships(anyObjectDAO.find(1L));
+        assertTrue(relationships.isEmpty());
+    }
+
+    @Test
+    public void ships() {
+        User user = userDAO.find(4L);
+        assertNotNull(user);
+        assertEquals(1, user.getMemberships().size());
+        assertEquals(7L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
+
+        user.remove(user.getMemberships().get(0));
+
+        UMembership newM = entityFactory.newEntity(UMembership.class);
+        newM.setLeftEnd(user);
+        newM.setRightEnd(groupDAO.find(13L));
+        user.add(newM);
+
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+        assertEquals(1, user.getMemberships().size());
+        assertEquals(13L, user.getMemberships().get(0).getRightEnd().getKey(), 0);
+        assertEquals(1, user.getRelationships().size());
+        assertEquals(1L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
+
+        user.remove(user.getRelationships().get(0));
+
+        URelationship newR = entityFactory.newEntity(URelationship.class);
+        newR.setType(relationshipTypeDAO.find("neighborhood"));
+        newR.setLeftEnd(user);
+        newR.setRightEnd(anyObjectDAO.find(2L));
+        user.add(newR);
+
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+        assertEquals(1, user.getRelationships().size());
+        assertEquals(2L, user.getRelationships().get(0).getRightEnd().getKey(), 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index b038222..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnySearchTest.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.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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
deleted file mode 100644
index 4b5f2f5..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
+++ /dev/null
@@ -1,62 +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 org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-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 AnyTypeClassTest extends AbstractTest {
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void delete() {
-        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
-        assertNotNull(minimalUser);
-
-        PlainSchema surname = plainSchemaDAO.find("surname");
-        assertNotNull(surname);
-        assertTrue(minimalUser.getPlainSchemas().contains(surname));
-        int before = minimalUser.getPlainSchemas().size();
-
-        plainSchemaDAO.delete("surname");
-
-        anyTypeClassDAO.flush();
-
-        minimalUser = anyTypeClassDAO.find("minimal user");
-        assertNotNull(minimalUser);
-        assertEquals(before, minimalUser.getPlainSchemas().size() + 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
deleted file mode 100644
index 60ff041..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.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.core.persistence.jpa.relationship;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
-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 AnyTypeTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void delete() {
-        AnyType userType = anyTypeDAO.findUser();
-        assertNotNull(userType);
-
-        AnyTypeClass other = anyTypeClassDAO.find("other");
-        assertNotNull(other);
-        assertTrue(userType.getClasses().contains(other));
-        int before = userType.getClasses().size();
-
-        anyTypeClassDAO.delete("other");
-
-        anyTypeDAO.flush();
-
-        userType = anyTypeDAO.findUser();
-        assertNotNull(userType);
-        assertEquals(before, userType.getClasses().size() + 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 34aaef5..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/ConnInstanceTest.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.relationship;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.common.lib.types.ConnectorCapability;
-import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class ConnInstanceTest extends AbstractTest {
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private ConnInstanceDAO connInstanceDAO;
-
-    @Test
-    public void deleteCascade() {
-        ConnInstance connInstance = connInstanceDAO.find(103L);
-        assertNotNull(connInstance);
-
-        List<? extends ExternalResource> resources = connInstance.getResources();
-        assertNotNull(resources);
-        assertFalse(resources.isEmpty());
-
-        connInstanceDAO.delete(connInstance.getKey());
-
-        connInstanceDAO.flush();
-
-        ConnInstance actual = connInstanceDAO.find(103L);
-        assertNull(actual);
-
-        for (ExternalResource resource : resources) {
-            assertNull(resourceDAO.find(resource.getKey()));
-        }
-    }
-
-    /**
-     * Connector change used to miss connector bean registration.
-     *
-     * http://code.google.com/p/syncope/issues/detail?id=176
-     */
-    @Test
-    public void issue176() {
-        ConnInstance connInstance = connInstanceDAO.find(103L);
-        assertNotNull(connInstance);
-        assertTrue(connInstance.getCapabilities().isEmpty());
-
-        List<? extends ExternalResource> resources = connInstance.getResources();
-        assertNotNull(resources);
-        assertEquals(4, resources.size());
-        assertTrue(
-                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
-
-        connInstance.addCapability(ConnectorCapability.SEARCH);
-
-        connInstance = connInstanceDAO.save(connInstance);
-        assertNotNull(connInstance);
-        assertFalse(connInstance.getCapabilities().isEmpty());
-
-        resources = connInstance.getResources();
-        assertNotNull(resources);
-        assertEquals(4, resources.size());
-        assertTrue(
-                "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
-                || "ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 9448886..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/DerSchemaTest.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.jpa.relationship;
-
-import static org.junit.Assert.assertNull;
-
-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.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class DerSchemaTest extends AbstractTest {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Test
-    public void test() {
-        DerSchema schema = derSchemaDAO.find("cn");
-
-        derSchemaDAO.delete(schema.getKey());
-
-        derSchemaDAO.flush();
-
-        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/d8927ef4/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
deleted file mode 100644
index 50b4c56..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/GroupTest.java
+++ /dev/null
@@ -1,328 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-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.AnyTypeKind;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.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.RealmDAO;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
-import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-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.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.User;
-import org.apache.syncope.core.persistence.jpa.AbstractTest;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
-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;
-
-@Transactional
-public class GroupTest extends AbstractTest {
-
-    @Autowired
-    private EntityManager entityManager;
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private AnyObjectDAO anyObjectDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private PlainAttrValueDAO plainAttrValueDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveWithTwoOwners() {
-        Group root = groupDAO.find("root");
-        assertNotNull("did not find expected group", root);
-
-        User user = userDAO.find(1L);
-        assertNotNull("did not find expected user", user);
-
-        Group group = entityFactory.newEntity(Group.class);
-        group.setRealm(realmDAO.getRoot());
-        group.setName("error");
-        group.setUserOwner(user);
-        group.setGroupOwner(root);
-
-        groupDAO.save(group);
-    }
-
-    @Test
-    public void findByOwner() {
-        Group group = groupDAO.find(6L);
-        assertNotNull("did not find expected group", group);
-
-        User user = userDAO.find(5L);
-        assertNotNull("did not find expected user", user);
-
-        assertEquals(user, group.getUserOwner());
-
-        List<Group> ownedGroups = groupDAO.findOwnedByUser(user.getKey());
-        assertFalse(ownedGroups.isEmpty());
-        assertEquals(1, ownedGroups.size());
-        assertTrue(ownedGroups.contains(group));
-    }
-
-    @Test
-    public void delete() {
-        groupDAO.delete(2L);
-
-        groupDAO.flush();
-
-        assertNull(groupDAO.find(2L));
-        assertEquals(userDAO.findAllGroups(userDAO.find(2L)).size(), 2);
-        assertNull(plainAttrDAO.find(700L, GPlainAttr.class));
-        assertNull(plainAttrValueDAO.find(41L, GPlainAttrValue.class));
-        assertNotNull(plainSchemaDAO.find("icon"));
-    }
-
-    /**
-     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same signature:
-     * required for avoiding creating of a new transaction - good for general use case but bad for the way how
-     * this test class is architected.
-     */
-    private Collection<Group> findDynGroupMemberships(final User user) {
-        TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e.group FROM " + JPAUDynGroupMembership.class.getSimpleName()
-                + " e WHERE :user MEMBER OF e.users", Group.class);
-        query.setParameter("user", user);
-
-        return query.getResultList();
-    }
-
-    @Test
-    public void udynMembership() {
-        // 0. create user matching the condition below
-        User user = entityFactory.newEntity(User.class);
-        user.setUsername("username");
-        user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("other"));
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(plainSchemaDAO.find("cool"));
-        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        user = userDAO.save(user);
-        Long newUserKey = user.getKey();
-        assertNotNull(newUserKey);
-
-        // 1. create group with dynamic membership
-        Group group = entityFactory.newEntity(Group.class);
-        group.setRealm(realmDAO.getRoot());
-        group.setName("new");
-
-        UDynGroupMembership dynMembership = entityFactory.newEntity(UDynGroupMembership.class);
-        dynMembership.setFIQLCond("cool==true");
-        dynMembership.setGroup(group);
-
-        group.setUDynMembership(dynMembership);
-
-        Group actual = groupDAO.save(group);
-        assertNotNull(actual);
-
-        groupDAO.flush();
-
-        // 2. verify that dynamic membership is there
-        actual = groupDAO.find(actual.getKey());
-        assertNotNull(actual);
-        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.getUDynMembership().getMembers().size());
-        assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
-                CollectionUtils.collect(actual.getUDynMembership().getMembers(), new Transformer<User, Long>() {
-
-                    @Override
-                    public Long transform(final User input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
-
-        user = userDAO.find(4L);
-        assertNotNull(user);
-        Collection<Group> dynGroupMemberships = findDynGroupMemberships(user);
-        assertEquals(1, dynGroupMemberships.size());
-        assertTrue(dynGroupMemberships.contains(actual.getUDynMembership().getGroup()));
-
-        // 4. delete the new user and verify that dynamic membership was updated
-        userDAO.delete(newUserKey);
-
-        userDAO.flush();
-
-        actual = groupDAO.find(actual.getKey());
-        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.getUDynMembership().getKey();
-
-        groupDAO.delete(actual);
-
-        groupDAO.flush();
-
-        assertNull(entityManager.find(JPAUDynGroupMembership.class, dynMembershipKey));
-
-        dynGroupMemberships = findDynGroupMemberships(user);
-        assertTrue(dynGroupMemberships.isEmpty());
-    }
-
-    /**
-     * Static copy of {@link org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO} method with same signature:
-     * required for avoiding creating of a new transaction - good for general use case but bad for the way how
-     * this test class is architected.
-     */
-    private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
-        TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
-                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
-        query.setParameter("anyObject", anyObject);
-
-        return query.getResultList();
-    }
-
-    @Test
-    public void adynMembership() {
-        // 0. create any object matching the condition below
-        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
-        anyObject.setType(anyTypeDAO.find("PRINTER"));
-        anyObject.setRealm(realmDAO.find("/even/two"));
-
-        APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
-        attr.setOwner(anyObject);
-        attr.setSchema(plainSchemaDAO.find("model"));
-        attr.add("Canon MFC8030", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
-        anyObject.add(attr);
-
-        anyObject = anyObjectDAO.save(anyObject);
-        Long newAnyObjectKey = anyObject.getKey();
-        assertNotNull(newAnyObjectKey);
-
-        // 1. create group with dynamic membership
-        Group group = entityFactory.newEntity(Group.class);
-        group.setRealm(realmDAO.getRoot());
-        group.setName("new");
-
-        ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
-        dynMembership.setFIQLCond("model==Canon MFC8030");
-        dynMembership.setGroup(group);
-
-        group.setADynMembership(dynMembership);
-
-        Group actual = groupDAO.save(group);
-        assertNotNull(actual);
-
-        groupDAO.flush();
-
-        // 2. verify that dynamic membership is there
-        actual = groupDAO.find(actual.getKey());
-        assertNotNull(actual);
-        assertNotNull(actual.getADynMembership());
-        assertNotNull(actual.getADynMembership().getKey());
-        assertEquals(actual, actual.getADynMembership().getGroup());
-
-        // 3. verify that expected any objects have the created group dynamically assigned
-        assertEquals(2, actual.getADynMembership().getMembers().size());
-        assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
-                CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() {
-
-                    @Override
-                    public Long transform(final AnyObject input) {
-                        return input.getKey();
-                    }
-                }, new HashSet<Long>()));
-
-        anyObject = anyObjectDAO.find(1L);
-        assertNotNull(anyObject);
-        Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject);
-        assertEquals(1, dynGroupMemberships.size());
-        assertTrue(dynGroupMemberships.contains(actual.getADynMembership().getGroup()));
-
-        // 4. delete the new any object and verify that dynamic membership was updated
-        anyObjectDAO.delete(newAnyObjectKey);
-
-        anyObjectDAO.flush();
-
-        actual = groupDAO.find(actual.getKey());
-        assertEquals(1, actual.getADynMembership().getMembers().size());
-        assertEquals(1L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
-
-        // 5. delete group and verify that dynamic membership was also removed
-        Long dynMembershipKey = actual.getADynMembership().getKey();
-
-        groupDAO.delete(actual);
-
-        groupDAO.flush();
-
-        assertNull(entityManager.find(JPAADynGroupMembership.class, dynMembershipKey));
-
-        dynGroupMemberships = findDynGroupMemberships(anyObject);
-        assertTrue(dynGroupMemberships.isEmpty());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
deleted file mode 100644
index ae4220c..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainAttrTest.java
+++ /dev/null
@@ -1,179 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-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.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
-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.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.UserDAO;
-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.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.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 PlainAttrTest extends AbstractTest {
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private DerAttrDAO derAttrDAO;
-
-    @Autowired
-    private PlainAttrValueDAO plainAttrValueDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private AnyTypeClassDAO anyTypeClassDAO;
-
-    @Test
-    public void deleteAttribute() {
-        plainAttrDAO.delete(117L, UPlainAttr.class);
-
-        plainAttrDAO.flush();
-
-        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
-        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
-    }
-
-    @Test
-    public void deleteAttributeValue() {
-        UPlainAttrValue value = plainAttrValueDAO.find(14L, UPlainAttrValue.class);
-        int attributeValueNumber = value.getAttr().getValues().size();
-
-        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
-
-        plainAttrValueDAO.flush();
-
-        assertNull(plainAttrValueDAO.find(value.getKey(), UPlainAttrValue.class));
-
-        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
-    }
-
-    @Test
-    public void checkForEnumType() {
-        User user = userDAO.find(1L);
-        user.setPassword("password123", CipherAlgorithm.SHA);
-        assertNotNull(user);
-
-        AnyTypeClass other = anyTypeClassDAO.find("other");
-
-        PlainSchema color = entityFactory.newEntity(PlainSchema.class);
-        color.setType(AttrSchemaType.Enum);
-        color.setKey("color");
-        color.setEnumerationValues("red" + SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
-
-        color = plainSchemaDAO.save(color);
-
-        other.add(color);
-        color.setAnyTypeClass(other);
-
-        plainSchemaDAO.flush();
-
-        color = plainSchemaDAO.find("color");
-        assertNotNull("expected save to work", color);
-        assertEquals(other, color.getAnyTypeClass());
-
-        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
-        attr.setOwner(user);
-        attr.setSchema(color);
-        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
-        user.add(attr);
-
-        userDAO.save(user);
-        userDAO.flush();
-
-        user = userDAO.find(1L);
-        assertNotNull(user);
-        assertNotNull(user.getPlainAttr(color.getKey()));
-        assertNotNull(user.getPlainAttr(color.getKey()).getValues());
-        assertEquals(user.getPlainAttr(color.getKey()).getValues().size(), 1);
-    }
-
-    @Test
-    public void derAttrFromSpecialAttrs() {
-        AnyTypeClass other = anyTypeClassDAO.find("other");
-
-        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
-        sderived.setKey("sderived");
-        sderived.setExpression("username + ' - ' + creationDate + '[' + failedLogins + ']'");
-
-        sderived = derSchemaDAO.save(sderived);
-
-        derSchemaDAO.flush();
-
-        other.add(sderived);
-        sderived.setAnyTypeClass(other);
-
-        derSchemaDAO.flush();
-
-        sderived = derSchemaDAO.find("sderived");
-        assertNotNull("expected save to work", sderived);
-        assertEquals(other, sderived.getAnyTypeClass());
-
-        User owner = userDAO.find(3L);
-        assertNotNull("did not get expected user", owner);
-
-        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
-        derAttr.setOwner(owner);
-        derAttr.setSchema(sderived);
-
-        derAttr = derAttrDAO.save(derAttr);
-        derAttrDAO.flush();
-
-        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
-        assertNotNull("expected save to work", derAttr);
-
-        String value = derAttr.getValue(owner.getPlainAttrs());
-        assertNotNull(value);
-        assertFalse(value.isEmpty());
-        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
-        assertTrue(value.endsWith("[0]"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 7d363c2..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/PlainSchemaTest.java
+++ /dev/null
@@ -1,170 +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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
-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.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.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class PlainSchemaTest extends AbstractTest {
-
-    @Autowired
-    private AnyTypeDAO anyTypeDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Test
-    public void deleteFullname() {
-        // 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").
-                getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-
-            if ("fullname".equals(item.getIntAttrName())) {
-                item.setConnObjectKey(false);
-            } else if ("surname".equals(item.getIntAttrName())) {
-                item.setConnObjectKey(true);
-            }
-        }
-
-        // search for user schema fullname
-        PlainSchema schema = plainSchemaDAO.find("fullname");
-        assertNotNull(schema);
-
-        // check for associated mappings
-        Set<MappingItem> mapItems = new HashSet<>();
-        for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()) != null
-                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
-
-                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
-                        mapItems.add(mapItem);
-                    }
-                }
-            }
-        }
-        assertFalse(mapItems.isEmpty());
-
-        // delete user schema fullname
-        plainSchemaDAO.delete("fullname");
-
-        plainSchemaDAO.flush();
-
-        // check for schema deletion
-        schema = plainSchemaDAO.find("fullname");
-        assertNull(schema);
-
-        plainSchemaDAO.clear();
-
-        // check for mappings deletion
-        mapItems = new HashSet<>();
-        for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()) != null
-                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
-
-                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-                    if ("fullname".equals(mapItem.getIntAttrName())) {
-                        mapItems.add(mapItem);
-                    }
-                }
-            }
-        }
-        assertTrue(mapItems.isEmpty());
-
-        assertNull(plainAttrDAO.find(100L, UPlainAttr.class));
-        assertNull(plainAttrDAO.find(300L, UPlainAttr.class));
-        assertNull(userDAO.find(1L).getPlainAttr("fullname"));
-        assertNull(userDAO.find(3L).getPlainAttr("fullname"));
-    }
-
-    @Test
-    public void deleteSurname() {
-        // search for user schema fullname
-        PlainSchema schema = plainSchemaDAO.find("surname");
-        assertNotNull(schema);
-
-        // check for associated mappings
-        Set<MappingItem> mappings = new HashSet<>();
-        for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()) != null
-                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
-
-                for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
-                        mappings.add(mapItem);
-                    }
-                }
-            }
-        }
-        assertFalse(mappings.isEmpty());
-
-        // delete user schema fullname
-        plainSchemaDAO.delete("surname");
-
-        plainSchemaDAO.flush();
-
-        // check for schema deletion
-        schema = plainSchemaDAO.find("surname");
-        assertNull(schema);
-    }
-
-    @Test
-    public void deleteALong() {
-        assertEquals(6, resourceDAO.find("resource-db-sync").
-                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
-
-        plainSchemaDAO.delete("aLong");
-        assertNull(plainSchemaDAO.find("aLong"));
-
-        plainSchemaDAO.flush();
-
-        assertEquals(5, resourceDAO.find("resource-db-sync").
-                getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java
deleted file mode 100644
index e652e62..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/RealmTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.relationship;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-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.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Role;
-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 RealmTest extends AbstractTest {
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Test
-    public void test() {
-        Realm realm = realmDAO.find("/odd");
-        assertNotNull(realm);
-
-        Role role = roleDAO.find(1L);
-        assertTrue(role.getRealms().contains(realm));
-
-        int beforeSize = role.getRealms().size();
-
-        realmDAO.delete(realm);
-
-        realmDAO.flush();
-
-        role = roleDAO.find(1L);
-        assertEquals(beforeSize - 1, role.getRealms().size());
-    }
-}


[50/70] syncope git commit: [SYNCOPE-666] More cleanup + test for using realm in ConnObjectLink

Posted by il...@apache.org.
[SYNCOPE-666] More cleanup + test for using realm in ConnObjectLink


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

Branch: refs/heads/master
Commit: 54de3984790735467e69b46feb934d17f2fd2b42
Parents: a64ef15
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 09:04:50 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 09:04:50 2015 +0200

----------------------------------------------------------------------
 .../syncope/core/logic/ResourceLogic.java       |  8 +-
 .../apache/syncope/core/logic/AbstractTest.java | 41 +++++++++
 .../apache/syncope/core/logic/MappingTest.java  | 67 ++++++++++++++
 .../syncope/core/logic/NotificationTest.java    | 21 +----
 .../syncope/core/misc/ConnObjectUtils.java      |  2 +-
 .../apache/syncope/core/misc/MappingUtils.java  | 97 +++++++++++++++-----
 .../syncope/core/misc/jexl/JexlUtils.java       | 23 +++--
 .../core/persistence/api/entity/AnyUtils.java   | 10 --
 .../persistence/jpa/entity/JPAAnyUtils.java     | 83 -----------------
 .../core/provisioning/api/VirAttrHandler.java   |  6 +-
 .../provisioning/java/VirAttrHandlerImpl.java   | 24 ++---
 .../java/data/AbstractAnyDataBinder.java        | 10 +-
 .../AbstractPropagationTaskExecutor.java        |  8 +-
 .../propagation/PropagationManagerImpl.java     | 21 ++---
 .../core/provisioning/java/sync/SyncUtils.java  | 13 +--
 .../core/reference/AuthenticationITCase.java    | 12 ++-
 16 files changed, 247 insertions(+), 199 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 863af12..df09b5f 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
@@ -50,7 +50,6 @@ 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;
@@ -201,10 +200,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         if (any == null) {
             throw new NotFoundException(anyType + " " + key);
         }
-
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(anyType.getKind());
-
-        MappingItem connObjectKeyItem = attrUtils.getConnObjectKeyItem(provision);
+        MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
         if (connObjectKeyItem == null) {
             throw new NotFoundException(
                     "ConnObjectKey mapping for " + anyType + " " + key + " on resource '" + resourceKey + "'");
@@ -214,7 +210,7 @@ public class ResourceLogic extends AbstractTransactionalLogic<ResourceTO> {
         Connector connector = connFactory.getConnector(resource);
         ConnectorObject connectorObject = connector.getObject(
                 provision.getObjectClass(), new Uid(connObjectKeyValue),
-                connector.getOperationOptions(attrUtils.getMappingItems(provision, MappingPurpose.BOTH)));
+                connector.getOperationOptions(MappingUtils.getMappingItems(provision, MappingPurpose.BOTH)));
         if (connectorObject == null) {
             throw new NotFoundException("Object " + connObjectKeyValue + " with class " + provision.getObjectClass()
                     + " not found on resource " + resourceKey);

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
new file mode 100644
index 0000000..161d0c1
--- /dev/null
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.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.logic;
+
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+    "classpath:provisioningContext.xml",
+    "classpath:logicContext.xml",
+    "classpath:workflowContext.xml",
+    "classpath:persistenceTest.xml",
+    "classpath:logicTest.xml"
+})
+@Transactional
+public abstract class AbstractTest {
+
+    protected static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
new file mode 100644
index 0000000..1f1dab7
--- /dev/null
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.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.core.logic;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.syncope.core.misc.MappingUtils;
+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.UserDAO;
+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.identityconnectors.framework.common.objects.Name;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class MappingTest extends AbstractTest {
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void connObjectLink() {
+        ExternalResource ldap = resourceDAO.find("resource-ldap");
+        assertNotNull(ldap);
+
+        Provision provision = ldap.getProvision(anyTypeDAO.findUser());
+        assertNotNull(provision);
+        assertNotNull(provision.getMapping());
+        assertNotNull(provision.getMapping().getConnObjectLink());
+
+        User user = userDAO.find("rossini");
+        assertNotNull(user);
+
+        Name name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        assertEquals("uid=rossini,ou=people,o=isp", name.getNameValue());
+
+        provision.getMapping().setConnObjectLink("'uid=' + username + ',o=' + realm + ',ou=people,o=isp'");
+
+        name = MappingUtils.evaluateNAME(user, provision, user.getUsername());
+        assertEquals("uid=rossini,o=even,ou=people,o=isp", name.getNameValue());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 4401a6b..bc425dc 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
@@ -70,9 +70,6 @@ import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
@@ -82,22 +79,8 @@ import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {
-    "classpath:provisioningContext.xml",
-    "classpath:logicContext.xml",
-    "classpath:workflowContext.xml",
-    "classpath:persistenceTest.xml",
-    "classpath:logicTest.xml"
-})
-@Transactional
-public class NotificationTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NotificationTest.class);
+
+public class NotificationTest extends AbstractTest {
 
     private static final String SMTP_HOST = "localhost";
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 c86ee7c..807ea0f 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
@@ -199,7 +199,7 @@ public class ConnObjectUtils {
 
         // 1. fill with data from connector object
         anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
-        for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
+        for (MappingItem item : MappingUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
             Attribute attr = obj.getAttributeByName(item.getExtAttrName());
 
             AttrTO attrTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 97008d0..140c5ad 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
@@ -120,7 +120,6 @@ public final class MappingUtils {
     /**
      * Prepare attributes for sending to a connector instance.
      *
-     * @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
@@ -130,8 +129,8 @@ public final class MappingUtils {
      * @param provision provision information
      * @return connObjectLink + prepared attributes
      */
-    public static Pair<String, Set<Attribute>> prepareAttributes(
-            final AnyUtils anyUtils, final Any<?, ?, ?> any,
+    public static Pair<String, Set<Attribute>> prepareAttrs(
+            final Any<?, ?, ?> any,
             final String password,
             final boolean changePwd,
             final Set<String> vAttrsToBeRemoved,
@@ -149,7 +148,7 @@ public final class MappingUtils {
         Set<Attribute> attributes = new HashSet<>();
         String connObjectKey = null;
 
-        for (MappingItem mapping : anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+        for (MappingItem mapping : getMappingItems(provision, MappingPurpose.PROPAGATION)) {
             LOG.debug("Processing schema {}", mapping.getIntAttrName());
 
             try {
@@ -188,11 +187,10 @@ public final class MappingUtils {
         }
 
         Attribute connObjectKeyExtAttr =
-                AttributeUtil.find(anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), attributes);
+                AttributeUtil.find(getConnObjectKeyItem(provision).getExtAttrName(), attributes);
         if (connObjectKeyExtAttr != null) {
             attributes.remove(connObjectKeyExtAttr);
-            attributes.add(AttributeBuilder.build(
-                    anyUtils.getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
+            attributes.add(AttributeBuilder.build(getConnObjectKeyItem(provision).getExtAttrName(), connObjectKey));
         }
         attributes.add(evaluateNAME(any, provision, connObjectKey));
 
@@ -373,26 +371,23 @@ public final class MappingUtils {
      * @param connObjectKey connector object key
      * @return the value to be propagated as __NAME__
      */
-    public static Name evaluateNAME(final Any<?, ?, ?> any,
-            final Provision provision, final String connObjectKey) {
-
-        final AnyUtilsFactory anyUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
-        final AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
+    public static Name evaluateNAME(final Any<?, ?, ?> any, final Provision provision, final String connObjectKey) {
         if (StringUtils.isBlank(connObjectKey)) {
             // LOG error but avoid to throw exception: leave it to the external resource
             LOG.error("Missing ConnObjectKey for '{}': ", provision.getResource());
         }
 
         // Evaluate connObjectKey expression
+        String connObjectLink = provision == null || provision.getMapping() == null
+                ? null
+                : provision.getMapping().getConnObjectLink();
         String evalConnObjectLink = null;
-        if (StringUtils.isNotBlank(anyUtils.getConnObjectLink(provision))) {
-            final JexlContext jexlContext = new MapContext();
+        if (StringUtils.isNotBlank(connObjectLink)) {
+            JexlContext jexlContext = new MapContext();
             JexlUtils.addFieldsToContext(any, jexlContext);
             JexlUtils.addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
             JexlUtils.addDerAttrsToContext(any.getDerAttrs(), any.getPlainAttrs(), jexlContext);
-            evalConnObjectLink = JexlUtils.evaluate(anyUtils.getConnObjectLink(provision), jexlContext);
+            evalConnObjectLink = JexlUtils.evaluate(connObjectLink, jexlContext);
         }
 
         // If connObjectLink evaluates to an empty string, just use the provided connObjectKey as Name(),
@@ -414,11 +409,7 @@ public final class MappingUtils {
     }
 
     private static String getGroupOwnerValue(final Provision provision, final Any<?, ?, ?> any) {
-        AnyUtilsFactory anyUtilsFactory =
-                ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
-
-        Pair<String, Attribute> preparedAttr = prepareAttr(
-                provision, anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision),
+        Pair<String, Attribute> preparedAttr = prepareAttr(provision, getConnObjectKeyItem(provision),
                 any, null, null, Collections.<String>emptySet(), Collections.<String, AttrMod>emptyMap());
         String connObjectKey = preparedAttr.getKey();
 
@@ -611,6 +602,68 @@ public final class MappingUtils {
                 : values.get(0).getValueAsString();
     }
 
+    public static MappingItem getConnObjectKeyItem(final Provision provision) {
+        Mapping mapping = null;
+        if (provision != null) {
+            mapping = provision.getMapping();
+        }
+
+        return mapping == null
+                ? null
+                : mapping.getConnObjectKeyItem();
+    }
+
+    public static 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;
+    }
+
     /**
      * Private default constructor, for static-only classes.
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 9aad079..443bbae 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
@@ -22,7 +22,6 @@ import java.beans.IntrospectionException;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -106,24 +105,22 @@ public final class JexlUtils {
 
         try {
             for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
-                final Class<?> type = desc.getPropertyType();
-                final String fieldName = desc.getName();
+                Class<?> type = desc.getPropertyType();
+                String fieldName = desc.getName();
 
                 if ((!fieldName.startsWith("pc"))
                         && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
                         && (!Iterable.class.isAssignableFrom(type))
                         && (!type.isArray())) {
-                    try {
-                        final Method getter = desc.getReadMethod();
-
-                        final Object fieldValue;
 
-                        if (getter == null) {
+                    try {
+                        Object fieldValue;
+                        if (desc.getReadMethod() == null) {
                             final Field field = object.getClass().getDeclaredField(fieldName);
                             field.setAccessible(true);
                             fieldValue = field.get(object);
                         } else {
-                            fieldValue = getter.invoke(object);
+                            fieldValue = desc.getReadMethod().invoke(object);
                         }
 
                         context.set(fieldName, fieldValue == null
@@ -133,7 +130,6 @@ public final class JexlUtils {
                                         : fieldValue));
 
                         LOG.debug("Add field {} with value {}", fieldName, fieldValue);
-
                     } catch (Exception iae) {
                         LOG.error("Reading '{}' value error", fieldName, iae);
                     }
@@ -143,6 +139,13 @@ public final class JexlUtils {
             LOG.error("Reading class attributes error", ie);
         }
 
+        if (object instanceof Any) {
+            Any<?, ?, ?> any = (Any<?, ?, ?>) object;
+            if (any.getRealm() != null) {
+                context.set("realm", any.getRealm().getName());
+            }
+        }
+
         return context;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
index 836f0e3..8c64086 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
@@ -18,13 +18,9 @@
  */
 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 {
 
@@ -52,12 +48,6 @@ public interface AnyUtils {
 
     <T extends VirAttr<?>> T newVirAttr();
 
-    MappingItem getConnObjectKeyItem(Provision provision);
-
-    String getConnObjectLink(Provision provision);
-
-    List<MappingItem> getMappingItems(Provision provision, MappingPurpose purpose);
-
     IntMappingType plainIntMappingType();
 
     IntMappingType derIntMappingType();

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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
index 989c642..9d0f798 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -18,25 +18,18 @@
  */
 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;
@@ -319,82 +312,6 @@ public class JPAAnyUtils implements AnyUtils {
     }
 
     @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;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
index 4cec074..8916d27 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/VirAttrHandler.java
@@ -26,7 +26,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.PropagationByResource;
 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.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 
@@ -64,8 +63,7 @@ public interface VirAttrHandler {
     void retrieveVirAttrValues(Any<?, ?, ?> any);
 
     void updateOnResourcesIfMappingMatches(
-            Any<?, ?, ?> any, AnyUtils anyUtils, String schemaKey,
-            Iterable<? extends ExternalResource> resources, IntMappingType mappingType,
-            PropagationByResource propByRes);
+            Any<?, ?, ?> any, String schemaKey, Iterable<? extends ExternalResource> resources,
+            IntMappingType mappingType, PropagationByResource propByRes);
 
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
index 21626f5..888329c 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandlerImpl.java
@@ -117,12 +117,12 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
     }
 
     @Override
-    public void updateOnResourcesIfMappingMatches(final Any<?, ?, ?> any, final AnyUtils anyUtils,
-            final String schemaKey, final Iterable<? extends ExternalResource> resources,
-            final IntMappingType mappingType, final PropagationByResource propByRes) {
+    public void updateOnResourcesIfMappingMatches(final Any<?, ?, ?> any, final String schemaKey,
+            final Iterable<? extends ExternalResource> resources, final IntMappingType mappingType,
+            final PropagationByResource propByRes) {
 
         for (ExternalResource resource : resources) {
-            for (MappingItem mapItem : anyUtils.getMappingItems(
+            for (MappingItem mapItem : MappingUtils.getMappingItems(
                     resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
                 if (schemaKey.equals(mapItem.getIntAttrName()) && mapItem.getIntMappingType() == mappingType) {
@@ -166,7 +166,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
                 }
 
                 for (ExternalResource resource : externalResources) {
-                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                    for (MappingItem mapItem : MappingUtils.getMappingItems(
                             resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
                         if (virSchema.getKey().equals(mapItem.getIntAttrName())
@@ -199,8 +199,8 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
                     any.add(virAttr);
                 }
 
-                updateOnResourcesIfMappingMatches(any, anyUtils, virSchema.getKey(),
-                        externalResources, anyUtils.derIntMappingType(), propByRes);
+                updateOnResourcesIfMappingMatches(
+                        any, virSchema.getKey(), externalResources, anyUtils.derIntMappingType(), propByRes);
 
                 List<String> values = new ArrayList<>(virAttr.getValues());
                 values.removeAll(vAttrToBeUpdated.getValuesToBeRemoved());
@@ -322,19 +322,19 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
 
             AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
 
-            for (ExternalResource resource : getTargetResources(virAttr, type, anyUtils, any.getType())) {
+            for (ExternalResource resource : getTargetResources(virAttr, type, any.getType())) {
                 Provision provision = resource.getProvision(any.getType());
                 LOG.debug("Search values into {},{}", resource, provision);
 
                 try {
-                    List<MappingItem> mappings = anyUtils.getMappingItems(provision, MappingPurpose.BOTH);
+                    List<MappingItem> mappings = MappingUtils.getMappingItems(provision, MappingPurpose.BOTH);
 
                     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
+                        String connObjectKey = MappingUtils.getConnObjectKeyItem(provision) == null
                                 ? null
                                 : MappingUtils.getConnObjectKeyValue(any, provision);
 
@@ -395,7 +395,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
     }
 
     private Collection<ExternalResource> getTargetResources(
-            final VirAttr<?> attr, final IntMappingType type, final AnyUtils anyUtils, final AnyType anyType) {
+            final VirAttr<?> attr, final IntMappingType type, final AnyType anyType) {
 
         return CollectionUtils.select(getAllResources(attr.getOwner()), new Predicate<ExternalResource>() {
 
@@ -403,7 +403,7 @@ public class VirAttrHandlerImpl implements VirAttrHandler {
             public boolean evaluate(final ExternalResource resource) {
                 return resource.getProvision(anyType) != null
                         && !MappingUtils.getMatchingMappingItems(
-                                anyUtils.getMappingItems(resource.getProvision(anyType), MappingPurpose.BOTH),
+                                MappingUtils.getMappingItems(resource.getProvision(anyType), MappingPurpose.BOTH),
                                 attr.getSchema().getKey(), type).isEmpty();
             }
         });

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index 4a8a35b..90f5e91 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -368,7 +368,7 @@ abstract class AbstractAnyDataBinder {
                 }
 
                 for (ExternalResource resource : resources) {
-                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                    for (MappingItem mapItem : MappingUtils.getMappingItems(
                             resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
                         if (schema.getKey().equals(mapItem.getIntAttrName())
@@ -402,7 +402,7 @@ abstract class AbstractAnyDataBinder {
             }
 
             if (schema != null && attr != null && attr.getSchema() != null) {
-                virAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, schema.getKey(),
+                virAttrHander.updateOnResourcesIfMappingMatches(any, schema.getKey(),
                         resources, anyUtils.plainIntMappingType(), propByRes);
 
                 // 1.1 remove values
@@ -460,7 +460,7 @@ abstract class AbstractAnyDataBinder {
                 }
 
                 for (ExternalResource resource : resources) {
-                    for (MappingItem mapItem : anyUtils.getMappingItems(
+                    for (MappingItem mapItem : MappingUtils.getMappingItems(
                             resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
                         if (derSchema.getKey().equals(mapItem.getIntAttrName())
@@ -486,7 +486,7 @@ abstract class AbstractAnyDataBinder {
         for (String derAttrToBeAdded : anyMod.getDerAttrsToAdd()) {
             DerSchema derSchema = getDerSchema(derAttrToBeAdded);
             if (derSchema != null) {
-                virAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, derSchema.getKey(),
+                virAttrHander.updateOnResourcesIfMappingMatches(any, derSchema.getKey(),
                         resources, anyUtils.derIntMappingType(), propByRes);
 
                 DerAttr derAttr = any.getDerAttr(derSchema.getKey());
@@ -700,7 +700,7 @@ abstract class AbstractAnyDataBinder {
         for (ExternalResource resource : iterable) {
             Provision provision = resource.getProvision(any.getType());
             if (provision != null && provision.getMapping() != null) {
-                MappingItem connObjectKeyItem = anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision);
+                MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
                 if (connObjectKeyItem == null) {
                     throw new NotFoundException(
                             "ConnObjectKey mapping for " + any.getType().getKey() + " " + any.getKey()

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 6a67ccf..e557699 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
@@ -48,9 +48,9 @@ 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.misc.MappingUtils;
 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.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
@@ -124,9 +124,6 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
     protected AuditManager auditManager;
 
     @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
-
-    @Autowired
     protected EntityFactory entityFactory;
 
     @Override
@@ -537,8 +534,7 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
                     task.getPropagationOperation(),
                     new ObjectClass(task.getObjectClassName()),
                     new Uid(connObjectKey),
-                    connector.getOperationOptions(anyUtilsFactory.getInstance(task.getAnyTypeKind()).
-                            getMappingItems(provision, MappingPurpose.PROPAGATION)));
+                    connector.getOperationOptions(MappingUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)));
         } catch (TimeoutException toe) {
             LOG.debug("Request timeout", toe);
             throw toe;

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 2649623..59f8994 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
@@ -49,8 +49,6 @@ 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;
@@ -102,9 +100,6 @@ public class PropagationManagerImpl implements PropagationManager {
     protected ConnObjectUtils connObjectUtils;
 
     @Autowired
-    protected AnyUtilsFactory anyUtilsFactory;
-
-    @Autowired
     protected VirAttrHandler virAttrHandler;
 
     @Override
@@ -412,8 +407,6 @@ public class PropagationManagerImpl implements PropagationManager {
 
         LOG.debug("Provisioning any {}:\n{}", any, propByRes);
 
-        AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
         if (!propByRes.get(ResourceOperation.CREATE).isEmpty()
                 && vAttrsToBeRemoved != null && vAttrsToBeUpdated != null) {
 
@@ -421,9 +414,9 @@ public class PropagationManagerImpl implements PropagationManager {
 
             // update vAttrsToBeUpdated as well
             for (VirAttr<?> virAttr : any.getVirAttrs()) {
-                final String schema = virAttr.getSchema().getKey();
+                String schema = virAttr.getSchema().getKey();
 
-                final AttrMod attributeMod = new AttrMod();
+                AttrMod attributeMod = new AttrMod();
                 attributeMod.setSchema(schema);
                 attributeMod.getValuesToBeAdded().addAll(virAttr.getValues());
 
@@ -446,7 +439,7 @@ public class PropagationManagerImpl implements PropagationManager {
                 } 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()) {
+                } else if (MappingUtils.getMappingItems(provision, MappingPurpose.PROPAGATION).isEmpty()) {
                     LOG.warn("Requesting propagation for {} but no propagation mapping provided for {}",
                             any.getType(), resource);
                 } else {
@@ -454,7 +447,7 @@ public class PropagationManagerImpl implements PropagationManager {
                     task.setResource(resource);
                     task.setObjectClassName(
                             resource.getProvision(any.getType()).getObjectClass().getObjectClassValue());
-                    task.setAnyTypeKind(anyUtils.getAnyTypeKind());
+                    task.setAnyTypeKind(any.getType().getKind());
                     if (!deleteOnResource) {
                         task.setAnyKey(any.getKey());
                     }
@@ -462,15 +455,15 @@ public class PropagationManagerImpl implements PropagationManager {
                     task.setPropagationMode(resource.getPropagationMode());
                     task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
 
-                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttributes(anyUtils, any,
-                            password, changePwd, vAttrsToBeRemoved, vAttrsToBeUpdated, enable, provision);
+                    Pair<String, Set<Attribute>> preparedAttrs = MappingUtils.prepareAttrs(
+                            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 : anyUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
+                    for (MappingItem item : MappingUtils.getMappingItems(provision, MappingPurpose.PROPAGATION)) {
                         if (!item.isConnObjectKey()
                                 && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 71ad319..14c94f70 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
@@ -28,6 +28,7 @@ import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.core.misc.MappingUtils;
 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;
@@ -119,7 +120,7 @@ public class SyncUtils {
 
         List<ConnectorObject> found = connector.search(provision.getObjectClass(),
                 new EqualsFilter(new Name(name)), connector.getOperationOptions(
-                        anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)));
+                        MappingUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)));
 
         if (found.isEmpty()) {
             LOG.debug("No {} found on {} with __NAME__ {}", provision.getObjectClass(), resource, name);
@@ -162,7 +163,7 @@ public class SyncUtils {
 
         List<Long> result = new ArrayList<>();
 
-        MappingItem connObjectKeyItem = anyUtils.getConnObjectKeyItem(provision);
+        MappingItem connObjectKeyItem = MappingUtils.getConnObjectKeyItem(provision);
         switch (connObjectKeyItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
@@ -249,12 +250,12 @@ public class SyncUtils {
             final ConnectorObject connObj,
             final List<String> altSearchSchemas,
             final Provision provision,
-            final AnyUtils anyUtils) {
+            final AnyTypeKind anyTypeKind) {
 
         // search for external attribute's name/value of each specified name
         Map<String, Attribute> extValues = new HashMap<>();
 
-        for (MappingItem item : anyUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
+        for (MappingItem item : MappingUtils.getMappingItems(provision, MappingPurpose.SYNCHRONIZATION)) {
             extValues.put(item.getIntAttrName(), connObj.getAttributeByName(item.getExtAttrName()));
         }
 
@@ -309,7 +310,7 @@ public class SyncUtils {
                     : SearchCond.getAndCond(searchCond, nodeCond);
         }
 
-        return search(searchCond, anyUtils.getAnyTypeKind());
+        return search(searchCond, anyTypeKind);
     }
 
     private SyncCorrelationRule getCorrelationRule(final Provision provision, final SyncPolicySpec policySpec) {
@@ -367,7 +368,7 @@ public class SyncUtils {
         return syncRule == null
                 ? altSearchSchemas == null || altSearchSchemas.isEmpty()
                         ? findByConnObjectKeyItem(uid, provision, anyUtils)
-                        : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils)
+                        : findByAnySearch(connObj, altSearchSchemas, provision, anyUtils.getAnyTypeKind())
                 : findByCorrelationRule(connObj, syncRule, anyUtils.getAnyTypeKind());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/54de3984/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 8005b24..6ea8cb0 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
@@ -30,6 +30,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.lib.SyncopeClient;
@@ -194,6 +195,8 @@ public class AuthenticationITCase extends AbstractITCase {
         userTO = createUser(userTO);
         assertNotNull(userTO);
 
+        // 1. user assigned to role 1, with search entitlement on realms /odd and /even: won't find anything with 
+        // root realm
         UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
                 getService(UserService.class);
 
@@ -214,13 +217,20 @@ public class AuthenticationITCase extends AbstractITCase {
         assertFalse(matchedUserKeys.contains(2L));
         assertFalse(matchedUserKeys.contains(5L));
 
+        // 2. user assigned to role 4, with search entitlement on realm /even/two
         UserService userService3 = clientFactory.create("puccini", ADMIN_PWD).getService(UserService.class);
 
         matchedUsers = userService3.search(
                 SyncopeClient.getAnySearchQueryBuilder().realm("/even/two").
                 fiql(SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query()).build());
         assertNotNull(matchedUsers);
-        assertTrue(matchedUsers.getResult().isEmpty());
+        assertTrue(CollectionUtils.matchesAll(matchedUsers.getResult(), new Predicate<UserTO>() {
+
+            @Override
+            public boolean evaluate(final UserTO matched) {
+                return "/even/two".equals(matched.getRealm());
+            }
+        }));
     }
 
     @Test


[52/70] syncope git commit: [SYNCOPE-666] Checkstyle fix...

Posted by il...@apache.org.
[SYNCOPE-666] Checkstyle fix...


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

Branch: refs/heads/master
Commit: fbfe9447f3396aefd28b1c36397dd121724d3d09
Parents: 64d475e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 13:54:08 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 13:54:08 2015 +0200

----------------------------------------------------------------------
 .../syncope/client/console/rest/UserRestClient.java   | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/fbfe9447/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 b2fb4e3..64daf50 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
@@ -162,8 +162,8 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class));
+            associationMod.getTargetResources().addAll(
+                    CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(), ResourceKey.class));
             service.bulkAssociation(userId, ResourceAssociationActionType.LINK, associationMod);
 
             resetClient(UserService.class);
@@ -191,8 +191,9 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class));
+            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
+                    getResourceNames(),
+                    ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 
@@ -224,8 +225,9 @@ public class UserRestClient extends AbstractAnyRestClient {
             UserService service = getService(etag, UserService.class);
 
             final ResourceAssociationMod associationMod = new ResourceAssociationMod();
-            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).getResourceNames(),
-                            ResourceKey.class));
+            associationMod.getTargetResources().addAll(CollectionWrapper.wrap(StatusUtils.buildStatusMod(statuses).
+                    getResourceNames(),
+                    ResourceKey.class));
             associationMod.setChangePwd(changepwd);
             associationMod.setPassword(password);
 


[48/70] syncope git commit: Merge branch 'master' into SYNCOPE-666

Posted by il...@apache.org.
Merge branch 'master' into SYNCOPE-666


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

Branch: refs/heads/master
Commit: 1da1ea4b532d2201f165cb91414de11c35cdab27
Parents: dd88efb 8f25b25
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jun 5 17:37:29 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jun 5 17:37:29 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/1da1ea4b/pom.xml
----------------------------------------------------------------------


[58/70] syncope git commit: [SYNCOPE-666] Any* tests added

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 001d71c..7d48b46 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
@@ -19,47 +19,21 @@
 package org.apache.syncope.common.rest.api.service;
 
 import java.util.List;
-import javax.validation.constraints.NotNull;
-import javax.ws.rs.BeanParam;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
-import javax.ws.rs.POST;
 import javax.ws.rs.Path;
-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.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.mod.GroupMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
 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.ResourceKey;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for groups.
  */
 @Path("groups")
-public interface GroupService extends JAXRSService {
-
-    /**
-     * Reads the group matching the provided groupKey.
-     *
-     * @param groupKey key of group to be read
-     * @return group with matching id
-     */
-    @GET
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    GroupTO read(@NotNull @PathParam("groupKey") Long groupKey);
+public interface GroupService extends AnyService<GroupTO, GroupMod> {
 
     /**
      * This method is similar to {@link #read(Long)}, but uses different authentication handling to ensure that a user
@@ -76,134 +50,4 @@ public interface GroupService extends JAXRSService {
     @Path("own")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     List<GroupTO> own();
-
-    /**
-     * Returns a paged list of existing groups matching the given query.
-     *
-     * @param listQuery query conditions
-     * @return paged list of existing groups matching the given query
-     */
-    @GET
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> list(@BeanParam AnyListQuery listQuery);
-
-    /**
-     * Returns a paged list of groups matching the given query.
-     *
-     * @param searchQuery query conditions
-     * @return paged list of groups matching the given query
-     */
-    @GET
-    @Path("search")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<GroupTO> search(@BeanParam AnySearchQuery searchQuery);
-
-    /**
-     * Creates a new group.
-     *
-     * @param groupTO group to be created
-     * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created group as well as the group itself
-     * enriched with propagation status information - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>Location</tt> header of created group as well as the "
-                + "group itself enriched with propagation status information - <tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response create(@NotNull GroupTO groupTO);
-
-    /**
-     * Updates group matching the provided groupKey.
-     *
-     * @param groupKey key of group to be updated
-     * @param groupMod modification to be applied to group matching the provided groupKey
-     * @return <tt>Response</tt> object featuring the updated group enriched with propagation status information
-     * - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the updated group enriched with propagation status information - "
-                + "<tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("groupKey") Long groupKey, @NotNull GroupMod groupMod);
-
-    /**
-     * Deletes group matching provided groupKey.
-     *
-     * @param groupKey key of group to be deleted
-     * @return <tt>Response</tt> object featuring the deleted group enriched with propagation status information
-     * - {@link GroupTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the deleted group enriched with propagation status information - "
-                + "<tt>GroupTO</tt> as <tt>Entity</tt>")
-    })
-    @DELETE
-    @Path("{groupKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response delete(@NotNull @PathParam("groupKey") Long groupKey);
-
-    /**
-     * Executes resource-related operations on given group.
-     *
-     * @param groupKey group id.
-     * @param type resource association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring
-     * {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}/deassociate/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
-            @NotNull @PathParam("groupKey") Long groupKey,
-            @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes resource-related operations on given group.
-     *
-     * @param groupKey group id.
-     * @param type resource association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{groupKey}/associate/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
-            @NotNull @PathParam("groupKey") Long groupKey,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes the provided bulk action.
-     *
-     * @param bulkAction list of group ids against which the bulk action will be performed.
-     * @return Bulk action result
-     */
-    @POST
-    @Path("bulk")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    BulkActionResult bulk(@NotNull BulkAction bulkAction);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 4866f95..bf1e6b7 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
@@ -18,13 +18,9 @@
  */
 package org.apache.syncope.common.rest.api.service;
 
-import java.util.List;
 import javax.validation.constraints.NotNull;
-import javax.ws.rs.BeanParam;
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
 import javax.ws.rs.OPTIONS;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
@@ -36,86 +32,45 @@ import javax.ws.rs.core.Response;
 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.mod.ResourceAssociationMod;
 import org.apache.syncope.common.lib.mod.StatusMod;
 import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.BulkAction;
-import org.apache.syncope.common.lib.to.BulkActionResult;
-import org.apache.syncope.common.lib.to.PagedResult;
 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.ResourceKey;
-import org.apache.syncope.common.rest.api.beans.AnyListQuery;
-import org.apache.syncope.common.rest.api.beans.AnySearchQuery;
 
 /**
  * REST operations for users.
  */
 @Path("users")
-public interface UserService extends JAXRSService {
+public interface UserService extends AnyService<UserTO, UserMod> {
 
     /**
      * Gives the username for the provided user key.
      *
-     * @param userKey user key
-     * @return <tt>Response</tt> object featuring HTTP header with username matching the given userKey
+     * @param key user key
+     * @return <tt>Response</tt> object featuring HTTP header with username matching the given key
      */
     @Descriptions({
         @Description(target = DocTarget.RESPONSE,
-                value = "Featuring HTTP header with username matching the given userKey")
+                value = "Featuring HTTP header with username matching the given key")
     })
     @OPTIONS
-    @Path("{userKey}/username")
-    Response getUsername(@NotNull @PathParam("userKey") Long userKey);
+    @Path("{key}/username")
+    Response getUsername(@NotNull @PathParam("key") Long key);
 
     /**
      * Gives the user key for the provided username.
      *
      * @param username username
-     * @return <tt>Response</tt> object featuring HTTP header with userKey matching the given username
+     * @return <tt>Response</tt> object featuring HTTP header with key matching the given username
      */
     @Descriptions({
         @Description(target = DocTarget.RESPONSE,
-                value = "Featuring HTTP header with userKey matching the given username")
+                value = "Featuring HTTP header with key matching the given username")
     })
     @OPTIONS
-    @Path("{username}/userKey")
+    @Path("{username}/key")
     Response getUserKey(@NotNull @PathParam("username") String username);
 
     /**
-     * Reads the user matching the provided userKey.
-     *
-     * @param userKey id of user to be read
-     * @return User matching the provided userKey
-     */
-    @GET
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    UserTO read(@NotNull @PathParam("userKey") Long userKey);
-
-    /**
-     * Returns a paged list of existing users matching the given query.
-     *
-     * @param listQuery query conditions
-     * @return paged list of existing users matching the given query
-     */
-    @GET
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> list(@BeanParam AnyListQuery listQuery);
-
-    /**
-     * Returns a paged list of users matching the given query.
-     *
-     * @param searchQuery query conditions
-     * @return paged list of users matching the given query
-     */
-    @GET
-    @Path("search")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    PagedResult<UserTO> search(@BeanParam AnySearchQuery searchQuery);
-
-    /**
      * Creates a new user.
      *
      * @param userTO user to be created
@@ -136,28 +91,9 @@ public interface UserService extends JAXRSService {
             @DefaultValue("true") @QueryParam("storePassword") boolean storePassword);
 
     /**
-     * Updates user matching the provided userKey.
+     * Performs a status update on user matching provided key.
      *
-     * @param userKey id of user to be updated
-     * @param userMod modification to be applied to user matching the provided userKey
-     * @return <tt>Response</tt> object featuring the updated user enriched with propagation status information
-     * - {@link UserTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the updated user enriched with propagation status information - "
-                + "<tt>UserTO</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response update(@NotNull @PathParam("userKey") Long userKey, @NotNull UserMod userMod);
-
-    /**
-     * Performs a status update on user matching provided userKey.
-     *
-     * @param userKey id of user to be subjected to status update
+     * @param key id of user to be subjected to status update
      * @param statusMod status update details
      * @return <tt>Response</tt> object featuring the updated user enriched with propagation status information
      * - {@link UserTO} as <tt>Entity</tt>
@@ -168,78 +104,8 @@ public interface UserService extends JAXRSService {
                 + "<tt>UserTO</tt> as <tt>Entity</tt>")
     })
     @POST
-    @Path("{userKey}/status")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response status(@NotNull @PathParam("userKey") Long userKey, @NotNull StatusMod statusMod);
-
-    /**
-     * Deletes user matching provided userKey.
-     *
-     * @param userKey id of user to be deleted
-     * @return <tt>Response</tt> object featuring the deleted user enriched with propagation status information
-     * - {@link UserTO} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring the deleted user enriched with propagation status information - "
-                + "<tt>UserTO</tt> as <tt>Entity</tt>")
-    })
-    @DELETE
-    @Path("{userKey}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response delete(@NotNull @PathParam("userKey") Long userKey);
-
-    /**
-     * Executes resource-related operations on given user.
-     *
-     * @param userKey user key
-     * @param type resource de-association action type
-     * @param resourceNames external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE,
-                value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}/bulkDeassociation/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkDeassociation(
-            @NotNull @PathParam("userKey") Long userKey,
-            @NotNull @PathParam("type") ResourceDeassociationActionType type,
-            @NotNull List<ResourceKey> resourceNames);
-
-    /**
-     * Executes resource-related operations on given user.
-     *
-     * @param userKey user key.
-     * @param type resource association action type
-     * @param associationMod external resources to be used for propagation-related operations
-     * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
-     */
-    @Descriptions({
-        @Description(target = DocTarget.RESPONSE, value = "Featuring <tt>BulkActionResult</tt> as <tt>Entity</tt>")
-    })
-    @POST
-    @Path("{userKey}/bulkAssociation/{type}")
-    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    Response bulkAssociation(
-            @NotNull @PathParam("userKey") Long userKey,
-            @NotNull @PathParam("type") ResourceAssociationActionType type,
-            @NotNull ResourceAssociationMod associationMod);
-
-    /**
-     * Executes the provided bulk action.
-     *
-     * @param bulkAction list of user keys against which the bulk action will be performed.
-     * @return Bulk action result
-     */
-    @POST
-    @Path("bulk")
+    @Path("{key}/status")
     @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
-    BulkActionResult bulk(@NotNull BulkAction bulkAction);
+    Response status(@NotNull @PathParam("key") Long key, @NotNull StatusMod statusMod);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index 83e90da..d24b08e 100644
--- 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
@@ -30,8 +30,8 @@ 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> {
+public abstract class AbstractAnyLogic<TO extends AnyTO, MOD extends AnyMod>
+        extends AbstractResourceAssociator<TO> {
 
     private static class StartsWithPredicate implements Predicate<String> {
 
@@ -67,17 +67,19 @@ public abstract class AbstractAnyLogic<T extends AnyTO, V extends AnyMod>
         return effective;
     }
 
-    public abstract T read(Long key);
+    public abstract TO read(Long key);
 
     public abstract int count(List<String> realms);
 
-    public abstract T update(V anyMod);
+    public abstract TO create(TO anyTO);
 
-    public abstract T delete(Long key);
+    public abstract TO update(MOD anyMod);
 
-    public abstract List<T> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
+    public abstract TO delete(Long key);
 
-    public abstract List<T> search(
+    public abstract List<TO> list(int page, int size, List<OrderByClause> orderBy, List<String> realms);
+
+    public abstract List<TO> 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/a45a46bb/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
index 4919097..257bf42 100644
--- 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
@@ -29,6 +29,7 @@ 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.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
@@ -107,9 +108,19 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     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),
+        return list(null, page, size, orderBy, realms);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_LIST + "')")
+    @Transactional(readOnly = true)
+    public List<AnyObjectTO> list(final String type,
+            final int page, final int size, final List<OrderByClause> orderBy, final List<String> realms) {
+
+        Set<String> effectiveRealms = getEffectiveRealms(SyncopeConstants.FULL_ADMIN_REALMS, realms);
+
+        return CollectionUtils.collect(StringUtils.isBlank(type)
+                ? anyObjectDAO.findAll(effectiveRealms, page, size, orderBy)
+                : anyObjectDAO.findAll(type, effectiveRealms, page, size, orderBy),
                 new Transformer<AnyObject, AnyObjectTO>() {
 
                     @Override
@@ -147,10 +158,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
     }
 
     @PreAuthorize("hasRole('" + Entitlement.ANY_OBJECT_CREATE + "')")
+    @Override
     public AnyObjectTO create(final AnyObjectTO anyObjectTO) {
         if (anyObjectTO.getRealm() == null) {
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);
-            throw sce;
+            throw SyncopeClientException.build(ClientExceptionType.InvalidRealm);
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_CREATE),
@@ -163,6 +174,10 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
         AnyObjectTO actual = attrTransformer.transform(anyObjectTO);
         LOG.debug("Transformed: {}", actual);
 
+        if (anyObjectTO.getType() == null) {
+            throw SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+        }
+
         /*
          * Actual operations: workflow, propagation
          */
@@ -181,7 +196,7 @@ public class AnyObjectLogic extends AbstractAnyLogic<AnyObjectTO, AnyObjectMod>
         }
         Set<String> effectiveRealms = getEffectiveRealms(
                 AuthContextUtils.getAuthorizations().get(Entitlement.ANY_OBJECT_UPDATE),
-                Collections.singleton(anyObjectMod.getRealm()));
+                Collections.singleton(anyObject.getRealm().getFullPath()));
         if (effectiveRealms.isEmpty()) {
             throw new UnauthorizedException(AnyTypeKind.ANY_OBJECT, anyObject.getKey());
         }

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
index 93af622..b0cfa03 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AnyTypeLogic.java
@@ -25,7 +25,9 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
@@ -96,7 +98,13 @@ public class AnyTypeLogic extends AbstractTransactionalLogic<AnyTypeTO> {
         }
 
         AnyTypeTO deleted = binder.getAnyTypeTO(anyType);
-        anyTypeDAO.delete(key);
+        try {
+            anyTypeDAO.delete(key);
+        } catch (IllegalArgumentException e) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add(e.getMessage());
+            throw sce;
+        }
         return deleted;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 d9216da..877a272 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
@@ -166,6 +166,7 @@ public class GroupLogic extends AbstractAnyLogic<GroupTO, GroupMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.GROUP_CREATE + "')")
+    @Override
     public GroupTO create(final GroupTO groupTO) {
         if (groupTO.getRealm() == null) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 4ecab47..28e5cab 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
@@ -183,6 +183,12 @@ public class UserLogic extends AbstractAnyLogic<UserTO, UserMod> {
     }
 
     @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
+    @Override
+    public UserTO create(final UserTO userTO) {
+        return create(userTO, true);
+    }
+
+    @PreAuthorize("hasRole('" + Entitlement.USER_CREATE + "')")
     public UserTO create(final UserTO userTO, final boolean storePassword) {
         if (userTO.getRealm() == null) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRealm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 807ea0f..6257d59 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
@@ -196,6 +196,7 @@ public class ConnObjectUtils {
             final SyncTask syncTask, final Provision provision, final AnyUtils anyUtils) {
 
         T anyTO = anyUtils.newAnyTO();
+        anyTO.setType(provision.getAnyType().getKey());
 
         // 1. fill with data from connector object
         anyTO.setRealm(syncTask.getDestinatioRealm().getFullPath());
@@ -206,6 +207,7 @@ public class ConnObjectUtils {
             switch (item.getIntMappingType()) {
                 case UserKey:
                 case GroupKey:
+                case AnyObjectKey:
                     break;
 
                 case Password:
@@ -252,6 +254,7 @@ public class ConnObjectUtils {
 
                 case UserPlainSchema:
                 case GroupPlainSchema:
+                case AnyObjectPlainSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
 
@@ -292,6 +295,7 @@ public class ConnObjectUtils {
 
                 case UserDerivedSchema:
                 case GroupDerivedSchema:
+                case AnyObjectDerivedSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
                     anyTO.getDerAttrs().add(attrTO);
@@ -299,6 +303,7 @@ public class ConnObjectUtils {
 
                 case UserVirtualSchema:
                 case GroupVirtualSchema:
+                case AnyObjectVirtualSchema:
                     attrTO = new AttrTO();
                     attrTO.setSchema(item.getIntAttrName());
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 140c5ad..e655809 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
@@ -154,7 +154,7 @@ public final class MappingUtils {
             try {
                 if (mapping.getIntMappingType() == IntMappingType.UserVirtualSchema
                         || mapping.getIntMappingType() == IntMappingType.GroupVirtualSchema
-                        || mapping.getIntMappingType() == IntMappingType.AnyVirtualSchema) {
+                        || mapping.getIntMappingType() == IntMappingType.AnyObjectVirtualSchema) {
 
                     LOG.debug("Expire entry cache {}-{}", any.getKey(), mapping.getIntAttrName());
                     virAttrCache.expire(any.getType().getKey(), any.getKey(), mapping.getIntAttrName());
@@ -270,7 +270,7 @@ public final class MappingUtils {
         switch (mapItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
                 schema = plainSchemaDAO.find(mapItem.getIntAttrName());
                 schemaType = schema == null ? AttrSchemaType.String : schema.getType();
@@ -278,7 +278,7 @@ public final class MappingUtils {
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-            case AnyVirtualSchema:
+            case AnyObjectVirtualSchema:
                 VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
                 VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
                 readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
@@ -442,7 +442,7 @@ public final class MappingUtils {
         switch (mappingItem.getIntMappingType()) {
             case UserPlainSchema:
             case GroupPlainSchema:
-            case AnyPlainSchema:
+            case AnyObjectPlainSchema:
                 for (Any<?, ?, ?> any : anys) {
                     PlainAttr<?> attr = any.getPlainAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
@@ -464,7 +464,7 @@ public final class MappingUtils {
 
             case UserVirtualSchema:
             case GroupVirtualSchema:
-            case AnyVirtualSchema:
+            case AnyObjectVirtualSchema:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     VirAttr<?> virAttr = any.getVirAttr(mappingItem.getIntAttrName());
@@ -501,7 +501,7 @@ public final class MappingUtils {
 
             case UserDerivedSchema:
             case GroupDerivedSchema:
-            case AnyDerivedSchema:
+            case AnyObjectDerivedSchema:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     DerAttr<?> derAttr = any.getDerAttr(mappingItem.getIntAttrName());
@@ -521,7 +521,7 @@ public final class MappingUtils {
 
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 for (Any<?, ?, ?> any : anys) {
                     AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
                     attrValue = anyUtils.newPlainAttrValue();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 a67cbf5..c7efa8a 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
@@ -37,6 +37,7 @@ 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.AnyTypeCond;
 
 /**
  * Converts CXF's <tt>SearchCondition</tt> into internal <tt>SearchCond</tt>.
@@ -98,6 +99,12 @@ public class SearchCondVisitor extends AbstractSearchConditionVisitor<SearchBean
                     leaf = SearchCond.getLeafCond(attributeCond);
                 } else {
                     switch (specialAttrName) {
+                        case TYPE:
+                            AnyTypeCond typeCond = new AnyTypeCond();
+                            typeCond.setAnyTypeName(value);
+                            leaf = SearchCond.getLeafCond(typeCond);
+                            break;
+
                         case GROUPS:
                             MembershipCond groupCond = new MembershipCond();
                             groupCond.setGroupKey(Long.valueOf(value));

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 26068e9..caa9c54 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
@@ -20,6 +20,7 @@ package org.apache.syncope.core.misc.search;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.syncope.common.lib.search.AnyObjectFiqlSearchConditionBuilder;
 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;
@@ -28,6 +29,7 @@ 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.AnyTypeCond;
 import org.junit.Test;
 
 public class SearchCondConverterTest {
@@ -119,6 +121,18 @@ public class SearchCondConverterTest {
     }
 
     @Test
+    public void type() {
+        String fiqlExpression = new AnyObjectFiqlSearchConditionBuilder().type("PRINTER").query();
+        assertEquals(SpecialAttr.TYPE + "==PRINTER", fiqlExpression);
+
+        AnyTypeCond acond = new AnyTypeCond();
+        acond.setAnyTypeName("PRINTER");
+        SearchCond simpleCond = SearchCond.getLeafCond(acond);
+
+        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
+    }
+
+    @Test
     public void and() {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().
                 is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index bd2f938..11d3c8e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -20,6 +20,8 @@ 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.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -28,7 +30,11 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 
 public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
-    List<AnyObject> findByAnyType(String anyTypeName);
+    List<AnyObject> findAll(String anyTypeName,
+            Set<String> adminRealms, int page, int itemsPerPage);
+
+    List<AnyObject> findAll(String anyTypeName,
+            Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
 
     List<Group> findDynGroupMemberships(AnyObject anyObject);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
new file mode 100644
index 0000000..a12a3e7
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.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.search;
+
+public class AnyTypeCond extends AbstractSearchCond {
+
+    private static final long serialVersionUID = 4298076973281246633L;
+
+    private String anyTypeName;
+
+    public String getAnyTypeName() {
+        return anyTypeName;
+    }
+
+    public void setAnyTypeName(final String anyTypeName) {
+        this.anyTypeName = anyTypeName;
+    }
+
+    @Override
+    public boolean isValid() {
+        return anyTypeName != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 d942591..82da594 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,6 +35,8 @@ public class SearchCond extends AbstractSearchCond {
 
     private Type type;
 
+    private AnyTypeCond anyTypeCond;
+
     private AnyCond anyCond;
 
     private AttributeCond attributeCond;
@@ -51,6 +53,15 @@ public class SearchCond extends AbstractSearchCond {
 
     private SearchCond rightNodeCond;
 
+    public static SearchCond getLeafCond(final AnyTypeCond anyTypeCond) {
+        SearchCond nodeCond = new SearchCond();
+
+        nodeCond.type = Type.LEAF;
+        nodeCond.anyTypeCond = anyTypeCond;
+
+        return nodeCond;
+    }
+
     public static SearchCond getLeafCond(final AttributeCond attributeCond) {
         SearchCond nodeCond = new SearchCond();
 
@@ -173,6 +184,14 @@ public class SearchCond extends AbstractSearchCond {
         }
     }
 
+    public AnyTypeCond getAnyTypeCond() {
+        return anyTypeCond;
+    }
+
+    public void setAnyTypeCond(final AnyTypeCond anyTypeCond) {
+        this.anyTypeCond = anyTypeCond;
+    }
+
     public AnyCond getAnyCond() {
         return anyCond;
     }
@@ -256,9 +275,10 @@ public class SearchCond extends AbstractSearchCond {
         switch (type) {
             case LEAF:
             case NOT_LEAF:
-                isValid = (anyCond != null || attributeCond != null
+                isValid = (anyTypeCond != null || anyCond != null || attributeCond != null
                         || relationshipCond != null || membershipCond != null
                         || roleCond != null || resourceCond != null)
+                        && (anyTypeCond == null || anyTypeCond.isValid())
                         && (anyCond == null || anyCond.isValid())
                         && (attributeCond == null || attributeCond.isValid())
                         && (membershipCond == null || membershipCond.isValid())

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index 298f5c4..968f990 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -20,6 +20,7 @@ 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;
@@ -33,6 +34,9 @@ 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.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AnyTypeCond;
+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.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
@@ -43,7 +47,6 @@ import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 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.JPAARelationship;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
@@ -77,12 +80,21 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     }
 
     @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);
+    public final List<AnyObject> findAll(final String anyTypeName,
+            final Set<String> adminRealms, final int page, final int itemsPerPage) {
 
-        return query.getResultList();
+        return findAll(anyTypeName, adminRealms, page, itemsPerPage, Collections.<OrderByClause>emptyList());
+    }
+
+    @Override
+    public final List<AnyObject> findAll(final String anyTypeName,
+            final Set<String> adminRealms, final int page, final int itemsPerPage, final List<OrderByClause> orderBy) {
+
+        AnyTypeCond anyTypeCond = new AnyTypeCond();
+        anyTypeCond.setAnyTypeName(anyTypeName);
+
+        return searchDAO.search(adminRealms, SearchCond.getLeafCond(anyTypeCond), page, itemsPerPage, orderBy,
+                getAnyUtils().getAnyTypeKind());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index 6a14e58..b8ab75d 100644
--- 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
@@ -53,6 +53,7 @@ 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.AnyTypeCond;
 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;
@@ -420,6 +421,10 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
 
             case LEAF:
             case NOT_LEAF:
+                if (nodeCond.getAnyTypeCond() != null && AnyTypeKind.ANY_OBJECT == type) {
+                    query.append(getQuery(nodeCond.getAnyTypeCond(),
+                            nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+                }
                 if (nodeCond.getRelationshipCond() != null
                         && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
 
@@ -470,6 +475,23 @@ public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements
         return query;
     }
 
+    private String getQuery(final AnyTypeCond 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 type_name");
+
+        if (not) {
+            query.append("<>");
+        } else {
+            query.append('=');
+        }
+
+        query.append('?').append(setParameter(parameters, cond.getAnyTypeName()));
+
+        return query.toString();
+    }
+
     private String getQuery(final RelationshipCond cond, final boolean not, final List<Object> parameters,
             final SearchSupport svs) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index 9d0f798..645c60c 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -321,7 +321,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyPlainSchema;
+                result = IntMappingType.AnyObjectPlainSchema;
                 break;
 
             case USER:
@@ -344,7 +344,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyDerivedSchema;
+                result = IntMappingType.AnyObjectDerivedSchema;
                 break;
 
             case USER:
@@ -367,7 +367,7 @@ public class JPAAnyUtils implements AnyUtils {
                 break;
 
             case ANY_OBJECT:
-                result = IntMappingType.AnyVirtualSchema;
+                result = IntMappingType.AnyObjectVirtualSchema;
                 break;
 
             case USER:

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
index 227f0fd..2066f6f 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMapping.java
@@ -115,7 +115,7 @@ public class JPAMapping extends AbstractEntity<Long> implements Mapping {
     protected boolean addConnObjectKeyItem(final MappingItem connObjectKeyItem) {
         if (IntMappingType.UserVirtualSchema == connObjectKeyItem.getIntMappingType()
                 || IntMappingType.GroupVirtualSchema == connObjectKeyItem.getIntMappingType()
-                || IntMappingType.AnyVirtualSchema == connObjectKeyItem.getIntMappingType()
+                || IntMappingType.AnyObjectVirtualSchema == connObjectKeyItem.getIntMappingType()
                 || IntMappingType.Password == connObjectKeyItem.getIntMappingType()) {
 
             throw new IllegalArgumentException("Virtual attributes cannot be set as ConnObjectKey");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
index 2aa587f..ae9a117 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAMappingItem.java
@@ -143,7 +143,7 @@ public class JPAMappingItem extends AbstractEntity<Long> implements MappingItem
         switch (getIntMappingType()) {
             case UserKey:
             case GroupKey:
-            case AnyKey:
+            case AnyObjectKey:
                 name = "id";
                 break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
index e3a4a74..e149969 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -48,6 +49,15 @@ public class AnyObjectTest extends AbstractTest {
     }
 
     @Test
+    public void findAllByType() {
+        List<AnyObject> list = anyObjectDAO.findAll("PRINTER", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+
+        list = anyObjectDAO.findAll("UNEXISTING", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
     public void find() {
         AnyObject anyObject = anyObjectDAO.find(2L);
         assertNotNull(anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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
index fcc3982..018f632 100644
--- 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
@@ -30,7 +30,6 @@ 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;
@@ -44,6 +43,7 @@ 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.AnyTypeCond;
 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;
@@ -72,7 +72,7 @@ public class AnySearchTest extends AbstractTest {
     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));
@@ -385,6 +385,26 @@ public class AnySearchTest extends AbstractTest {
     }
 
     @Test
+    public void searchByType() {
+        AnyTypeCond tcond = new AnyTypeCond();
+        tcond.setAnyTypeName("PRINTER");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(tcond);
+        assertTrue(searchCondition.isValid());
+
+        List<AnyObject> printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertEquals(2, printers.size());
+
+        tcond.setAnyTypeName("UNEXISTING");
+        printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertTrue(printers.isEmpty());
+    }
+
+    @Test
     public void userOrderBy() {
         AnyCond usernameLeafCond = new AnyCond(AnyCond.Type.EQ);
         usernameLeafCond.setSchema("username");

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
index 2337a32..13937cc 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
@@ -57,10 +57,10 @@ public class AnyTypeTest extends AbstractTest {
         assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
         assertFalse(groupType.getClasses().isEmpty());
 
-        AnyType otherType = anyTypeDAO.find("OTHER");
+        AnyType otherType = anyTypeDAO.find("PRINTER");
         assertNotNull(otherType);
         assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
-        assertEquals("OTHER", otherType.getKey());
+        assertEquals("PRINTER", otherType.getKey());
     }
 
     @Test
@@ -100,11 +100,11 @@ public class AnyTypeTest extends AbstractTest {
 
     @Test
     public void delete() {
-        AnyType otherType = anyTypeDAO.find("OTHER");
+        AnyType otherType = anyTypeDAO.find("PRINTER");
         assertNotNull(otherType);
 
         anyTypeDAO.delete(otherType.getKey());
-        assertNull(anyTypeDAO.find("OTHER"));
+        assertNull(anyTypeDAO.find("PRINTER"));
     }
 
     @Test(expected = IllegalArgumentException.class)

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 967a6be..7e86689 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
@@ -47,7 +47,7 @@ public class PlainSchemaTest extends AbstractTest {
     @Test
     public void findAll() {
         List<PlainSchema> schemas = plainSchemaDAO.findAll();
-        assertEquals(40, schemas.size());
+        assertEquals(42, schemas.size());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 ee9a9f7..c058db7 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
@@ -82,7 +82,7 @@ public class ResourceTest extends AbstractTest {
     public void findAll() {
         List<ExternalResource> resources = resourceDAO.findAll();
         assertNotNull(resources);
-        assertEquals(18, resources.size());
+        assertEquals(19, resources.size());
     }
 
     @Test
@@ -294,7 +294,7 @@ public class ResourceTest extends AbstractTest {
         item = entityFactory.newEntity(MappingItem.class);
         item.setIntAttrName("mderiveddata");
         item.setExtAttrName("mderiveddata");
-        item.setIntMappingType(IntMappingType.AnyDerivedSchema);
+        item.setIntMappingType(IntMappingType.AnyObjectDerivedSchema);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.add(item);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 43d65d1..a4aed30 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
@@ -67,7 +67,7 @@ public class TaskTest extends AbstractTest {
         assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
         assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
-        assertEquals(9, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
         assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 b32e970..50b4c56 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
@@ -158,7 +158,7 @@ public class GroupTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("minimal other"));
+        user.add(anyTypeClassDAO.find("other"));
 
         UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
         attr.setOwner(user);
@@ -250,13 +250,13 @@ public class GroupTest extends AbstractTest {
     public void adynMembership() {
         // 0. create any object matching the condition below
         AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
-        anyObject.setType(anyTypeDAO.find("OTHER"));
+        anyObject.setType(anyTypeDAO.find("PRINTER"));
         anyObject.setRealm(realmDAO.find("/even/two"));
 
         APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
         attr.setOwner(anyObject);
-        attr.setSchema(plainSchemaDAO.find("cool"));
-        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        attr.setSchema(plainSchemaDAO.find("model"));
+        attr.add("Canon MFC8030", anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
         anyObject.add(attr);
 
         anyObject = anyObjectDAO.save(anyObject);
@@ -269,7 +269,7 @@ public class GroupTest extends AbstractTest {
         group.setName("new");
 
         ADynGroupMembership dynMembership = entityFactory.newEntity(ADynGroupMembership.class);
-        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setFIQLCond("model==Canon MFC8030");
         dynMembership.setGroup(group);
 
         group.setADynMembership(dynMembership);
@@ -288,7 +288,7 @@ public class GroupTest extends AbstractTest {
 
         // 3. verify that expected any objects have the created group dynamically assigned
         assertEquals(2, actual.getADynMembership().getMembers().size());
-        assertEquals(new HashSet<>(Arrays.asList(2L, newAnyObjectKey)),
+        assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
                 CollectionUtils.collect(actual.getADynMembership().getMembers(), new Transformer<AnyObject, Long>() {
 
                     @Override
@@ -297,7 +297,7 @@ public class GroupTest extends AbstractTest {
                     }
                 }, new HashSet<Long>()));
 
-        anyObject = anyObjectDAO.find(2L);
+        anyObject = anyObjectDAO.find(1L);
         assertNotNull(anyObject);
         Collection<Group> dynGroupMemberships = findDynGroupMemberships(anyObject);
         assertEquals(1, dynGroupMemberships.size());
@@ -310,7 +310,7 @@ public class GroupTest extends AbstractTest {
 
         actual = groupDAO.find(actual.getKey());
         assertEquals(1, actual.getADynMembership().getMembers().size());
-        assertEquals(2L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
+        assertEquals(1L, actual.getADynMembership().getMembers().get(0).getKey(), 0);
 
         // 5. delete group and verify that dynamic membership was also removed
         Long dynMembershipKey = actual.getADynMembership().getKey();

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 b92debb..7d363c2 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
@@ -79,7 +79,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for associated mappings
         Set<MappingItem> mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
@@ -103,7 +105,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for mappings deletion
         mapItems = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if ("fullname".equals(mapItem.getIntAttrName())) {
                         mapItems.add(mapItem);
@@ -128,7 +132,9 @@ public class PlainSchemaTest extends AbstractTest {
         // check for associated mappings
         Set<MappingItem> mappings = new HashSet<>();
         for (ExternalResource resource : resourceDAO.findAll()) {
-            if (resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
                 for (MappingItem mapItem : resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
                     if (schema.getKey().equals(mapItem.getIntAttrName())) {
                         mappings.add(mapItem);

http://git-wip-us.apache.org/repos/asf/syncope/blob/a45a46bb/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 71fa878..5fdc803 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
@@ -88,7 +88,7 @@ public class RoleTest extends AbstractTest {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.find("/even/two"));
-        user.add(anyTypeClassDAO.find("minimal other"));
+        user.add(anyTypeClassDAO.find("other"));
 
         UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
         attr.setOwner(user);


[20/70] 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);


[22/70] 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();
 }


[24/70] 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);
 


[15/70] 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";
-
-}


[11/70] 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());
     }
 }


[53/70] syncope git commit: Merge branch 'master' into SYNCOPE-666

Posted by il...@apache.org.
Merge branch 'master' into SYNCOPE-666


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

Branch: refs/heads/master
Commit: a8a40639d59ca79fccc321f514aaab5a8ec9973b
Parents: fbfe944 a6bcbd4
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Mon Jun 8 15:19:10 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Mon Jun 8 15:19:10 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/a8a40639/pom.xml
----------------------------------------------------------------------


[38/70] syncope git commit: [SYNCOPE-666] All but integration tests work

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 952343b..8f52059 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
@@ -113,10 +113,19 @@ public class PropagationManagerImpl implements PropagationManager {
 
     @Override
     public List<PropagationTask> getAnyObjectCreateTasks(
+            final WorkflowResult<Long> wfResult,
+            final Collection<AttrTO> vAttrs,
+            final Collection<String> noPropResourceNames) {
+
+        return getAnyObjectCreateTasks(wfResult.getResult(), vAttrs, wfResult.getPropByRes(), noPropResourceNames);
+    }
+
+    @Override
+    public List<PropagationTask> getAnyObjectCreateTasks(
             final Long key,
             final Collection<AttrTO> vAttrs,
             final PropagationByResource propByRes,
-            final List<String> noPropResourceNames) {
+            final Collection<String> noPropResourceNames) {
 
         AnyObject anyObject = anyObjectDAO.authFind(key);
         if (vAttrs != null && !vAttrs.isEmpty()) {
@@ -142,14 +151,6 @@ public class PropagationManagerImpl implements PropagationManager {
         return getCreateTaskIds(user, password, enable, propByRes, noPropResourceNames);
     }
 
-    /**
-     * Create the group on every associated resource.
-     *
-     * @param wfResult group to be propagated (and info associated), as per result from workflow
-     * @param vAttrs virtual attributes to be set
-     * @param noPropResourceNames external resources performing not to be considered for propagation
-     * @return list of propagation tasks
-     */
     @Override
     public List<PropagationTask> getGroupCreateTasks(
             final WorkflowResult<Long> wfResult,
@@ -159,15 +160,6 @@ public class PropagationManagerImpl implements PropagationManager {
         return getGroupCreateTasks(wfResult.getResult(), vAttrs, wfResult.getPropByRes(), noPropResourceNames);
     }
 
-    /**
-     * Create the group on every associated resource.
-     *
-     * @param key group key
-     * @param vAttrs virtual attributes to be set
-     * @param propByRes operation to be performed per resource
-     * @param noPropResourceNames external resources performing not to be considered for propagation
-     * @return list of propagation tasks
-     */
     @Override
     public List<PropagationTask> getGroupCreateTasks(
             final Long key,
@@ -199,14 +191,17 @@ public class PropagationManagerImpl implements PropagationManager {
         return createTasks(any, password, true, null, null, enable, false, propByRes);
     }
 
-    /**
-     * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter.
-     *
-     * @param user to be propagated
-     * @param enable whether user must be enabled or not
-     * @param noPropResourceNames external resource names not to be considered for propagation
-     * @return list of propagation tasks
-     */
+    @Override
+    public List<PropagationTask> getAnyObjectUpdateTasks(
+            final WorkflowResult<Long> wfResult,
+            final Set<String> vAttrsToBeRemoved, final Set<AttrMod> vAttrsToBeUpdated,
+            final Set<String> noPropResourceNames) {
+
+        AnyObject anyObject = anyObjectDAO.authFind(wfResult.getResult());
+        return getUpdateTasks(anyObject, null, false, null,
+                vAttrsToBeRemoved, vAttrsToBeUpdated, wfResult.getPropByRes(), noPropResourceNames);
+    }
+
     @Override
     public List<PropagationTask> getUserUpdateTasks(final User user, final Boolean enable,
             final Collection<String> noPropResourceNames) {
@@ -222,14 +217,6 @@ public class PropagationManagerImpl implements PropagationManager {
                 noPropResourceNames);
     }
 
-    /**
-     * Performs update on each resource associated to the user.
-     *
-     * @param wfResult user to be propagated (and info associated), as per result from workflow
-     * @param changePwd whether password should be included for propagation attributes or not
-     * @param noPropResourceNames external resources not to be considered for propagation
-     * @return list of propagation tasks
-     */
     @Override
     public List<PropagationTask> getUserUpdateTasks(final WorkflowResult<Pair<UserMod, Boolean>> wfResult,
             final boolean changePwd, final Collection<String> noPropResourceNames) {
@@ -329,6 +316,11 @@ public class PropagationManagerImpl implements PropagationManager {
     }
 
     @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(final Long anyObjectKey) {
+        return getAnyObjectDeleteTasks(anyObjectKey, Collections.<String>emptySet());
+    }
+
+    @Override
     public List<PropagationTask> getAnyObjectDeleteTasks(final Long anyObjectKey, final String noPropResourceName) {
         return getAnyObjectDeleteTasks(anyObjectKey, Collections.<String>singleton(noPropResourceName));
     }
@@ -342,6 +334,14 @@ public class PropagationManagerImpl implements PropagationManager {
     }
 
     @Override
+    public List<PropagationTask> getAnyObjectDeleteTasks(
+            final Long groupKey, final Set<String> resourceNames, final Collection<String> noPropResourceNames) {
+
+        AnyObject anyObject = anyObjectDAO.authFind(groupKey);
+        return getDeleteTaskIds(anyObject, resourceNames, noPropResourceNames);
+    }
+
+    @Override
     public List<PropagationTask> getUserDeleteTasks(final Long userKey, final Collection<String> noPropResourceNames) {
         User user = userDAO.authFind(userKey);
         return getDeleteTaskIds(user, userDAO.findAllResourceNames(user), noPropResourceNames);
@@ -356,12 +356,6 @@ public class PropagationManagerImpl implements PropagationManager {
     }
 
     @Override
-    public List<PropagationTask> getUserDeleteTasks(final WorkflowResult<Long> wfResult) {
-        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());
     }
@@ -460,7 +454,8 @@ public class PropagationManagerImpl implements PropagationManager {
                 } else {
                     PropagationTask task = entityFactory.newEntity(PropagationTask.class);
                     task.setResource(resource);
-                    task.setObjectClassName(resource.getProvision(any.getType()).getObjectClass().getObjectClassValue());
+                    task.setObjectClassName(
+                            resource.getProvision(any.getType()).getObjectClass().getObjectClassValue());
                     task.setAnyTypeKind(anyUtils.getAnyTypeKind());
                     if (!deleteOnResource) {
                         task.setAnyKey(any.getKey());

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 2c04f26..4f7b744 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
@@ -414,21 +414,21 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
                 throw new JobExecutionException("Task " + taskId + " isn't a SyncTask");
             }
 
-            T _task = clazz.cast(this.task);
+            T provisioningTask = clazz.cast(this.task);
 
             Connector connector;
             try {
-                connector = connFactory.getConnector(_task.getResource());
+                connector = connFactory.getConnector(provisioningTask.getResource());
             } catch (Exception e) {
                 final String msg = String.
                         format("Connector instance bean for resource %s and connInstance %s not found",
-                                _task.getResource(), _task.getResource().getConnector());
+                                provisioningTask.getResource(), provisioningTask.getResource().getConnector());
 
                 throw new JobExecutionException(msg, e);
             }
 
             boolean noMapping = true;
-            for (Provision provision : _task.getResource().getProvisions()) {
+            for (Provision provision : provisioningTask.getResource().getProvisions()) {
                 Mapping mapping = provision.getMapping();
                 if (mapping != null) {
                     noMapping = false;
@@ -443,7 +443,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
             }
 
             return executeWithSecurityContext(
-                    _task,
+                    provisioningTask,
                     connector,
                     dryRun);
         } catch (Throwable t) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/resources/provisioning.properties
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioning.properties b/core/provisioning-java/src/main/resources/provisioning.properties
index 9c0abff..af1dd4b 100644
--- a/core/provisioning-java/src/main/resources/provisioning.properties
+++ b/core/provisioning-java/src/main/resources/provisioning.properties
@@ -16,4 +16,5 @@
 # under the License.
 userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserProvisioningManager
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
+anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/provisioning-java/src/main/resources/provisioningContext.xml
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index 9b50b7d..32120f4 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -33,6 +33,7 @@ under the License.
   
   <bean class="${userProvisioningManager}"/>
   <bean class="${groupProvisioningManager}"/>
+  <bean class="${anyObjectProvisioningManager}"/>
 
   <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
         lazy-init="false" depends-on="nonJPAdbInitializer">

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 969dd89..039337f 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
@@ -29,6 +29,7 @@ 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.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
 import org.apache.syncope.common.lib.types.PropagationMode;
@@ -39,6 +40,7 @@ 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.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -82,7 +84,8 @@ public class ResourceDataBinderTest extends AbstractTest {
         resourceTO.setEnforceMandatoryCondition(true);
 
         ProvisionTO provisionTO = new ProvisionTO();
-        provisionTO.setAnyType("user");
+        provisionTO.setAnyType(AnyTypeKind.USER.name());
+        provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
         resourceTO.getProvisions().add(provisionTO);
 
         MappingTO mapping = new MappingTO();

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.java
new file mode 100644
index 0000000..ef15ab0
--- /dev/null
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/AbstractAnyObjectWorkflowAdapter.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.java;
+
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
+import org.apache.syncope.core.workflow.api.AnyObjectWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional(rollbackFor = { Throwable.class })
+public abstract class AbstractAnyObjectWorkflowAdapter implements AnyObjectWorkflowAdapter {
+
+    @Autowired
+    protected AnyObjectDataBinder dataBinder;
+
+    @Autowired
+    protected AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    protected EntityFactory entityFactory;
+
+    @Override
+    public String getPrefix() {
+        return null;
+    }
+
+    protected abstract WorkflowResult<Long> doUpdate(AnyObject anyObject, AnyObjectMod anyObjectMod);
+
+    @Override
+    public WorkflowResult<Long> update(final AnyObjectMod anyObjectMod) {
+        return doUpdate(anyObjectDAO.authFind(anyObjectMod.getKey()), anyObjectMod);
+    }
+
+    protected abstract void doDelete(AnyObject anyObject);
+
+    @Override
+    public void delete(final Long anyObjectKey) {
+        doDelete(anyObjectDAO.authFind(anyObjectKey));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
new file mode 100644
index 0000000..09f007d
--- /dev/null
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.java;
+
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.AnyObjectMod;
+import org.apache.syncope.common.lib.to.AnyObjectTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import org.apache.syncope.core.workflow.api.WorkflowDefinitionFormat;
+import org.apache.syncope.core.workflow.api.WorkflowException;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Simple implementation basically not involving any workflow engine.
+ */
+@Transactional(rollbackFor = { Throwable.class })
+public class DefaultAnyObjectWorkflowAdapter extends AbstractAnyObjectWorkflowAdapter {
+
+    @Override
+    public WorkflowResult<Long> create(final AnyObjectTO anyObjectTO) {
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        dataBinder.create(anyObject, anyObjectTO);
+        anyObject = anyObjectDAO.save(anyObject);
+
+        PropagationByResource propByRes = new PropagationByResource();
+        propByRes.set(ResourceOperation.CREATE, anyObject.getResourceNames());
+
+        return new WorkflowResult<>(anyObject.getKey(), propByRes, "create");
+    }
+
+    @Override
+    protected WorkflowResult<Long> doUpdate(final AnyObject anyObject, final AnyObjectMod anyObjectMod) {
+        PropagationByResource propByRes = dataBinder.update(anyObject, anyObjectMod);
+
+        AnyObject updated = anyObjectDAO.save(anyObject);
+
+        return new WorkflowResult<>(updated.getKey(), propByRes, "update");
+    }
+
+    @Override
+    protected void doDelete(final AnyObject anyObject) {
+        anyObjectDAO.delete(anyObject);
+    }
+
+    @Override
+    public WorkflowResult<Long> execute(final AnyObjectTO anyObject, final String taskId) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
+    public void exportDefinition(final WorkflowDefinitionFormat format, final OutputStream os) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
+    public void exportDiagram(final OutputStream os) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
+    public void importDefinition(final WorkflowDefinitionFormat format, final String definition) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
+    public List<WorkflowFormTO> getForms() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<WorkflowFormTO> getForms(final String workflowId, final String name) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public WorkflowFormTO getForm(final String workflowId) {
+        return null;
+    }
+
+    @Override
+    public WorkflowFormTO claimForm(final String taskId) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
+    public WorkflowResult<AnyObjectMod> submitForm(final WorkflowFormTO form) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/workflow-java/src/main/resources/workflow.properties
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/resources/workflow.properties b/core/workflow-java/src/main/resources/workflow.properties
index 7167164..f05a464 100644
--- a/core/workflow-java/src/main/resources/workflow.properties
+++ b/core/workflow-java/src/main/resources/workflow.properties
@@ -18,3 +18,4 @@ wf.directory=${conf.directory}
 jobExecutorActivate=false
 uwfAdapter=org.apache.syncope.core.workflow.java.DefaultUserWorkflowAdapter
 gwfAdapter=org.apache.syncope.core.workflow.java.DefaultGroupWorkflowAdapter
+awfAdapter=org.apache.syncope.core.workflow.java.DefaultAnyObjectWorkflowAdapter

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/core/workflow-java/src/main/resources/workflowContext.xml
----------------------------------------------------------------------
diff --git a/core/workflow-java/src/main/resources/workflowContext.xml b/core/workflow-java/src/main/resources/workflowContext.xml
index 8a6935e..8db5e17 100644
--- a/core/workflow-java/src/main/resources/workflowContext.xml
+++ b/core/workflow-java/src/main/resources/workflowContext.xml
@@ -24,5 +24,6 @@ under the License.
 
   <bean id="uwfAdapter" class="${uwfAdapter}"/>
   <bean id="gwfAdapter" class="${gwfAdapter}"/>
+  <bean id="awfAdapter" class="${awfAdapter}"/>
     
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
index 18aadcc..f97203a 100644
--- a/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
+++ b/ext/camel/provisioning-camel/src/main/java/org/apache/syncope/core/provisioning/camel/CamelGroupProvisioningManager.java
@@ -108,11 +108,19 @@ public class CamelGroupProvisioningManager
     }
 
     @Override
+    public List<PropagationStatus> delete(final Long groupObjectKey) {
+        return delete(groupObjectKey, Collections.<String>emptySet());
+    }
+
+    @Override
     @SuppressWarnings("unchecked")
-    public List<PropagationStatus> delete(final Long groupKey) {
+    public List<PropagationStatus> delete(final Long groupKey, final Set<String> excludedResources) {
         PollingConsumer pollingConsumer = getConsumer("direct:deleteGroupPort");
 
-        sendMessage("direct:deleteGroup", groupKey);
+        Map<String, Object> props = new HashMap<>();
+        props.put("excludedResources", excludedResources);
+
+        sendMessage("direct:deleteGroup", groupKey, props);
 
         Exchange exchange = pollingConsumer.receive();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 a258751..8f0d9d2 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
@@ -56,6 +56,11 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
+    public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final Set<String> excludedResources) {
+        return create(userTO, false, false, null, excludedResources);
+    }
+
+    @Override
     @SuppressWarnings("unchecked")
     public Pair<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword,
             final boolean disablePwdPolicyCheck, final Boolean enabled, final Set<String> excludedResources) {
@@ -80,6 +85,7 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Pair<Long, List<PropagationStatus>> update(final UserMod userMod) {
         PollingConsumer pollingConsumer = getConsumer("direct:updatePort");
 
@@ -95,6 +101,11 @@ public class CamelUserProvisioningManager extends AbstractCamelProvisioningManag
     }
 
     @Override
+    public Pair<Long, List<PropagationStatus>> update(final UserMod anyMod, final Set<String> excludedResources) {
+        return update(anyMod, anyMod.getKey(), new ProvisioningResult(), null, excludedResources);
+    }
+
+    @Override
     public List<PropagationStatus> delete(final Long userKey) {
         return delete(userKey, Collections.<String>emptySet());
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/705bfb86/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 f452ffd..8643f6a 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
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.syncope.common.lib.types.PropagationByResource;
@@ -61,22 +62,31 @@ public class GroupDeleteProcessor implements Processor {
     public void process(final Exchange exchange) throws Exception {
         Long anyKey = exchange.getIn().getBody(Long.class);
         Group group = groupDAO.find(anyKey);
+        @SuppressWarnings("unchecked")
+        Set<String> excludedResources = exchange.getProperty("excludedResources", Set.class);
 
-        final List<PropagationTask> tasks = new ArrayList<>();
+        List<PropagationTask> tasks = new ArrayList<>();
 
         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.findUsersWithTransitiveResources(group.getKey()).entrySet()) {
+
+                WorkflowResult<Long> wfResult =
+                        new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
+                tasks.addAll(propagationManager.getUserDeleteTasks(wfResult.getResult(), excludedResources));
+            }
+            for (Map.Entry<Long, PropagationByResource> entry
                     : groupDAO.findAnyObjectsWithTransitiveResources(group.getKey()).entrySet()) {
 
                 WorkflowResult<Long> wfResult =
                         new WorkflowResult<>(entry.getKey(), entry.getValue(), Collections.<String>emptySet());
-                tasks.addAll(propagationManager.getUserDeleteTasks(wfResult));
+                tasks.addAll(propagationManager.getAnyObjectDeleteTasks(wfResult.getResult(), excludedResources));
             }
 
             // Generate propagation tasks for deleting this group from resources
-            tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey()));
+            tasks.addAll(propagationManager.getGroupDeleteTasks(group.getKey(), excludedResources));
         }
 
         PropagationReporter propagationReporter =


[26/70] 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);
     }


[44/70] syncope git commit: [SYNCOPE-666] All tests are green, time to add more

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
index fb01aa4..4a8a35b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAnyDataBinder.java
@@ -18,14 +18,17 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
+import java.util.ArrayList;
 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.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -33,6 +36,8 @@ 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.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
 import org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.IntMappingType;
 import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -60,21 +65,25 @@ 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.misc.ConnObjectUtils;
-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.AnyTypeClassDAO;
 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.AnyTypeClass;
 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.Membership;
 import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Relationship;
 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.apache.syncope.core.provisioning.api.VirAttrHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,10 +92,18 @@ abstract class AbstractAnyDataBinder {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractAnyDataBinder.class);
 
+    private static final IntMappingType[] FOR_MANDATORY = new IntMappingType[] {
+        IntMappingType.AnyPlainSchema, IntMappingType.AnyDerivedSchema,
+        IntMappingType.UserPlainSchema, IntMappingType.UserDerivedSchema,
+        IntMappingType.GroupPlainSchema, IntMappingType.GroupDerivedSchema };
+
     @Autowired
     protected RealmDAO realmDAO;
 
     @Autowired
+    protected AnyTypeClassDAO anyTypeClassDAO;
+
+    @Autowired
     protected AnyObjectDAO anyObjectDAO;
 
     @Autowired
@@ -129,7 +146,7 @@ abstract class AbstractAnyDataBinder {
     protected AnyUtilsFactory anyUtilsFactory;
 
     @Autowired
-    protected VirAttrHandler virtAttrHander;
+    protected VirAttrHandler virAttrHander;
 
     @Autowired
     protected ConnObjectUtils connObjectUtils;
@@ -138,7 +155,7 @@ abstract class AbstractAnyDataBinder {
         if (StringUtils.isNotBlank(anyMod.getRealm())) {
             Realm newRealm = realmDAO.find(anyMod.getRealm());
             if (newRealm == null) {
-                LOG.warn("Invalid realm specified: {}, ignoring", anyMod.getRealm());
+                LOG.debug("Invalid realm specified: {}, ignoring", anyMod.getRealm());
             } else {
                 any.setRealm(newRealm);
             }
@@ -155,7 +172,6 @@ abstract class AbstractAnyDataBinder {
                 LOG.debug("Ignoring invalid schema {}", schemaName);
             } else if (schema.isReadonly()) {
                 schema = null;
-
                 LOG.debug("Ignoring readonly schema {}", schemaName);
             }
         }
@@ -175,7 +191,7 @@ abstract class AbstractAnyDataBinder {
         return schema;
     }
 
-    protected void fillAttribute(final List<String> values, final AnyUtils anyUtils,
+    private 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;
@@ -201,54 +217,57 @@ abstract class AbstractAnyDataBinder {
         }
     }
 
-    private boolean evaluateMandatoryCondition(final AnyUtils anyUtils, final ExternalResource resource,
-            final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) {
+    private List<String> evaluateMandatoryCondition(final Provision provision, final Any<?, ?, ?> any) {
+        List<String> missingAttrNames = new ArrayList<>();
+
+        if (provision != null) {
+            for (MappingItem item : provision.getMapping().getItems()) {
+                if (ArrayUtils.contains(FOR_MANDATORY, item.getIntMappingType())
+                        && (item.getPurpose() == MappingPurpose.PROPAGATION
+                        || item.getPurpose() == MappingPurpose.BOTH)) {
 
-        boolean result = false;
+                    List<PlainAttrValue> values = MappingUtils.getIntValues(
+                            provision, item, Collections.<Any<?, ?, ?>>singletonList(any), null, null);
+                    if ((values == null || values.isEmpty())
+                            && JexlUtils.evaluateMandatoryCondition(item.getMandatoryCondition(), any)) {
 
-        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);
+                        missingAttrNames.add(item.getIntAttrName());
+                    }
+                }
+            }
         }
 
-        return result;
+        return missingAttrNames;
     }
 
-    private boolean evaluateMandatoryCondition(final AnyUtils anyUtils,
-            final Any<?, ?, ?> any, final String intAttrName, final IntMappingType intMappingType) {
+    private SyncopeClientException checkMandatoryOnResources(
+            final Any<?, ?, ?> any, final Set<ExternalResource> resources) {
 
-        boolean result = false;
+        SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
 
-        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);
+        for (ExternalResource resource : resources) {
+            Provision provision = resource.getProvision(any.getType());
+            if (resource.isEnforceMandatoryCondition() && provision != null) {
+                List<String> missingAttrNames = evaluateMandatoryCondition(provision, any);
+                if (!missingAttrNames.isEmpty()) {
+                    LOG.error("Mandatory schemas {} not provided with values", missingAttrNames);
+
+                    reqValMissing.getElements().addAll(missingAttrNames);
+                }
             }
         }
 
-        return result;
+        return reqValMissing;
     }
 
-    private SyncopeClientException checkMandatory(final AnyUtils anyUtils, final Any<?, ?, ?> any) {
+    private SyncopeClientException checkMandatory(final Any<?, ?, ?> any) {
         SyncopeClientException reqValMissing = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
 
         // Check if there is some mandatory schema defined for which no value has been provided
         for (PlainSchema schema : any.getAllowedPlainSchemas()) {
             if (any.getPlainAttr(schema.getKey()) == null
                     && !schema.isReadonly()
-                    && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any)
-                    || evaluateMandatoryCondition(anyUtils, any, schema.getKey(),
-                            anyUtils.plainIntMappingType()))) {
+                    && (JexlUtils.evaluateMandatoryCondition(schema.getMandatoryCondition(), any))) {
 
                 LOG.error("Mandatory schema " + schema.getKey() + " not provided with values");
 
@@ -256,30 +275,21 @@ abstract class AbstractAnyDataBinder {
             }
         }
 
-        for (DerSchema derSchema : any.getAllowedDerSchemas()) {
-            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());
-            }
-        }
-
-        for (VirSchema virSchema : any.getAllowedVirSchemas()) {
-            if (any.getVirAttr(virSchema.getKey()) == null
-                    && !virSchema.isReadonly()
-                    && evaluateMandatoryCondition(anyUtils, any, virSchema.getKey(),
-                            anyUtils.virIntMappingType())) {
+        return reqValMissing;
+    }
 
-                LOG.error("Mandatory virtual schema " + virSchema.getKey() + " not provided with values");
+    private Set<ExternalResource> getAllResources(final Any<?, ?, ?> any) {
+        Set<ExternalResource> resources = new HashSet<>();
 
-                reqValMissing.getElements().add(virSchema.getKey());
-            }
+        if (any instanceof User) {
+            resources.addAll(userDAO.findAllResources((User) any));
+        } else if (any instanceof Group) {
+            resources.addAll(((Group) any).getResources());
+        } else if (any instanceof AnyObject) {
+            resources.addAll(anyObjectDAO.findAllResources((AnyObject) any));
         }
 
-        return reqValMissing;
+        return resources;
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -288,9 +298,29 @@ abstract class AbstractAnyDataBinder {
 
         PropagationByResource propByRes = new PropagationByResource();
 
+        // 1. anyTypeClass to be removed
+        for (String className : anyMod.getAuxClassesToRemove()) {
+            AnyTypeClass auxClass = anyTypeClassDAO.find(className);
+            if (auxClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName() + "{}, ignoring...", auxClass);
+            } else {
+                any.remove(auxClass);
+            }
+        }
+
+        // 2. anyTypeClass to be added
+        for (String className : anyMod.getAuxClassesToAdd()) {
+            AnyTypeClass auxClass = anyTypeClassDAO.find(className);
+            if (auxClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName() + "{}, ignoring...", auxClass);
+            } else {
+                any.add(auxClass);
+            }
+        }
+
         SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
 
-        // 1. resources to be removed
+        // 3. resources to be removed
         for (String resourceToBeRemoved : anyMod.getResourcesToRemove()) {
             ExternalResource resource = resourceDAO.find(resourceToBeRemoved);
             if (resource != null) {
@@ -301,7 +331,7 @@ abstract class AbstractAnyDataBinder {
 
         LOG.debug("Resources to be removed:\n{}", propByRes);
 
-        // 2. resources to be added
+        // 4. resources to be added
         for (String resourceToBeAdded : anyMod.getResourcesToAdd()) {
             ExternalResource resource = resourceDAO.find(resourceToBeAdded);
             if (resource != null) {
@@ -312,16 +342,9 @@ abstract class AbstractAnyDataBinder {
 
         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));
-        }
+        Set<ExternalResource> resources = getAllResources(any);
 
-        // 3. attributes to be removed
+        // 5. attributes to be removed
         for (String attributeToBeRemoved : anyMod.getPlainAttrsToRemove()) {
             PlainSchema schema = getPlainSchema(attributeToBeRemoved);
             if (schema != null) {
@@ -344,7 +367,7 @@ abstract class AbstractAnyDataBinder {
                     }
                 }
 
-                for (ExternalResource resource : externalResources) {
+                for (ExternalResource resource : resources) {
                     for (MappingItem mapItem : anyUtils.getMappingItems(
                             resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
@@ -364,7 +387,7 @@ abstract class AbstractAnyDataBinder {
 
         LOG.debug("Attributes to be removed:\n{}", propByRes);
 
-        // 4. attributes to be updated
+        // 6. attributes to be updated
         for (AttrMod attributeMod : anyMod.getPlainAttrsToUpdate()) {
             PlainSchema schema = getPlainSchema(attributeMod.getSchema());
             PlainAttr attr = null;
@@ -372,19 +395,15 @@ abstract class AbstractAnyDataBinder {
                 attr = any.getPlainAttr(schema.getKey());
                 if (attr == null) {
                     attr = anyUtils.newPlainAttr();
+                    attr.setOwner(any);
                     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);
-                    }
+                    any.add(attr);
                 }
             }
 
             if (schema != null && attr != null && attr.getSchema() != null) {
-                virtAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, schema.getKey(),
-                        externalResources, anyUtils.plainIntMappingType(), propByRes);
+                virAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, schema.getKey(),
+                        resources, anyUtils.plainIntMappingType(), propByRes);
 
                 // 1.1 remove values
                 Set<Long> valuesToBeRemoved = new HashSet<>();
@@ -429,7 +448,7 @@ abstract class AbstractAnyDataBinder {
 
         LOG.debug("Attributes to be updated:\n{}", propByRes);
 
-        // 5. derived attributes to be removed
+        // 7. derived attributes to be removed
         for (String derAttrToBeRemoved : anyMod.getDerAttrsToRemove()) {
             DerSchema derSchema = getDerSchema(derAttrToBeRemoved);
             if (derSchema != null) {
@@ -440,7 +459,7 @@ abstract class AbstractAnyDataBinder {
                     derAttrDAO.delete(derAttr);
                 }
 
-                for (ExternalResource resource : externalResources) {
+                for (ExternalResource resource : resources) {
                     for (MappingItem mapItem : anyUtils.getMappingItems(
                             resource.getProvision(any.getType()), MappingPurpose.PROPAGATION)) {
 
@@ -463,19 +482,18 @@ abstract class AbstractAnyDataBinder {
 
         LOG.debug("Derived attributes to be removed:\n{}", propByRes);
 
-        // 6. derived attributes to be added
+        // 8. 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);
+                virAttrHander.updateOnResourcesIfMappingMatches(any, anyUtils, derSchema.getKey(),
+                        resources, 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 derAttr = any.getDerAttr(derSchema.getKey());
+                if (derAttr == null) {
+                    derAttr = anyUtils.newDerAttr();
                     derAttr.setOwner(any);
+                    derAttr.setSchema(derSchema);
                     any.add(derAttr);
                 }
             }
@@ -483,8 +501,11 @@ abstract class AbstractAnyDataBinder {
 
         LOG.debug("Derived attributes to be added:\n{}", propByRes);
 
-        // Finally, check if mandatory values are missing
-        SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any);
+        SyncopeClientException requiredValuesMissing = checkMandatory(any);
+        if (!requiredValuesMissing.isEmpty()) {
+            scce.addException(requiredValuesMissing);
+        }
+        requiredValuesMissing = checkMandatoryOnResources(any, resources);
         if (!requiredValuesMissing.isEmpty()) {
             scce.addException(requiredValuesMissing);
         }
@@ -501,6 +522,17 @@ abstract class AbstractAnyDataBinder {
     protected void fill(final Any any, final AnyTO anyTO,
             final AnyUtils anyUtils, final SyncopeClientCompositeException scce) {
 
+        // 0. aux classes
+        any.getAuxClasses().clear();
+        for (String className : anyTO.getAuxClasses()) {
+            AnyTypeClass auxClass = anyTypeClassDAO.find(className);
+            if (auxClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName() + "{}, ignoring...", auxClass);
+            } else {
+                any.add(auxClass);
+            }
+        }
+
         // 1. attributes
         SyncopeClientException invalidValues = SyncopeClientException.build(ClientExceptionType.InvalidValues);
 
@@ -508,7 +540,6 @@ abstract class AbstractAnyDataBinder {
         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) {
@@ -534,7 +565,6 @@ abstract class AbstractAnyDataBinder {
         // 2. derived attributes
         for (AttrTO attributeTO : anyTO.getDerAttrs()) {
             DerSchema derSchema = getDerSchema(attributeTO.getSchema());
-
             if (derSchema != null) {
                 DerAttr derAttr = anyUtils.newDerAttr();
                 derAttr.setOwner(any);
@@ -545,8 +575,7 @@ abstract class AbstractAnyDataBinder {
 
         // 3. virtual attributes
         for (AttrTO vattrTO : anyTO.getVirAttrs()) {
-            VirSchema virSchema = virtAttrHander.getVirSchema(vattrTO.getSchema());
-
+            VirSchema virSchema = virAttrHander.getVirSchema(vattrTO.getSchema());
             if (virSchema != null) {
                 VirAttr virAttr = anyUtils.newVirAttr();
                 virAttr.setOwner(any);
@@ -555,27 +584,32 @@ abstract class AbstractAnyDataBinder {
             }
         }
 
-        virtAttrHander.fillVirtual(any, anyTO.getVirAttrs(), anyUtils);
+        SyncopeClientException requiredValuesMissing = checkMandatory(any);
+        if (!requiredValuesMissing.isEmpty()) {
+            scce.addException(requiredValuesMissing);
+        }
+
+        virAttrHander.fillVirtual(any, anyTO.getVirAttrs());
 
         // 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());
+            noRealm.getElements().add("Invalid or null realm specified: " + anyTO.getRealm());
             scce.addException(noRealm);
         }
         any.setRealm(realm);
 
         for (String resourceName : anyTO.getResources()) {
             ExternalResource resource = resourceDAO.find(resourceName);
-
-            if (resource != null) {
+            if (resource == null) {
+                LOG.debug("Invalid " + ExternalResource.class.getSimpleName() + "{}, ignoring...", resourceName);
+            } else {
                 any.add(resource);
             }
         }
 
-        SyncopeClientException requiredValuesMissing = checkMandatory(anyUtils, any);
+        requiredValuesMissing = checkMandatoryOnResources(any, getAllResources(any));
         if (!requiredValuesMissing.isEmpty()) {
             scce.addException(requiredValuesMissing);
         }
@@ -588,11 +622,22 @@ abstract class AbstractAnyDataBinder {
 
     protected void fillTO(final AnyTO anyTO,
             final String realmFullPath,
+            final Collection<? extends AnyTypeClass> auxClasses,
             final Collection<? extends PlainAttr<?>> attrs,
             final Collection<? extends DerAttr<?>> derAttrs,
             final Collection<? extends VirAttr<?>> virAttrs,
             final Collection<? extends ExternalResource> resources) {
 
+        anyTO.setRealm(realmFullPath);
+
+        CollectionUtils.collect(auxClasses, new Transformer<AnyTypeClass, String>() {
+
+            @Override
+            public String transform(final AnyTypeClass role) {
+                return role.getKey();
+            }
+        }, anyTO.getAuxClasses());
+
         AttrTO attributeTO;
         for (PlainAttr<?> attr : attrs) {
             attributeTO = new AttrTO();
@@ -621,12 +666,29 @@ abstract class AbstractAnyDataBinder {
             anyTO.getVirAttrs().add(attributeTO);
         }
 
-        anyTO.setRealm(realmFullPath);
         for (ExternalResource resource : resources) {
             anyTO.getResources().add(resource.getKey());
         }
     }
 
+    protected RelationshipTO getRelationshipTO(final Relationship<? extends Any<?, ?, ?>, AnyObject> relationship) {
+        RelationshipTO relationshipTO = new RelationshipTO();
+        relationshipTO.setLeftKey(relationship.getLeftEnd().getKey());
+        relationshipTO.setLeftType(relationship.getLeftEnd().getType().getKey());
+        relationshipTO.setRightKey(relationship.getRightEnd().getKey());
+        relationshipTO.setRightType(relationship.getRightEnd().getType().getKey());
+        return relationshipTO;
+    }
+
+    protected MembershipTO getMembershipTO(final Membership<? extends Any<?, ?, ?>> membership) {
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setLeftKey(membership.getLeftEnd().getKey());
+        membershipTO.setLeftType(membership.getLeftEnd().getType().getKey());
+        membershipTO.setRightKey(membership.getRightEnd().getKey());
+        membershipTO.setGroupName(membership.getRightEnd().getName());
+        return membershipTO;
+    }
+
     protected Map<String, String> getConnObjectKeys(final Any<?, ?, ?> any) {
         Map<String, String> connObjectKeys = new HashMap<>();
 
@@ -637,7 +699,7 @@ abstract class AbstractAnyDataBinder {
                         : ((Group) any).getResources();
         for (ExternalResource resource : iterable) {
             Provision provision = resource.getProvision(any.getType());
-            if (provision.getMapping() != null) {
+            if (provision != null && provision.getMapping() != null) {
                 MappingItem connObjectKeyItem = anyUtilsFactory.getInstance(any).getConnObjectKeyItem(provision);
                 if (connObjectKeyItem == null) {
                     throw new NotFoundException(

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
index eb7586d..462a488 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyObjectDataBinderImpl.java
@@ -31,11 +31,13 @@ import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.mod.AnyObjectMod;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RelationshipTO;
 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.misc.spring.BeanUtils;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.provisioning.api.data.AnyObjectDataBinder;
@@ -47,7 +49,8 @@ import org.springframework.transaction.annotation.Transactional;
 public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements AnyObjectDataBinder {
 
     private static final String[] IGNORE_PROPERTIES = {
-        "realm", "memberships", "plainAttrs", "derAttrs", "virAttrs", "resources"
+        "type", "realm", "auxClasses", "relationships", "memberships", "dynGroups",
+        "plainAttrs", "derAttrs", "virAttrs", "resources"
     };
 
     @Transactional(readOnly = true)
@@ -62,20 +65,29 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
 
         BeanUtils.copyProperties(anyObject, anyObjectTO, IGNORE_PROPERTIES);
 
-        connObjectUtils.retrieveVirAttrValues(anyObject);
-        fillTO(anyObjectTO, anyObject.getRealm().getFullPath(),
+        virAttrHander.retrieveVirAttrValues(anyObject);
+        fillTO(anyObjectTO, anyObject.getRealm().getFullPath(), anyObject.getAuxClasses(),
                 anyObject.getPlainAttrs(), anyObject.getDerAttrs(), anyObject.getVirAttrs(),
                 anyObjectDAO.findAllResources(anyObject));
 
-        for (AMembership membership : anyObject.getMemberships()) {
-            MembershipTO membershipTO = new MembershipTO();
+        // relationships
+        CollectionUtils.collect(anyObject.getRelationships(), new Transformer<ARelationship, RelationshipTO>() {
 
-            membershipTO.setKey(membership.getKey());
-            membershipTO.setRightKey(membership.getRightEnd().getKey());
-            membershipTO.setGroupName(membership.getRightEnd().getName());
+            @Override
+            public RelationshipTO transform(final ARelationship relationship) {
+                return AnyObjectDataBinderImpl.this.getRelationshipTO(relationship);
+            }
 
-            anyObjectTO.getMemberships().add(membershipTO);
-        }
+        }, anyObjectTO.getRelationships());
+
+        // memberships
+        CollectionUtils.collect(anyObject.getMemberships(), new Transformer<AMembership, MembershipTO>() {
+
+            @Override
+            public MembershipTO transform(final AMembership membership) {
+                return AnyObjectDataBinderImpl.this.getMembershipTO(membership);
+            }
+        }, anyObjectTO.getMemberships());
 
         // dynamic memberships
         CollectionUtils.collect(anyObjectDAO.findDynGroupMemberships(anyObject), new Transformer<Group, Long>() {
@@ -93,6 +105,29 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
     public void create(final AnyObject anyObject, final AnyObjectTO anyObjectTO) {
         SyncopeClientCompositeException scce = SyncopeClientException.buildComposite();
 
+        // relationships
+        for (RelationshipTO relationshipTO : anyObjectTO.getRelationships()) {
+            AnyObject otherEnd = anyObjectDAO.find(relationshipTO.getRightKey());
+
+            if (otherEnd == null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+                }
+            } else {
+                ARelationship relationship = null;
+                if (anyObject.getKey() != null) {
+                    relationship = anyObject.getRelationship(otherEnd.getKey());
+                }
+                if (relationship == null) {
+                    relationship = entityFactory.newEntity(ARelationship.class);
+                    relationship.setRightEnd(otherEnd);
+                    relationship.setLeftEnd(anyObject);
+
+                    anyObject.add(relationship);
+                }
+            }
+        }
+
         // memberships
         for (MembershipTO membershipTO : anyObjectTO.getMemberships()) {
             Group group = groupDAO.find(membershipTO.getRightKey());
@@ -137,11 +172,44 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
         // attributes, derived attributes, virtual attributes and resources
         propByRes.merge(fill(anyObject, anyObjectMod, anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT), scce));
 
-        // store the group ids of membership required to be added
-        Set<Long> membershipToBeAddedGroupKeys = new HashSet<>(anyObjectMod.getMembershipsToAdd());
+        Set<String> toBeDeprovisioned = new HashSet<>();
+        Set<String> toBeProvisioned = new HashSet<>();
+
+        // relationships to be removed
+        for (Long anyObjectKey : anyObjectMod.getRelationshipsToRemove()) {
+            LOG.debug("Relationship to be removed for any object {}", anyObjectKey);
+
+            ARelationship relationship = anyObject.getRelationship(anyObjectKey);
+            if (relationship == null) {
+                LOG.warn("Invalid anyObject key specified for relationship to be removed: {}", anyObjectKey);
+            } else {
+                if (!anyObjectMod.getRelationshipsToAdd().contains(anyObjectKey)) {
+                    anyObject.remove(relationship);
+                    toBeDeprovisioned.addAll(relationship.getRightEnd().getResourceNames());
+                }
+            }
+        }
+
+        // relationships to be added
+        for (Long anyObjectKey : anyObjectMod.getRelationshipsToAdd()) {
+            LOG.debug("Relationship to be added for any object {}", anyObjectKey);
+
+            AnyObject otherEnd = anyObjectDAO.find(anyObjectKey);
+            if (otherEnd == null) {
+                LOG.debug("Ignoring invalid any object {}", anyObjectKey);
+            } else {
+                ARelationship relationship = anyObject.getRelationship(otherEnd.getKey());
+                if (relationship == null) {
+                    relationship = entityFactory.newEntity(ARelationship.class);
+                    relationship.setRightEnd(otherEnd);
+                    relationship.setLeftEnd(anyObject);
+
+                    anyObject.add(relationship);
 
-        final Set<String> toBeDeprovisioned = new HashSet<>();
-        final Set<String> toBeProvisioned = new HashSet<>();
+                    toBeProvisioned.addAll(otherEnd.getResourceNames());
+                }
+            }
+        }
 
         // memberships to be removed
         for (Long groupKey : anyObjectMod.getMembershipsToRemove()) {
@@ -151,9 +219,8 @@ public class AnyObjectDataBinderImpl extends AbstractAnyDataBinder implements An
             if (membership == null) {
                 LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey);
             } else {
-                if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
+                if (!anyObjectMod.getMembershipsToAdd().contains(groupKey)) {
                     anyObject.remove(membership);
-                } else {
                     toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.java
new file mode 100644
index 0000000..5917190
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeClassDataBinderImpl.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.provisioning.java.data;
+
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+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.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+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;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeClassDataBinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyTypeClassDataBinderImpl implements AnyTypeClassDataBinder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyTypeClassDataBinder.class);
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Override
+    public AnyTypeClass create(final AnyTypeClassTO anyTypeClassTO) {
+        AnyTypeClass anyTypeClass = entityFactory.newEntity(AnyTypeClass.class);
+        update(anyTypeClass, anyTypeClassTO);
+        return anyTypeClass;
+    }
+
+    @Override
+    public void update(final AnyTypeClass anyTypeClass, final AnyTypeClassTO anyTypeClassTO) {
+        if (anyTypeClass.getKey() == null) {
+            anyTypeClass.setKey(anyTypeClassTO.getKey());
+        }
+
+        anyTypeClass.getPlainSchemas().clear();
+        for (String schemaName : anyTypeClassTO.getPlainSchemas()) {
+            PlainSchema schema = plainSchemaDAO.find(schemaName);
+            if (schema == null) {
+                LOG.debug("Invalid " + PlainSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            } else {
+                anyTypeClass.add(schema);
+            }
+        }
+
+        anyTypeClass.getDerSchemas().clear();
+        for (String schemaName : anyTypeClassTO.getDerSchemas()) {
+            DerSchema schema = derSchemaDAO.find(schemaName);
+            if (schema == null) {
+                LOG.debug("Invalid " + DerSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            } else {
+                anyTypeClass.add(schema);
+            }
+        }
+
+        anyTypeClass.getVirSchemas().clear();
+        for (String schemaName : anyTypeClassTO.getVirSchemas()) {
+            VirSchema schema = virSchemaDAO.find(schemaName);
+            if (schema == null) {
+                LOG.debug("Invalid " + VirSchema.class.getSimpleName() + "{}, ignoring...", schemaName);
+            } else {
+                anyTypeClass.add(schema);
+            }
+        }
+    }
+
+    @Override
+    public AnyTypeClassTO getAnyTypeClassTO(final AnyTypeClass anyTypeClass) {
+        AnyTypeClassTO anyTypeClassTO = new AnyTypeClassTO();
+
+        anyTypeClassTO.setKey(anyTypeClass.getKey());
+        for (PlainSchema schema : anyTypeClass.getPlainSchemas()) {
+            anyTypeClassTO.getPlainSchemas().add(schema.getKey());
+        }
+        for (DerSchema schema : anyTypeClass.getDerSchemas()) {
+            anyTypeClassTO.getDerSchemas().add(schema.getKey());
+        }
+        for (VirSchema schema : anyTypeClass.getVirSchemas()) {
+            anyTypeClassTO.getVirSchemas().add(schema.getKey());
+        }
+
+        return anyTypeClassTO;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
new file mode 100644
index 0000000..0e85d3a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AnyTypeDataBinderImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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 org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AnyTypeDataBinderImpl implements AnyTypeDataBinder {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AnyTypeDataBinder.class);
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Autowired
+    private EntityFactory entityFactory;
+
+    @Override
+    public AnyType create(final AnyTypeTO anyTypeTO) {
+        AnyType anyType = entityFactory.newEntity(AnyType.class);
+        update(anyType, anyTypeTO);
+        return anyType;
+    }
+
+    @Override
+    public void update(final AnyType anyType, final AnyTypeTO anyTypeTO) {
+        if (anyType.getKey() == null) {
+            anyType.setKey(anyTypeTO.getKey());
+        }
+        if (anyType.getKind() == null) {
+            anyType.setKind(anyTypeTO.getKind());
+        }
+        if (anyType.getKind() != anyTypeTO.getKind()) {
+            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
+            sce.getElements().add("AnyTypeKind cannot be changed");
+            throw sce;
+        }
+
+        anyType.getClasses().clear();
+        for (String anyTypeClassName : anyTypeTO.getClasses()) {
+            AnyTypeClass anyTypeClass = anyTypeClassDAO.find(anyTypeClassName);
+            if (anyTypeClass == null) {
+                LOG.debug("Invalid " + AnyTypeClass.class.getSimpleName() + "{}, ignoring...", anyTypeClassName);
+            } else {
+                anyType.add(anyTypeClass);
+            }
+        }
+    }
+
+    @Override
+    public AnyTypeTO getAnyTypeTO(final AnyType anyType) {
+        AnyTypeTO anyTypeTO = new AnyTypeTO();
+
+        anyTypeTO.setKey(anyType.getKey());
+        anyTypeTO.setKind(anyType.getKind());
+        for (AnyTypeClass anyTypeClass : anyType.getClasses()) {
+            anyTypeTO.getClasses().add(anyTypeClass.getKey());
+        }
+
+        return anyTypeTO;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 fe5668d..3cf65fd 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
@@ -47,8 +47,8 @@ public class ConfigurationDataBinderImpl extends AbstractAnyDataBinder implement
         ConfTO confTO = new ConfTO();
         confTO.setKey(conf.getKey());
 
-        fillTO(confTO, null, conf.getPlainAttrs(),
-                conf.getDerAttrs(), conf.getVirAttrs(), Collections.<ExternalResource>emptySet());
+        fillTO(confTO, null, conf.getAuxClasses(),
+                conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs(), Collections.<ExternalResource>emptySet());
 
         return confTO;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 a900e70..a393fda 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
@@ -105,7 +105,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
         if (groupTO.getADynMembershipCond() != null) {
             setDynMembership(group, AnyTypeKind.ANY_OBJECT, groupTO.getADynMembershipCond());
         }
-        if (groupTO.getADynMembershipCond() != null) {
+        if (groupTO.getUDynMembershipCond() != null) {
             setDynMembership(group, AnyTypeKind.USER, groupTO.getUDynMembershipCond());
         }
 
@@ -188,7 +188,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
     @Transactional(readOnly = true)
     @Override
     public GroupTO getGroupTO(final Group group) {
-        connObjectUtils.retrieveVirAttrValues(group);
+        virAttrHander.retrieveVirAttrValues(group);
 
         GroupTO groupTO = new GroupTO();
 
@@ -208,7 +208,7 @@ public class GroupDataBinderImpl extends AbstractAnyDataBinder implements GroupD
             groupTO.setGroupOwner(group.getGroupOwner().getKey());
         }
 
-        fillTO(groupTO, group.getRealm().getFullPath(),
+        fillTO(groupTO, group.getRealm().getFullPath(), group.getAuxClasses(),
                 group.getPlainAttrs(), group.getDerAttrs(), group.getVirAttrs(), group.getResources());
 
         if (group.getADynMembership() != null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 eec346e..0d7ee47 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
@@ -19,6 +19,8 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
 import org.apache.syncope.common.lib.to.NotificationTO;
@@ -72,23 +74,35 @@ public class NotificationDataBinderImpl implements NotificationDataBinder {
     @Override
     public void update(final Notification notification, final NotificationTO notificationTO) {
         BeanUtils.copyProperties(notificationTO, notification, IGNORE_PROPERTIES);
+        notification.setRecipients(notificationTO.getRecipients());
 
-        notification.getAbouts().clear();
+        // 1. add or update all (valid) abouts from TO
         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());
+                    LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
                 } else {
-                    AnyAbout about = entityFactory.newEntity(AnyAbout.class);
-                    about.setAnyType(anyType);
-                    about.setNotification(notification);
-
-                    notification.add(about);
+                    AnyAbout about = notification.getAbout(anyType);
+                    if (about == null) {
+                        about = entityFactory.newEntity(AnyAbout.class);
+                        about.setAnyType(anyType);
+                        about.setNotification(notification);
+
+                        notification.add(about);
+                    }
+                    about.set(entry.getValue());
                 }
             }
         }
 
-        notification.setRecipients(notificationTO.getRecipients());
+        // 2. remove all abouts not contained in the TO
+        CollectionUtils.filter(notification.getAbouts(), new Predicate<AnyAbout>() {
+
+            @Override
+            public boolean evaluate(final AnyAbout anyAbout) {
+                return notificationTO.getAbouts().containsKey(anyAbout.getAnyType().getKey());
+            }
+        });
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 20b3c58..cb8f979 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
@@ -22,6 +22,8 @@ import org.apache.syncope.core.provisioning.api.data.ResourceDataBinder;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.lang3.SerializationUtils;
 import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -89,8 +91,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         resource.setKey(resourceTO.getKey());
 
-        if (resourceTO.getConnectorId() != null) {
-            ConnInstance connector = connInstanceDAO.find(resourceTO.getConnectorId());
+        if (resourceTO.getConnector() != null) {
+            ConnInstance connector = connInstanceDAO.find(resourceTO.getConnector());
             resource.setConnector(connector);
 
             if (!connector.getResources().contains(resource)) {
@@ -108,10 +110,11 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
         resource.setPropagationMode(resourceTO.getPropagationMode());
 
+        // 1. add or update all (valid) provisions from TO
         for (ProvisionTO provisionTO : resourceTO.getProvisions()) {
             AnyType anyType = anyTypeDAO.find(provisionTO.getAnyType());
             if (anyType == null) {
-                LOG.warn("Invalid type specified {}, ignoring...", provisionTO.getAnyType());
+                LOG.debug("Invalid AnyType specified {}, ignoring...", provisionTO.getAnyType());
             } else {
                 Provision provision = resource.getProvision(anyType);
                 if (provision == null) {
@@ -135,14 +138,28 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
                 if (provisionTO.getMapping() == null) {
                     provision.setMapping(null);
                 } else {
-                    Mapping mapping = entityFactory.newEntity(Mapping.class);
-                    mapping.setProvision(provision);
-                    provision.setMapping(mapping);
+                    Mapping mapping = provision.getMapping();
+                    if (mapping == null) {
+                        mapping = entityFactory.newEntity(Mapping.class);
+                        mapping.setProvision(provision);
+                        provision.setMapping(mapping);
+                    } else {
+                        mapping.getItems().clear();
+                    }
                     populateMapping(provisionTO.getMapping(), mapping, entityFactory.newEntity(MappingItem.class));
                 }
             }
         }
 
+        // 2. remove all abouts not contained in the TO
+        CollectionUtils.filter(resource.getProvisions(), new Predicate<Provision>() {
+
+            @Override
+            public boolean evaluate(final Provision provision) {
+                return resourceTO.getProvision(provision.getAnyType().getKey()) != null;
+            }
+        });
+
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
         resource.setUpdateTraceLevel(resourceTO.getUpdateTraceLevel());
         resource.setDeleteTraceLevel(resourceTO.getDeleteTraceLevel());
@@ -207,8 +224,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
             }
         }
 
-        // Throw composite exception if there is at least one element set
-        // in the composing exceptions
+        // Throw composite exception if there is at least one element set in the composing exceptions
         if (!requiredValuesMissing.isEmpty()) {
             scce.addException(requiredValuesMissing);
         }
@@ -234,9 +250,9 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
 
     @Override
     public ConnInstance getConnInstance(final ResourceTO resourceTO) {
-        ConnInstance connInstance = connInstanceDAO.find(resourceTO.getConnectorId());
+        ConnInstance connInstance = connInstanceDAO.find(resourceTO.getConnector());
         if (connInstance == null) {
-            throw new NotFoundException("Connector '" + resourceTO.getConnectorId() + "'");
+            throw new NotFoundException("Connector '" + resourceTO.getConnector() + "'");
         }
 
         final ConnInstance connInstanceClone = SerializationUtils.clone(connInstance);
@@ -279,7 +295,7 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
         // set the connector instance
         ConnInstance connector = resource.getConnector();
 
-        resourceTO.setConnectorId(connector == null ? null : connector.getKey());
+        resourceTO.setConnector(connector == null ? null : connector.getKey());
         resourceTO.setConnectorDisplayName(connector == null ? null : connector.getDisplayName());
 
         // set the provision information
@@ -295,6 +311,8 @@ public class ResourceDataBinderImpl implements ResourceDataBinder {
                 provisionTO.setMapping(mappingTO);
                 populateMappingTO(provision.getMapping(), mappingTO);
             }
+
+            resourceTO.getProvisions().add(provisionTO);
         }
 
         resourceTO.setEnforceMandatoryCondition(resource.isEnforceMandatoryCondition());

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 b286043..124bb7f 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
@@ -84,7 +84,7 @@ public class RoleDataBinderImpl implements RoleDataBinder {
         for (String realmFullPath : roleTO.getRealms()) {
             Realm realm = realmDAO.find(realmFullPath);
             if (realm == null) {
-                LOG.warn("Invalid realm full path {}, ignoring", realmFullPath);
+                LOG.debug("Invalid realm full path {}, ignoring", realmFullPath);
             } else {
                 role.addRealm(realm);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 e44198b..f20a265 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
@@ -70,7 +70,7 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
         boolean hasAttrs = false;
         for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
             AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
-            hasAttrs &= schemaDAO.findAttrs(schema, anyUtils.plainAttrClass()).isEmpty();
+            hasAttrs |= schemaDAO.findAttrs(schema, anyUtils.plainAttrClass()).isEmpty();
         }
 
         if (hasAttrs) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 c25b3ed..762cca5 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
@@ -19,6 +19,8 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.util.Map;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.syncope.core.provisioning.api.data.TaskDataBinder;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.SyncopeClientException;
@@ -72,13 +74,10 @@ import org.springframework.stereotype.Component;
 @Component
 public class TaskDataBinderImpl implements TaskDataBinder {
 
-    /**
-     * Logger.
-     */
     private static final Logger LOG = LoggerFactory.getLogger(TaskDataBinder.class);
 
     private static final String[] IGNORE_TASK_PROPERTIES = {
-        "destinationRealm", "executions", "resource", "matchingRule", "unmatchingRule" };
+        "destinationRealm", "templates", "filters", "executions", "resource", "matchingRule", "unmatchingRule" };
 
     private static final String[] IGNORE_TASK_EXECUTION_PROPERTIES = { "key", "task" };
 
@@ -100,40 +99,82 @@ public class TaskDataBinderImpl implements TaskDataBinder {
     @Autowired
     private SchedulerFactoryBean scheduler;
 
-    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));
+    private void checkTemplateJEXL(final SyncTaskTO syncTaskTO) {
+        SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSyncTask);
+
+        for (Map.Entry<String, AnyTO> entry : syncTaskTO.getTemplates().entrySet()) {
+            for (AttrTO attrTO : entry.getValue().getPlainAttrs()) {
+                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+                }
+            }
+
+            for (AttrTO attrTO : entry.getValue().getVirAttrs()) {
+                if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
+                    sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+                }
             }
-        }
 
-        for (AttrTO attrTO : anyTO.getVirAttrs()) {
-            if (!attrTO.getValues().isEmpty() && !JexlUtils.isExpressionValid(attrTO.getValues().get(0))) {
-                sce.getElements().add("Invalid JEXL: " + attrTO.getValues().get(0));
+            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 (!sce.isEmpty()) {
+            throw sce;
+        }
     }
 
     private void fill(final ProvisioningTask task, final AbstractProvisioningTaskTO taskTO) {
         if (task instanceof PushTask && taskTO instanceof PushTaskTO) {
-            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());
-
-                filter.setPushTask(pushTask);
-                pushTask.add(filter);
-            }
+            final PushTask pushTask = (PushTask) task;
+            final PushTaskTO pushTaskTO = (PushTaskTO) taskTO;
 
             pushTask.setMatchingRule(pushTaskTO.getMatchingRule() == null
                     ? MatchingRule.LINK : pushTaskTO.getMatchingRule());
-
             pushTask.setUnmatchingRule(pushTaskTO.getUnmatchingRule() == null
                     ? UnmatchingRule.ASSIGN : pushTaskTO.getUnmatchingRule());
 
+            for (Map.Entry<String, String> entry : pushTaskTO.getFilters().entrySet()) {
+                AnyType type = anyTypeDAO.find(entry.getKey());
+                if (type == null) {
+                    LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
+                } else {
+                    AnyFilter filter = pushTask.getFilter(type);
+                    if (filter == null) {
+                        filter = entityFactory.newEntity(AnyFilter.class);
+                        filter.setAnyType(anyTypeDAO.find(entry.getKey()));
+                        filter.setPushTask(pushTask);
+                        pushTask.add(filter);
+                    }
+                    filter.set(entry.getValue());
+                }
+            }
+            // remove all filters not contained in the TO
+            CollectionUtils.filter(pushTask.getFilters(), new Predicate<AnyFilter>() {
+
+                @Override
+                public boolean evaluate(final AnyFilter anyFilter) {
+                    return pushTaskTO.getFilters().containsKey(anyFilter.getAnyType().getKey());
+                }
+            });
         } else if (task instanceof SyncTask && taskTO instanceof SyncTaskTO) {
             final SyncTask syncTask = (SyncTask) task;
             final SyncTaskTO syncTaskTO = (SyncTaskTO) taskTO;
@@ -142,52 +183,35 @@ public class TaskDataBinderImpl implements TaskDataBinder {
 
             syncTask.setMatchingRule(syncTaskTO.getMatchingRule() == null
                     ? MatchingRule.UPDATE : syncTaskTO.getMatchingRule());
-
             syncTask.setUnmatchingRule(syncTaskTO.getUnmatchingRule() == null
                     ? UnmatchingRule.PROVISION : syncTaskTO.getUnmatchingRule());
 
-            SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidSyncTask);
-            // 1. validate JEXL expressions in user and group templates
+            // validate JEXL expressions from templates and proceed if fine
+            checkTemplateJEXL(syncTaskTO);
             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());
+                AnyType type = anyTypeDAO.find(entry.getKey());
+                if (type == null) {
+                    LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
+                } else {
+                    AnyTemplate anyTemplate = syncTask.getTemplate(type);
+                    if (anyTemplate == null) {
+                        anyTemplate = entityFactory.newEntity(AnyTemplate.class);
+                        anyTemplate.setAnyType(type);
+                        anyTemplate.setSyncTask(syncTask);
+
+                        syncTask.add(anyTemplate);
                     }
+                    anyTemplate.set(entry.getValue());
                 }
             }
-            if (!sce.isEmpty()) {
-                throw sce;
-            }
+            // remove all templates not contained in the TO
+            CollectionUtils.filter(syncTask.getTemplates(), new Predicate<AnyTemplate>() {
 
-            // 2. all JEXL expressions are valid: accept user and group templates
-            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);
+                @Override
+                public boolean evaluate(final AnyTemplate anyTemplate) {
+                    return syncTaskTO.getTemplates().containsKey(anyTemplate.getAnyType().getKey());
                 }
-            }
+            });
 
             syncTask.setFullReconciliation(syncTaskTO.isFullReconciliation());
         }
@@ -197,18 +221,13 @@ 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
-    ) {
-        final Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
-
+    public SchedTask createSchedTask(final SchedTaskTO taskTO, final TaskUtils taskUtils) {
+        Class<? extends AbstractTaskTO> taskTOClass = taskUtils.taskTOClass();
         if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
             throw new IllegalArgumentException(
                     String.format("taskUtils is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
@@ -222,7 +241,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
         if (taskUtils.getType() == TaskType.SCHEDULED) {
             task.setJobClassName(taskTO.getJobClassName());
         } else if (taskTO instanceof AbstractProvisioningTaskTO) {
-            final AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
+            AbstractProvisioningTaskTO provisioningTaskTO = (AbstractProvisioningTaskTO) taskTO;
 
             ExternalResource resource = resourceDAO.find(provisioningTaskTO.getResource());
             if (resource == null) {
@@ -237,10 +256,7 @@ 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();
 
@@ -268,8 +284,7 @@ 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);
 
@@ -347,6 +362,10 @@ public class TaskDataBinderImpl implements TaskDataBinder {
                         ? MatchingRule.UPDATE : ((SyncTask) task).getMatchingRule());
                 ((SyncTaskTO) taskTO).setUnmatchingRule(((SyncTask) task).getUnmatchingRule() == null
                         ? UnmatchingRule.PROVISION : ((SyncTask) task).getUnmatchingRule());
+
+                for (AnyTemplate template : ((SyncTask) task).getTemplates()) {
+                    ((SyncTaskTO) taskTO).getTemplates().put(template.getAnyType().getKey(), template.get());
+                }
                 break;
 
             case PUSH:
@@ -362,6 +381,10 @@ public class TaskDataBinderImpl implements TaskDataBinder {
                         ? MatchingRule.LINK : ((PushTask) task).getMatchingRule());
                 ((PushTaskTO) taskTO).setUnmatchingRule(((PushTask) task).getUnmatchingRule() == null
                         ? UnmatchingRule.ASSIGN : ((PushTask) task).getUnmatchingRule());
+
+                for (AnyFilter filter : ((PushTask) task).getFilters()) {
+                    ((PushTaskTO) taskTO).getFilters().put(filter.getAnyType().getKey(), filter.get());
+                }
                 break;
 
             case NOTIFICATION:

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 54d10bc..6c5e0d6 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
@@ -32,6 +32,7 @@ import org.apache.syncope.common.lib.SyncopeClientCompositeException;
 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.RelationshipTO;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
@@ -49,7 +50,9 @@ import org.apache.syncope.core.misc.security.Encryptor;
 import org.apache.syncope.core.misc.spring.BeanUtils;
 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.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
@@ -58,9 +61,9 @@ import org.springframework.transaction.annotation.Transactional;
 @Transactional(rollbackFor = { Throwable.class })
 public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDataBinder {
 
-    private static final String[] IGNORE_USER_PROPERTIES = {
-        "realm", "roles", "memberships", "plainAttrs", "derAttrs", "virAttrs", "resources",
-        "securityQuestion", "securityAnswer"
+    private static final String[] IGNORE_PROPERTIES = {
+        "type", "realm", "auxClasses", "roles", "dynRoles", "relationships", "memberships", "dynGroups",
+        "plainAttrs", "derAttrs", "virAttrs", "resources", "securityQuestion", "securityAnswer"
     };
 
     @Autowired
@@ -144,6 +147,29 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
             }
         }
 
+        // relationships
+        for (RelationshipTO relationshipTO : userTO.getRelationships()) {
+            AnyObject anyObject = anyObjectDAO.find(relationshipTO.getRightKey());
+
+            if (anyObject == null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Ignoring invalid anyObject " + relationshipTO.getRightKey());
+                }
+            } else {
+                URelationship relationship = null;
+                if (user.getKey() != null) {
+                    relationship = user.getRelationship(anyObject.getKey());
+                }
+                if (relationship == null) {
+                    relationship = entityFactory.newEntity(URelationship.class);
+                    relationship.setRightEnd(anyObject);
+                    relationship.setLeftEnd(user);
+
+                    user.add(relationship);
+                }
+            }
+        }
+
         // memberships
         for (MembershipTO membershipTO : userTO.getMemberships()) {
             Group group = groupDAO.find(membershipTO.getRightKey());
@@ -266,11 +292,44 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         // attributes, derived attributes, virtual attributes and resources
         propByRes.merge(fill(user, userMod, anyUtilsFactory.getInstance(AnyTypeKind.USER), scce));
 
-        // store the group ids of membership required to be added
-        Set<Long> membershipToBeAddedGroupKeys = new HashSet<>(userMod.getMembershipsToAdd());
+        Set<String> toBeDeprovisioned = new HashSet<>();
+        Set<String> toBeProvisioned = new HashSet<>();
+
+        // relationships to be removed
+        for (Long anyObjectKey : userMod.getRelationshipsToRemove()) {
+            LOG.debug("Relationship to be removed for any object {}", anyObjectKey);
+
+            URelationship relationship = user.getRelationship(anyObjectKey);
+            if (relationship == null) {
+                LOG.warn("Invalid anyObject key specified for relationship to be removed: {}", anyObjectKey);
+            } else {
+                if (!userMod.getRelationshipsToAdd().contains(anyObjectKey)) {
+                    user.remove(relationship);
+                    toBeDeprovisioned.addAll(relationship.getRightEnd().getResourceNames());
+                }
+            }
+        }
+
+        // relationships to be added
+        for (Long anyObjectKey : userMod.getRelationshipsToAdd()) {
+            LOG.debug("Relationship to be added for any object {}", anyObjectKey);
+
+            AnyObject otherEnd = anyObjectDAO.find(anyObjectKey);
+            if (otherEnd == null) {
+                LOG.debug("Ignoring invalid any object {}", anyObjectKey);
+            } else {
+                URelationship relationship = user.getRelationship(otherEnd.getKey());
+                if (relationship == null) {
+                    relationship = entityFactory.newEntity(URelationship.class);
+                    relationship.setRightEnd(otherEnd);
+                    relationship.setLeftEnd(user);
+
+                    user.add(relationship);
 
-        final Set<String> toBeDeprovisioned = new HashSet<>();
-        final Set<String> toBeProvisioned = new HashSet<>();
+                    toBeProvisioned.addAll(otherEnd.getResourceNames());
+                }
+            }
+        }
 
         // memberships to be removed
         for (Long groupKey : userMod.getMembershipsToRemove()) {
@@ -278,11 +337,10 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
 
             UMembership membership = user.getMembership(groupKey);
             if (membership == null) {
-                LOG.warn("Invalid group key specified for membership to be removed: {}", groupKey);
+                LOG.debug("Invalid group key specified for membership to be removed: {}", groupKey);
             } else {
-                if (membershipToBeAddedGroupKeys.contains(membership.getRightEnd().getKey())) {
+                if (!userMod.getMembershipsToAdd().contains(groupKey)) {
                     user.remove(membership);
-                } else {
                     toBeDeprovisioned.addAll(membership.getRightEnd().getResourceNames());
                 }
             }
@@ -312,10 +370,8 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
         propByRes.addAll(ResourceOperation.DELETE, toBeDeprovisioned);
         propByRes.addAll(ResourceOperation.UPDATE, toBeProvisioned);
 
-        /**
-         * In case of new memberships all the current resources have to be updated in order to propagate new group and
-         * membership attribute values.
-         */
+        // In case of new memberships all current resources need to be updated in order to propagate new group
+        // attribute values.
         if (!toBeDeprovisioned.isEmpty() || !toBeProvisioned.isEmpty()) {
             currentResources.removeAll(toBeDeprovisioned);
             propByRes.addAll(ResourceOperation.UPDATE, currentResources);
@@ -340,25 +396,43 @@ public class UserDataBinderImpl extends AbstractAnyDataBinder implements UserDat
     public UserTO getUserTO(final User user) {
         UserTO userTO = new UserTO();
 
-        BeanUtils.copyProperties(user, userTO, IGNORE_USER_PROPERTIES);
+        BeanUtils.copyProperties(user, userTO, IGNORE_PROPERTIES);
 
         if (user.getSecurityQuestion() != null) {
             userTO.setSecurityQuestion(user.getSecurityQuestion().getKey());
         }
 
-        connObjectUtils.retrieveVirAttrValues(user);
-        fillTO(userTO, user.getRealm().getFullPath(),
+        virAttrHander.retrieveVirAttrValues(user);
+        fillTO(userTO, user.getRealm().getFullPath(), user.getAuxClasses(),
                 user.getPlainAttrs(), user.getDerAttrs(), user.getVirAttrs(), userDAO.findAllResources(user));
 
-        for (UMembership membership : user.getMemberships()) {
-            MembershipTO membershipTO = new MembershipTO();
+        // roles
+        CollectionUtils.collect(user.getRoles(), new Transformer<Role, Long>() {
+
+            @Override
+            public Long transform(final Role role) {
+                return role.getKey();
+            }
+        }, userTO.getRoles());
+
+        // relationships
+        CollectionUtils.collect(user.getRelationships(), new Transformer<URelationship, RelationshipTO>() {
 
-            membershipTO.setKey(membership.getKey());
-            membershipTO.setRightKey(membership.getRightEnd().getKey());
-            membershipTO.setGroupName(membership.getRightEnd().getName());
+            @Override
+            public RelationshipTO transform(final URelationship relationship) {
+                return UserDataBinderImpl.this.getRelationshipTO(relationship);
+            }
 
-            userTO.getMemberships().add(membershipTO);
-        }
+        }, userTO.getRelationships());
+
+        // memberships
+        CollectionUtils.collect(user.getMemberships(), new Transformer<UMembership, MembershipTO>() {
+
+            @Override
+            public MembershipTO transform(final UMembership membership) {
+                return UserDataBinderImpl.this.getMembershipTO(membership);
+            }
+        }, userTO.getMemberships());
 
         // dynamic memberships
         CollectionUtils.collect(userDAO.findDynRoleMemberships(user), new Transformer<Role, Long>() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/dd88efbd/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 a0469a2..cdc540c 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
@@ -54,14 +54,13 @@ 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.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.syncope.core.provisioning.api.VirAttrHandler;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.context.Context;
@@ -143,7 +142,7 @@ public class NotificationManagerImpl implements NotificationManager {
     private ToolManager velocityToolManager;
 
     @Autowired
-    private ConnObjectUtils connObjectUtils;
+    private VirAttrHandler virAttrHander;
 
     @Autowired
     private UserDataBinder userDataBinder;
@@ -154,9 +153,6 @@ public class NotificationManagerImpl implements NotificationManager {
     @Autowired
     private EntityFactory entityFactory;
 
-    @Autowired
-    private AnyUtilsFactory anyUtilsFactory;
-
     @Transactional(readOnly = true)
     @Override
     public long getMaxRetries() {
@@ -177,10 +173,10 @@ public class NotificationManagerImpl implements NotificationManager {
             final Map<String, Object> model) {
 
         if (any != null) {
-            connObjectUtils.retrieveVirAttrValues(any);
+            virAttrHander.retrieveVirAttrValues(any);
         }
 
-        final List<User> recipients = new ArrayList<>();
+        List<User> recipients = new ArrayList<>();
 
         if (notification.getRecipients() != null) {
             recipients.addAll(searchDAO.<User>search(SyncopeConstants.FULL_ADMIN_REALMS,
@@ -192,10 +188,10 @@ public class NotificationManagerImpl implements NotificationManager {
             recipients.add((User) any);
         }
 
-        final Set<String> recipientEmails = new HashSet<>();
-        final List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
+        Set<String> recipientEmails = new HashSet<>();
+        List<UserTO> recipientTOs = new ArrayList<>(recipients.size());
         for (User recipient : recipients) {
-            connObjectUtils.retrieveVirAttrValues(recipient);
+            virAttrHander.retrieveVirAttrValues(recipient);
 
             String email = getRecipientEmail(notification.getRecipientAttrType(),
                     notification.getRecipientAttrName(), recipient);


[68/70] syncope git commit: [SYNCOPE-666] All done now

Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index c058db7..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
+++ /dev/null
@@ -1,372 +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.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-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.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.identityconnectors.framework.common.objects.ObjectClass;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-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");
-        assertNotNull("findById did not work", resource);
-
-        ConnInstance connector = resource.getConnector();
-        assertNotNull("connector not found", connector);
-        assertEquals("invalid connector name",
-                "net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
-        assertEquals("invalid bundle name", "net.tirasa.connid.bundles.soap", connector.getBundleName());
-
-        Mapping mapping = resource.getProvision(anyTypeDAO.findUser()).getMapping();
-        assertFalse("no mapping specified", mapping.getItems().isEmpty());
-
-        assertTrue(CollectionUtils.exists(mapping.getItems(), new Predicate<MappingItem>() {
-
-            @Override
-            public boolean evaluate(final MappingItem item) {
-                return 100 == item.getKey();
-            }
-        }));
-    }
-
-    @Test
-    public void findAll() {
-        List<ExternalResource> resources = resourceDAO.findAll();
-        assertNotNull(resources);
-        assertEquals(19, resources.size());
-    }
-
-    @Test
-    public void findAllByPriority() {
-        List<ExternalResource> resources = resourceDAO.findAllByPriority();
-        assertNotNull(resources);
-        assertFalse(resources.isEmpty());
-    }
-
-    @Test
-    public void getConnObjectKey() {
-        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
-        assertNotNull(resource);
-        assertEquals("fullname",
-                resource.getProvision(anyTypeDAO.findUser()).getMapping().getConnObjectKeyItem().getIntAttrName());
-    }
-
-    @Test
-    public void save() {
-        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
-        resource.setKey("ws-target-resource-basic-save");
-        resource.setPropagationPriority(2);
-        resource.setPropagationPrimary(true);
-
-        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);
-
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
-        connObjectKey.setExtAttrName("username");
-        connObjectKey.setIntAttrName("fullname");
-        connObjectKey.setIntMappingType(IntMappingType.UserKey);
-        connObjectKey.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(connObjectKey);
-
-        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
-        resource.setConnector(connector);
-
-        // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-
-        assertNotNull(actual);
-        assertNotNull(actual.getConnector());
-        assertNotNull(actual.getProvision(anyTypeDAO.findUser()).getMapping());
-        assertFalse(actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems().isEmpty());
-        assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
-        assertTrue(actual.isPropagationPrimary());
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidMappingIntAttr() {
-        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);
-
-        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);
-
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
-        connObjectKey.setConnObjectKey(true);
-        connObjectKey.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.add(connObjectKey);
-
-        // save the resource
-        resourceDAO.save(resource);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    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);
-
-        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);
-
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
-        connObjectKey.setConnObjectKey(true);
-        connObjectKey.setIntMappingType(IntMappingType.UserVirtualSchema);
-        mapping.setConnObjectKeyItem(connObjectKey);
-
-        // save the resource
-        resourceDAO.save(resource);
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidMappingExtAttr() {
-        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);
-
-        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);
-
-        MappingItem item = entityFactory.newEntity(MappingItem.class);
-        item.setConnObjectKey(true);
-        item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.add(item);
-
-        item = entityFactory.newEntity(MappingItem.class);
-        item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        mapping.add(item);
-
-        resourceDAO.save(resource);
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void saveInvalidProvision() {
-        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
-        resource.setKey("invalidProvision");
-
-        Provision provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findUser());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
-
-        Mapping mapping = entityFactory.newEntity(Mapping.class);
-        mapping.setProvision(provision);
-        provision.setMapping(mapping);
-
-        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
-        connObjectKey.setExtAttrName("username");
-        connObjectKey.setIntAttrName("fullname");
-        connObjectKey.setIntMappingType(IntMappingType.UserKey);
-        connObjectKey.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(connObjectKey);
-
-        provision = entityFactory.newEntity(Provision.class);
-        provision.setAnyType(anyTypeDAO.findGroup());
-        provision.setObjectClass(ObjectClass.ACCOUNT);
-        provision.setResource(resource);
-        resource.add(provision);
-
-        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
-        resource.setConnector(connector);
-
-        // save the resource
-        resourceDAO.save(resource);
-    }
-
-    @Test
-    public void saveWithGroupMappingType() {
-        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);
-
-        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);
-
-        MappingItem item = entityFactory.newEntity(MappingItem.class);
-        item.setIntAttrName("fullname");
-        item.setExtAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        item = entityFactory.newEntity(MappingItem.class);
-        item.setIntAttrName("icon");
-        item.setExtAttrName("icon");
-        item.setIntMappingType(IntMappingType.GroupPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        item = entityFactory.newEntity(MappingItem.class);
-        item.setIntAttrName("mderiveddata");
-        item.setExtAttrName("mderiveddata");
-        item.setIntMappingType(IntMappingType.AnyObjectDerivedSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.add(item);
-
-        // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
-
-        int items = 0;
-        for (MappingItem mapItem : actual.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
-            items++;
-
-            if ("icon".equals(mapItem.getIntAttrName())) {
-                assertTrue(IntMappingType.contains(AnyTypeKind.GROUP, mapItem.getIntMappingType().toString()));
-            }
-            if ("mderiveddata".equals(mapItem.getIntAttrName())) {
-                assertTrue(IntMappingType.contains(AnyTypeKind.ANY_OBJECT, mapItem.getIntMappingType().toString()));
-            }
-        }
-        assertEquals(3, items);
-    }
-
-    @Test
-    public void delete() {
-        ExternalResource resource = resourceDAO.find("ws-target-resource-2");
-        assertNotNull(resource);
-
-        resourceDAO.delete(resource.getKey());
-
-        ExternalResource actual = resourceDAO.find("ws-target-resource-2");
-        assertNull(actual);
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
-        resource.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-
-        try {
-            resourceDAO.save(resource);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
-        }
-    }
-
-    @Test(expected = InvalidEntityException.class)
-    public void issueSYNCOPE645() {
-        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);
-
-        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);
-
-        final MappingItem item = entityFactory.newEntity(MappingItem.class);
-        item.setIntAttrName("icon");
-        item.setExtAttrName("icon");
-        item.setIntMappingType(IntMappingType.GroupPlainSchema);
-        item.setPurpose(MappingPurpose.BOTH);
-        mapping.setConnObjectKeyItem(item);
-
-        // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.java
deleted file mode 100644
index 7a20e89..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/RoleTest.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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-import org.apache.syncope.common.lib.types.Entitlement;
-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.entity.Role;
-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 RoleTest extends AbstractTest {
-
-    @Autowired
-    private RoleDAO roleDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Test
-    public void find() {
-        Role role1 = roleDAO.find(2L);
-        assertNotNull(role1);
-        assertNotNull(role1.getName());
-        assertFalse(role1.getRealms().isEmpty());
-        assertFalse(role1.getEntitlements().isEmpty());
-        assertTrue(role1.getEntitlements().contains(Entitlement.USER_LIST));
-
-        Role role2 = roleDAO.find(role1.getName());
-        assertEquals(role1, role2);
-    }
-
-    @Test
-    public void findAll() {
-        List<Role> list = roleDAO.findAll();
-        assertNotNull(list);
-        assertFalse(list.isEmpty());
-        for (Role role : list) {
-            assertNotNull(role);
-        }
-    }
-
-    @Test
-    public void save() {
-        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);
-
-        Role actual = roleDAO.save(role);
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void delete() {
-        assertNotNull(roleDAO.find(3L));
-
-        roleDAO.delete(3L);
-        assertNull(roleDAO.find(3L));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SecurityQuestionTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SecurityQuestionTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SecurityQuestionTest.java
deleted file mode 100644
index 950bccc..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/SecurityQuestionTest.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 static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import java.util.List;
-import org.apache.syncope.core.persistence.api.dao.SecurityQuestionDAO;
-import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
-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 SecurityQuestionTest extends AbstractTest {
-
-    @Autowired
-    private SecurityQuestionDAO securityQuestionDAO;
-
-    @Test
-    public void find() {
-        SecurityQuestion securityQuestion = securityQuestionDAO.find(1L);
-        assertNotNull(securityQuestion);
-        assertNotNull(securityQuestion.getContent());
-    }
-
-    @Test
-    public void findAll() {
-        List<SecurityQuestion> securityQuestions = securityQuestionDAO.findAll();
-        assertNotNull(securityQuestions);
-        assertFalse(securityQuestions.isEmpty());
-    }
-
-    @Test
-    public void save() {
-        SecurityQuestion securityQuestion = entityFactory.newEntity(SecurityQuestion.class);
-        securityQuestion.setContent("What is your favorite pet's name?");
-
-        SecurityQuestion actual = securityQuestionDAO.save(securityQuestion);
-        assertNotNull(actual);
-        assertNotNull(actual.getKey());
-    }
-
-    @Test
-    public void delete() {
-        securityQuestionDAO.delete(1L);
-        assertNull(securityQuestionDAO.find(1L));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskExecTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskExecTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskExecTest.java
deleted file mode 100644
index 99f44ae..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskExecTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Date;
-import java.util.List;
-import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-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.TaskExecDAO;
-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.persistence.jpa.AbstractTest;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class TaskExecTest extends AbstractTest {
-
-    @Autowired
-    private TaskExecDAO taskExecDAO;
-
-    @Autowired
-    private TaskDAO taskDAO;
-
-    @Test
-    public void findAll() {
-        List<TaskExec> list = taskExecDAO.findAll(TaskType.PROPAGATION);
-        assertEquals(2, list.size());
-
-        list = taskExecDAO.findAll(TaskType.SCHEDULED);
-        assertTrue(list.isEmpty());
-
-        list = taskExecDAO.findAll(TaskType.SYNCHRONIZATION);
-        assertTrue(list.isEmpty());
-
-        list = taskExecDAO.findAll(TaskType.NOTIFICATION);
-        assertTrue(list.isEmpty());
-    }
-
-    @Test
-    public void findLatestStarted() {
-        PropagationTask task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        TaskExec latestStarted = taskExecDAO.findLatestStarted(task);
-        assertNotNull(latestStarted);
-        assertEquals(Long.valueOf(1L), latestStarted.getKey());
-    }
-
-    @Test
-    public void issueSYNCOPE214() {
-        PropagationTask task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        String faultyMessage = "A faulty message";
-        faultyMessage = faultyMessage.replace('a', '\0');
-
-        TaskExec exec = entityFactory.newEntity(TaskExec.class);
-        exec.setStartDate(new Date());
-        exec.setEndDate(new Date());
-        exec.setStatus(PropagationTaskExecStatus.SUCCESS.name());
-        exec.setMessage(faultyMessage);
-
-        task.addExec(exec);
-        exec.setTask(task);
-
-        exec = taskExecDAO.save(exec);
-        assertNotNull(exec);
-
-        assertEquals(faultyMessage.replace('\0', '\n'), exec.getMessage());
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index a4aed30..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/TaskTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.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.assertNull;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-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.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;
-import org.identityconnectors.framework.common.objects.Attribute;
-import org.identityconnectors.framework.common.objects.AttributeBuilder;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class TaskTest extends AbstractTest {
-
-    @Autowired
-    private TaskDAO taskDAO;
-
-    @Autowired
-    private ExternalResourceDAO resourceDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Test
-    public void findWithoutExecs() {
-        List<PropagationTask> tasks = taskDAO.findToExec(TaskType.PROPAGATION);
-        assertNotNull(tasks);
-        assertEquals(3, tasks.size());
-    }
-
-    @Test
-    public void findAll() {
-        assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
-        assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
-        assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
-        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
-        assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
-    }
-
-    @Test
-    public void savePropagationTask() {
-        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
-        assertNotNull(resource);
-
-        User user = userDAO.find(2L);
-        assertNotNull(user);
-
-        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
-        task.setResource(resource);
-        task.setAnyTypeKind(AnyTypeKind.USER);
-        task.setPropagationMode(PropagationMode.TWO_PHASES);
-        task.setPropagationOperation(ResourceOperation.CREATE);
-        task.setConnObjectKey("one@two.com");
-
-        Set<Attribute> attributes = new HashSet<>();
-        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", "testValue2"));
-        attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
-        task.setAttributes(attributes);
-
-        task = taskDAO.save(task);
-        assertNotNull(task);
-
-        PropagationTask actual = taskDAO.find(task.getKey());
-        assertEquals(task, actual);
-    }
-
-    @Test
-    public void delete() {
-        PropagationTask task = taskDAO.find(1L);
-        assertNotNull(task);
-
-        ExternalResource resource = task.getResource();
-        assertNotNull(resource);
-
-        taskDAO.delete(task);
-        task = taskDAO.find(1L);
-        assertNull(task);
-
-        resource = resourceDAO.find(resource.getKey());
-        assertNotNull(resource);
-        assertFalse(taskDAO.findAll(resource, TaskType.PROPAGATION).contains(task));
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/UserTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/UserTest.java
deleted file mode 100644
index d606dac..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/UserTest.java
+++ /dev/null
@@ -1,241 +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 static org.junit.Assert.fail;
-
-import java.util.Date;
-import java.util.List;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.persistence.api.dao.UserDAO;
-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;
-import org.apache.syncope.core.misc.policy.InvalidPasswordPolicySpecException;
-import org.apache.syncope.core.misc.security.PasswordGenerator;
-import org.apache.syncope.core.persistence.api.dao.RealmDAO;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class UserTest extends AbstractTest {
-
-    @Autowired
-    private PasswordGenerator passwordGenerator;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private RealmDAO realmDAO;
-
-    @Test
-    public void findAll() {
-        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
-        assertEquals("did not get expected number of users ", 5, list.size());
-    }
-
-    @Test
-    public void count() {
-        Integer count = userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
-        assertNotNull(count);
-        assertEquals(5, count, 0);
-    }
-
-    @Test
-    public void findAllByPageAndSize() {
-        // get first page
-        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 2);
-        assertEquals("did not get expected number of users ", 2, list.size());
-
-        // get second page
-        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 2);
-        assertEquals("did not get expected number of users ", 2, list.size());
-
-        // get second page with uncomplete set
-        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 3);
-        assertEquals("did not get expected number of users ", 2, list.size());
-
-        // get unexistent page
-        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 3, 2);
-        assertEquals("did not get expected number of users ", 1, list.size());
-    }
-
-    @Test
-    public void findByDerAttributeValue() {
-        final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, Antonio");
-        assertEquals("did not get expected number of users ", 1, list.size());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void findByInvalidDerAttrValue() {
-        userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi");
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void findByInvalidDerAttrExpression() {
-        userDAO.findByDerAttrValue("noschema", "Antonio, Maria");
-    }
-
-    @Test
-    public void findByAttributeValue() {
-        final UPlainAttrValue fullnameValue = entityFactory.newEntity(UPlainAttrValue.class);
-        fullnameValue.setStringValue("Gioacchino Rossini");
-
-        final List<User> list = userDAO.findByAttrValue("fullname", fullnameValue);
-        assertEquals("did not get expected number of users ", 1, list.size());
-    }
-
-    @Test
-    public void findByAttributeBooleanValue() {
-        final UPlainAttrValue coolValue = entityFactory.newEntity(UPlainAttrValue.class);
-        coolValue.setBooleanValue(true);
-
-        final List<User> list = userDAO.findByAttrValue("cool", coolValue);
-        assertEquals("did not get expected number of users ", 1, list.size());
-    }
-
-    @Test
-    public void findById() {
-        User user = userDAO.find(1L);
-        assertNotNull("did not find expected user", user);
-        user = userDAO.find(3L);
-        assertNotNull("did not find expected user", user);
-        user = userDAO.find(6L);
-        assertNull("found user but did not expect it", user);
-    }
-
-    @Test
-    public void findByUsername() {
-        User user = userDAO.find("rossini");
-        assertNotNull("did not find expected user", user);
-        user = userDAO.find("vivaldi");
-        assertNotNull("did not find expected user", user);
-        user = userDAO.find("user6");
-        assertNull("found user but did not expect it", user);
-    }
-
-    @Test
-    public void save() {
-        User user = entityFactory.newEntity(User.class);
-        user.setUsername("username");
-        user.setRealm(realmDAO.find("/even/two"));
-        user.setCreationDate(new Date());
-
-        user.setPassword("pass", CipherAlgorithm.SHA256);
-
-        try {
-            userDAO.save(user);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertNotNull(e);
-        }
-
-        user.setPassword("password", CipherAlgorithm.SHA256);
-
-        user.setUsername("username!");
-
-        try {
-            userDAO.save(user);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertNotNull(e);
-        }
-
-        user.setUsername("username");
-
-        User actual = userDAO.save(user);
-        assertNotNull("expected save to work", actual);
-        assertEquals(1, actual.getPasswordHistory().size());
-    }
-
-    @Test
-    public void delete() {
-        User user = userDAO.find(3L);
-
-        userDAO.delete(user.getKey());
-
-        User actual = userDAO.find(3L);
-        assertNull("delete did not work", actual);
-    }
-
-    @Test
-    public void issue237() {
-        User user = entityFactory.newEntity(User.class);
-        user.setUsername("username");
-        user.setRealm(realmDAO.find("/even/two"));
-        user.setCreationDate(new Date());
-
-        user.setPassword("password123", CipherAlgorithm.AES);
-
-        User actual = userDAO.save(user);
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void issueSYNCOPE391() {
-        User user = entityFactory.newEntity(User.class);
-        user.setUsername("username");
-        user.setPassword(null, CipherAlgorithm.AES);
-        user.setRealm(realmDAO.find("/even/two"));
-
-        User actual = userDAO.save(user);
-        assertNull(user.getPassword());
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void issueSYNCOPE226() {
-        User user = userDAO.find(5L);
-        String password = "";
-        try {
-            password = passwordGenerator.generate(user);
-        } catch (InvalidPasswordPolicySpecException ex) {
-            fail(ex.getMessage());
-        }
-        assertNotNull(password);
-
-        user.setPassword(password, CipherAlgorithm.AES);
-
-        User actual = userDAO.save(user);
-        assertNotNull(actual);
-    }
-
-    @Test
-    public void testPasswordGenerator() {
-        User user = userDAO.find(5L);
-
-        String password = "";
-        try {
-            password = passwordGenerator.generate(user);
-
-        } catch (InvalidPasswordPolicySpecException ex) {
-            fail(ex.getMessage());
-        }
-        assertNotNull(password);
-        user.setPassword(password, CipherAlgorithm.SHA);
-        userDAO.save(user);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/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
deleted file mode 100644
index 02815b8..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirAttrTest.java
+++ /dev/null
@@ -1,118 +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.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.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
-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.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 VirAttrTest extends AbstractTest {
-
-    @Autowired
-    private VirAttrDAO virAttrDAO;
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private GroupDAO groupDAO;
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Test
-    public void findAll() {
-        List<UVirAttr> list = virAttrDAO.findAll(UVirAttr.class);
-        assertEquals("did not get expected number of derived attributes ", 1, list.size());
-    }
-
-    @Test
-    public void findById() {
-        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-    }
-
-    @Test
-    public void saveUVirAttribute() {
-        VirSchema virSchema = virSchemaDAO.find("virtualdata");
-        assertNotNull(virSchema);
-
-        User owner = userDAO.find(3L);
-        assertNotNull("did not get expected user", owner);
-
-        UVirAttr virAttr = entityFactory.newEntity(UVirAttr.class);
-        virAttr.setOwner(owner);
-        virAttr.setSchema(virSchema);
-
-        virAttr = virAttrDAO.save(virAttr);
-
-        UVirAttr actual = virAttrDAO.find(virAttr.getKey(), UVirAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(virAttr, actual);
-    }
-
-    @Test
-    public void saveGVirAttribute() {
-        VirSchema virSchema = virSchemaDAO.find("rvirtualdata");
-        assertNotNull(virSchema);
-
-        Group owner = groupDAO.find(3L);
-        assertNotNull("did not get expected membership", owner);
-
-        GVirAttr virAttr = entityFactory.newEntity(GVirAttr.class);
-        virAttr.setOwner(owner);
-        virAttr.setSchema(virSchema);
-
-        virAttr = virAttrDAO.save(virAttr);
-
-        GVirAttr actual = virAttrDAO.find(virAttr.getKey(), GVirAttr.class);
-        assertNotNull("expected save to work", actual);
-        assertEquals(virAttr, actual);
-    }
-
-    @Test
-    public void delete() {
-        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
-        String attributeSchemaName = attribute.getSchema().getKey();
-
-        virAttrDAO.delete(attribute.getKey(), UVirAttr.class);
-
-        UVirAttr actual = virAttrDAO.find(1000L, UVirAttr.class);
-        assertNull("delete did not work", actual);
-
-        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/d8927ef4/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
deleted file mode 100644
index 3706f5f..0000000
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/VirSchemaTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.List;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-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 VirSchemaTest extends AbstractTest {
-
-    @Autowired
-    private VirSchemaDAO virSchemaDAO;
-
-    @Test
-    public void findAll() {
-        List<VirSchema> list = virSchemaDAO.findAll();
-        assertEquals(4, list.size());
-    }
-
-    @Test
-    public void findByName() {
-        VirSchema attributeSchema = virSchemaDAO.find("virtualdata");
-        assertNotNull("did not find expected virtual attribute schema", attributeSchema);
-    }
-
-    @Test
-    public void save() {
-        VirSchema virtualAttributeSchema = entityFactory.newEntity(VirSchema.class);
-        virtualAttributeSchema.setKey("virtual");
-        virtualAttributeSchema.setReadonly(true);
-
-        virSchemaDAO.save(virtualAttributeSchema);
-
-        VirSchema actual = virSchemaDAO.find("virtual");
-        assertNotNull("expected save to work", actual);
-        assertTrue(actual.isReadonly());
-    }
-
-    @Test
-    public void delete() {
-        VirSchema virtualdata = virSchemaDAO.find("virtualdata");
-
-        virSchemaDAO.delete(virtualdata.getKey());
-
-        VirSchema actual = virSchemaDAO.find("virtualdata");
-        assertNull("delete did not work", actual);
-
-        // ------------- //
-        VirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata");
-        assertNotNull(rvirtualdata);
-
-        virSchemaDAO.delete(rvirtualdata.getKey());
-
-        actual = virSchemaDAO.find("rvirtualdata");
-        assertNull("delete did not work", actual);
-    }
-
-    @Test
-    public void issueSYNCOPE418() {
-        VirSchema schema = entityFactory.newEntity(VirSchema.class);
-        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
-
-        try {
-            virSchemaDAO.save(schema);
-            fail();
-        } catch (InvalidEntityException e) {
-            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java
new file mode 100644
index 0000000..5130c28
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyObjectTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+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.anyobject.AnyObject;
+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 AnyObjectTest extends AbstractTest {
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<AnyObject> list = anyObjectDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void findAllByType() {
+        List<AnyObject> list = anyObjectDAO.findAll("PRINTER", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+
+        list = anyObjectDAO.findAll("UNEXISTING", SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void find() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        assertNotNull(anyObject);
+        assertNotNull(anyObject.getType());
+        assertFalse(anyObject.getType().getClasses().isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
+
+        anyObject = anyObjectDAO.save(anyObject);
+        assertNotNull(anyObject);
+    }
+
+    @Test
+    public void delete() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        anyObjectDAO.delete(anyObject.getKey());
+
+        AnyObject actual = anyObjectDAO.find(2L);
+        assertNull(actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
new file mode 100644
index 0000000..37aef3c
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -0,0 +1,520 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+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.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.AnyTypeCond;
+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 searchByBooleanAnyCond() {
+        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 searchByType() {
+        AnyTypeCond tcond = new AnyTypeCond();
+        tcond.setAnyTypeName("PRINTER");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(tcond);
+        assertTrue(searchCondition.isValid());
+
+        List<AnyObject> printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertEquals(2, printers.size());
+
+        tcond.setAnyTypeName("UNEXISTING");
+        printers = searchDAO.search(
+                SyncopeConstants.FULL_ADMIN_REALMS, searchCondition, AnyTypeKind.ANY_OBJECT);
+        assertNotNull(printers);
+        assertTrue(printers.isEmpty());
+    }
+
+    @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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.java
new file mode 100644
index 0000000..ed83f65
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeClassTest.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.core.persistence.jpa.inner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+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 AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyTypeClass minimalGroup = anyTypeClassDAO.find("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyTypeClass> list = anyTypeClassDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyTypeClass newClass = entityFactory.newEntity(AnyTypeClass.class);
+        newClass.setKey("new class");
+        newClass.add(plainSchemaDAO.find("firstname"));
+
+        newClass = anyTypeClassDAO.save(newClass);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        anyTypeClassDAO.delete(minimalUser.getKey());
+        assertNull(anyTypeClassDAO.find("minimal user"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
new file mode 100644
index 0000000..be60f46
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+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.AnyTypeClassDAO;
+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.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyType groupType = anyTypeDAO.findGroup();
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyType otherType = anyTypeDAO.find("PRINTER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("PRINTER", otherType.getKey());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyType> list = anyTypeDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.add(anyTypeClassDAO.find("generic membership"));
+        newType.add(anyTypeClassDAO.find("csv"));
+
+        newType = anyTypeDAO.save(newType);
+        assertNotNull(newType);
+        assertFalse(newType.getClasses().isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidKind() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidName() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test
+    public void delete() {
+        AnyType otherType = anyTypeDAO.find("PRINTER");
+        assertNotNull(otherType);
+
+        anyTypeDAO.delete(otherType.getKey());
+        assertNull(anyTypeDAO.find("PRINTER"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void deleteInvalid() {
+        anyTypeDAO.delete(anyTypeDAO.findUser().getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConfTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConfTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConfTest.java
new file mode 100644
index 0000000..1e90e5c
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ConfTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+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.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.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;
+
+@Transactional
+public class ConfTest extends AbstractTest {
+
+    @Autowired
+    private ConfDAO confDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Test
+    public void read() {
+        CPlainAttr conf = confDAO.find("selfRegistration.allowed");
+        assertNotNull(conf);
+        assertTrue(conf.getValues().get(0).getBooleanValue());
+
+        conf = confDAO.find("authentication.statuses");
+        assertNotNull(conf);
+        assertEquals(2, conf.getValues().size());
+
+        conf = confDAO.find("non.existing");
+        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
+        PlainSchema useless = entityFactory.newEntity(PlainSchema.class);
+        useless.setKey("useless");
+        useless.setType(AttrSchemaType.Date);
+        useless.setConversionPattern("yyyy-MM-dd");
+        useless = plainSchemaDAO.save(useless);
+
+        // 2. create conf
+        CPlainAttr newConf = entityFactory.newEntity(CPlainAttr.class);
+        newConf.setSchema(useless);
+        add(newConf, "2014-06-20");
+        confDAO.save(newConf);
+
+        CPlainAttr actual = confDAO.find("useless");
+        assertEquals(actual.getValuesAsStrings(), newConf.getValuesAsStrings());
+
+        // 3. update conf
+        newConf.getValues().clear();
+        add(newConf, "2014-06-20");
+        confDAO.save(newConf);
+
+        actual = confDAO.find("useless");
+        assertEquals(actual.getValuesAsStrings(), newConf.getValuesAsStrings());
+
+        // 4. delete conf
+        confDAO.delete("useless");
+        assertNull(confDAO.find("useless"));
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        try {
+            PlainSchema failing = entityFactory.newEntity(PlainSchema.class);
+            failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+            failing.setType(AttrSchemaType.String);
+            plainSchemaDAO.save(failing);
+
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}