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

Reply via email to