<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def intersection(self, other):
 """ Returns a new range containing all points shared by both ranges. If no points are shared an empty range is returned. intrange([1,5)) intrange(empty) intrange([5,10)) This is the same as the ``+`` operator for two ranges in PostgreSQL. :param other: Range to interect with. :return: A new range that is the intersection between this and `other`. """


        if not self.is_valid_range(other):
            msg = "Unsupported type to test for intersection '{.__class__.__name__}'"
            raise TypeError(msg.format(other))

        # Handle ranges not intersecting
        if not self or not other or not self.overlap(other):
            return self.empty()

        lower_end_span = self if self.startsafter(other) else other
        upper_end_span = self if self.endsbefore(other) else other

        return lower_end_span.replace(
            upper=upper_end_span.upper,
            upper_inc=upper_end_span.upper_inc)