// Path: src/main/java/net/rauros/jzwave/utils/ByteEnum.java
// public interface ByteEnum
// {
// 	byte getByteValue();
// }
// 
// Path: src/main/java/net/rauros/jzwave/utils/Enums.java
// public class Enums
// {
// 	public static <E extends Enum<E> & ByteEnum> E byByteValue(Class<E> enumClass, byte value)
// 	{
// 		for(E e : enumClass.getEnumConstants())
// 			if(((ByteEnum) e).getByteValue() == value)
// 				return e;
// 
// 		return null;
// 	}
// }
// 
// Path: src/main/java/net/rauros/jzwave/utils/StringUtils.java
// public class StringUtils
// {
// 	/**
// 	 * Parse at most length bytes from a byte array into a ASCII String,
// 	 * starting at offset. If a null character is found before length then
// 	 * parsing will halt.
// 	 * 
// 	 * @param rawDatap
// 	 * @param offset
// 	 * @param length
// 	 * @return
// 	 */
// 	public static String parseASCIINullTerm(byte rawDatap[], int offset, int length)
// 	{
// 		int searchLength = 0;
// 		while(searchLength < length && rawDatap[offset + searchLength] != 0)
// 			searchLength++;
// 		return new String(rawDatap, offset, searchLength, Charset.forName("US-ASCII"));
// 	}
// 
// 	public static String toHexString(byte data[])
// 	{
// 		return toHexString(data, 0, data.length);
// 	}
// 
// 	public static String toHexString(byte data[], int offset, int length)
// 	{
// 		StringBuilder sb = new StringBuilder();
// 		for(int i = 0; i < length; i++)
// 		{
// 			sb.append(Integer.toHexString((data[offset + i] & 0xF0) >> 4));
// 			sb.append(Integer.toHexString(data[offset + i] & 0x0F));
// 			if(i < length)
// 			{
// 				sb.append(" ");
// 			}
// 		}
// 		return sb.toString();
// 	}
// 
// }


import net.rauros.jzwave.utils.ByteEnum;
import net.rauros.jzwave.utils.Enums;
import net.rauros.jzwave.utils.StringUtils;
import java.util.Arrays;
	private static int callbackCounter = 1;

	/**
	 * Generate a Job-wide callbackId using a rotating 8bit counter, never using
	 * zero only [1,255]
	 * 
	 * @return [1,255]
	 */
	private static synchronized int generateCallbackId()
	{
		if(callbackCounter > 255)
			callbackCounter = 1;
		return callbackCounter++;
	}

	// OpenZWave pre-allocates at buffer of 256 ... max message length, likely
	// since datalength is 8bit
	// perhaps 258 since SOF + 1 byte data length + possible 256 = 258
	protected int dataSize = 0;
	protected int size = 0;
	protected byte buffer[] = new byte[258];
	protected boolean requiresChecksum = true;

	protected int generatedCallbackId = 0;

	public Message(MsgType msgType, Function func, Object... parameters)
	{
		buffer[0] = ZWaveConstants.SOF;
		buffer[1] = 0x00; // length
		buffer[2] = msgType.getByteValue();
// Path: src/main/java/net/rauros/jzwave/utils/ByteEnum.java
// public interface ByteEnum
// {
// 	byte getByteValue();
// }
// 
// Path: src/main/java/net/rauros/jzwave/utils/Enums.java
// public class Enums
// {
// 	public static <E extends Enum<E> & ByteEnum> E byByteValue(Class<E> enumClass, byte value)
// 	{
// 		for(E e : enumClass.getEnumConstants())
// 			if(((ByteEnum) e).getByteValue() == value)
// 				return e;
// 
// 		return null;
// 	}
// }
// 
// Path: src/main/java/net/rauros/jzwave/utils/StringUtils.java
// public class StringUtils
// {
// 	/**
// 	 * Parse at most length bytes from a byte array into a ASCII String,
// 	 * starting at offset. If a null character is found before length then
// 	 * parsing will halt.
// 	 * 
// 	 * @param rawDatap
// 	 * @param offset
// 	 * @param length
// 	 * @return
// 	 */
// 	public static String parseASCIINullTerm(byte rawDatap[], int offset, int length)
// 	{
// 		int searchLength = 0;
// 		while(searchLength < length && rawDatap[offset + searchLength] != 0)
// 			searchLength++;
// 		return new String(rawDatap, offset, searchLength, Charset.forName("US-ASCII"));
// 	}
// 
// 	public static String toHexString(byte data[])
// 	{
// 		return toHexString(data, 0, data.length);
// 	}
// 
// 	public static String toHexString(byte data[], int offset, int length)
// 	{
// 		StringBuilder sb = new StringBuilder();
// 		for(int i = 0; i < length; i++)
// 		{
// 			sb.append(Integer.toHexString((data[offset + i] & 0xF0) >> 4));
// 			sb.append(Integer.toHexString(data[offset + i] & 0x0F));
// 			if(i < length)
// 			{
// 				sb.append(" ");
// 			}
// 		}
// 		return sb.toString();
// 	}
// 
// }


// Path: src/main/java/net/rauros/jzwave/core/Message.java
import net.rauros.jzwave.utils.ByteEnum;
import net.rauros.jzwave.utils.Enums;
import net.rauros.jzwave.utils.StringUtils;
import java.util.Arrays;

	private static int callbackCounter = 1;

	/**
	 * Generate a Job-wide callbackId using a rotating 8bit counter, never using
	 * zero only [1,255]
	 * 
	 * @return [1,255]
	 */
	private static synchronized int generateCallbackId()
	{
		if(callbackCounter > 255)
			callbackCounter = 1;
		return callbackCounter++;
	}

	// OpenZWave pre-allocates at buffer of 256 ... max message length, likely
	// since datalength is 8bit
	// perhaps 258 since SOF + 1 byte data length + possible 256 = 258
	protected int dataSize = 0;
	protected int size = 0;
	protected byte buffer[] = new byte[258];
	protected boolean requiresChecksum = true;

	protected int generatedCallbackId = 0;

	public Message(MsgType msgType, Function func, Object... parameters)
	{
		buffer[0] = ZWaveConstants.SOF;
		buffer[1] = 0x00; // length
		buffer[2] = msgType.getByteValue();
		buffer[3] = func.getByteValue();