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/04/21 09:49:47 UTC

[32/40] syncope git commit: [SYNCOPE-119] New security model implemented

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 0094aef..6d530ae 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
@@ -18,11 +18,11 @@
  */
 package org.apache.syncope.core.misc.security;
 
-import java.util.Collections;
 import java.util.Date;
 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.AuditElements;
 import org.apache.syncope.common.lib.types.AuditElements.Result;
@@ -30,16 +30,16 @@ 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.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory;
+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.conf.CPlainAttr;
-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.ConnectorFactory;
 import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.MappingUtil;
+import org.apache.syncope.core.misc.MappingUtils;
+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;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,6 +68,9 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     protected ConfDAO confDAO;
 
     @Autowired
+    protected RealmDAO realmDAO;
+
+    @Autowired
     protected UserDAO userDAO;
 
     @Autowired
@@ -77,7 +80,7 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
     protected ConnectorFactory connFactory;
 
     @Autowired
-    protected AttributableUtilFactory attrUtilFactory;
+    protected AttributableUtilsFactory attrUtilsFactory;
 
     @Resource(name = "adminUser")
     protected String adminUser;
@@ -232,46 +235,32 @@ public class SyncopeAuthenticationProvider implements AuthenticationProvider {
             }
         }
 
-        // 2. look for owned groups, pick the ones whose account policy has authentication resources
-        for (Group group : user.getGroups()) {
-            if (group.getAccountPolicy() != null && !group.getAccountPolicy().getResources().isEmpty()) {
+        // 2. look for realms, pick the ones whose account policy has authentication resources
+        for (Realm realm : realmDAO.findAncestors(user.getRealm())) {
+            if (realm.getAccountPolicy() != null && !realm.getAccountPolicy().getResources().isEmpty()) {
                 if (result == null) {
-                    result = group.getAccountPolicy().getResources();
+                    result = realm.getAccountPolicy().getResources();
                 } else {
-                    result.retainAll(group.getAccountPolicy().getResources());
+                    result.retainAll(realm.getAccountPolicy().getResources());
                 }
             }
         }
 
-        // 3. look for global account policy (if defined)
-        AccountPolicy global = policyDAO.getGlobalAccountPolicy();
-        if (global != null && !global.getResources().isEmpty()) {
-            if (result == null) {
-                result = global.getResources();
-            } else {
-                result.retainAll(global.getResources());
-            }
-        }
-
-        if (result == null) {
-            result = Collections.emptySet();
-        }
-
-        return result;
+        return SetUtils.emptyIfNull(result);
     }
 
     protected boolean authenticate(final User user, final String password) {
         boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
         LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
 
-        final AttributableUtil attrUtil = attrUtilFactory.getInstance(AttributableType.USER);
+        final AttributableUtils attrUtils = attrUtilsFactory.getInstance(AttributableType.USER);
         for (Iterator<? extends ExternalResource> itor = getPassthroughResources(user).iterator();
                 itor.hasNext() && !authenticated;) {
 
             ExternalResource resource = itor.next();
             String accountId = null;
             try {
-                accountId = MappingUtil.getAccountIdValue(user, resource, attrUtil.getAccountIdItem(resource));
+                accountId = MappingUtils.getAccountIdValue(user, resource, attrUtils.getAccountIdItem(resource));
                 Uid uid = connFactory.getConnector(resource).authenticate(accountId, password, null);
                 if (uid != null) {
                     authenticated = true;

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
new file mode 100644
index 0000000..860224e
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/SyncopeGrantedAuthority.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc.security;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.collections4.Closure;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.SetUtils;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.springframework.security.core.GrantedAuthority;
+
+public class SyncopeGrantedAuthority implements GrantedAuthority {
+
+    private static final long serialVersionUID = -5647624636011919735L;
+
+    private final Entitlement entitlement;
+
+    private final Set<String> realms = SetUtils.orderedSet(new HashSet<String>());
+
+    public SyncopeGrantedAuthority(final Entitlement entitlement) {
+        this.entitlement = entitlement;
+    }
+
+    public SyncopeGrantedAuthority(final Entitlement entitlement, final String realm) {
+        this.entitlement = entitlement;
+        this.realms.add(realm);
+    }
+
+    public boolean addRealm(final String newRealm) {
+        return RealmUtils.normalizingAddTo(realms, newRealm);
+    }
+
+    public void addRealms(final List<String> newRealms) {
+        CollectionUtils.forAllDo(newRealms, new Closure<String>() {
+
+            @Override
+            public void execute(final String newRealm) {
+                addRealm(newRealm);
+            }
+        });
+    }
+
+    public Entitlement getEntitlement() {
+        return entitlement;
+    }
+
+    public Set<String> getRealms() {
+        return Collections.unmodifiableSet(realms);
+    }
+
+    @Override
+    public String getAuthority() {
+        return entitlement.name();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 d617ae2..31f8346 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
@@ -18,20 +18,27 @@
  */
 package org.apache.syncope.core.misc.security;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 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.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.core.persistence.api.GroupEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
+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.UserDAO;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Configurable;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
@@ -46,9 +53,6 @@ public class SyncopeUserDetailsService implements UserDetailsService {
     @Autowired
     protected GroupDAO groupDAO;
 
-    @Autowired
-    protected EntitlementDAO entitlementDAO;
-
     @Resource(name = "adminUser")
     protected String adminUser;
 
@@ -57,45 +61,60 @@ public class SyncopeUserDetailsService implements UserDetailsService {
 
     @Override
     public UserDetails loadUserByUsername(final String username) {
-        final Set<SimpleGrantedAuthority> authorities = new HashSet<>();
+        final Set<SyncopeGrantedAuthority> authorities = new HashSet<>();
         if (anonymousUser.equals(username)) {
-            authorities.add(new SimpleGrantedAuthority(SyncopeConstants.ANONYMOUS_ENTITLEMENT));
+            authorities.add(new SyncopeGrantedAuthority(Entitlement.ANONYMOUS));
         } else if (adminUser.equals(username)) {
-            for (Entitlement entitlement : entitlementDAO.findAll()) {
-                authorities.add(new SimpleGrantedAuthority(entitlement.getKey()));
-            }
+            CollectionUtils2.collect(Arrays.asList(Entitlement.values()),
+                    new Transformer<Entitlement, SyncopeGrantedAuthority>() {
+
+                        @Override
+                        public SyncopeGrantedAuthority transform(final Entitlement entitlement) {
+                            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);
-
             if (user == null) {
                 throw new UsernameNotFoundException("Could not find any user with id " + username);
             }
 
-            // Give entitlements based on groups assigned to user (and their ancestors)
-            final Set<Group> groups = new HashSet<>(user.getGroups());
-            for (Group group : user.getGroups()) {
-                groups.addAll(groupDAO.findAncestors(group));
-            }
-            for (Group group : groups) {
-                for (Entitlement entitlement : group.getEntitlements()) {
-                    authorities.add(new SimpleGrantedAuthority(entitlement.getKey()));
-                }
+            // Give entitlements as assigned by roles (with realms, where applicable)
+            for (final Role role : user.getRoles()) {
+                CollectionUtils.forAllDo(role.getEntitlements(), new Closure<Entitlement>() {
+
+                    @Override
+                    public void execute(final Entitlement entitlement) {
+                        SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
+                        authorities.add(authority);
+
+                        List<String> realmFullPahs = new ArrayList<>();
+                        CollectionUtils.collect(role.getRealms(), new Transformer<Realm, String>() {
+
+                            @Override
+                            public String transform(final Realm realm) {
+                                return realm.getFullPath();
+                            }
+                        }, realmFullPahs);
+                        authority.addRealms(realmFullPahs);
+                    }
+                });
             }
-            // Give group operational entitlements for owned groups
-            List<Group> ownedGroups = groupDAO.findOwnedByUser(user.getKey());
-            if (!ownedGroups.isEmpty()) {
-                authorities.add(new SimpleGrantedAuthority("GROUP_CREATE"));
-                authorities.add(new SimpleGrantedAuthority("GROUP_READ"));
-                authorities.add(new SimpleGrantedAuthority("GROUP_UPDATE"));
-                authorities.add(new SimpleGrantedAuthority("GROUP_DELETE"));
 
-                for (Group group : ownedGroups) {
-                    authorities.add(new SimpleGrantedAuthority(
-                            GroupEntitlementUtil.getEntitlementNameFromGroupKey(group.getKey())));
+            // Give group entitlements for owned groups
+            for (Group group : groupDAO.findOwnedByUser(user.getKey())) {
+                for (Entitlement entitlement : Arrays.asList(
+                        Entitlement.GROUP_READ, Entitlement.GROUP_UPDATE, Entitlement.GROUP_DELETE)) {
+
+                    SyncopeGrantedAuthority authority = new SyncopeGrantedAuthority(entitlement);
+                    authority.addRealm(RealmUtils.getGroupOwnerRealm(group.getRealm().getFullPath(), group.getKey()));
+                    authorities.add(authority);
                 }
             }
         }
 
-        return new User(username, "<PASSWORD_PLACEHOLDER>", true, true, true, true, authorities);
+        return new User(username, "<PASSWORD_PLACEHOLDER>", authorities);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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
new file mode 100644
index 0000000..85df5b7
--- /dev/null
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.misc.security;
+
+import org.apache.syncope.common.lib.types.SubjectType;
+
+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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedGroupException.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedGroupException.java b/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedGroupException.java
deleted file mode 100644
index e1a817f..0000000
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/security/UnauthorizedGroupException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.misc.security;
-
-import java.util.Collection;
-import java.util.Collections;
-
-public class UnauthorizedGroupException extends RuntimeException {
-
-    private static final long serialVersionUID = 7540587364235915081L;
-
-    private final Collection<Long> groupIds;
-
-    public UnauthorizedGroupException(final Collection<Long> groupIds) {
-        super("Missing entitlement for group(s) " + groupIds);
-        this.groupIds = groupIds;
-    }
-
-    public UnauthorizedGroupException(final Long groupId) {
-        this(Collections.singleton(groupId));
-    }
-
-    public Collection<Long> getGroupIds() {
-        return groupIds;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 f358de2..db222af 100644
--- a/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
+++ b/core/misc/src/test/java/org/apache/syncope/core/misc/search/SearchCondConverterTest.java
@@ -20,11 +20,9 @@ package org.apache.syncope.core.misc.search;
 
 import static org.junit.Assert.assertEquals;
 
-import org.apache.syncope.common.lib.search.GroupFiqlSearchConditionBuilder;
 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.EntitlementCond;
 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.SearchCond;
@@ -108,18 +106,6 @@ public class SearchCondConverterTest {
     }
 
     @Test
-    public void entitlements() {
-        String fiqlExpression = new GroupFiqlSearchConditionBuilder().hasEntitlements("USER_LIST").query();
-        assertEquals(SpecialAttr.ENTITLEMENTS + "==USER_LIST", fiqlExpression);
-
-        EntitlementCond entCond = new EntitlementCond();
-        entCond.setExpression("USER_LIST");
-        SearchCond simpleCond = SearchCond.getLeafCond(entCond);
-
-        assertEquals(simpleCond, SearchCondConverter.convert(fiqlExpression));
-    }
-
-    @Test
     public void and() {
         String fiqlExpression = new UserFiqlSearchConditionBuilder().
                 is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query();

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/GroupEntitlementUtil.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/GroupEntitlementUtil.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/GroupEntitlementUtil.java
deleted file mode 100644
index 723dfe1..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/GroupEntitlementUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, 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;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class for manipulating entitlements.
- */
-public final class GroupEntitlementUtil {
-
-    private static final Pattern GROUP_ENTITLEMENT_NAME_PATTERN = Pattern.compile("^GROUP_([\\d])+");
-
-    private static final Logger LOG = LoggerFactory.getLogger(GroupEntitlementUtil.class);
-
-    public static String getEntitlementNameFromGroupKey(final Long groupKey) {
-        return "GROUP_" + groupKey;
-    }
-
-    public static boolean isGroupEntitlement(final String entitlementName) {
-        return GROUP_ENTITLEMENT_NAME_PATTERN.matcher(entitlementName).matches();
-    }
-
-    public static Long getGroupKey(final String entitlementName) {
-        Long result = null;
-
-        if (isGroupEntitlement(entitlementName)) {
-            try {
-                result = Long.valueOf(entitlementName.substring(entitlementName.indexOf('_') + 1));
-            } catch (Exception e) {
-                LOG.error("unable to parse {} to Long", entitlementName, e);
-            }
-        }
-
-        return result;
-    }
-
-    public static Set<Long> getGroupKeys(final Set<String> entitlements) {
-        Set<Long> result = new HashSet<>();
-
-        for (String entitlement : entitlements) {
-            if (isGroupEntitlement(entitlement)) {
-                Long groupId = getGroupKey(entitlement);
-                if (groupId != null) {
-                    result.add(groupId);
-                }
-            }
-        }
-
-        return result;
-    }
-
-    public static Set<Long> getGroupKeys(final List<Entitlement> entitlements) {
-        return getGroupKeys(CollectionUtils.collect(entitlements, new Transformer<Entitlement, String>() {
-
-            @Override
-            public String transform(final Entitlement entitlement) {
-                return entitlement.getKey();
-            }
-        }, new HashSet<String>()));
-    }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private GroupEntitlementUtil() {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 3376e3f..6c959aa 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,7 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+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;
 
@@ -33,5 +33,5 @@ public interface DerSchemaDAO extends DAO<DerSchema, String> {
 
     <T extends DerSchema> T save(T derSchema);
 
-    void delete(String name, AttributableUtil attributableUtil);
+    void delete(String name, AttributableUtils attributableUtil);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/EntitlementDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/EntitlementDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/EntitlementDAO.java
deleted file mode 100644
index 560ff91..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/EntitlementDAO.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, 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.Entitlement;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-
-public interface EntitlementDAO extends DAO<Entitlement, String> {
-
-    Entitlement find(String key);
-
-    List<Entitlement> findAll();
-
-    Entitlement save(Entitlement entitlement);
-
-    Entitlement saveGroupEntitlement(Group group);
-
-    void delete(String key);
-
-    void delete(Entitlement entitlement);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/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 56ea6c2..a81db9d 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,12 +20,10 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import java.util.Map;
-import org.apache.syncope.common.lib.types.PolicyType;
+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.Entitlement;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Policy;
 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;
@@ -37,41 +35,27 @@ public interface GroupDAO extends SubjectDAO<GPlainAttr, GDerAttr, GVirAttr> {
 
     Group find(Long key);
 
-    List<Group> find(String name);
+    Group find(String name);
 
-    Group find(String name, Long parent);
+    List<Group> findOwnedByUser(Long userKey);
 
-    List<Group> findOwnedByUser(Long userId);
+    List<Group> findOwnedByGroup(Long groupKey);
 
-    List<Group> findOwnedByGroup(Long groupId);
-
-    List<Group> findByEntitlement(Entitlement entitlement);
-
-    List<Group> findByPolicy(Policy policy);
-
-    List<Group> findWithoutPolicy(PolicyType type);
-
-    List<Group> findAncestors(Group group);
-
-    List<Group> findChildren(Group group);
-
-    List<Group> findDescendants(Group group);
+    List<Group> findByAttrValue(String schemaName, GPlainAttrValue attrValue);
 
     List<Group> findByDerAttrValue(String schemaName, String value);
 
-    List<Group> findByAttrValue(String schemaName, GPlainAttrValue attrValue);
-
     Group findByAttrUniqueValue(String schemaName, GPlainAttrValue attrUniqueValue);
 
     List<Group> findByResource(ExternalResource resource);
 
-    List<Group> findAll();
+    List<Group> findAll(Set<String> adminRealms, int page, int itemsPerPage);
 
-    List<Group> findAll(int page, int itemsPerPage, List<OrderByClause> orderBy);
+    List<Group> findAll(Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
 
     List<Membership> findMemberships(Group group);
 
-    int count();
+    int count(Set<String> adminRealms);
 
     Group save(Group group);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
index 717a3c4..122faee 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 
@@ -33,5 +33,5 @@ public interface PlainSchemaDAO extends DAO<PlainSchema, String> {
 
     <T extends PlainSchema> T save(T schema);
 
-    void delete(String name, AttributableUtil attributableUtil);
+    void delete(String name, AttributableUtils attributableUtil);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
index 0eefcbb..dff687d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PolicyDAO.java
@@ -22,9 +22,7 @@ import java.util.List;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
-import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
 
 public interface PolicyDAO extends DAO<Policy, Long> {
 
@@ -34,12 +32,6 @@ public interface PolicyDAO extends DAO<Policy, Long> {
 
     List<AccountPolicy> findByResource(ExternalResource resource);
 
-    PasswordPolicy getGlobalPasswordPolicy();
-
-    AccountPolicy getGlobalAccountPolicy();
-
-    SyncPolicy getGlobalSyncPolicy();
-
     List<Policy> findAll();
 
     <T extends Policy> T save(T policy);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
index 5aa6106..515779e 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RealmDAO.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 
 public interface RealmDAO extends DAO<Realm, Long> {
@@ -29,6 +30,10 @@ public interface RealmDAO extends DAO<Realm, Long> {
 
     Realm find(String fullPath);
 
+    <T extends Policy> List<Realm> findByPolicy(T policy);
+
+    List<Realm> findAncestors(Realm realm);
+
     List<Realm> findChildren(Realm realm);
 
     List<Realm> findDescendants(Realm realm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
index 9e909d7..aca7bf4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectDAO.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
@@ -31,14 +31,14 @@ public interface SubjectDAO<P extends PlainAttr, D extends DerAttr, V extends Vi
         extends DAO<Subject<P, D, V>, Long> {
 
     List<? extends Subject<P, D, V>> findByAttrValue(
-            String schemaName, PlainAttrValue attrValue, AttributableUtil attrUtil);
+            String schemaName, PlainAttrValue attrValue, AttributableUtils attrUtils);
 
     Subject<P, D, V> findByAttrUniqueValue(
-            String schemaName, PlainAttrValue attrUniqueValue, AttributableUtil attrUtil);
+            String schemaName, PlainAttrValue attrUniqueValue, AttributableUtils attrUtils);
 
     List<? extends Subject<P, D, V>> findByDerAttrValue(
-            String schemaName, String value, AttributableUtil attrUtil);
+            String schemaName, String value, AttributableUtils attrUtils);
 
     List<? extends Subject<P, D, V>> findByResource(
-            ExternalResource resource, AttributableUtil attrUtil);
+            ExternalResource resource, AttributableUtils attrUtils);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
index c90cdf8..a4cd7d4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SubjectSearchDAO.java
@@ -28,25 +28,25 @@ import org.apache.syncope.core.persistence.api.entity.Subject;
 public interface SubjectSearchDAO extends DAO<Subject<?, ?, ?>, Long> {
 
     /**
-     * @param adminGroups the set of admin groups owned by the caller
+     * @param adminRealms realms for which the caller owns the proper entitlement(s)
      * @param searchCondition the search condition
      * @param type user or group
      * @return size of search result
      */
-    int count(Set<Long> adminGroups, SearchCond searchCondition, SubjectType type);
+    int count(Set<String> adminRealms, SearchCond searchCondition, SubjectType type);
 
     /**
-     * @param adminGroups the set of admin groups owned by the caller
+     * @param adminRealms realms for which the caller owns the proper entitlement(s)
      * @param searchCondition the search condition
      * @param type user or group
      * @param <T> user/group
      * @return the list of users/groups matching the given search condition
      */
     <T extends Subject<?, ?, ?>> List<T> search(
-            Set<Long> adminGroups, SearchCond searchCondition, SubjectType type);
+            Set<String> adminRealms, SearchCond searchCondition, SubjectType type);
 
     /**
-     * @param adminGroups the set of admin groups owned by the caller
+     * @param adminRealms the set of admin groups owned by the caller
      * @param searchCondition the search condition
      * @param orderBy list of ordering clauses
      * @param type user or group
@@ -54,10 +54,10 @@ public interface SubjectSearchDAO extends DAO<Subject<?, ?, ?>, Long> {
      * @return the list of users/groups matching the given search condition
      */
     <T extends Subject<?, ?, ?>> List<T> search(
-            Set<Long> adminGroups, SearchCond searchCondition, List<OrderByClause> orderBy, SubjectType type);
+            Set<String> adminRealms, SearchCond searchCondition, List<OrderByClause> orderBy, SubjectType type);
 
     /**
-     * @param adminGroups the set of admin groups owned by the caller
+     * @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
@@ -67,7 +67,7 @@ public interface SubjectSearchDAO extends DAO<Subject<?, ?, ?>, Long> {
      * @return the list of users/groups matching the given search condition (in the given page)
      */
     <T extends Subject<?, ?, ?>> List<T> search(
-            Set<Long> adminGroups, SearchCond searchCondition, int page, int itemsPerPage,
+            Set<String> adminRealms, SearchCond searchCondition, int page, int itemsPerPage,
             List<OrderByClause> orderBy, SubjectType type);
 
     /**

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
index adc0a36..46388b3 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/UserDAO.java
@@ -49,11 +49,11 @@ public interface UserDAO extends SubjectDAO<UPlainAttr, UDerAttr, UVirAttr> {
 
     List<User> findByResource(ExternalResource resource);
 
-    List<User> findAll(Set<Long> adminGroups, int page, int itemsPerPage);
+    List<User> findAll(Set<String> adminRealms, int page, int itemsPerPage);
 
-    List<User> findAll(Set<Long> adminGroups, int page, int itemsPerPage, List<OrderByClause> orderBy);
+    List<User> findAll(Set<String> adminRealms, int page, int itemsPerPage, List<OrderByClause> orderBy);
 
-    int count(Set<Long> adminGroups);
+    int count(Set<String> adminRealms);
 
     User save(User user);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
index 149ef97..160f109 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
@@ -33,5 +33,5 @@ public interface VirSchemaDAO extends DAO<VirSchema, String> {
 
     <T extends VirSchema> T save(T virSchema);
 
-    void delete(String key, AttributableUtil attributableUtil);
+    void delete(String key, AttributableUtils attributableUtil);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtil.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtil.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtil.java
deleted file mode 100644
index eb46fd0..0000000
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtil.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.api.entity;
-
-import java.util.List;
-import org.apache.syncope.common.lib.to.AbstractAttributableTO;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-
-public interface AttributableUtil {
-
-    AttributableType getType();
-
-    <T extends Attributable<?, ?, ?>> Class<T> attributableClass();
-
-    <T extends PlainSchema> Class<T> plainSchemaClass();
-
-    <T extends PlainSchema> T newPlainSchema();
-
-    <T extends PlainAttr> Class<T> plainAttrClass();
-
-    <T extends PlainAttr> T newPlainAttr();
-
-    <T extends PlainAttrValue> Class<T> plainAttrValueClass();
-
-    <T extends PlainAttrValue> T newPlainAttrValue();
-
-    <T extends AttrTemplate<PlainSchema>> Class<T> plainAttrTemplateClass();
-
-    <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass();
-
-    <T extends PlainAttrValue> T newPlainAttrUniqueValue();
-
-    <T extends DerSchema> Class<T> derSchemaClass();
-
-    <T extends DerSchema> T newDerSchema();
-
-    <T extends DerAttr> Class<T> derAttrClass();
-
-    <T extends DerAttr> T newDerAttr();
-
-    <T extends AttrTemplate<DerSchema>> Class<T> derAttrTemplateClass();
-
-    <T extends VirSchema> Class<T> virSchemaClass();
-
-    <T extends VirSchema> T newVirSchema();
-
-    <T extends VirAttr> Class<T> virAttrClass();
-
-    <T extends VirAttr> T newVirAttr();
-
-    <T extends AttrTemplate<VirSchema>> Class<T> virAttrTemplateClass();
-
-    <T extends MappingItem> T getAccountIdItem(ExternalResource resource);
-
-    String getAccountLink(ExternalResource resource);
-
-    <T extends MappingItem> List<T> getMappingItems(ExternalResource resource, MappingPurpose purpose);
-
-    <T extends MappingItem> List<T> getUidToMappingItems(ExternalResource resource, MappingPurpose purpose);
-
-    IntMappingType plainIntMappingType();
-
-    IntMappingType derIntMappingType();
-
-    IntMappingType virIntMappingType();
-
-    <T extends MappingItem> Class<T> mappingItemClass();
-
-    <T extends AbstractAttributableTO> T newAttributableTO();
-
-    <T extends AbstractSubjectTO> T newSubjectTO();
-}

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
new file mode 100644
index 0000000..b36cd18
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AttributableUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.api.entity;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+
+public interface AttributableUtils {
+
+    AttributableType getType();
+
+    <T extends Attributable<?, ?, ?>> Class<T> attributableClass();
+
+    <T extends PlainSchema> Class<T> plainSchemaClass();
+
+    <T extends PlainSchema> T newPlainSchema();
+
+    <T extends PlainAttr> Class<T> plainAttrClass();
+
+    <T extends PlainAttr> T newPlainAttr();
+
+    <T extends PlainAttrValue> Class<T> plainAttrValueClass();
+
+    <T extends PlainAttrValue> T newPlainAttrValue();
+
+    <T extends AttrTemplate<PlainSchema>> Class<T> plainAttrTemplateClass();
+
+    <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass();
+
+    <T extends PlainAttrValue> T newPlainAttrUniqueValue();
+
+    <T extends DerSchema> Class<T> derSchemaClass();
+
+    <T extends DerSchema> T newDerSchema();
+
+    <T extends DerAttr> Class<T> derAttrClass();
+
+    <T extends DerAttr> T newDerAttr();
+
+    <T extends AttrTemplate<DerSchema>> Class<T> derAttrTemplateClass();
+
+    <T extends VirSchema> Class<T> virSchemaClass();
+
+    <T extends VirSchema> T newVirSchema();
+
+    <T extends VirAttr> Class<T> virAttrClass();
+
+    <T extends VirAttr> T newVirAttr();
+
+    <T extends AttrTemplate<VirSchema>> Class<T> virAttrTemplateClass();
+
+    <T extends MappingItem> T getAccountIdItem(ExternalResource resource);
+
+    String getAccountLink(ExternalResource resource);
+
+    <T extends MappingItem> List<T> getMappingItems(ExternalResource resource, MappingPurpose purpose);
+
+    <T extends MappingItem> List<T> getUidToMappingItems(ExternalResource resource, MappingPurpose purpose);
+
+    IntMappingType plainIntMappingType();
+
+    IntMappingType derIntMappingType();
+
+    IntMappingType virIntMappingType();
+
+    <T extends MappingItem> Class<T> mappingItemClass();
+
+    <T extends AbstractAttributableTO> T newAttributableTO();
+
+    <T extends AbstractSubjectTO> T newSubjectTO();
+}

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
index f827703..91a6a0f 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/EntityFactory.java
@@ -22,7 +22,5 @@ public interface EntityFactory {
 
     <KEY, T extends Entity<KEY>> T newEntity(Class<T> reference);
 
-    <T extends Policy> T newPolicy(Class<T> reference, boolean global);
-
     ConnPoolConf newConnPoolConf();
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
index 11e33b5..8474778 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
@@ -22,7 +22,7 @@ import java.util.List;
 
 public interface PlainAttr extends Attr<PlainSchema> {
 
-    void addValue(String value, AttributableUtil attributableUtil);
+    void addValue(String value, AttributableUtils attributableUtil);
 
     boolean removeValue(PlainAttrValue attrValue);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
index 7753ee2..0705804 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Role.java
@@ -28,10 +28,6 @@ public interface Role extends Entity<Long> {
 
     void setName(String name);
 
-    String getCriteria();
-
-    void setCriteria(String criteria);
-
     Set<Entitlement> getEntitlements();
 
     boolean addRealm(Realm realm);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
index 78b898c..11f0c81 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Subject.java
@@ -22,6 +22,10 @@ import java.util.Set;
 
 public interface Subject<N extends PlainAttr, D extends DerAttr, V extends VirAttr> extends Attributable<N, D, V> {
 
+    Realm getRealm();
+
+    void setRealm(Realm realm);
+
     boolean addResource(ExternalResource resource);
 
     boolean removeResource(ExternalResource resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
index 3c9f5df..6de9a81 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/group/Group.java
@@ -19,11 +19,7 @@
 package org.apache.syncope.core.persistence.api.entity.group;
 
 import java.util.List;
-import java.util.Set;
-import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Entitlement;
-import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Schema;
 import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.user.User;
@@ -32,100 +28,18 @@ public interface Group extends Subject<GPlainAttr, GDerAttr, GVirAttr> {
 
     String getName();
 
-    Group getParent();
-
-    boolean addEntitlement(Entitlement entitlement);
-
-    boolean removeEntitlement(Entitlement entitlement);
-
-    /**
-     * Get all inherited attributes from the ancestors.
-     *
-     * @return a list of inherited and only inherited attributes.
-     */
-    List<? extends GPlainAttr> findLastInheritedAncestorPlainAttrs();
-
-    /**
-     * Get all inherited derived attributes from the ancestors.
-     *
-     * @return a list of inherited and only inherited attributes.
-     */
-    List<? extends GDerAttr> findLastInheritedAncestorDerAttrs();
-
-    /**
-     * Get all inherited virtual attributes from the ancestors.
-     *
-     * @return a list of inherited and only inherited attributes.
-     */
-    List<? extends GVirAttr> findLastInheritedAncestorVirAttrs();
-
-    /**
-     * Get first valid account policy.
-     *
-     * @return parent account policy if isInheritAccountPolicy is 'true' and parent is not null, local account policy
-     * otherwise.
-     */
-    AccountPolicy getAccountPolicy();
-
-    <T extends AttrTemplate<K>, K extends Schema> List<T> findInheritedTemplates(Class<T> reference);
-
-    <T extends AttrTemplate<K>, K extends Schema> T getAttrTemplate(
-            Class<T> reference, String schemaName);
+    <T extends AttrTemplate<K>, K extends Schema> T getAttrTemplate(Class<T> reference, String schemaName);
 
     <T extends AttrTemplate<K>, K extends Schema> List<K> getAttrTemplateSchemas(Class<T> reference);
 
     <T extends AttrTemplate<K>, K extends Schema> List<T> getAttrTemplates(Class<T> reference);
 
-    Set<? extends Entitlement> getEntitlements();
-
-    /**
-     * Get first valid password policy.
-     *
-     * @return parent password policy if isInheritPasswordPolicy is 'true' and parent is not null, local password policy
-     * otherwise
-     */
-    PasswordPolicy getPasswordPolicy();
-
     Group getGroupOwner();
 
     User getUserOwner();
 
-    boolean isInheritAccountPolicy();
-
-    boolean isInheritPlainAttrs();
-
-    boolean isInheritDerAttrs();
-
-    boolean isInheritOwner();
-
-    boolean isInheritPasswordPolicy();
-
-    boolean isInheritTemplates();
-
-    boolean isInheritVirAttrs();
-
-    void setAccountPolicy(AccountPolicy accountPolicy);
-
-    void setInheritAccountPolicy(boolean condition);
-
-    void setInheritPlainAttrs(boolean inheritAttrs);
-
-    void setInheritDerAttrs(boolean inheritDerAttrs);
-
-    void setInheritOwner(boolean inheritOwner);
-
-    void setInheritPasswordPolicy(boolean condition);
-
-    void setInheritTemplates(boolean condition);
-
-    void setInheritVirAttrs(boolean inheritVirAttrs);
-
     void setName(String name);
 
-    void setParent(Group parent);
-
-    void setPasswordPolicy(PasswordPolicy passwordPolicy);
-
     void setGroupOwner(Group groupOwner);
 
     void setUserOwner(User userOwner);
@@ -134,12 +48,21 @@ public interface Group extends Subject<GPlainAttr, GDerAttr, GVirAttr> {
     boolean addPlainAttr(GPlainAttr attr);
 
     @Override
+    boolean removePlainAttr(GPlainAttr attr);
+
+    @Override
     boolean addDerAttr(GDerAttr attr);
 
     @Override
+    boolean removeDerAttr(GDerAttr derAttr);
+
+    @Override
     boolean addVirAttr(GVirAttr attr);
 
     @Override
+    boolean removeVirAttr(GVirAttr virAttr);
+
+    @Override
     GPlainAttr getPlainAttr(String plainSchemaName);
 
     @Override
@@ -157,12 +80,4 @@ public interface Group extends Subject<GPlainAttr, GDerAttr, GVirAttr> {
     @Override
     List<? extends GVirAttr> getVirAttrs();
 
-    @Override
-    boolean removePlainAttr(GPlainAttr attr);
-
-    @Override
-    boolean removeDerAttr(GDerAttr derAttr);
-
-    @Override
-    boolean removeVirAttr(GVirAttr virAttr);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
index 0d3b24c..600ef88 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/SyncTask.java
@@ -20,9 +20,12 @@ package org.apache.syncope.core.persistence.api.entity.task;
 
 import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
 
 public interface SyncTask extends ProvisioningTask {
 
+    Realm getDestinatioRealm();
+
     GroupTO getGroupTemplate();
 
     UserTO getUserTemplate();
@@ -34,4 +37,6 @@ public interface SyncTask extends ProvisioningTask {
     void setGroupTemplate(GroupTO groupTemplate);
 
     void setUserTemplate(UserTO userTemplate);
+
+    void setDestinationRealm(Realm destinationRealm);
 }

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

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilsFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilsFactory.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilsFactory.java
new file mode 100644
index 0000000..6da4de9
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/task/TaskUtilsFactory.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.entity.task;
+
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
+
+public interface TaskUtilsFactory {
+
+    TaskUtils getInstance(TaskType type);
+
+    TaskUtils getInstance(Task task);
+
+    TaskUtils getInstance(Class<? extends AbstractTaskTO> taskClass);
+
+    TaskUtils getInstance(AbstractTaskTO taskTO);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
index 5c3ec4d..303d756 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/user/User.java
@@ -23,12 +23,15 @@ import java.util.List;
 import java.util.Set;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.Subject;
 import org.apache.syncope.core.persistence.api.entity.membership.Membership;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 
 public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
 
+    boolean addRole(Role role);
+
     boolean addMembership(Membership membership);
 
     boolean canDecodePassword();
@@ -47,6 +50,8 @@ public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
 
     Date getLastLoginDate();
 
+    List<? extends Role> getRoles();
+
     Membership getMembership(Long groupKey);
 
     List<? extends Membership> getMemberships();
@@ -81,6 +86,8 @@ public interface User extends Subject<UPlainAttr, UDerAttr, UVirAttr> {
 
     void removeClearPassword();
 
+    boolean removeRole(Role role);
+
     boolean removeMembership(Membership membership);
 
     void removeToken();

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-jpa/pom.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index bd9ce25..26422f6 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -112,6 +112,11 @@ under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
index 0361773..49b573a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/ContentLoaderHandler.java
@@ -65,7 +65,8 @@ class ContentLoaderHandler extends DefaultHandler {
 
                         Map<String, Integer> colTypes = new HashMap<>();
                         for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
-                            colTypes.put(rs.getMetaData().getColumnName(i).toUpperCase(),
+                            colTypes.put(
+                                    rs.getMetaData().getColumnName(i).toUpperCase(),
                                     rs.getMetaData().getColumnType(i));
                         }
                         return colTypes;
@@ -191,7 +192,6 @@ class ContentLoaderHandler extends DefaultHandler {
         query.append(") VALUES (").append(values).append(')');
 
         JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
-
         try {
             jdbcTemplate.update(query.toString(), getParameters(qName, atts));
         } catch (DataAccessException e) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/65d652af/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
index 93c54e9..247da9e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
@@ -35,7 +35,11 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.SubjectDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.SubjectCond;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
@@ -56,6 +60,15 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
     @Autowired
     protected DerSchemaDAO derSchemaDAO;
 
+    @Autowired
+    protected SubjectSearchDAO searchDAO;
+
+    protected SearchCond getAllMatchingCond() {
+        SubjectCond idCond = new SubjectCond(AttributeCond.Type.ISNOTNULL);
+        idCond.setSchema("id");
+        return SearchCond.getLeafCond(idCond);
+    }
+
     /**
      * Split an attribute value recurring on provided literals/tokens.
      *
@@ -82,10 +95,10 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
      *
      * @param expression derived schema expression
      * @param value derived attribute value
-     * @param attrUtil USER / GROUP
+     * @param attrUtils USER / GROUP
      * @return where clauses to use to build the query
      */
-    private Set<String> getWhereClause(final String expression, final String value, final AttributableUtil attrUtil) {
+    private Set<String> getWhereClause(final String expression, final String value, final AttributableUtils attrUtils) {
         final Parser parser = new Parser(new StringReader(expression));
 
         // Schema names
@@ -149,7 +162,7 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
             if (!used.contains(identifiers.get(i))) {
 
                 // verify schema existence and get schema type
-                PlainSchema schema = plainSchemaDAO.find(identifiers.get(i), attrUtil.plainSchemaClass());
+                PlainSchema schema = plainSchemaDAO.find(identifiers.get(i), attrUtils.plainSchemaClass());
                 if (schema == null) {
                     LOG.error("Invalid schema name '{}'", identifiers.get(i));
                     throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i));
@@ -217,17 +230,17 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
     @Override
     @SuppressWarnings("unchecked")
     public List<? extends Subject<P, D, V>> findByAttrValue(
-            final String schemaName, final PlainAttrValue attrValue, final AttributableUtil attrUtil) {
+            final String schemaName, final PlainAttrValue attrValue, final AttributableUtils attrUtils) {
 
-        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass());
+        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
         if (schema == null) {
             LOG.error("Invalid schema name '{}'", schemaName);
             return Collections.<Subject<P, D, V>>emptyList();
         }
 
         final String entityName = schema.isUniqueConstraint()
-                ? attrUtil.plainAttrUniqueValueClass().getName()
-                : attrUtil.plainAttrValueClass().getName();
+                ? attrUtils.plainAttrUniqueValueClass().getName()
+                : attrUtils.plainAttrValueClass().getName();
 
         Query query = findByAttrValueQuery(entityName);
 
@@ -257,9 +270,9 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
 
     @Override
     public Subject<P, D, V> findByAttrUniqueValue(
-            final String schemaName, final PlainAttrValue attrUniqueValue, final AttributableUtil attrUtil) {
+            final String schemaName, final PlainAttrValue attrUniqueValue, final AttributableUtils attrUtils) {
 
-        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass());
+        PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtils.plainSchemaClass());
         if (schema == null) {
             LOG.error("Invalid schema name '{}'", schemaName);
             return null;
@@ -269,7 +282,7 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
             return null;
         }
 
-        List<? extends Subject<P, D, V>> result = findByAttrValue(schemaName, attrUniqueValue, attrUtil);
+        List<? extends Subject<P, D, V>> result = findByAttrValue(schemaName, attrUniqueValue, attrUtils);
         return result.isEmpty()
                 ? null
                 : result.iterator().next();
@@ -283,14 +296,14 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
      *
      * @param schemaName derived schema name
      * @param value derived attribute value
-     * @param attrUtil AttributableUtil
+     * @param attrUtils AttributableUtil
      * @return list of users / groups
      */
     @Override
     public List<? extends Subject<P, D, V>> findByDerAttrValue(
-            final String schemaName, final String value, final AttributableUtil attrUtil) {
+            final String schemaName, final String value, final AttributableUtils attrUtils) {
 
-        DerSchema schema = derSchemaDAO.find(schemaName, attrUtil.derSchemaClass());
+        DerSchema schema = derSchemaDAO.find(schemaName, attrUtils.derSchemaClass());
         if (schema == null) {
             LOG.error("Invalid schema name '{}'", schemaName);
             return Collections.<Subject<P, D, V>>emptyList();
@@ -300,16 +313,16 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
         final StringBuilder querystring = new StringBuilder();
 
         boolean subquery = false;
-        for (String clause : getWhereClause(schema.getExpression(), value, attrUtil)) {
+        for (String clause : getWhereClause(schema.getExpression(), value, attrUtils)) {
             if (querystring.length() > 0) {
                 subquery = true;
                 querystring.append(" AND a.owner_id IN ( ");
             }
 
             querystring.append("SELECT a.owner_id ").
-                    append("FROM ").append(attrUtil.plainAttrClass().getSimpleName().substring(3)).append(" a, ").
-                    append(attrUtil.plainAttrValueClass().getSimpleName().substring(3)).append(" v, ").
-                    append(attrUtil.plainSchemaClass().getSimpleName().substring(3)).append(" s ").
+                    append("FROM ").append(attrUtils.plainAttrClass().getSimpleName().substring(3)).append(" a, ").
+                    append(attrUtils.plainAttrValueClass().getSimpleName().substring(3)).append(" v, ").
+                    append(attrUtils.plainSchemaClass().getSimpleName().substring(3)).append(" s ").
                     append("WHERE ").append(clause);
 
             if (subquery) {
@@ -335,10 +348,10 @@ abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V exte
     @Override
     @SuppressWarnings("unchecked")
     public List<? extends Subject<P, D, V>> findByResource(
-            final ExternalResource resource, final AttributableUtil attrUtil) {
+            final ExternalResource resource, final AttributableUtils attrUtils) {
 
         Query query = entityManager.createQuery(
-                "SELECT e FROM " + attrUtil.attributableClass().getSimpleName() + " e "
+                "SELECT e FROM " + attrUtils.attributableClass().getSimpleName() + " e "
                 + "WHERE :resource MEMBER OF e.resources");
         query.setParameter("resource", resource);