private void CallAdvice(MethodDefinition method, ILProcessor processor, IAdviceInfo advice, List <Instruction> instructions, string propertyName, string methodSignature)
        {
            if (advice == null)
            {
                throw new ArgumentNullException("advice");
            }

            var pendingSwitchIndex    = context.PendingSwitchIndex;
            var firstIndex            = instructions.Count;
            var needContextVariable   = advice.ParameterFlag.Contains(AdviceParameterFlag.Context);
            var needExecutionVariable = advice.ParameterFlag.Contains(AdviceParameterFlag.Execution);
            var needReturnVariable    = advice.ParameterFlag.Contains(AdviceParameterFlag.Return);

            if (advice.IsSwitchedOn.HasValue)
            {
                var field = switchHandlerBuilder.GetSwitchField(
                    propertyName,
                    methodSignature,
                    advice.AspectName,
                    advice.IsSwitchedOn.Value);
                var index = context.GetLocalVariableForField(field);
                if (index < 0)
                {
                    index = method.Body.Variables.Count;
                    method.Body.Variables.Add(new VariableDefinition(context.GetTypeReference(typeof(bool))));
                    context.RecordLocalVariableForField(field, index);
                }

                if (needContextVariable)
                {
                    context.ExecutionContextSwitches.RegisterSwitch(index);
                }

                if (needExecutionVariable)
                {
                    context.ExecutionSwitches.RegisterSwitch(index);
                }

                if (needReturnVariable)
                {
                    context.ReturnSwitches.RegisterSwitch(index);
                }

                instructions.Add(processor.Create(OpCodes.Ldloc, index));

                // the null instruction is to be filled in later
                context.PendingSwitchIndex = instructions.Count;
                instructions.Add(null);
            }
            else
            {
                if (needContextVariable)
                {
                    context.ExecutionContextSwitches.SetUnSwitchable();
                }

                if (needExecutionVariable)
                {
                    context.ExecutionSwitches.SetUnSwitchable();
                }

                if (needReturnVariable)
                {
                    context.ReturnSwitches.SetUnSwitchable();
                }
            }

            if (needContextVariable)
            {
                instructions.Add(processor.Create(OpCodes.Ldloc, context.ExecutionContextVariableIndex));
            }

            if (needExecutionVariable)
            {
                instructions.Add(processor.Create(OpCodes.Ldloc, context.ExecutionVariableIndex));
            }

            if (advice.ParameterFlag.Contains(AdviceParameterFlag.Exception))
            {
                instructions.Add(processor.Create(OpCodes.Ldloc, context.ExceptionVariableIndex));
            }

            if (needReturnVariable)
            {
                instructions.Add(processor.Create(OpCodes.Ldloc, context.ReturnVariableIndex));
            }

            if (advice.ParameterFlag.Contains(AdviceParameterFlag.HasException))
            {
                instructions.Add(processor.Create(OpCodes.Ldloc, context.HasExceptionVariableIndex));
            }

            instructions.Add(processor.Create(OpCodes.Call, context.GetMethodReference(advice.Advice)));

            // apply switch from last advice call
            if (pendingSwitchIndex >= 0)
            {
                // here brfalse_S is safe, considering only several instructions are inserted after break instruction.
                instructions[pendingSwitchIndex] = processor.Create(OpCodes.Brfalse_S, instructions[firstIndex]);

                // reset pending switch index if no switch this time
                if (!advice.IsSwitchedOn.HasValue)
                {
                    context.PendingSwitchIndex = -1;
                }
            }
        }