<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def repack(self, to_width, *, msb_first, start=0, start_bit=0, length=None):
 """Extracts a part of a BinArray's data and converts it to a BinArray of a different width. For the purposes of this conversion, words in this BinArray are joined side-by-side, starting from a given start index (defaulting to 0), skipping ``start_bit`` first bits of the first word, then the resulting stream is split into ``to_width``-sized words and ``length`` first such words are returned as a new BinArray. If ``msb_first`` is False, everything proceeds with little endian ordering: the first word provides the least significant bits of the combined stream, ``start_bit`` skips bits starting from the LSB, and the first output word is made from the lowest bits of the combined stream. Otherwise (``msb_first`` is True), everything proceeds with big endian ordering: the first word provides the most significant bits of the combined stream, ``start_bit`` skips bits starting from the MSB, and the first output word is made from the highest bits of the combined stream. ``start_bits`` must be smaller than the width of the input word. It is an error to request a larger length than can be provided from the input array. If ``length`` is not provided, this function returns as many words as can be extracted. For example, consider a 10-to-3 repack with start_bit=2, length=4 msb_first=True: +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ | start |X|X|a|b|c|d|e|f|g|h| +---------+-+-+-+-+-+-+-+-+-+-+ | start+1 |i|j|k|l|X|X|X|X|X|X| +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ is repacked to: +-+-+-+-+ |0|a|b|c| +-+-+-+-+ |1|d|e|f| +-+-+-+-+ |2|g|h|i| +-+-+-+-+ |3|j|k|l| +-+-+-+-+ The same repack for msb_first=False is performed as follows: +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ | start |h|g|f|e|d|c|b|a|X|X| +---------+-+-+-+-+-+-+-+-+-+-+ | start+1 |X|X|X|X|X|X|l|k|j|i| +---------+-+-+-+-+-+-+-+-+-+-+ +---------+-+-+-+-+-+-+-+-+-+-+ into: +-+-+-+-+ |0|c|b|a| +-+-+-+-+ |1|f|e|d| +-+-+-+-+ |2|i|h|g| +-+-+-+-+ |3|l|k|j| +-+-+-+-+ """

        to_width = operator.index(to_width)
        if not isinstance(msb_first, bool):
            raise TypeError('msb_first must be a bool')
        available = self.repack_data_available(
                to_width, start=start, start_bit=start_bit)
        if length is None:
            length = available
        else:
            length = operator.index(length)
            if length > available:
                raise ValueError('not enough data available')
            if length < 0:
                raise ValueError('length cannot be negative')
        start = operator.index(start)
        start_bit = operator.index(start_bit)
        pos = start
        accum = BinWord(0, 0)
        if start_bit:
            accum = self[pos]
            pos += 1
            rest = accum.width - start_bit
            if msb_first:
                accum = accum.extract(0, rest)
            else:
                accum = accum.extract(start_bit, rest)
        res = BinArray(width=to_width, length=length)
        for idx in range(length):
            while len(accum) < to_width:
                cur = self[pos]
                pos += 1
                if msb_first:
                    accum = BinWord.concat(cur, accum)
                else:
                    accum = BinWord.concat(accum, cur)
            rest = accum.width - to_width
            if msb_first:
                cur = accum.extract(rest, to_width)
                accum = accum.extract(0, rest)
            else:
                cur = accum.extract(0, to_width)
                accum = accum.extract(to_width, rest)
            res[idx] = cur
        return res