/// <summary>
        /// Takes several opcode information and returns the best match of InstructionFormKind and InstructionOperandCountKind.
        /// </summary>
        /// <param name="opcodeNumber">The opcode number.</param>
        /// <param name="opcodeType">The opcode type as written in the table of opcodes.</param>
        /// <param name="operands">The operands to use.</param>
        /// <returns>A tuple of InstructionFormKind and InstructionOperandCountKind.</returns>
        /// <exception cref="ArgumentOutOfRangeException"> If <paramref name="opcodeNumber"/> has an invalid value or <paramref name="operands"/> an invalid count of operands.</exception>
        /// <exception cref="ArgumentException"> If <paramref name="operands"/> contains an unknown enum value.</exception>
        public static Tuple<InstructionFormKind, InstructionOperandCountKind> GetFormAndCount(byte opcodeNumber, OpcodeTypeKind opcodeType, ZOperand[] operands)
        {
            InstructionFormKind instructionForm;
            InstructionOperandCountKind operandCount;

            if (opcodeType == OpcodeTypeKind.ZeroOP)
            {
                if (opcodeNumber > 0xF)
                    throw new ArgumentOutOfRangeException("opcodeNumber", opcodeNumber, "The opcode number of an OpcodeTypeKind.ZeroOP must be in range of 0x0 - 0xF.");

                if (operands.Count() > 0)
                    throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.ZeroOP no operands must be given.");

                instructionForm = InstructionFormKind.Short;
                operandCount = InstructionOperandCountKind.ZeroOP;
            }
            else if (opcodeType == OpcodeTypeKind.OneOP)
            {
                if (opcodeNumber > 0xF)
                    throw new ArgumentOutOfRangeException("opcodeNumber", opcodeNumber, "The opcode number of an OpcodeTypeKind.OneOP must be in range of 0x0 - 0xF.");

                if (operands.Count() != 1)
                    throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.OneOP excactly operands must be given.");

                instructionForm = InstructionFormKind.Short;
                operandCount = InstructionOperandCountKind.OneOP;
            }
            else if (opcodeType == OpcodeTypeKind.TwoOP)
            {
                if (opcodeNumber > 0x1F)
                    throw new ArgumentOutOfRangeException("opcodeNumber", opcodeNumber, "The opcode number of an OpcodeTypeKind.TwoOP must be in range of 0x00 - 0x1F.");

                if (operands.Count() != 2)
                    throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.TwoOP exactly two operands must be given.");

                // Could be in long form for two small constants or variables
                // But let's keep this logic dumb
                // We could save 1 byte per OpcodeTypeKind.TwoOP at best
                instructionForm = InstructionFormKind.Variable;
                operandCount = InstructionOperandCountKind.TwoOP;
            }
            else if (opcodeType == OpcodeTypeKind.Var)
            {
                if (opcodeNumber > 0x1F)
                    throw new ArgumentOutOfRangeException("opcodeNumber", opcodeNumber, "The opcode number of an OpcodeTypeKind.Var must be in range of 0x00-0x1F.");

                if (operands.Count() > 4)
                {
                    if (operands.Count() <= 8)
                        throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.Var only 0 to 4 operands can be given. Up to 8 operands are not supported yet (only call_vs2 and call_vn2 make use of this).");
                    else
                        throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.Var only 0 to 4 operands can be given.");
                }

                instructionForm = InstructionFormKind.Variable;
                operandCount = InstructionOperandCountKind.Var;
            }
            else if (opcodeType == OpcodeTypeKind.Ext)
            {
                if (operands.Count() > 4)
                    throw new ArgumentOutOfRangeException("operands", operands.Count(), "With OpcodeTypeKind.Ext only 0 to 4 operands can be given.");

                instructionForm = InstructionFormKind.Extended;
                operandCount = InstructionOperandCountKind.Var;
            }
            else
                throw new ArgumentException(String.Format("Unknown OpcodeTypeKind '{0}'", opcodeType.ToString()), "opcodeType");

            return new Tuple<InstructionFormKind, InstructionOperandCountKind>(instructionForm, operandCount);
        }