<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _parse(encoded_data, data_len, pointer=0, lengths_only=False):
 """ Parses a byte string into component parts :param encoded_data: A byte string that contains BER-encoded data :param data_len: The integer length of the encoded data :param pointer: The index in the byte string to parse from :param lengths_only: A boolean to cause the call to return a 2-element tuple of the integer number of bytes in the header and the integer number of bytes in the contents. Internal use only. :return: A 2-element tuple: - 0: A tuple of (class_, method, tag, header, content, trailer) - 1: An integer indicating how many bytes were consumed """


    if data_len < pointer + 2:
        raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (2, data_len - pointer))

    start = pointer
    first_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
    pointer += 1

    tag = first_octet & 31
    # Base 128 length using 8th bit as continuation indicator
    if tag == 31:
        tag = 0
        while True:
            num = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
            pointer += 1
            tag *= 128
            tag += num & 127
            if num >> 7 == 0:
                break

    length_octet = ord(encoded_data[pointer]) if _PY2 else encoded_data[pointer]
    pointer += 1

    if length_octet >> 7 == 0:
        if lengths_only:
            return (pointer, pointer + (length_octet & 127))
        contents_end = pointer + (length_octet & 127)

    else:
        length_octets = length_octet & 127
        if length_octets:
            pointer += length_octets
            contents_end = pointer + int_from_bytes(encoded_data[pointer - length_octets:pointer], signed=False)
            if lengths_only:
                return (pointer, contents_end)

        else:
            # To properly parse indefinite length values, we need to scan forward
            # parsing headers until we find a value with a length of zero. If we
            # just scanned looking for \x00\x00, nested indefinite length values
            # would not work.
            contents_end = pointer
            # Unfortunately we need to understand the contents of the data to
            # properly scan forward, which bleeds some representation info into
            # the parser. This condition handles the unused bits byte in
            # constructed bit strings.
            if tag == 3:
                contents_end += 1
            while contents_end < data_len:
                sub_header_end, contents_end = _parse(encoded_data, data_len, contents_end, lengths_only=True)
                if contents_end == sub_header_end and encoded_data[contents_end - 2:contents_end] == b'\x00\x00':
                    break
            if lengths_only:
                return (pointer, contents_end)
            if contents_end > data_len:
                raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end, data_len))
            return (
                (
                    first_octet >> 6,
                    (first_octet >> 5) & 1,
                    tag,
                    encoded_data[start:pointer],
                    encoded_data[pointer:contents_end - 2],
                    b'\x00\x00'
                ),
                contents_end
            )

    if contents_end > data_len:
        raise ValueError(_INSUFFICIENT_DATA_MESSAGE % (contents_end, data_len))
    return (
        (
            first_octet >> 6,
            (first_octet >> 5) & 1,
            tag,
            encoded_data[start:pointer],
            encoded_data[pointer:contents_end],
            b''
        ),
        contents_end
    )