public ByteBuffer toBuffer() {
	byte fixed = 0x00;
	int length;
	
	fixed |= (TypeValues.indexOf(type) << Shift.TYPE);
	
	if (duplicate) {
	    fixed |= OrMask.DUPLICATE;
	}
	
	if (qos > 0) {
	    fixed |= (qos << Shift.QOS);
	}
	
	if (retain) {
	    fixed |= OrMask.RETAIN;
	}
	
	if (changed) {
	    generate();
	}
	
	length = variable.size();
	if (hasPayload()) {
	    for (ByteBuffer buffer : getPayload()) {
		length += (buffer.limit() - buffer.position());
	    }
	}
	
	int l = length, d;
	byte[] remaining = new byte[4];
	short i = 0;
	
	do {
	    d = l % 128;
	    l = l / 128;
	
	    if (l > 0) {
		d |= 0x80;
	    }
	    
	    remaining[i] = (byte)d;
	    i++;
	} while (l > 0);
	
	ByteBuffer buffer = ByteBuffer.allocate(1 + i + length);
	buffer.put(fixed);
	buffer.put(remaining, 0, i);
	if (length > 0) {
	    buffer.put(variable.toByteArray());
	}
	
	buffer.flip();
	return buffer;
    }