http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
index a97d2dd..8b1f451 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/PushActions.java
@@ -27,10 +27,10 @@ import org.quartz.JobExecutionException;
 public interface PushActions extends ProvisioningActions {
 
     /**
-     * Action to be executed before to assign (link & provision) a 
synchronized user / role to the resource.
+     * Action to be executed before to assign (link & provision) a 
synchronized user / group to the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -39,10 +39,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to provision a synchronized user / role to 
the resource.
+     * Action to be executed before to provision a synchronized user / group 
to the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -51,10 +51,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to update a synchronized user / role on 
the resource.
+     * Action to be executed before to update a synchronized user / group on 
the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be updated.
+     * @param subject user / group to be updated.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -63,10 +63,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to link a synchronized user / role to the 
resource.
+     * Action to be executed before to link a synchronized user / group to the 
resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -75,10 +75,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unlink a synchronized user / role from 
the resource.
+     * Action to be executed before to unlink a synchronized user / group from 
the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -87,10 +87,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user / role 
from the resource.
+     * Action to be executed before to unassign a synchronized user / group 
from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -99,10 +99,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user / role 
from the resource.
+     * Action to be executed before to unassign a synchronized user / group 
from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -111,10 +111,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before delete a synchronized user / role locally 
and from the resource.
+     * Action to be executed before delete a synchronized user / group locally 
and from the resource.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject user / role to be created.
+     * @param subject user / group to be created.
      * @return subject.
      * @throws JobExecutionException in case of generic failure
      */
@@ -123,10 +123,10 @@ public interface PushActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user / role synchronization.
+     * Action to be executed after each local user / group synchronization.
      *
      * @param profile profile of the synchronization being executed.
-     * @param subject synchronized user / role.
+     * @param subject synchronized user / group.
      * @param result operation result.
      * @throws JobExecutionException in case of generic failure
      */

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

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

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
index 87f3d05..2824f99 100644
--- 
a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
+++ 
b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/sync/SyncActions.java
@@ -29,13 +29,13 @@ import org.quartz.JobExecutionException;
 public interface SyncActions extends ProvisioningActions {
 
     /**
-     * Action to be executed before to create a synchronized user / role 
locally.
-     * User/role is created locally upon synchronization in case of the 
un-matching rule
+     * Action to be executed before to create a synchronized user / group 
locally.
+     * User/group is created locally upon synchronization in case of the 
un-matching rule
      * {@link org.apache.syncope.common.types.UnmatchingRule#PROVISION} 
(default un-matching rule) is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -45,13 +45,13 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before creating (and linking to the resource) a 
synchronized user / role locally.
-     * User/role is created locally and linked to the synchronized resource 
upon synchronization in case of the
+     * Action to be executed before creating (and linking to the resource) a 
synchronized user / group locally.
+     * User/group is created locally and linked to the synchronized resource 
upon synchronization in case of the
      * un-matching rule {@link 
org.apache.syncope.common.types.UnmatchingRule#ASSIGN} is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -61,13 +61,13 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before unlinking resource from the synchronized 
user / role and de-provisioning.
-     * User/role is unlinked and de-provisioned from the synchronized resource 
upon synchronization in case of the
+     * Action to be executed before unlinking resource from the synchronized 
user / group and de-provisioning.
+     * User/group is unlinked and de-provisioned from the synchronized 
resource upon synchronization in case of the
      * matching rule {@link 
org.apache.syncope.common.types.MatchingRule#UNASSIGN} is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -78,12 +78,12 @@ public interface SyncActions extends ProvisioningActions {
 
     /**
      * Action to be executed before de-provisioning action only.
-     * User/role is de-provisioned (without unlinking) from the synchronized 
resource upon synchronization in case of
+     * User/group is de-provisioned (without unlinking) from the synchronized 
resource upon synchronization in case of
      * the matching rule {@link 
org.apache.syncope.common.types.MatchingRule#DEPROVISION} is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -93,13 +93,13 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before unlinking resource from the synchronized 
user / role.
-     * User/role is unlinked (without de-provisioning) from the synchronized 
resource upon synchronization in case of
+     * Action to be executed before unlinking resource from the synchronized 
user / group.
+     * User/group is unlinked (without de-provisioning) from the synchronized 
resource upon synchronization in case of
      * the matching rule {@link 
org.apache.syncope.common.types.MatchingRule#UNLINK} is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -109,13 +109,13 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before linking resource to the synchronized user 
/ role.
-     * User/role is linked (without updating) to the synchronized resource 
upon synchronization in case of
+     * Action to be executed before linking resource to the synchronized user 
/ group.
+     * User/group is linked (without updating) to the synchronized resource 
upon synchronization in case of
      * the matching rule {@link 
org.apache.syncope.common.types.MatchingRule#LINK} is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject user / role to be created
+     * @param subject user / group to be created
      * @return synchronization information used for user status evaluation and 
to be passed to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -125,13 +125,13 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to update a synchronized user / role 
locally.
-     * User/role is updated upon synchronization in case of the matching rule
+     * Action to be executed before to update a synchronized user / group 
locally.
+     * User/group is updated upon synchronization in case of the matching rule
      * {@link org.apache.syncope.common.types.MatchingRule#UPDATE} (default 
matching rule) is applied.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject local user / role information
+     * @param subject local user / group information
      * @param subjectMod modification
      * @return synchronization information used for logging and to be passed 
to the 'after' method.
      * @throws JobExecutionException in case of generic failure.
@@ -144,11 +144,11 @@ public interface SyncActions extends ProvisioningActions {
             throws JobExecutionException;
 
     /**
-     * Action to be executed before to delete a synchronized user / role 
locally.
+     * Action to be executed before to delete a synchronized user / group 
locally.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information
-     * @param subject local user / role to be deleted
+     * @param subject local user / group to be deleted
      * @return synchronization information used for logging and to be passed 
to the 'after' method.
      * @throws JobExecutionException in case of generic failure
      */
@@ -158,12 +158,12 @@ public interface SyncActions extends ProvisioningActions {
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user / role synchronization.
+     * Action to be executed after each local user / group synchronization.
      *
      * @param profile profile of the synchronization being executed.
      * @param delta retrieved synchronization information (may be modified by
      * 'beforeProvision/beforeUpdate/beforeDelete')
-     * @param subject synchronized local user / role
+     * @param subject synchronized local user / group
      * @param result global synchronization results at the current 
synchronization step
      * @throws JobExecutionException in case of generic failure
      */

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
new file mode 100644
index 0000000..7dc3366
--- /dev/null
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultGroupProvisioningManager.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.persistence.api.GroupEntitlementUtil;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.provisioning.api.GroupProvisioningManager;
+import org.apache.syncope.core.provisioning.api.WorkflowResult;
+import 
org.apache.syncope.core.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
+import 
org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
+import 
org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
+import org.apache.syncope.core.misc.security.AuthContextUtil;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.workflow.api.GroupWorkflowAdapter;
+
+public class DefaultGroupProvisioningManager implements 
GroupProvisioningManager {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(GroupProvisioningManager.class);
+
+    @Autowired
+    protected GroupWorkflowAdapter gwfAdapter;
+
+    @Autowired
+    protected PropagationManager propagationManager;
+
+    @Autowired
+    protected PropagationTaskExecutor taskExecutor;
+
+    @Autowired
+    protected GroupDAO groupDAO;
+
+    @Override
+    public Map.Entry<Long, List<PropagationStatus>> create(final GroupTO 
subject) {
+        return create(subject, Collections.<String>emptySet());
+    }
+
+    @Override
+    public Map.Entry<Long, List<PropagationStatus>> create(final GroupTO 
subject, final Set<String> excludedResources) {
+        WorkflowResult<Long> created = gwfAdapter.create(subject);
+
+        AuthContextUtil.extendAuthContext(created.getResult(), 
GroupEntitlementUtil.getEntitlementNameFromGroupKey(created.getResult()));
+
+        List<PropagationTask> tasks =
+                propagationManager.getGroupCreateTaskIds(created, 
subject.getVirAttrs(), excludedResources);
+        PropagationReporter propagationReporter = 
ApplicationContextProvider.getApplicationContext().getBean(
+                PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        return new AbstractMap.SimpleEntry<>(created.getResult(), 
propagationReporter.getStatuses());
+    }
+
+    @Override
+    public Map.Entry<Long, List<PropagationStatus>> create(
+            final GroupTO groupTO, final Map<Long, String> groupOwnerMap, 
final Set<String> excludedResources) {
+
+        WorkflowResult<Long> created = gwfAdapter.create(groupTO);
+        AttrTO groupOwner = groupTO.getPlainAttrMap().get(StringUtils.EMPTY);
+        if (groupOwner != null) {
+            groupOwnerMap.put(created.getResult(), 
groupOwner.getValues().iterator().next());
+        }
+
+        AuthContextUtil.extendAuthContext(created.getResult(), 
+                
GroupEntitlementUtil.getEntitlementNameFromGroupKey(created.getResult()));
+
+        List<PropagationTask> tasks = propagationManager.getGroupCreateTaskIds(
+                created, groupTO.getVirAttrs(), excludedResources);
+
+        taskExecutor.execute(tasks);
+
+        return new AbstractMap.SimpleEntry<>(created.getResult(), null);
+    }
+
+    @Override
+    public Map.Entry<Long, List<PropagationStatus>> update(final GroupMod 
subjectMod) {
+        return update(subjectMod, Collections.<String>emptySet());
+    }
+
+    @Override
+    public Map.Entry<Long, List<PropagationStatus>> update(
+            final GroupMod subjectMod, final Set<String> excludedResources) {
+
+        WorkflowResult<Long> updated = gwfAdapter.update(subjectMod);
+
+        List<PropagationTask> tasks = 
propagationManager.getGroupUpdateTaskIds(updated,
+                subjectMod.getVirAttrsToRemove(), 
subjectMod.getVirAttrsToUpdate());
+        PropagationReporter propagationReporter =
+                
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        Map.Entry<Long, List<PropagationStatus>> result = new 
AbstractMap.SimpleEntry<>(
+                updated.getResult(), propagationReporter.getStatuses());
+        return result;
+    }
+
+    @Override
+    public List<PropagationStatus> delete(final Long subjectKey) {
+        final List<Group> toBeDeprovisioned = new ArrayList<>();
+
+        final Group syncopeGroup = groupDAO.find(subjectKey);
+
+        if (syncopeGroup != null) {
+            toBeDeprovisioned.add(syncopeGroup);
+
+            final List<Group> descendants = 
groupDAO.findDescendants(toBeDeprovisioned.get(0));
+            if (descendants != null) {
+                toBeDeprovisioned.addAll(descendants);
+            }
+        }
+
+        final List<PropagationTask> tasks = new ArrayList<>();
+
+        for (Group group : toBeDeprovisioned) {
+            // Generate propagation tasks for deleting users from group 
resources, if they are on those resources only
+            // because of the reason being deleted (see SYNCOPE-357)
+            for (Map.Entry<Long, PropagationByResource> entry : 
groupDAO.findUsersWithIndirectResources(group.
+                    getKey()).entrySet()) {
+
+                WorkflowResult<Long> wfResult =
+                        new WorkflowResult<>(entry.getKey(), entry.getValue(), 
Collections.<String>emptySet());
+                
tasks.addAll(propagationManager.getUserDeleteTaskIds(wfResult));
+            }
+
+            // Generate propagation tasks for deleting this group from 
resources
+            
tasks.addAll(propagationManager.getGroupDeleteTaskIds(group.getKey()));
+        }
+
+        PropagationReporter propagationReporter = 
ApplicationContextProvider.getApplicationContext().
+                getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+
+        try {
+            gwfAdapter.delete(subjectKey);
+        } catch (RuntimeException e) {
+            throw e;
+        }
+
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public Long unlink(final GroupMod subjectMod) {
+        WorkflowResult<Long> updated = gwfAdapter.update(subjectMod);
+        return updated.getResult();
+    }
+
+    @Override
+    public List<PropagationStatus> deprovision(final Long groupKey, final 
Collection<String> resources) {
+        Group group = groupDAO.authFetch(groupKey);
+
+        Set<String> noPropResourceName = group.getResourceNames();
+        noPropResourceName.removeAll(resources);
+
+        List<PropagationTask> tasks = propagationManager.getGroupDeleteTaskIds(
+                groupKey, new HashSet<>(resources), noPropResourceName);
+        PropagationReporter propagationReporter =
+                
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+        try {
+            taskExecutor.execute(tasks, propagationReporter);
+        } catch (PropagationException e) {
+            LOG.error("Error propagation primary resource", e);
+            propagationReporter.onPrimaryResourceFailure(tasks);
+        }
+        return propagationReporter.getStatuses();
+    }
+
+    @Override
+    public Long link(final GroupMod subjectMod) {
+        return gwfAdapter.update(subjectMod).getResult();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultRoleProvisioningManager.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultRoleProvisioningManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultRoleProvisioningManager.java
deleted file mode 100644
index d78e0fc..0000000
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultRoleProvisioningManager.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.provisioning.java;
-
-import java.util.AbstractMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.mod.RoleMod;
-import org.apache.syncope.common.lib.to.AttrTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.core.persistence.api.RoleEntitlementUtil;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
-import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
-import org.apache.syncope.core.provisioning.api.RoleProvisioningManager;
-import org.apache.syncope.core.provisioning.api.WorkflowResult;
-import 
org.apache.syncope.core.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
-import 
org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import 
org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.security.AuthContextUtil;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.workflow.api.RoleWorkflowAdapter;
-
-public class DefaultRoleProvisioningManager implements RoleProvisioningManager 
{
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(RoleProvisioningManager.class);
-
-    @Autowired
-    protected RoleWorkflowAdapter rwfAdapter;
-
-    @Autowired
-    protected PropagationManager propagationManager;
-
-    @Autowired
-    protected PropagationTaskExecutor taskExecutor;
-
-    @Autowired
-    protected RoleDAO roleDAO;
-
-    @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final RoleTO 
subject) {
-        return create(subject, Collections.<String>emptySet());
-    }
-
-    @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(final RoleTO 
subject, final Set<String> excludedResources) {
-        WorkflowResult<Long> created = rwfAdapter.create(subject);
-
-        AuthContextUtil.extendAuthContext(
-                created.getResult(), 
RoleEntitlementUtil.getEntitlementNameFromRoleKey(created.getResult()));
-
-        List<PropagationTask> tasks =
-                propagationManager.getRoleCreateTaskIds(created, 
subject.getVirAttrs(), excludedResources);
-        PropagationReporter propagationReporter = 
ApplicationContextProvider.getApplicationContext().getBean(
-                PropagationReporter.class);
-        try {
-            taskExecutor.execute(tasks, propagationReporter);
-        } catch (PropagationException e) {
-            LOG.error("Error propagation primary resource", e);
-            propagationReporter.onPrimaryResourceFailure(tasks);
-        }
-
-        return new AbstractMap.SimpleEntry<>(created.getResult(), 
propagationReporter.getStatuses());
-    }
-
-    @Override
-    public Map.Entry<Long, List<PropagationStatus>> create(
-            final RoleTO roleTO, final Map<Long, String> roleOwnerMap, final 
Set<String> excludedResources) {
-
-        WorkflowResult<Long> created = rwfAdapter.create(roleTO);
-        AttrTO roleOwner = roleTO.getPlainAttrMap().get(StringUtils.EMPTY);
-        if (roleOwner != null) {
-            roleOwnerMap.put(created.getResult(), 
roleOwner.getValues().iterator().next());
-        }
-
-        AuthContextUtil.extendAuthContext(
-                created.getResult(), 
RoleEntitlementUtil.getEntitlementNameFromRoleKey(created.getResult()));
-
-        List<PropagationTask> tasks = propagationManager.getRoleCreateTaskIds(
-                created, roleTO.getVirAttrs(), excludedResources);
-
-        taskExecutor.execute(tasks);
-
-        return new AbstractMap.SimpleEntry<>(created.getResult(), null);
-    }
-
-    @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(final RoleMod 
subjectMod) {
-        return update(subjectMod, Collections.<String>emptySet());
-    }
-
-    @Override
-    public Map.Entry<Long, List<PropagationStatus>> update(
-            final RoleMod subjectMod, final Set<String> excludedResources) {
-
-        WorkflowResult<Long> updated = rwfAdapter.update(subjectMod);
-
-        List<PropagationTask> tasks = 
propagationManager.getRoleUpdateTaskIds(updated,
-                subjectMod.getVirAttrsToRemove(), 
subjectMod.getVirAttrsToUpdate());
-        PropagationReporter propagationReporter =
-                
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
-        try {
-            taskExecutor.execute(tasks, propagationReporter);
-        } catch (PropagationException e) {
-            LOG.error("Error propagation primary resource", e);
-            propagationReporter.onPrimaryResourceFailure(tasks);
-        }
-
-        Map.Entry<Long, List<PropagationStatus>> result = new 
AbstractMap.SimpleEntry<>(
-                updated.getResult(), propagationReporter.getStatuses());
-        return result;
-    }
-
-    @Override
-    public List<PropagationStatus> delete(final Long subjectKey) {
-        final List<Role> toBeDeprovisioned = new ArrayList<>();
-
-        final Role syncopeRole = roleDAO.find(subjectKey);
-
-        if (syncopeRole != null) {
-            toBeDeprovisioned.add(syncopeRole);
-
-            final List<Role> descendants = 
roleDAO.findDescendants(toBeDeprovisioned.get(0));
-            if (descendants != null) {
-                toBeDeprovisioned.addAll(descendants);
-            }
-        }
-
-        final List<PropagationTask> tasks = new ArrayList<>();
-
-        for (Role role : toBeDeprovisioned) {
-            // Generate propagation tasks for deleting users from role 
resources, if they are on those resources only
-            // because of the reason being deleted (see SYNCOPE-357)
-            for (Map.Entry<Long, PropagationByResource> entry : 
roleDAO.findUsersWithIndirectResources(role.
-                    getKey()).entrySet()) {
-
-                WorkflowResult<Long> wfResult =
-                        new WorkflowResult<>(entry.getKey(), entry.getValue(), 
Collections.<String>emptySet());
-                
tasks.addAll(propagationManager.getUserDeleteTaskIds(wfResult));
-            }
-
-            // Generate propagation tasks for deleting this role from resources
-            
tasks.addAll(propagationManager.getRoleDeleteTaskIds(role.getKey()));
-        }
-
-        PropagationReporter propagationReporter = 
ApplicationContextProvider.getApplicationContext().
-                getBean(PropagationReporter.class);
-        try {
-            taskExecutor.execute(tasks, propagationReporter);
-        } catch (PropagationException e) {
-            LOG.error("Error propagation primary resource", e);
-            propagationReporter.onPrimaryResourceFailure(tasks);
-        }
-
-        try {
-            rwfAdapter.delete(subjectKey);
-        } catch (RuntimeException e) {
-            throw e;
-        }
-
-        return propagationReporter.getStatuses();
-    }
-
-    @Override
-    public Long unlink(final RoleMod subjectMod) {
-        WorkflowResult<Long> updated = rwfAdapter.update(subjectMod);
-        return updated.getResult();
-    }
-
-    @Override
-    public List<PropagationStatus> deprovision(final Long roleKey, final 
Collection<String> resources) {
-        Role role = roleDAO.authFetch(roleKey);
-
-        Set<String> noPropResourceName = role.getResourceNames();
-        noPropResourceName.removeAll(resources);
-
-        List<PropagationTask> tasks = propagationManager.getRoleDeleteTaskIds(
-                roleKey, new HashSet<>(resources), noPropResourceName);
-        PropagationReporter propagationReporter =
-                
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
-        try {
-            taskExecutor.execute(tasks, propagationReporter);
-        } catch (PropagationException e) {
-            LOG.error("Error propagation primary resource", e);
-            propagationReporter.onPrimaryResourceFailure(tasks);
-        }
-        return propagationReporter.getStatuses();
-    }
-
-    @Override
-    public Long link(final RoleMod subjectMod) {
-        return rwfAdapter.update(subjectMod).getResult();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
index b11cfe4..c9fbe0f 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultUserProvisioningManager.java
@@ -123,7 +123,7 @@ public class DefaultUserProvisioningManager implements 
UserProvisioningManager {
             for (MembershipMod membershipMod : userMod.getMembershipsToAdd()) {
                 if (!virtAttrHandler.fillMembershipVirtual(
                         updated.getResult().getKey().getKey(),
-                        membershipMod.getRole(),
+                        membershipMod.getGroup(),
                         null,
                         membershipMod.getVirAttrsToRemove(),
                         membershipMod.getVirAttrsToUpdate(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
index 449f949..c948de4 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/VirAttrHandler.java
@@ -47,9 +47,9 @@ import 
org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
 import 
org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
 import org.slf4j.Logger;
@@ -100,15 +100,15 @@ public class VirAttrHandler {
 
         if (virAttr instanceof UVirAttr) {
             ((UVirAttr) virAttr).setSchema((UVirSchema) virSchema);
-        } else if (virAttr instanceof RVirAttr) {
-            RVirAttrTemplate template = ((Role) attributable).
-                    getAttrTemplate(RVirAttrTemplate.class, 
virSchema.getKey());
+        } else if (virAttr instanceof GVirAttr) {
+            GVirAttrTemplate template = ((Group) attributable).
+                    getAttrTemplate(GVirAttrTemplate.class, 
virSchema.getKey());
             if (template != null) {
-                ((RVirAttr) virAttr).setTemplate(template);
+                ((GVirAttr) virAttr).setTemplate(template);
             }
         } else if (virAttr instanceof MVirAttr) {
             MVirAttrTemplate template =
-                    ((Membership) attributable).getRole().
+                    ((Membership) attributable).getGroup().
                     getAttrTemplate(MVirAttrTemplate.class, 
virSchema.getKey());
             if (template != null) {
                 ((MVirAttr) virAttr).setTemplate(template);
@@ -141,7 +141,7 @@ public class VirAttrHandler {
             externalResources.addAll(((Subject<?, ?, ?>) 
attributable).getResources());
         } else if (attributable instanceof Membership) {
             externalResources.addAll(((Membership) 
attributable).getUser().getResources());
-            externalResources.addAll(((Membership) 
attributable).getRole().getResources());
+            externalResources.addAll(((Membership) 
attributable).getGroup().getResources());
         }
 
         // 1. virtual attributes to be removed
@@ -282,7 +282,7 @@ public class VirAttrHandler {
      * SYNCOPE-501: build membership virtual attribute changes in case no 
other changes were made.
      *
      * @param key user key
-     * @param roleKey role key
+     * @param groupKey group key
      * @param membershipKey membership key
      * @param vAttrsToBeRemoved virtual attributes to be removed.
      * @param vAttrsToBeUpdated virtual attributes to be updated.
@@ -290,11 +290,11 @@ public class VirAttrHandler {
      * @return operations to be performed on external resources for membership 
virtual attributes changes
      */
     public PropagationByResource fillMembershipVirtual(
-            final Long key, final Long roleKey, final Long membershipKey, 
final Set<String> vAttrsToBeRemoved,
+            final Long key, final Long groupKey, final Long membershipKey, 
final Set<String> vAttrsToBeRemoved,
             final Set<AttrMod> vAttrsToBeUpdated, final boolean isRemoval) {
 
         final Membership membership = membershipKey == null
-                ? userDAO.authFetch(key).getMembership(roleKey)
+                ? userDAO.authFetch(key).getMembership(groupKey)
                 : membershipDAO.authFetch(membershipKey);
 
         return membership == null ? new PropagationByResource() : isRemoval

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
index d746ae4..8a32e99 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/cache/MemoryVirAttrCache.java
@@ -56,8 +56,8 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Cache virtual attribute values.
      *
-     * @param type user or role
-     * @param key user or role id
+     * @param type user or group
+     * @param key user or group id
      * @param schemaName virtual attribute name
      * @param value virtual attribute values
      */
@@ -81,8 +81,8 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Retrieve cached value. Return null in case of virtual attribute not 
cached.
      *
-     * @param type user or role
-     * @param id user or role id
+     * @param type user or group
+     * @param id user or group id
      * @param schemaName virtual attribute schema name.
      * @return cached values or null if virtual attribute is not cached.
      */
@@ -94,8 +94,8 @@ public class MemoryVirAttrCache implements VirAttrCache {
     /**
      * Force entry expiring.
      *
-     * @param type user or role
-     * @param id user or role id
+     * @param type user or group
+     * @param id user or group id
      * @param schemaName virtual attribute schema name
      */
     @Override
@@ -113,7 +113,7 @@ public class MemoryVirAttrCache implements VirAttrCache {
      * This method is not thread safe: the caller have to take care to 
synchronize the call.
      */
     private void free() {
-        final Set<VirAttrCacheKey> toBeRemoved = new 
HashSet<VirAttrCacheKey>();
+        final Set<VirAttrCacheKey> toBeRemoved = new HashSet<>();
 
         Map.Entry<VirAttrCacheKey, VirAttrCacheValue> latest = null;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
index ea12fad..65fc97e 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AbstractAttributableDataBinder.java
@@ -49,7 +49,7 @@ import 
org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
@@ -74,12 +74,12 @@ import 
org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
 import 
org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
 import 
org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
 import org.apache.syncope.core.persistence.api.entity.membership.Membership;
-import org.apache.syncope.core.persistence.api.entity.role.RDerAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.RVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
 import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
@@ -101,7 +101,7 @@ abstract class AbstractAttributableDataBinder {
     protected static final Logger LOG = 
LoggerFactory.getLogger(AbstractAttributableDataBinder.class);
 
     @Autowired
-    protected RoleDAO roleDAO;
+    protected GroupDAO groupDAO;
 
     @Autowired
     protected PlainSchemaDAO plainSchemaDAO;
@@ -259,12 +259,12 @@ abstract class AbstractAttributableDataBinder {
         // Check if there is some mandatory schema defined for which no value 
has been provided
         List<? extends PlainSchema> plainSchemas;
         switch (attrUtil.getType()) {
-            case ROLE:
-                plainSchemas = ((Role) 
attributable).getAttrTemplateSchemas(RPlainAttrTemplate.class);
+            case GROUP:
+                plainSchemas = ((Group) 
attributable).getAttrTemplateSchemas(GPlainAttrTemplate.class);
                 break;
 
             case MEMBERSHIP:
-                plainSchemas = ((Membership) 
attributable).getRole().getAttrTemplateSchemas(MPlainAttrTemplate.class);
+                plainSchemas = ((Membership) 
attributable).getGroup().getAttrTemplateSchemas(MPlainAttrTemplate.class);
                 break;
 
             case USER:
@@ -286,12 +286,12 @@ abstract class AbstractAttributableDataBinder {
 
         List<? extends DerSchema> derSchemas;
         switch (attrUtil.getType()) {
-            case ROLE:
-                derSchemas = ((Role) 
attributable).getAttrTemplateSchemas(RDerAttrTemplate.class);
+            case GROUP:
+                derSchemas = ((Group) 
attributable).getAttrTemplateSchemas(GDerAttrTemplate.class);
                 break;
 
             case MEMBERSHIP:
-                derSchemas = ((Membership) 
attributable).getRole().getAttrTemplateSchemas(MDerAttrTemplate.class);
+                derSchemas = ((Membership) 
attributable).getGroup().getAttrTemplateSchemas(MDerAttrTemplate.class);
                 break;
 
             case USER:
@@ -311,12 +311,12 @@ abstract class AbstractAttributableDataBinder {
 
         List<? extends VirSchema> virSchemas;
         switch (attrUtil.getType()) {
-            case ROLE:
-                virSchemas = ((Role) 
attributable).getAttrTemplateSchemas(RVirAttrTemplate.class);
+            case GROUP:
+                virSchemas = ((Group) 
attributable).getAttrTemplateSchemas(GVirAttrTemplate.class);
                 break;
 
             case MEMBERSHIP:
-                virSchemas = ((Membership) 
attributable).getRole().getAttrTemplateSchemas(MVirAttrTemplate.class);
+                virSchemas = ((Membership) 
attributable).getGroup().getAttrTemplateSchemas(MVirAttrTemplate.class);
                 break;
 
             case USER:
@@ -343,14 +343,14 @@ abstract class AbstractAttributableDataBinder {
 
         if (attr instanceof UPlainAttr) {
             ((UPlainAttr) attr).setSchema((UPlainSchema) schema);
-        } else if (attr instanceof RPlainAttr) {
-            RPlainAttrTemplate template =
-                    ((Role) 
attributable).getAttrTemplate(RPlainAttrTemplate.class, schema.getKey());
+        } else if (attr instanceof GPlainAttr) {
+            GPlainAttrTemplate template =
+                    ((Group) 
attributable).getAttrTemplate(GPlainAttrTemplate.class, schema.getKey());
             if (template != null) {
-                ((RPlainAttr) attr).setTemplate(template);
+                ((GPlainAttr) attr).setTemplate(template);
             }
         } else if (attr instanceof MPlainAttr) {
-            MPlainAttrTemplate template = ((Membership) 
attributable).getRole().
+            MPlainAttrTemplate template = ((Membership) 
attributable).getGroup().
                     getAttrTemplate(MPlainAttrTemplate.class, schema.getKey());
             if (template != null) {
                 ((MPlainAttr) attr).setTemplate(template);
@@ -363,14 +363,14 @@ abstract class AbstractAttributableDataBinder {
 
         if (derAttr instanceof UDerAttr) {
             ((UDerAttr) derAttr).setSchema((UDerSchema) derSchema);
-        } else if (derAttr instanceof RDerAttr) {
-            RDerAttrTemplate template = ((Role) attributable).
-                    getAttrTemplate(RDerAttrTemplate.class, 
derSchema.getKey());
+        } else if (derAttr instanceof GDerAttr) {
+            GDerAttrTemplate template = ((Group) attributable).
+                    getAttrTemplate(GDerAttrTemplate.class, 
derSchema.getKey());
             if (template != null) {
-                ((RDerAttr) derAttr).setTemplate(template);
+                ((GDerAttr) derAttr).setTemplate(template);
             }
         } else if (derAttr instanceof MDerAttr) {
-            MDerAttrTemplate template = ((Membership) attributable).getRole().
+            MDerAttrTemplate template = ((Membership) attributable).getGroup().
                     getAttrTemplate(MDerAttrTemplate.class, 
derSchema.getKey());
             if (template != null) {
                 ((MDerAttr) derAttr).setTemplate(template);
@@ -416,7 +416,7 @@ abstract class AbstractAttributableDataBinder {
             externalResources.addAll(((Subject<?, ?, ?>) 
attributable).getResources());
         } else if (attributable instanceof Membership) {
             externalResources.addAll(((Membership) 
attributable).getUser().getResources());
-            externalResources.addAll(((Membership) 
attributable).getRole().getResources());
+            externalResources.addAll(((Membership) 
attributable).getGroup().getResources());
         }
 
         // 3. attributes to be removed
@@ -591,8 +591,8 @@ abstract class AbstractAttributableDataBinder {
 
         LOG.debug("Derived attributes to be added:\n{}", propByRes);
 
-        // 7. virtual attributes: for users and roles this is delegated to 
PropagationManager
-        if (AttributableType.USER != attrUtil.getType() && 
AttributableType.ROLE != attrUtil.getType()) {
+        // 7. virtual attributes: for users and groups this is delegated to 
PropagationManager
+        if (AttributableType.USER != attrUtil.getType() && 
AttributableType.GROUP != attrUtil.getType()) {
             virtAttrHander.fillVirtual(attributable, 
attributableMod.getVirAttrsToRemove(),
                     attributableMod.getVirAttrsToUpdate(), attrUtil);
         }
@@ -663,9 +663,9 @@ abstract class AbstractAttributableDataBinder {
             }
         }
 
-        // 3. user and role virtual attributes will be evaluated by the 
propagation manager only (if needed).
+        // 3. user and group virtual attributes will be evaluated by the 
propagation manager only (if needed).
         if (AttributableType.USER == attrUtil.getType()
-                || AttributableType.ROLE == attrUtil.getType()) {
+                || AttributableType.GROUP == attrUtil.getType()) {
 
             for (AttrTO vattrTO : attributableTO.getVirAttrs()) {
                 VirSchema virSchema = 
virtAttrHander.getVirSchema(vattrTO.getSchema(), attrUtil.virSchemaClass());
@@ -753,7 +753,7 @@ abstract class AbstractAttributableDataBinder {
 
         for (ExternalResource resource : subject.getResources()) {
             if ((type == AttributableType.USER && resource.getUmapping() != 
null)
-                    || (type == AttributableType.ROLE && 
resource.getRmapping() != null)) {
+                    || (type == AttributableType.GROUP && 
resource.getGmapping() != null)) {
 
                 MappingItem accountIdItem =
                         
attrUtilFactory.getInstance(type).getAccountIdItem(resource);

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
new file mode 100644
index 0000000..4a5ed5f
--- /dev/null
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GroupDataBinderImpl.java
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.SyncopeClientCompositeException;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.GroupMod;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
+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.membership.MDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
+import 
org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
+import 
org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
+import org.apache.syncope.core.misc.ConnObjectUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+@Transactional(rollbackFor = { Throwable.class })
+public class GroupDataBinderImpl extends AbstractAttributableDataBinder 
implements GroupDataBinder {
+
+    @Autowired
+    private ConnObjectUtil connObjectUtil;
+
+    @Autowired
+    private EntitlementDAO entitlementDAO;
+
+    private <T extends AttrTemplate<S>, S extends Schema> void 
setAttrTemplates(
+            final Group group, final List<String> schemaNames,
+            final Class<T> templateClass, final Class<S> schemaClass) {
+
+        List<T> toRemove = new ArrayList<>();
+        for (T template : group.getAttrTemplates(templateClass)) {
+            if (!schemaNames.contains(template.getSchema().getKey())) {
+                toRemove.add(template);
+            }
+        }
+        group.getAttrTemplates(templateClass).removeAll(toRemove);
+
+        for (String schemaName : schemaNames) {
+            if (group.getAttrTemplate(templateClass, schemaName) == null) {
+                S schema = getSchema(schemaName, schemaClass);
+                if (schema != null) {
+                    try {
+                        T template = entityFactory.newEntity(templateClass);
+                        template.setSchema(schema);
+                        template.setOwner(group);
+                        group.getAttrTemplates(templateClass).add(template);
+                    } catch (Exception e) {
+                        LOG.error("Could not create template for {}", 
templateClass, e);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public Group create(final Group group, final GroupTO groupTO) {
+        group.setInheritOwner(groupTO.isInheritOwner());
+
+        group.setInheritPlainAttrs(groupTO.isInheritPlainAttrs());
+        group.setInheritDerAttrs(groupTO.isInheritDerAttrs());
+        group.setInheritVirAttrs(groupTO.isInheritVirAttrs());
+
+        group.setInheritTemplates(groupTO.isInheritTemplates());
+
+        group.setInheritPasswordPolicy(groupTO.isInheritPasswordPolicy());
+        group.setInheritAccountPolicy(groupTO.isInheritAccountPolicy());
+
+        SyncopeClientCompositeException scce = 
SyncopeClientException.buildComposite();
+
+        // name and parent
+        SyncopeClientException invalidGroups = 
SyncopeClientException.build(ClientExceptionType.InvalidGroups);
+        if (groupTO.getName() == null) {
+            LOG.error("No name specified for this group");
+
+            invalidGroups.getElements().add("No name specified for this 
group");
+        } else {
+            group.setName(groupTO.getName());
+        }
+        Long parentGroupKey = null;
+        if (groupTO.getParent() != 0) {
+            Group parentGroup = groupDAO.find(groupTO.getParent());
+            if (parentGroup == null) {
+                LOG.error("Could not find group with id " + 
groupTO.getParent());
+
+                
invalidGroups.getElements().add(String.valueOf(groupTO.getParent()));
+                scce.addException(invalidGroups);
+            } else {
+                group.setParent(parentGroup);
+                parentGroupKey = group.getParent().getKey();
+            }
+        }
+
+        Group otherGroup = groupDAO.find(groupTO.getName(), parentGroupKey);
+        if (otherGroup != null) {
+            LOG.error("Another group exists with the same name and the same 
parent group: " + otherGroup);
+
+            invalidGroups.getElements().add(groupTO.getName());
+        }
+
+        // attribute templates
+        setAttrTemplates(group, groupTO.getGPlainAttrTemplates(), 
GPlainAttrTemplate.class, GPlainSchema.class);
+        setAttrTemplates(group, groupTO.getGDerAttrTemplates(), 
GDerAttrTemplate.class, GDerSchema.class);
+        setAttrTemplates(group, groupTO.getGVirAttrTemplates(), 
GVirAttrTemplate.class, GVirSchema.class);
+        setAttrTemplates(group, groupTO.getMPlainAttrTemplates(), 
MPlainAttrTemplate.class, MPlainSchema.class);
+        setAttrTemplates(group, groupTO.getMDerAttrTemplates(), 
MDerAttrTemplate.class, MDerSchema.class);
+        setAttrTemplates(group, groupTO.getMVirAttrTemplates(), 
MVirAttrTemplate.class, MVirSchema.class);
+
+        // attributes, derived attributes, virtual attributes and resources
+        fill(group, groupTO, 
attrUtilFactory.getInstance(AttributableType.GROUP), scce);
+
+        // entitlements
+        for (String entitlementName : groupTO.getEntitlements()) {
+            Entitlement entitlement = entitlementDAO.find(entitlementName);
+            if (entitlement == null) {
+                LOG.warn("Ignoring invalid entitlement {}", entitlementName);
+            } else {
+                group.addEntitlement(entitlement);
+            }
+        }
+
+        // owner
+        if (groupTO.getUserOwner() != null) {
+            User owner = userDAO.find(groupTO.getUserOwner());
+            if (owner == null) {
+                LOG.warn("Ignoring invalid user specified as owner: {}", 
groupTO.getUserOwner());
+            } else {
+                group.setUserOwner(owner);
+            }
+        }
+        if (groupTO.getGroupOwner() != null) {
+            Group owner = groupDAO.find(groupTO.getGroupOwner());
+            if (owner == null) {
+                LOG.warn("Ignoring invalid group specified as owner: {}", 
groupTO.getGroupOwner());
+            } else {
+                group.setGroupOwner(owner);
+            }
+        }
+
+        // policies
+        if (groupTO.getPasswordPolicy() != null) {
+            group.setPasswordPolicy((PasswordPolicy) 
policyDAO.find(groupTO.getPasswordPolicy()));
+        }
+        if (groupTO.getAccountPolicy() != null) {
+            group.setAccountPolicy((AccountPolicy) 
policyDAO.find(groupTO.getAccountPolicy()));
+        }
+
+        return group;
+    }
+
+    @Override
+    public PropagationByResource update(final Group group, final GroupMod 
groupMod) {
+        PropagationByResource propByRes = new PropagationByResource();
+
+        SyncopeClientCompositeException scce = 
SyncopeClientException.buildComposite();
+
+        // fetch account ids before update
+        Map<String, String> oldAccountIds = getAccountIds(group, 
AttributableType.GROUP);
+
+        // name
+        SyncopeClientException invalidGroups = 
SyncopeClientException.build(ClientExceptionType.InvalidGroups);
+        if (groupMod.getName() != null) {
+            Group otherGroup = groupDAO.find(groupMod.getName(),
+                    group.getParent() == null ? null : 
group.getParent().getKey());
+            if (otherGroup == null || group.equals(otherGroup)) {
+                if (!groupMod.getName().equals(group.getName())) {
+                    propByRes.addAll(ResourceOperation.UPDATE, 
group.getResourceNames());
+
+                    group.setName(groupMod.getName());
+                }
+            } else {
+                LOG.error("Another group exists with the same name and the 
same parent group: " + otherGroup);
+
+                invalidGroups.getElements().add(groupMod.getName());
+                scce.addException(invalidGroups);
+            }
+        }
+
+        if (groupMod.getInheritOwner() != null) {
+            group.setInheritOwner(groupMod.getInheritOwner());
+        }
+
+        if (groupMod.getInheritTemplates() != null) {
+            group.setInheritTemplates(groupMod.getInheritTemplates());
+        }
+
+        if (groupMod.getInheritPlainAttrs() != null) {
+            group.setInheritPlainAttrs(groupMod.getInheritPlainAttrs());
+        }
+        if (groupMod.getInheritDerAttrs() != null) {
+            group.setInheritDerAttrs(groupMod.getInheritDerAttrs());
+        }
+        if (groupMod.getInheritVirAttrs() != null) {
+            group.setInheritVirAttrs(groupMod.getInheritVirAttrs());
+        }
+
+        if (groupMod.getInheritPasswordPolicy() != null) {
+            
group.setInheritPasswordPolicy(groupMod.getInheritPasswordPolicy());
+        }
+        if (groupMod.getInheritAccountPolicy() != null) {
+            group.setInheritAccountPolicy(groupMod.getInheritAccountPolicy());
+        }
+
+        // entitlements
+        if (groupMod.isModEntitlements()) {
+            group.getEntitlements().clear();
+            for (String entitlementName : groupMod.getEntitlements()) {
+                Entitlement entitlement = entitlementDAO.find(entitlementName);
+                if (entitlement == null) {
+                    LOG.warn("Ignoring invalid entitlement {}", 
entitlementName);
+                } else {
+                    group.addEntitlement(entitlement);
+                }
+            }
+        }
+
+        // attribute templates
+        if (groupMod.isModRAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getRPlainAttrTemplates(), 
GPlainAttrTemplate.class, GPlainSchema.class);
+        }
+        if (groupMod.isModRDerAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getRDerAttrTemplates(), 
GDerAttrTemplate.class, GDerSchema.class);
+        }
+        if (groupMod.isModRVirAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getRVirAttrTemplates(), 
GVirAttrTemplate.class, GVirSchema.class);
+        }
+        if (groupMod.isModMAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getMPlainAttrTemplates(), 
MPlainAttrTemplate.class, MPlainSchema.class);
+        }
+        if (groupMod.isModMDerAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getMDerAttrTemplates(), 
MDerAttrTemplate.class, MDerSchema.class);
+        }
+        if (groupMod.isModMVirAttrTemplates()) {
+            setAttrTemplates(group, groupMod.getMVirAttrTemplates(), 
MVirAttrTemplate.class, MVirSchema.class);
+        }
+
+        // policies
+        if (groupMod.getPasswordPolicy() != null) {
+            group.setPasswordPolicy(groupMod.getPasswordPolicy().getKey() == 
null
+                    ? null
+                    : (PasswordPolicy) 
policyDAO.find(groupMod.getPasswordPolicy().getKey()));
+        }
+        if (groupMod.getAccountPolicy() != null) {
+            group.setAccountPolicy(groupMod.getAccountPolicy().getKey() == null
+                    ? null
+                    : (AccountPolicy) 
policyDAO.find(groupMod.getAccountPolicy().getKey()));
+        }
+
+        // owner
+        if (groupMod.getUserOwner() != null) {
+            group.setUserOwner(groupMod.getUserOwner().getKey() == null
+                    ? null
+                    : userDAO.find(groupMod.getUserOwner().getKey()));
+        }
+        if (groupMod.getGroupOwner() != null) {
+            group.setGroupOwner(groupMod.getGroupOwner().getKey() == null
+                    ? null
+                    : groupDAO.find(groupMod.getGroupOwner().getKey()));
+        }
+
+        // attributes, derived attributes, virtual attributes and resources
+        propByRes.merge(fill(group, groupMod, 
attrUtilFactory.getInstance(AttributableType.GROUP), scce));
+
+        // check if some account id was changed by the update above
+        Map<String, String> newAccountIds = getAccountIds(group, 
AttributableType.GROUP);
+        for (Map.Entry<String, String> entry : oldAccountIds.entrySet()) {
+            if (newAccountIds.containsKey(entry.getKey())
+                    && 
!entry.getValue().equals(newAccountIds.get(entry.getKey()))) {
+
+                propByRes.addOldAccountId(entry.getKey(), entry.getValue());
+                propByRes.add(ResourceOperation.UPDATE, entry.getKey());
+            }
+        }
+
+        return propByRes;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Transactional(readOnly = true)
+    @Override
+    public GroupTO getGroupTO(final Group group) {
+        connObjectUtil.retrieveVirAttrValues(group, 
attrUtilFactory.getInstance(AttributableType.GROUP));
+
+        GroupTO groupTO = new GroupTO();
+
+        // set sys info
+        groupTO.setCreator(group.getCreator());
+        groupTO.setCreationDate(group.getCreationDate());
+        groupTO.setLastModifier(group.getLastModifier());
+        groupTO.setLastChangeDate(group.getLastChangeDate());
+
+        groupTO.setKey(group.getKey());
+        groupTO.setName(group.getName());
+
+        groupTO.setInheritOwner(group.isInheritOwner());
+
+        groupTO.setInheritTemplates(group.isInheritTemplates());
+
+        groupTO.setInheritPlainAttrs(group.isInheritPlainAttrs());
+        groupTO.setInheritDerAttrs(group.isInheritDerAttrs());
+        groupTO.setInheritVirAttrs(group.isInheritVirAttrs());
+
+        groupTO.setInheritPasswordPolicy(group.isInheritPasswordPolicy());
+        groupTO.setInheritAccountPolicy(group.isInheritAccountPolicy());
+
+        if (group.getParent() != null) {
+            groupTO.setParent(group.getParent().getKey());
+        }
+
+        if (group.getUserOwner() != null) {
+            groupTO.setUserOwner(group.getUserOwner().getKey());
+        }
+        if (group.getGroupOwner() != null) {
+            groupTO.setGroupOwner(group.getGroupOwner().getKey());
+        }
+
+        // -------------------------
+        // Retrieve all [derived/virtual] attributes (inherited and not)
+        // -------------------------        
+        final List<? extends GPlainAttr> allAttributes = 
group.findLastInheritedAncestorPlainAttrs();
+
+        final List<? extends GDerAttr> allDerAttributes = 
group.findLastInheritedAncestorDerAttrs();
+
+        final List<? extends GVirAttr> allVirAttributes = 
group.findLastInheritedAncestorVirAttrs();
+        // -------------------------
+
+        fillTO(groupTO, allAttributes, allDerAttributes, allVirAttributes, 
group.getResources());
+
+        for (Entitlement entitlement : group.getEntitlements()) {
+            groupTO.getEntitlements().add(entitlement.getKey());
+        }
+
+        for (GPlainAttrTemplate template : 
group.findInheritedTemplates(GPlainAttrTemplate.class)) {
+            
groupTO.getGPlainAttrTemplates().add(template.getSchema().getKey());
+        }
+        for (GDerAttrTemplate template : 
group.findInheritedTemplates(GDerAttrTemplate.class)) {
+            groupTO.getGDerAttrTemplates().add(template.getSchema().getKey());
+        }
+        for (GVirAttrTemplate template : 
group.findInheritedTemplates(GVirAttrTemplate.class)) {
+            groupTO.getGVirAttrTemplates().add(template.getSchema().getKey());
+        }
+        for (MPlainAttrTemplate template : 
group.findInheritedTemplates(MPlainAttrTemplate.class)) {
+            
groupTO.getMPlainAttrTemplates().add(template.getSchema().getKey());
+        }
+        for (MDerAttrTemplate template : 
group.findInheritedTemplates(MDerAttrTemplate.class)) {
+            groupTO.getMDerAttrTemplates().add(template.getSchema().getKey());
+        }
+        for (MVirAttrTemplate template : 
group.findInheritedTemplates(MVirAttrTemplate.class)) {
+            groupTO.getMVirAttrTemplates().add(template.getSchema().getKey());
+        }
+
+        groupTO.setPasswordPolicy(group.getPasswordPolicy() == null
+                ? null
+                : group.getPasswordPolicy().getKey());
+        groupTO.setAccountPolicy(group.getAccountPolicy() == null
+                ? null
+                : group.getAccountPolicy().getKey());
+
+        return groupTO;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public GroupTO getGroupTO(final Long key) {
+        return getGroupTO(groupDAO.authFetch(key));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
index c18e079..ae6d8a8 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/NotificationDataBinderImpl.java
@@ -42,7 +42,7 @@ public class NotificationDataBinderImpl implements 
NotificationDataBinder {
 
         result.setKey(notification.getKey());
         result.setUserAbout(notification.getUserAbout());
-        result.setRoleAbout(notification.getRoleAbout());
+        result.setGroupAbout(notification.getGroupAbout());
         result.setRecipients(notification.getRecipients());
 
         return result;
@@ -60,7 +60,7 @@ public class NotificationDataBinderImpl implements 
NotificationDataBinder {
         BeanUtils.copyProperties(notificationTO, notification, 
IGNORE_PROPERTIES);
 
         notification.setUserAbout(notificationTO.getUserAbout());
-        notification.setRoleAbout(notificationTO.getRoleAbout());
+        notification.setGroupAbout(notificationTO.getGroupAbout());
         notification.setRecipients(notificationTO.getRecipients());
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
index ec735b6..1f0e308 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/PolicyDataBinderImpl.java
@@ -29,14 +29,14 @@ import 
org.apache.syncope.common.lib.types.ClientExceptionType;
 import org.apache.syncope.common.lib.types.PasswordPolicySpec;
 import org.apache.syncope.common.lib.types.SyncPolicySpec;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.Policy;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
-import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,7 +54,7 @@ public class PolicyDataBinderImpl implements PolicyDataBinder 
{
     private ExternalResourceDAO resourceDAO;
 
     @Autowired
-    private RoleDAO roleDAO;
+    private GroupDAO groupDAO;
 
     @Autowired
     private EntityFactory entityFactory;
@@ -102,12 +102,12 @@ public class PolicyDataBinderImpl implements 
PolicyDataBinder {
                 policyTO.getUsedByResources().add(resource.getKey());
             }
         }
-        for (Role role : roleDAO.findByPolicy(policy)) {
-            policyTO.getUsedByRoles().add(role.getKey());
+        for (Group group : groupDAO.findByPolicy(policy)) {
+            policyTO.getUsedByGroups().add(group.getKey());
         }
         if (policy.getType().isGlobal()) {
-            for (Role role : roleDAO.findWithoutPolicy(policy.getType())) {
-                policyTO.getUsedByRoles().add(role.getKey());
+            for (Group group : groupDAO.findWithoutPolicy(policy.getType())) {
+                policyTO.getUsedByGroups().add(group.getKey());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/4095f1e8/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
----------------------------------------------------------------------
diff --git 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
index 2bf756f..6b5a289 100644
--- 
a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
+++ 
b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ResourceDataBinderImpl.java
@@ -43,8 +43,8 @@ import org.apache.syncope.core.persistence.api.entity.Mapping;
 import org.apache.syncope.core.persistence.api.entity.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.PasswordPolicy;
 import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
-import org.apache.syncope.core.persistence.api.entity.role.RMapping;
-import org.apache.syncope.core.persistence.api.entity.role.RMappingItem;
+import org.apache.syncope.core.persistence.api.entity.group.GMapping;
+import org.apache.syncope.core.persistence.api.entity.group.GMappingItem;
 import org.apache.syncope.core.persistence.api.entity.user.UMapping;
 import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
 import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
@@ -117,13 +117,13 @@ public class ResourceDataBinderImpl implements 
ResourceDataBinder {
             resource.setUmapping(mapping);
             populateMapping(resourceTO.getUmapping(), mapping, 
entityFactory.newEntity(UMappingItem.class));
         }
-        if (resourceTO.getRmapping() == null || 
resourceTO.getRmapping().getItems().isEmpty()) {
-            resource.setRmapping(null);
+        if (resourceTO.getGmapping() == null || 
resourceTO.getGmapping().getItems().isEmpty()) {
+            resource.setGmapping(null);
         } else {
-            RMapping mapping = entityFactory.newEntity(RMapping.class);
+            GMapping mapping = entityFactory.newEntity(GMapping.class);
             mapping.setResource(resource);
-            resource.setRmapping(mapping);
-            populateMapping(resourceTO.getRmapping(), mapping, 
entityFactory.newEntity(RMappingItem.class));
+            resource.setGmapping(mapping);
+            populateMapping(resourceTO.getGmapping(), mapping, 
entityFactory.newEntity(GMappingItem.class));
         }
 
         resource.setCreateTraceLevel(resourceTO.getCreateTraceLevel());
@@ -276,10 +276,10 @@ public class ResourceDataBinderImpl implements 
ResourceDataBinder {
             resourceTO.setUmapping(mappingTO);
             populateMappingTO(resource.getUmapping(), mappingTO);
         }
-        if (resource.getRmapping() != null) {
+        if (resource.getGmapping() != null) {
             MappingTO mappingTO = new MappingTO();
-            resourceTO.setRmapping(mappingTO);
-            populateMappingTO(resource.getRmapping(), mappingTO);
+            resourceTO.setGmapping(mappingTO);
+            populateMappingTO(resource.getGmapping(), mappingTO);
         }
 
         
resourceTO.setEnforceMandatoryCondition(resource.isEnforceMandatoryCondition());

Reply via email to