public Expression BuildInstructionSpaceExpression(IEnumerable<InstructionInfo> instructions,
                                                   IProgramControlExpressionLibrary programControlExpressionLibrary,
                                                   IInstructionExpressionBuilder instructionBuilder,
                                                   InstructionSpace instructionSpace)
 {
     if (instructionSpace.Prefix == null)
         return BuildSwitch(instructions, programControlExpressionLibrary, instructionBuilder, String.Empty);
     else
         return BuildSwitch(instructions, programControlExpressionLibrary, instructionBuilder, instructionSpace.Prefix);
 }
        public Expression BuildInstructionSpaceExpression(IEnumerable<InstructionInfo> instructions, 
                                                          IProgramControlExpressionLibrary programControlExpressionLibrary, 
                                                          IInstructionExpressionBuilder instructionBuilder, 
                                                          InstructionSpace instructionSpace)
        {
            List<SwitchCase> switchCases = new List<SwitchCase>();

            foreach (var info in instructions)
            {
                if (String.IsNullOrEmpty(info.Prefix))
                    continue;

                if (info.Prefix.StartsWith(instructionSpace.Prefix))
                {
                    switchCases.Add(
                        Expression.SwitchCase(instructionBuilder.BuildExpression(info),
                            Expression.Constant(info.Opcode))
                    );
                }
            }

            return Expression.Block(
                    // Read index parameter.
                    // index - (index & 0x80) << 1     -  Handles negative indexes.
                    Expression.Assign(programControlExpressionLibrary.ParameterByte2, programControlExpressionLibrary.ReadAndIncrementProgramCounter),
                    Expression.Assign(programControlExpressionLibrary.ParameterByte1,
                            Expression.Subtract(
                                programControlExpressionLibrary.ParameterByte2,
                                Expression.LeftShift(
                                    Expression.And(programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01)
                                )
                            )
                        ),

                    Expression.Switch(programControlExpressionLibrary.ReadAndIncrementProgramCounter,
                        Expression.Assign(programControlExpressionLibrary.ParameterByte1, programControlExpressionLibrary.ParameterByte1),
                        switchCases.ToArray())
                );                
        }
        private SwitchExpression BuildSwitch(IEnumerable<InstructionInfo> instructions,
                                             IProgramControlExpressionLibrary programControlExpressionLibrary,
                                             IInstructionExpressionBuilder instructionBuilder,
                                             String prefix)
        {
            List<SwitchCase> switchCases = new List<SwitchCase>();

            // Build switch cases for instruction within this prefix space.
            foreach (var info in instructions)
            {
                if ((String.IsNullOrEmpty(prefix) && String.IsNullOrEmpty(info.Prefix)) || info.Prefix == prefix)
                {
                    try
                    {
                        switchCases.Add(
                            Expression.SwitchCase(
                                instructionBuilder.BuildExpression(info),
                                Expression.Constant(info.Opcode)
                            )
                        );
                    }
                    catch (Exception ex)
                    {
                        throw new ApplicationException(String.Format("There was an error trying to build the instruction expression for {0}", info.Mnemonic), ex);
                    }
                }
            }

            // Build switch cases for child instruction spaces.
            foreach (var prefixOpcode in FindPrefixOpcodes(prefix, instructions))
            {
                IInstructionSpaceBuilder instructionSpace;

                if ((prefix + prefixOpcode.ToString("X")) == "DDCB" || (prefix + prefixOpcode.ToString("X")) == "FDCB")
                {
                    instructionSpace = new CBInstructionSpaceBuilder();
                }
                else
                {
                    instructionSpace = new DefaultInstructionSpaceBuilder();
                }

                switchCases.Add(
                    Expression.SwitchCase(
                        instructionSpace.BuildInstructionSpaceExpression(instructions,
                                                programControlExpressionLibrary,
                                                instructionBuilder,
                                                new InstructionSpace(prefix + prefixOpcode.ToString("X"))),
                        Expression.Constant(prefixOpcode)
                    )
                );
            }

            var orderedSwitchCases = switchCases.OrderBy(sc => (Int32)((ConstantExpression)(sc.TestValues.First())).Value);

            return Expression.Switch(programControlExpressionLibrary.ReadAndIncrementProgramCounter,
                Expression.Block(
                    Expression.Throw(Expression.New(_unknownInstruction, Expression.Subtract(programControlExpressionLibrary.ProgramCounterRegister, Expression.Constant(1)))),
                    Expression.Assign(programControlExpressionLibrary.ParameterByte1, programControlExpressionLibrary.ParameterByte1)
                ),
                orderedSwitchCases.ToArray()
            );
        }