Inserts an interval to the tree. 
        Note that when inserting we do not maintain appropriate sorting of the "mid" data structure.
        This should be done after all intervals are inserted.

def add_interval(self, start, end, data=None):
        '''
        Inserts an interval to the tree. 
        Note that when inserting we do not maintain appropriate sorting of the "mid" data structure.
        This should be done after all intervals are inserted.
        '''
        # Ignore intervals of 0 or negative length
        if (end - start) <= 0:
            return
        if self.single_interval is None:
            # This is an empty tree and we are adding the first interval. Just record it in a field.
            self.single_interval = (start, end, data)
        elif self.single_interval == 0:
            # This is a usual tree, use standard addition method
            self._add_interval(start, end, data)
        else:
            # This is a tree with a single interval. Convert to a usual tree.
            self._add_interval(*self.single_interval)
            self.single_interval = 0
            self._add_interval(start, end, data)