def unlzw(data):
    """
    This function was adapted for Python from Mark Adler's C implementation
    https://github.com/umeat/unlzw
    Decompress compressed data generated by the Unix compress utility (LZW
    compression, files with .Z suffix). Input can be given as any type which
    can be 'converted' to a bytearray (e.g. string, or bytearray). Returns
    decompressed data as string, or raises error.
    Written by Brandon Owen, May 2016, brandon.owen@hotmail.com
    Adapted from original work by Mark Adler - orginal copyright notice below
    Copyright (C) 2014, 2015 Mark Adler
    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any damages
    arising from the use of this software.
    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:
    1. The origin of this software must not be misrepresented; you must not
    claim that you wrote the original software. If you use this software
    in a product, an acknowledgment in the product documentation would be
    appreciated but is not required.
    2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.
    3. This notice may not be removed or altered from any source distribution.
    Mark Adler
    madler@alumni.caltech.edu
    """
    try:
        ba_in = bytearray(data)
    except ValueError:
        raise TypeError('Unable to convert inputted data to bytearray')
    inlen = len(ba_in)
    prefix = [None] * 65536
    suffix = [None] * 65536
    if inlen < 3:
        raise ValueError(
            'Invalid Input: Length of input too short for processing')
    if ba_in[0] != 31 or ba_in[1] != 157:
        raise ValueError('Invalid Header Flags Byte: Incorrect magic bytes')
    flags = ba_in[2]
    if flags & 96:
        raise ValueError(
            'Invalid Header Flags Byte: Flag byte contains invalid data')
    max_ = flags & 31
    if max_ < 9 or max_ > 16:
        raise ValueError(
            'Invalid Header Flags Byte: Max code size bits out of range')
    if max_ == 9:
        max_ = 10
    flags &= 128
    bits = 9
    mask = 511
    end = 256 if flags else 255
    if inlen == 3:
        return 0
    if inlen == 4:
        raise ValueError('Invalid Data: Stream ended in the middle of a code')
    buf = ba_in[3]
    buf += ba_in[4] << 8
    final = prev = buf & mask
    buf >>= bits
    left = 16 - bits
    if prev > 255:
        raise ValueError('Invalid Data: First code must be a literal')
    put = [final]
    mark = 3
    nxt = 5
    while nxt < inlen:
        if end >= mask and bits < max_:
            rem = (nxt - mark) % bits
            if rem:
                rem = bits - rem
                if rem >= inlen - nxt:
                    break
                nxt += rem
            buf = 0
            left = 0
            mark = nxt
            bits += 1
            mask <<= 1
            mask += 1
        buf += ba_in[nxt] << left
        nxt += 1
        left += 8
        if left < bits:
            if nxt == inlen:
                raise ValueError(
                    'Invalid Data: Stream ended in the middle of a code')
            buf += ba_in[nxt] << left
            nxt += 1
            left += 8
        code = buf & mask
        buf >>= bits
        left -= bits
        if code == 256 and flags:
            rem = (nxt - mark) % bits
            if rem:
                rem = bits - rem
                if rem > inlen - nxt:
                    break
                nxt += rem
            buf = 0
            left = 0
            mark = nxt
            bits = 9
            mask = 511
            end = 255
            continue
        temp = code
        stack = []
        if code > end:
            if code != end + 1 or prev > end:
                raise ValueError('Invalid Data: Invalid code detected')
            stack.append(final)
            code = prev
        while code >= 256:
            stack.append(suffix[code])
            code = prefix[code]
        stack.append(code)
        final = code
        if end < mask:
            end += 1
            prefix[end] = prev
            suffix[end] = final
        prev = temp
        put += stack[::-1]
    return bytes(bytearray(put))
