private void writeTag(ByteQueue queue, int tagNumber, boolean classTag, long length) {
        int classValue = classTag ? 8 : 0;

        if (length < 0 || length > 0x100000000l)
            throw new IllegalArgumentException("Invalid length: " + length);

        boolean extendedTag = tagNumber > 14;

        if (length < 5) {
            if (extendedTag) {
                queue.push(0xf0 | classValue | length);
                queue.push(tagNumber);
            }
            else
                queue.push((tagNumber << 4) | classValue | length);
        }
        else {
            if (extendedTag) {
                queue.push(0xf5 | classValue);
                queue.push(tagNumber);
            }
            else
                queue.push((tagNumber << 4) | classValue | 0x5);

            if (length < 254)
                queue.push(length);
            else if (length < 65536) {
                queue.push(254);
                BACnetUtils.pushShort(queue, length);
            }
            else {
                queue.push(255);
                BACnetUtils.pushInt(queue, length);
            }
        }
    }