def context_role(self, bill=None, vote=None, session=None, term=None):
        '''Tell this legislator object which session to use when calculating
        the legisator's context_role for a given bill or vote.
        '''
        # If no hints were given about the context, look for a related bill,
        # then for a related vote.
        if not any([bill, vote, session, term]):
            try:
                bill = self.bill
            except AttributeError:
                # A vote?
                try:
                    vote = self.vote
                except AttributeError:
                    # If we're here, this method was called on a
                    # Legislator was that doesn't have a related bill or vote.
                    return ''

        # If we still have to historical point of reference, figuring
        # out the context role is impossible. Return emtpy string.
        if not any([bill, vote, session, term]):
            return ''

        # First figure out the term.
        if bill is not None:
            term = bill['_term']

        elif vote is not None:
            try:
                _bill = vote.bill
            except AttributeError:
                _bill = BillVote(vote).bill
            if callable(_bill):
                _bill = _bill()
            term = _bill['_term']

        if term is None and session is not None:
            term = term_for_session(self[settings.LEVEL_FIELD], session)

        # Use the term to get the related roles. First look in the current
        # roles list, then fail over to the old_roles list.
        roles = [r for r in self['roles']
                 if r.get('type') == 'member' and r.get('term') == term]
        roles = list(filter(None, roles))

        if not roles:
            roles = [r for r in self.get('old_roles', {}).get(term, [])
                     if r.get('type') == 'member']
        roles = list(filter(None, roles))

        if not roles:
            # Legislator had no roles for this term. If there is a related
            # bill ro vote, this shouldn't happen, but could if the
            # legislator's roles got deleted.
            return ''

        # If there's only one applicable role, we're done.
        if len(roles) == 1:
            role = roles.pop()
            self['context_role'] = role
            return role

        # If only one of term or session is given and there are multiple roles:
        if not list(filter(None, [bill, vote])):
            if term is not None:
                role = roles[0]
                self['context_role'] = role
                return role

            # Below, use the date of the related bill or vote to determine
            # which (of multiple) roles applies.
            # Get the context date.
            if session is not None:
                # If we're here, we have multiple roles for a single session.
                # Try to find the correct one in self.metadata,
                # else give up.
                session_data = self.metadata['session_details'][session]
                for role in roles:
                    role_start = role.get('start_date')
                    role_end = role.get('end_date')

                    # Return the first role that overlaps at all with the
                    # session.
                    session_start = session_data.get('start_date')
                    session_end = session_data.get('end_date')
                    if session_start and session_end:
                        started_during = (role_start < session_start <
                                          role_end)
                        ended_during = (role_start < session_end < role_end)
                        if started_during or ended_during:
                            self['context_role'] = role
                            return role
                    else:
                        continue

                # Return first role from the session?
                role = roles[0]
                self['context_role'] = role
                return role

        if vote is not None:
            date = vote['date']
        if bill is not None:
            date = bill['action_dates']['first']

        dates_exist = False
        for role in roles:
            start_date = role.get('start_date')
            end_date = role.get('end_date')
            if start_date and end_date:
                dates_exist = True
                if start_date < date < end_date:
                    self['context_role'] = role
                    return role

        if dates_exist:
            # If we're here, the context date didn't fall into any of the
            # legislator's role date ranges.
            return ''

        else:
            # Here the roles didn't have date ranges. Return the last one?
            role = roles.pop()
            self['context_role'] = role
            return role

        return ''
Tell this legislator object which session to use when calculating
        the legisator's context_role for a given bill or vote.