Get the rolls, i.e. the session at which to hop from contract to
        contract in the chain.

        Parameters
        ----------
        root_symbol : str
            The root symbol for which to calculate rolls.
        start : Timestamp
            Start of the date range.
        end : Timestamp
            End of the date range.
        offset : int
            Offset from the primary.

        Returns
        -------
        rolls - list[tuple(sid, roll_date)]
            A list of rolls, where first value is the first active `sid`,
        and the `roll_date` on which to hop to the next contract.
            The last pair in the chain has a value of `None` since the roll
            is after the range.

def get_rolls(self, root_symbol, start, end, offset):
        """
        Get the rolls, i.e. the session at which to hop from contract to
        contract in the chain.

        Parameters
        ----------
        root_symbol : str
            The root symbol for which to calculate rolls.
        start : Timestamp
            Start of the date range.
        end : Timestamp
            End of the date range.
        offset : int
            Offset from the primary.

        Returns
        -------
        rolls - list[tuple(sid, roll_date)]
            A list of rolls, where first value is the first active `sid`,
        and the `roll_date` on which to hop to the next contract.
            The last pair in the chain has a value of `None` since the roll
            is after the range.
        """
        oc = self.asset_finder.get_ordered_contracts(root_symbol)
        front = self._get_active_contract_at_offset(root_symbol, end, 0)
        back = oc.contract_at_offset(front, 1, end.value)
        if back is not None:
            end_session = self.trading_calendar.minute_to_session_label(end)
            first = self._active_contract(oc, front, back, end_session)
        else:
            first = front
        first_contract = oc.sid_to_contract[first]
        rolls = [((first_contract >> offset).contract.sid, None)]
        tc = self.trading_calendar
        sessions = tc.sessions_in_range(tc.minute_to_session_label(start),
                                        tc.minute_to_session_label(end))
        freq = sessions.freq
        if first == front:
            # This is a bit tricky to grasp. Once we have the active contract
            # on the given end date, we want to start walking backwards towards
            # the start date and checking for rolls. For this, we treat the
            # previous month's contract as the 'first' contract, and the
            # contract we just found to be active as the 'back'. As we walk
            # towards the start date, if the 'back' is no longer active, we add
            # that date as a roll.
            curr = first_contract << 1
        else:
            curr = first_contract << 2
        session = sessions[-1]

        while session > start and curr is not None:
            front = curr.contract.sid
            back = rolls[0][0]
            prev_c = curr.prev
            while session > start:
                prev = session - freq
                if prev_c is not None:
                    if prev < prev_c.contract.auto_close_date:
                        break
                if back != self._active_contract(oc, front, back, prev):
                    # TODO: Instead of listing each contract with its roll date
                    # as tuples, create a series which maps every day to the
                    # active contract on that day.
                    rolls.insert(0, ((curr >> offset).contract.sid, session))
                    break
                session = prev
            curr = curr.prev
            if curr is not None:
                session = min(session, curr.contract.auto_close_date + freq)

        return rolls