public (IInstruction Instruction, int AdditionalBytes) Read(byte[] data, int start = 0, int?length = null)
        {
            length = RangeUtils.Calculate(data.Length, start, length);

            if (length < 0)
            {
                throw new ArgumentException("Length cannot be negative.");
            }
            else if (length < Word.ByteCount)
            {
                return(null, Word.ByteCount - length.Value);
            }
            else if (length > InstructionSet.MaxInstructionSize)
            {
                throw new ArgumentException($"Length cannot be greater than the max size of {InstructionSet.MaxInstructionSize}.");
            }
            else if (length.Value % Word.ByteCount != 0)
            {
                throw new ArgumentException($"Length must be in words (2 bytes).");
            }
            else
            {
                IEnumerable <Word> GetWords()
                {
                    for (int i = 0; i < length.Value; i += Word.ByteCount)
                    {
                        yield return((ushort)new BitArray(new byte[] { data[start + i + 1], data[start + i] }).GetValue());
                    }
                }

                (IInstruction instruction, int additionalWords) = ReadWords(GetWords());
                if (instruction != null)
                {
                    return(instruction, 0);
                }
                else
                {
                    return(null, additionalWords *Word.ByteCount);
                }
            }
        }
        public (IInstruction Instruction, int AdditionalBytes) Read(byte[] data, int start = 0, int?length = null)
        {
            length = RangeUtils.Calculate(data.Length, start, length);

            if (length < 0)
            {
                throw new ArgumentException();
            }
            else if (length < 2)
            {
                return(null, 2 - length.Value);
            }
            else
            {
                InstructionId id = GetInstructionId(data, start);
                if (instructions.TryGetValue(id, out InstructionReader reader))
                {
                    return(reader.Read(data, start, length));
                }

                throw new InvalidOperationException($"No reader registered for {id}.");
            }
        }