class PUMAAuthServiceImpl extends AbstractSSOAuthServiceImpl {

    protected void syncGroupsMembershipFromPUMA(XWikiDocument userProfile, User user, PumaLocator pl,
        PumaProfile pumaProfile, XWikiContext context) throws XWikiException
    {
        // got valid group mappings
        Map<String, Collection<String>> groupMappings = getConfig().getGroupMapping(context);

        if (groupMappings != null && groupMappings.size() > 0) {
            try {
                Collection<String> xwikiGroupsIn = new ArrayList<String>();
                Collection<String> xwikiGroupsOut = new ArrayList<String>();

                Map<String, Collection<String>> groupsToRemove = new HashMap<String, Collection<String>>(groupMappings);

                List<Group> pumaUserGroups = pl.findGroupsByPrincipal(user, true);

                LOG.debug("The user belongs to following PUMA groups: ");

                // membership to add
                for (Group group : pumaUserGroups) {
                    String groupUid = pumaProfile.getIdentifier(group);

                    LOG.debug("  - " + groupUid);

                    Collection<String> xwikiGroups = groupsToRemove.get(groupUid);
                    if (xwikiGroups != null) {
                        xwikiGroupsIn.addAll(xwikiGroups);

                        groupsToRemove.remove(groupUid);
                    }
                }

                // membership to remove
                for (Collection<String> xwikiGroups : groupsToRemove.values()) {
                    xwikiGroupsOut.addAll(xwikiGroups);
                }

                // apply synch
                syncGroupsMembership(userProfile, xwikiGroupsIn, xwikiGroupsOut, context);
            } catch (Exception e) {
                LOG.error("Failed to synchronize groups for user [" + userProfile + "]", e);
            }
        }
    }

}