You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: role.go
    path of file: ./repos/corteza/server/system/service
    
    the code of the file until where you have to start completion: package service

import (
	"context"
	"fmt"
	"strconv"
	"strings"

	"github.com/cortezaproject/corteza/server/pkg/actionlog"
	intAuth "github.com/cortezaproject/corteza/server/pkg/auth"
	"github.com/cortezaproject/corteza/server/pkg/errors"
	"github.com/cortezaproject/corteza/server/pkg/eventbus"
	"github.com/cortezaproject/corteza/server/pkg/expr"
	"github.com/cortezaproject/corteza/server/pkg/handle"
	"github.com/cortezaproject/corteza/server/pkg/label"
	"github.com/cortezaproject/corteza/server/pkg/logger"
	"github.com/cortezaproject/corteza/server/pkg/options"
	"github.com/cortezaproject/corteza/server/pkg/rbac"
	"github.com/cortezaproject/corteza/server/pkg/slice"
	"github.com/cortezaproject/corteza/server/store"
	"github.com/cortezaproject/corteza/server/system/service/event"
	"github.com/cortezaproject/corteza/server/system/types"
	"go.uber.org/zap"
)

type (
	role struct {
		actionlog actionlog.Recorder

		ac       roleAccessController
		eventbus eventDispatcher
		rbac     rbacRuleService

		user UserService
		auth roleAuth

		store store.Storer

		// list of all system roles
		system map[string]bool

		// list of all closed roles
		closed map[string]bool
	}

	roleAccessController interface {
		CanGrant(context.Context) bool

		CanSearchRoles(context.Context) bool
		CanCreateRole(context.Context) bool
		CanReadRole(context.Context, *types.Role) bool
		Can
    
func (svc role) MemberRemove(ctx context.Context, roleID, memberID uint64) (err error) {
	var (
		r       *types.Role
		m       *types.User
		raProps = &roleActionProps{
			role:   &types.Role{ID: roleID},
			member: &types.User{ID: memberID},
		}
	)

	err = func() (err error) {
		if roleID == 0 || memberID == 0 {
			return RoleErrInvalidID()
		}

		if r, err = svc.findByID(ctx, roleID); err != nil {
			return
		}

		if svc.IsClosed(r) || svc.IsContextual(r) {
			return RoleErrNotAllowedToManageMembers()
		}

		raProps.setRole(r)

		if m, err = svc.user.FindByID(ctx, memberID); err != nil {
			return
		}

		raProps.setMember(m)

		if err = svc.eventbus.WaitFor(ctx, event.RoleMemberBeforeRemove(m, r)); err != nil {
			return
		}

		if !svc.ac.CanManageMembersOnRole(ctx, r) {
			return RoleErrNotAllowedToManageMembers()
		}

		if err = store.DeleteRoleMember(ctx, svc.store, &types.RoleMember{RoleID: r.ID, UserID: m.ID}); err != nil {
			return
		}

		// @todo skipping this for now,
		//			AS per now PUT `/role/{roleID}` endpoint updates role and it's member with it but
		//			only if one or more members are included in request otherwise we ignore it,
		//			which causes issue in admin when we remove all the members from role.
		//			we have to rework the role membership management logic in admin,
		//			and use the dedicated endpoints for POST, DELETE role member.
		// if err = svc.auth.RemoveAccessTokens(ctx, m); err != nil {
		//	 return
		// }

		_ = svc.eventbus.WaitFor(ctx, event.RoleMemberAfterRemove(m, r))
		return nil
	}()

	return svc.recordAction(ctx, raProps, RoleActionMemberRemove, err)
}