delete everything from elem to end_elem, including elem.
        if delete_end==True, also including end_elem; otherwise, leave it.

def remove_range(cls, elem, end_elem, delete_end=True):
        """delete everything from elem to end_elem, including elem.
        if delete_end==True, also including end_elem; otherwise, leave it."""
        while elem is not None and elem != end_elem and end_elem not in elem.xpath("descendant::*"):
            parent = elem.getparent()
            nxt = elem.getnext()
            parent.remove(elem)
            if DEBUG == True:
                print(etree.tounicode(elem))
            elem = nxt
        if elem == end_elem:
            if delete_end == True:
                cls.remove(end_elem, leave_tail=True)
        elif elem is None:
            if parent.tail not in [None, '']:
                parent.tail = ''
            cls.remove_range(parent.getnext(), end_elem)
            XML.remove_if_empty(parent)
        elif end_elem in elem.xpath("descendant::*"):
            if DEBUG == True:
                print(elem.text)
            elem.text = ''
            cls.remove_range(elem.getchildren()[0], end_elem)
            XML.remove_if_empty(elem)
        else:
            print("LOGIC ERROR", file=sys.stderr)