protected override void Execute(ConfuserContext context, ProtectionParameters parameters)
        {
            RandomGenerator random = context.Registry.GetService <IRandomService>().GetRandomGenerator(ReferenceProxyProtection._FullId);

            var store = new RPStore {
                random = random
            };

            foreach (MethodDef method in parameters.Targets.OfType <MethodDef>().WithProgress(context.Logger))
            {
                if (method.HasBody && method.Body.Instructions.Count > 0)
                {
                    ProcessMethod(ParseParameters(method, context, parameters, store));
                    context.CheckCancellation();
                }
            }

            RPContext ctx = ParseParameters(context.CurrentModule, context, parameters, store);

            if (store.mild != null)
            {
                store.mild.Finalize(ctx);
            }

            if (store.strong != null)
            {
                store.strong.Finalize(ctx);
            }
        }
        static RPContext ParseParameters(ModuleDef module, ConfuserContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Depth     = parameters.GetParameter(context, module, "depth", 3);
            ret.InitCount = parameters.GetParameter(context, module, "initCount", 0x10);

            ret.Random    = store.random;
            ret.Module    = module;
            ret.Context   = context;
            ret.Marker    = context.Registry.GetService <IMarkerService>();
            ret.DynCipher = context.Registry.GetService <IDynCipherService>();
            ret.Name      = context.Registry.GetService <INameService>();

            ret.Delegates = store.delegates;

            return(ret);
        }
        RPContext ParseParameters(MethodDef method, ConfuserContext context, ProtectionParameters parameters, RPStore store)
        {
            var ret = new RPContext();

            ret.Mode         = parameters.GetParameter(context, method, "mode", Mode.Mild);
            ret.Encoding     = parameters.GetParameter(context, method, "encoding", EncodingType.Normal);
            ret.InternalAlso = parameters.GetParameter(context, method, "internal", false);
            ret.TypeErasure  = parameters.GetParameter(context, method, "typeErasure", false);
            ret.Depth        = parameters.GetParameter(context, method, "depth", 3);

            ret.Module        = method.Module;
            ret.Method        = method;
            ret.Body          = method.Body;
            ret.BranchTargets = new HashSet <Instruction>(
                method.Body.Instructions
                .Select(instr => instr.Operand as Instruction)
                .Concat(method.Body.Instructions
                        .Where(instr => instr.Operand is Instruction[])
                        .SelectMany(instr => (Instruction[])instr.Operand))
                .Where(target => target != null));

            ret.Protection = (ReferenceProxyProtection)Parent;
            ret.Random     = store.random;
            ret.Context    = context;
            ret.Marker     = context.Registry.GetService <IMarkerService>();
            ret.DynCipher  = context.Registry.GetService <IDynCipherService>();
            ret.Name       = context.Registry.GetService <INameService>();

            ret.Delegates = store.delegates;

            switch (ret.Mode)
            {
            case Mode.Mild:
                ret.ModeHandler = store.mild ?? (store.mild = new MildMode());
                break;

            case Mode.Strong:
                ret.ModeHandler = store.strong ?? (store.strong = new StrongMode());
                break;

            default:
                throw new UnreachableException();
            }

            switch (ret.Encoding)
            {
            case EncodingType.Normal:
                ret.EncodingHandler = store.normal ?? (store.normal = new NormalEncoding());
                break;

            case EncodingType.Expression:
                ret.EncodingHandler = store.expression ?? (store.expression = new ExpressionEncoding());
                break;

            case EncodingType.x86:
                ret.EncodingHandler = store.x86 ?? (store.x86 = new x86Encoding());

                if ((context.CurrentModule.Cor20HeaderFlags & ComImageFlags.ILOnly) != 0)
                {
                    context.CurrentModuleWriterOptions.Cor20HeaderOptions.Flags &= ~ComImageFlags.ILOnly;
                }
                break;

            default:
                throw new UnreachableException();
            }

            return(ret);
        }