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

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

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);