class AcmPrivilegeService {

    public void setPrivileges(AcmAssignedObject obj, String accessSpec)
    {
        log.trace("Set privilege '{}' to object: {}[{}]", accessSpec, obj.getObjectType(), obj.getId());

        String[] parts = accessSpec.split(" ");
        // grant, deny, mandatory deny

        int idx = 0;
        String mode = parts[idx];
        if (DataAccessControlConstants.ACCESS_MANDATORY.equals(mode))
        {
            idx++;
            mode += " " + parts[idx];
        }

        idx++;
        String action = parts[idx];
        idx++;
        while (!parts[idx].equals(DataAccessControlConstants.ACCESS_LEVEL_PARTICIPANT_TYPE_SEPARATOR) && idx < parts.length)
        {
            action += " " + parts[idx];
            idx++;
        }

        // skip the word "to"
        idx++;
        String participantType = parts[idx];
        idx++;

        while (idx < parts.length)
        {
            participantType += " " + parts[idx];
            idx++;
        }

        List<String> participantTypes = participantTypesToList(participantType);

        // now we have the desired access, so we can grant it to every participant of the given participant type
        for (AcmParticipant ap : obj.getParticipants())
        {
            log.trace("checking type '{}', user '{}'", ap.getParticipantType(), ap.getParticipantLdapId());

            if (participantTypes.contains((ap.getParticipantType().toLowerCase())))
            {
                boolean found = false;
                for (AcmParticipantPrivilege priv : ap.getPrivileges())
                {
                    log.trace("object action: '{}', rule action: '{}'", priv.getObjectAction(), action);
                    if (action.equals(priv.getObjectAction()))
                    {
                        found = true;
                        if (!mode.equals(priv.getAccessType())
                                || !DataAccessControlConstants.ACCESS_REASON_POLICY.equals(priv.getAccessReason()))
                        {
                            priv.setAccessType(mode);
                            priv.setAccessReason(DataAccessControlConstants.ACCESS_REASON_POLICY);
                            log.debug("updated existing privilege [{} '{}' to '{}'='{}']", mode, action, ap.getParticipantType(),
                                    ap.getParticipantLdapId());
                            break;
                        }
                    }
                }

                if (!found)
                {
                    AcmParticipantPrivilege priv = new AcmParticipantPrivilege();
                    priv.setAccessType(mode);
                    priv.setAccessReason(DataAccessControlConstants.ACCESS_REASON_POLICY);
                    priv.setObjectAction(action);
                    ap.getPrivileges().add(priv);

                    log.debug("added privilege '{}' to '{}'", action, ap.getParticipantLdapId());
                }
            }
        }

    }

}