A 'private' helper member function to perform liftover in coordinate space
    when the length of the genomic match is smaller than the concensus match.
    We assume the genomic region contains deletions. In this case, we uniformly
    distribute the deletions (gaps) through the genomic region. This is the
    trickiest liftover case because it fragments the region after liftover.
    This method should only be called when the aboe condition is true (longer
    consensus region than genomic region) otherwise an assertion will be
    failed.

    :param intersecting_region: a region that intersects this occurrence.
    :return: list of GenomicInterval objects. This is a list because a genomic
             deletion of part of the retrotransposon can fragment the
             intersecting region and result in more than one returned interval.

def __liftover_coordinates_genomic_deletions(self, intersecting_region):
    """
    A 'private' helper member function to perform liftover in coordinate space
    when the length of the genomic match is smaller than the concensus match.
    We assume the genomic region contains deletions. In this case, we uniformly
    distribute the deletions (gaps) through the genomic region. This is the
    trickiest liftover case because it fragments the region after liftover.
    This method should only be called when the aboe condition is true (longer
    consensus region than genomic region) otherwise an assertion will be
    failed.

    :param intersecting_region: a region that intersects this occurrence.
    :return: list of GenomicInterval objects. This is a list because a genomic
             deletion of part of the retrotransposon can fragment the
             intersecting region and result in more than one returned interval.
    """
    # should never happen, but check anyway...
    consensus_match_length = self.consensus_end - self.consensus_start
    size_dif = consensus_match_length - len(self)
    assert(size_dif > 0)

    name = self.repeat_name()
    gap_interval = int(math.ceil(len(self) / float(size_dif)))
    s_dist_to_gen_start = max(intersecting_region.start - self.start, 0)
    e_dist_to_gen_start = min(max(intersecting_region.end -
                                  self.start, 0), len(self))
    gaps_before = s_dist_to_gen_start / gap_interval
    gaps_in = ((e_dist_to_gen_start - 1) / gap_interval) - gaps_before
    gen_s_dist = s_dist_to_gen_start
    left_to_lift = (min(self.end, intersecting_region.end) -
                    max(self.start, intersecting_region.start))
    res = []
    if self.consensus_match_strand is '+':
      s = s_dist_to_gen_start + self.consensus_start
      s = s + gaps_before
      for i in range(0, gaps_in):
        e = s + min((gap_interval - (gen_s_dist % gap_interval)), left_to_lift)
        res.append(GenomicInterval(name, s, e, intersecting_region.name,
                                   intersecting_region.score, self.strand))
        gen_s_dist += (e - s)
        left_to_lift -= (e - s)
        s = e + 1
      e = min(s + min(gap_interval, left_to_lift), self.consensus_end)
      if e - s != 0:
        res.append(GenomicInterval(name, s, e, intersecting_region.name,
                                   intersecting_region.score, self.strand))
    else:
      e = self.consensus_end - s_dist_to_gen_start
      e = e - gaps_before
      for i in range(0, gaps_in):
        s = e - min((gap_interval - (gen_s_dist % gap_interval)), left_to_lift)
        res.append(GenomicInterval(name, s, e, intersecting_region.name,
                                   intersecting_region.score, self.strand))
        gen_s_dist += (e - s)
        left_to_lift -= (e - s)
        e = s - 1
      s = max(e - min(gap_interval, left_to_lift), self.consensus_start)
      if e - s != 0:
        res.append(GenomicInterval(name, s, e, intersecting_region.name,
                                   intersecting_region.score, self.strand))
    return res