def METHOD_NAME(self, a, other, b, n):
    assert 0 <= a <= len(self)
    assert 0 <= b <= len(other)
    assert n >= 0
    if n == 0 or (self is other and a == b):
        return
    if a % 8 == 0 and b % 8 == 0:            # aligned case
        p1 = a // 8
        p2 = (a + n - 1) // 8
        m = bits2bytes(n)
        assert p1 + m == p2 + 1
        m2 = ones_table[is_be(self)][(a + n) % 8]
        t2 = memoryview(self)[p2]
        memoryview(self)[p1:p1 + m] = memoryview(other)[b // 8:b // 8 + m]
        if self.endian() != other.endian():
            self.bytereverse(p1, p2 + 1)
        if m2:
            memoryview(self)[p2] = (memoryview(self)[p2] & m2) | (t2 & ~m2)
        return
    if n < 8:                                # small n case
        if a <= b:  # loop forward
            for i in range(n):
                self[i + a] = other[i + b]
        else:       # loop backwards
            for i in range(n - 1, -1, -1):
                self[i + a] = other[i + b]
        return
    # -------------------------------------- # general case
    p1 = a // 8
    p2 = (a + n - 1) // 8
    p3 = b // 8
    sa = a % 8
    sb = -(b % 8)
    m1 = ones_table[is_be(self)][sa]
    m2 = ones_table[is_be(self)][(a + n) % 8]
    assert n >= 8
    assert a - sa == 8 * p1
    assert b + sb == 8 * p3
    assert a + n > 8 * p2
    if verbose:
        print('a =', a)
        print('b =', b)
        print('n =', n)
        print('p1 =', p1)
        print('p2 =', p2)
        print('p3 =', p3)
        print('sa =', sa)
        print('sb =', sb)
    t1 = memoryview(self)[p1]
    t2 = memoryview(self)[p2]
    t3 = memoryview(other)[p3]
    if sa + sb < 0:
        sb += 8
        if verbose:
            print(' -> sb =', sb)
    if verbose:
        print('other')
        pprint(other)
        mark_range_n(b, n, '^', 'b..b+n')
        mark_range_n(b + sb, n - sb, '=')
        mark_range_n(b, sb, '3')
        print('self')
        pprint(self)
        mark_range_n(a, n, '^', 'a..a+n')
        mark_range(8 * p1, a, '1')
        mark_range(a + n, 8 * p2 + 8, '2')
        print('copy_n')
        mark_range_n(a - sa, n - sb, '=')
    METHOD_NAME(self, a - sa, other, b + sb, n - sb)
    if verbose:
        pprint(self)
        print('rshift', sa + sb)
        mark_range(8 * p1, 8 * (p2 + 1), '>')
    shift_r8(self, p1, p2 + 1, sa + sb)
    if verbose:
        pprint(self)
        mark_range_n(8 * p1 + sa + sb, n - sb, '=', 'a..a+n')
    if m1:
        if verbose:
            mark_range(8 * p1, a, '1')
        memoryview(self)[p1] = (memoryview(self)[p1] & ~m1) | (t1 & m1)
    if m2 and sa + sb:
        if verbose:
            mark_range(a + n, 8 * p2 + 8, '2')
        memoryview(self)[p2] = (memoryview(self)[p2] & m2) | (t2 & ~m2)
    if verbose:
        mark_range_n(a, sb, '3')
    for i in range(sb):
        self[i + a] = bool(t3 & bitmask_table[is_be(other)][(i + b) % 8])
    if verbose:
        pprint(self)