def _fill(self, direction, stop_before=None):
        """
        If the bag contains only one cell, select all cells in the direction
        given, excluding the original cell. For example, from a column heading
        cell, you can "fill down" to get all the values underneath it.

        If you provide a stop_before function, it will be called on each cell
        as a stop condition. For example, if you provide a stop_before function
        which tests cell.value for an empty string. This would stop the fill
        function before it reaches the bottom of the sheet, for example.
        """
        raise DeprecationWarning("2D fill is deprecated. Yell if you need it.")
        if direction not in (UP, RIGHT, DOWN, LEFT, UP_RIGHT, DOWN_RIGHT,
                             UP_LEFT, DOWN_LEFT):
            raise ValueError("Invalid direction! Use one of UP, RIGHT, "
                             "DOWN_RIGHT etc")

        (left_right, up_down) = direction
        bag = self.select(
            lambda table, bag: cmp(table.x, bag.x) == left_right
            and cmp(table.y, bag.y) == up_down
        )

        if stop_before is not None:
            # NOTE(PMF): stop_before is limited to singleton bags, in the DOWN
            # or RIGHT direction. This isn't ideal, but with the above "magic"
            # cmp code I can't think of an elegant general way of doing this. I
            # also can't imagine what it means to run fill in multiple
            # directions, or with non singleton bags. TODO: Constrain?

            if direction not in (DOWN, RIGHT):
                raise ValueError("Oops, stop_before only works down or right!")
            self.assert_one("You can't use stop_before for bags with more than"
                            " one cell inside.")

            return Bag.from_list(list(
                takewhile(lambda c: not stop_before(c), bag)))

        return bag