class DBService implements RolesProvider {

    public void executePutRoleMeta(ResourceContext ctx, String domainName, String roleName, Role originalRole,
                                   RoleMeta meta, String auditRef, String caller) {

        // our exception handling code does the check for retry count
        // and throws the exception it had received when the retry
        // count reaches 0

        for (int retryCount = defaultRetryCount; ; retryCount--) {

            try (ObjectStoreConnection con = store.getConnection(false, true)) {

                checkObjectAuditEnabled(con, originalRole.getAuditEnabled(), originalRole.getName(),
                        auditRef, caller, getPrincipalName(ctx));

                // now process the request. first we're going to make a
                // copy of our role

                Role updatedRole = new Role()
                        .setName(originalRole.getName())
                        .setAuditEnabled(originalRole.getAuditEnabled())
                        .setTrust(originalRole.getTrust())
                        .setSelfServe(originalRole.getSelfServe())
                        .setMemberExpiryDays(originalRole.getMemberExpiryDays())
                        .setServiceExpiryDays(originalRole.getServiceExpiryDays())
                        .setGroupExpiryDays(originalRole.getGroupExpiryDays())
                        .setTokenExpiryMins(originalRole.getTokenExpiryMins())
                        .setCertExpiryMins(originalRole.getCertExpiryMins())
                        .setMemberReviewDays(originalRole.getMemberReviewDays())
                        .setServiceReviewDays(originalRole.getServiceReviewDays())
                        .setSignAlgorithm(originalRole.getSignAlgorithm())
                        .setReviewEnabled(originalRole.getReviewEnabled())
                        .setNotifyRoles(originalRole.getNotifyRoles())
                        .setUserAuthorityFilter(originalRole.getUserAuthorityFilter())
                        .setUserAuthorityExpiration(originalRole.getUserAuthorityExpiration());

                // then we're going to apply the updated fields
                // from the given object

                updateRoleMetaFields(updatedRole, meta);

                con.updateRole(domainName, updatedRole);
                saveChanges(con, domainName);

                // audit log the request

                StringBuilder auditDetails = new StringBuilder(ZMSConsts.STRING_BLDR_SIZE_DEFAULT);
                auditLogRoleMeta(auditDetails, updatedRole, roleName);

                auditLogRequest(ctx, domainName, auditRef, caller, ZMSConsts.HTTP_PUT,
                        domainName, auditDetails.toString());

                // if the role member expiry date or review date has changed then we're going
                // process all the members in the role and update the expiration and review
                // date accordingly

                updateRoleMembersDueDates(ctx, con, domainName, roleName, originalRole,
                        updatedRole, auditRef, caller);

                // if there was a change in the role user attribute filter then we need
                // to make the necessary changes as well.

                updateRoleMembersSystemDisabledState(ctx, con, domainName, roleName, originalRole,
                        updatedRole, auditRef, caller);

                return;

            } catch (ResourceException ex) {
                if (!shouldRetryOperation(ex, retryCount)) {
                    throw ex;
                }
            }
        }
    }

    public  DBService(ObjectStore store, AuditLogger auditLogger, ZMSConfig zmsConfig, AuditReferenceValidator auditReferenceValidator);

}