public InstructionInfo[] BuildInstructionInfo(Type type)
        {
            var instructions = new List<InstructionInfo>();

            foreach (var property in type.GetProperties())
            {
                foreach (var att in property.GetCustomAttributes(typeof(InstructionAttribute), false).Cast<InstructionAttribute>())
                {
                    Object instructionObject = BuildInstructionObject(type);

                    var info = new InstructionInfo() { Mnemonic = att.Mnemonic, Opcode = att.Opcode };
                    if (att.Cycles == 0)
                        info.Cycles = null;
                    else
                        info.Cycles = att.Cycles;

                    info.Body = (Expression)property.GetValue(instructionObject, null);

                    if (info.Body == null)
                        throw new NullExpressionException(String.Format("The instruction {0} on {1} was null.", property.Name, type));

                    info.ParameterMode = att.ParameterMode;

                    info.InstructionObject = instructionObject;
                    info.Prefix = att.Prefix;

                    instructions.Add(info);
                }
            }

            return instructions.ToArray();
        }
        public Expression BuildExpression(InstructionInfo info)
        {
            if (info.Body == null)
                throw new NullExpressionException();

            var expressions = new List<Expression>();

            switch (info.ParameterMode)
            {
                case InstructionParameterMode.None:
                    break;
                case InstructionParameterMode.Byte:
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));                    
                    break;

                case InstructionParameterMode.Index:
                    // index - (index & 0x80) << 1     -  Handles negative indexes.
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1,
                            Expression.Subtract(
                                _programControlExpressionLibrary.ParameterByte2,
                                Expression.LeftShift(
                                    Expression.And(_programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01)
                                )
                            )
                        )
                    );
                    break;

                case InstructionParameterMode.IndexAndByte:
                    // index - (index & 0x80) << 1     -  Handles negative indexes.
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1,
                            Expression.Subtract(
                                _programControlExpressionLibrary.ParameterByte2,
                                Expression.LeftShift(
                                    Expression.And(_programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01)
                                )
                            )
                        )
                    );

                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));
                    break;

                case InstructionParameterMode.Word:
                case InstructionParameterMode.Address:
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte2, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));
                    expressions.Add(Expression.Assign(_programControlExpressionLibrary.ParameterByte1, _programControlExpressionLibrary.ReadAndIncrementProgramCounter));

                    break;
                default:
                    break;
            }

            foreach (var advice in _preInstructionAdvice)
            {
                var a = advice.GetExpression(info, _expressionLibrary);

                if (a != null)
                    expressions.Add(a);
            }

            expressions.Add(info.Body);

            foreach (var advice in _postInstructionAdvice)
            {
                var a = advice.GetExpression(info, _expressionLibrary);

                if (a != null)
                    expressions.Add(a);
            }

            if (_postInstructionAdvice.Count > 0)
            {
                expressions.Add(Expression.Assign(_programControlExpressionLibrary.CycleCounter, _programControlExpressionLibrary.CycleCounter));
            }

            if (info.Cycles.HasValue)
            {
                expressions.Add(
                    Expression.SubtractAssign(
                        _programControlExpressionLibrary.CycleCounter,
                        Expression.Constant(info.Cycles)
                    )
                );
            }

            return Expression.Block(expressions.ToArray());
        }