'This method retrieves the list of possible roles that user can select
in the item permissions form. Admins can select any role so the
results are paginated in order to save the bandwidth and to speed
things up.
Standard users can select their own private role, any of their
sharing roles and any public role (not private and not sharing).'

def get_valid_roles(self, trans, item, query=None, page=None, page_limit=None, is_library_access=False):

    roles = []
    if (query is not None):
        query = query.replace('_', '/_').replace('%', '/%').replace('/', '//')
        search_query = (query + '%')
        log.debug(('search_query:    ' + str(search_query)))
    if ((page is not None) and (page_limit is not None)):
        paginated = True
        limit = (page * page_limit)
    else:
        paginated = False
    total_count = None
    if (isinstance(item, self.model.Library) and self.library_is_public(item)):
        is_public_item = True
    elif (isinstance(item, self.model.Dataset) and self.dataset_is_public(item)):
        is_public_item = True
    elif isinstance(item, self.model.LibraryFolder):
        is_public_item = True
    else:
        is_public_item = False
    if (trans.user_is_admin() and (is_public_item or is_library_access)):
        db_query = trans.sa_session.query(trans.app.model.Role).filter((self.model.Role.table.c.deleted == false()))
        if (query is not None):
            db_query = db_query.filter(self.model.Role.table.c.name.like(search_query, escape='/'))
        total_count = db_query.count()
        if paginated:
            roles = db_query.order_by(self.model.Role.table.c.name).limit(limit).all()
            page_start = ((page * page_limit) - page_limit)
            page_end = (page_start + page_limit)
            if (total_count < page_start):
                roles = []
            else:
                roles = roles[page_start:page_end]
        else:
            roles = db_query.order_by(self.model.Role.table.c.name)
    elif is_public_item:
        roles.append(self.get_private_user_role(trans.user))
        for role in self.get_sharing_roles(trans.user):
            roles.append(role)
        for role in self._get_npns_roles(trans):
            roles.append(role)
    else:
        access_roles = item.get_access_roles(trans)
        for role in access_roles:
            if (trans.user_is_admin() or self.ok_to_display(trans.user, role)):
                roles.append(role)
                for ura in role.users:
                    user = ura.user
                    for ura2 in user.roles:
                        if (trans.user_is_admin() or self.ok_to_display(trans.user, ura2.role)):
                            roles.append(ura2.role)
                for gra in role.groups:
                    group = gra.group
                    for uga in group.users:
                        user = uga.user
                        for ura in user.roles:
                            if (trans.user_is_admin() or self.ok_to_display(trans.user, ura.role)):
                                roles.append(ura.role)
    return_roles = set(roles)
    if (total_count is None):
        total_count = len(return_roles)
    return (self.sort_by_attr([role for role in return_roles], 'name'), total_count)
