/// <summary>
        ///   Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder
        ///   when invoked.
        /// </summary>
        public static Delegate GenerateHandler(Type eventSignature, IEventRecorder recorder)
        {
            Type returnType = GetDelegateReturnType(eventSignature);

            Type[] parameters = GetDelegateParameterTypes(eventSignature);

            var eventHandler = new DynamicMethod(
                eventSignature.Name + "DynamicHandler",
                returnType,
                AppendParameterListThisReference(parameters),
                recorder.GetType()
                .Module);
            MethodInfo methodToCall = typeof(IEventRecorder).GetMethod("RecordEvent",
                                                                       BindingFlags.Instance | BindingFlags.Public);

            ILGenerator ilGen = eventHandler.GetILGenerator();

            // Make room for the one and only local variable in our function
            ilGen.DeclareLocal(typeof(object[]));

            // Create the object array for the parameters and store in local var index 0
            ilGen.Emit(OpCodes.Ldc_I4, parameters.Length);
            ilGen.Emit(OpCodes.Newarr, typeof(Object));
            ilGen.Emit(OpCodes.Stloc_0);

            for (var index = 0; index < parameters.Length; index++)
            {
                // Push the object array onto the evaluation stack
                ilGen.Emit(OpCodes.Ldloc_0);

                // Push the array index to store our parameter in onto the evaluation stack
                ilGen.Emit(OpCodes.Ldc_I4, index);

                // Load the parameter
                ilGen.Emit(OpCodes.Ldarg, index + 1);

                // Box value-type parameters
                if (parameters[index]
                    .IsValueType)
                {
                    ilGen.Emit(OpCodes.Box, parameters[index]);
                }

                // Store the parameter in the object array
                ilGen.Emit(OpCodes.Stelem_Ref);
            }

            // Push the this-reference on the stack as param 0 for calling the handler
            ilGen.Emit(OpCodes.Ldarg_0);

            // Push the object array onto the stack as param 1 for calling the handler
            ilGen.Emit(OpCodes.Ldloc_0);

            // Call the handler
            ilGen.EmitCall(OpCodes.Call, methodToCall, null);

            ilGen.Emit(OpCodes.Ret);

            return(eventHandler.CreateDelegate(eventSignature, recorder));
        }
        /// <summary>
        ///   Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder
        ///   when invoked.
        /// </summary>
        public static Delegate GenerateHandler(Type eventSignature, IEventRecorder recorder)
        {
            Type returnType = GetDelegateReturnType(eventSignature);
            Type[] parameters = GetDelegateParameterTypes(eventSignature);

            var eventHandler = new DynamicMethod(
                eventSignature.Name + "DynamicHandler",
                returnType,
                AppendParameterListThisReference(parameters),
                recorder.GetType()
                .Module);
            MethodInfo methodToCall = typeof (IEventRecorder).GetMethod("RecordEvent",
                BindingFlags.Instance | BindingFlags.Public);

            ILGenerator ilGen = eventHandler.GetILGenerator();

            // Make room for the one and only local variable in our function
            ilGen.DeclareLocal(typeof (object[]));

            // Create the object array for the parameters and store in local var index 0
            ilGen.Emit(OpCodes.Ldc_I4, parameters.Length);
            ilGen.Emit(OpCodes.Newarr, typeof (Object));
            ilGen.Emit(OpCodes.Stloc_0);

            for (var index = 0; index < parameters.Length; index++)
            {
                // Push the object array onto the evaluation stack
                ilGen.Emit(OpCodes.Ldloc_0);

                // Push the array index to store our parameter in onto the evaluation stack
                ilGen.Emit(OpCodes.Ldc_I4, index);

                // Load the parameter
                ilGen.Emit(OpCodes.Ldarg, index + 1);

                // Box value-type parameters
                if (parameters[index]
                    .IsValueType)
                {
                    ilGen.Emit(OpCodes.Box, parameters[index]);
                }

                // Store the parameter in the object array
                ilGen.Emit(OpCodes.Stelem_Ref);
            }

            // Push the this-reference on the stack as param 0 for calling the handler
            ilGen.Emit(OpCodes.Ldarg_0);

            // Push the object array onto the stack as param 1 for calling the handler
            ilGen.Emit(OpCodes.Ldloc_0);

            // Call the handler
            ilGen.EmitCall(OpCodes.Call, methodToCall, null);

            ilGen.Emit(OpCodes.Ret);

            return eventHandler.CreateDelegate(eventSignature, recorder);
        }