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] != 0x1F) or (ba_in[1] != 0x9D):
		raise ValueError("Invalid Header Flags Byte: Incorrect magic bytes")
	flags = ba_in[2]
	if flags & 0x60:
		raise ValueError("Invalid Header Flags Byte: Flag byte contains invalid data")
	max_ = flags & 0x1F
	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 &= 0x80
	bits = 9
	mask = 0x1FF
	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 = 0x1FF
			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))