@staticmethod
def _split_length(length, split_point):
    """
        Utility method for splitting a note length into two pieces, including the case that the length is a tuple
        For instance, if length = (3, 2, 4) and the split_point = 4.5, this gives us the tuple (3, 1.5) and (0.5, 4)

        :param length: a note length, either a number or a tuple of numbers representing tied segments
        :param split_point: where to split the length
        :return: tuple of (first half length, second half length). Each of these lengths may themselves be a tuple,
            or may be a single number if they are not split.
        """
    if split_point <= 0 or split_point >= (sum(length) if hasattr(length,
        '__len__') else length):
        raise ValueError('Split point outside of length tuple.')
    if hasattr(length, '__len__'):
        part_sum = 0
        for i, segment_length in enumerate(length):
            if part_sum + segment_length < split_point:
                part_sum += segment_length
            elif part_sum + segment_length == split_point:
                first_part = length[:i + 1]
                second_part = length[i + 1:]
                return first_part if len(first_part) > 1 else first_part[0
                    ], second_part if len(second_part) > 1 else second_part[0]
            else:
                first_part = length[:i] + (split_point - part_sum,)
                second_part = (part_sum + segment_length - split_point,
                    ) + length[i + 1:]
                return first_part if len(first_part) > 1 else first_part[0
                    ], second_part if len(second_part) > 1 else second_part[0]
    else:
        return split_point, length - split_point
