    bool run(OperationContext* txn,
             const string& dbname,
             BSONObj& cmdObj,
             int options,
             string& errmsg,
             BSONObjBuilder& result) {
        std::string roleNameString;
        std::vector<RoleName> rolesToRemove;
        Status status = auth::parseRolePossessionManipulationCommands(
            cmdObj, "revokeRolesFromRole", dbname, &roleNameString, &rolesToRemove);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        ServiceContext* serviceContext = txn->getClient()->getServiceContext();
        stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));

        AuthorizationManager* authzManager = AuthorizationManager::get(serviceContext);
        status = requireAuthSchemaVersion26Final(txn, authzManager);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        RoleName roleName(roleNameString, dbname);
        if (RoleGraph::isBuiltinRole(roleName)) {
            return appendCommandStatus(
                result,
                Status(ErrorCodes::InvalidRoleModification,
                       str::stream() << roleName.getFullName()
                                     << " is a built-in role and cannot be modified."));
        }

        BSONObj roleDoc;
        status = authzManager->getRoleDescription(txn, roleName, PrivilegeFormat::kOmit, &roleDoc);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        std::vector<RoleName> roles;
        status = auth::parseRoleNamesFromBSONArray(
            BSONArray(roleDoc["roles"].Obj()), roleName.getDB(), &roles);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        for (vector<RoleName>::const_iterator it = rolesToRemove.begin(); it != rolesToRemove.end();
             ++it) {
            vector<RoleName>::iterator itToRm = std::find(roles.begin(), roles.end(), *it);
            if (itToRm != roles.end()) {
                roles.erase(itToRm);
            }
        }

        audit::logRevokeRolesFromRole(Client::getCurrent(), roleName, rolesToRemove);

        status = updateRoleDocument(
            txn, roleName, BSON("$set" << BSON("roles" << rolesVectorToBSONArray(roles))));
        // Must invalidate even on bad status - what if the write succeeded but the GLE failed?
        authzManager->invalidateUserCache();
        return appendCommandStatus(result, status);
    }
    bool run(OperationContext* txn,
             const string& dbname,
             BSONObj& cmdObj,
             int options,
             string& errmsg,
             BSONObjBuilder& result) {
        std::string roleNameString;
        std::vector<RoleName> rolesToRemove;
        Status status = auth::parseRolePossessionManipulationCommands(
            cmdObj, "revokeRolesFromRole", dbname, &roleNameString, &rolesToRemove);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        ServiceContext* serviceContext = txn->getClient()->getServiceContext();
        stdx::lock_guard<stdx::mutex> lk(getAuthzDataMutex(serviceContext));

        AuthorizationManager* authzManager = AuthorizationManager::get(serviceContext);
        status = requireAuthSchemaVersion26Final(txn, authzManager);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        RoleName roleName(roleNameString, dbname);
        if (RoleGraph::isBuiltinRole(roleName)) {
            return appendCommandStatus(
                result,
                Status(ErrorCodes::InvalidRoleModification,
                       str::stream() << roleName.getFullName()
                                     << " is a built-in role and cannot be modified."));
        }

        BSONObj roleDoc;
        status = authzManager->getRoleDescription(txn, roleName, PrivilegeFormat::kOmit, &roleDoc);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        std::vector<RoleName> roles;
        status = auth::parseRoleNamesFromBSONArray(
            BSONArray(roleDoc["roles"].Obj()), roleName.getDB(), &roles);
        if (!status.isOK()) {
            return appendCommandStatus(result, status);
        }

        for (vector<RoleName>::const_iterator it = rolesToRemove.begin(); it != rolesToRemove.end();
             ++it) {
            vector<RoleName>::iterator itToRm = std::find(roles.begin(), roles.end(), *it);
            if (itToRm != roles.end()) {
                roles.erase(itToRm);
            }
        }

        audit::logRevokeRolesFromRole(Client::getCurrent(), roleName, rolesToRemove);

        status = updateRoleDocument(
            txn, roleName, BSON("$set" << BSON("roles" << rolesVectorToBSONArray(roles))));
         
        authzManager->invalidateUserCache();
        return appendCommandStatus(result, status);
    }