private MethodReference GetBaseMethod(OverridableMethod overridableMethod)
        {
            if (overridableMethod.MethodReference != null)
            {
                return(overridableMethod.MethodReference);
            }

            return(GetBaseMethod(overridableMethod.BaseMethod));
        }
        private OverridableMethod CopyMethod(OverridableMethod overridableMethod, TypeReference targetType, TypeReference sourceType, ModuleDefinition md)
        {
            Logger.LogMessage("\tOverriding: " + overridableMethod.Method.FullName);
            var attributes = overridableMethod.Method.Attributes & ~MethodAttributes.NewSlot | MethodAttributes.ReuseSlot;
            var method     = new MethodDefinition(overridableMethod.Method.Name, attributes, md.ImportReference(typeof(void)));

            method.ImplAttributes      = overridableMethod.Method.ImplAttributes;
            method.SemanticsAttributes = overridableMethod.Method.SemanticsAttributes;
            method.DeclaringType       = targetType.Resolve();

            foreach (var genericParameter in overridableMethod.Method.GenericParameters)
            {
                method.GenericParameters.Add(new GenericParameter(targetType.GetUniqueGenericParameterName(), method));
            }

            TypeReference returnType = overridableMethod.Method.ReturnType.CopyType(targetType, sourceType, md, method);

            method.ReturnType = returnType;

            foreach (var parameter in overridableMethod.Method.Parameters)
            {
                TypeReference parameterType = parameter.ParameterType.CopyType(targetType, sourceType, md, method);
                method.Parameters.Add(new ParameterDefinition(parameter.Name, parameter.Attributes, parameterType)
                {
                    IsOptional = parameter.IsOptional,
                    IsIn       = parameter.IsIn,
                    IsOut      = parameter.IsOut
                });
            }
            var baseMethodReference = overridableMethod.Method.GetBaseReference(targetType, sourceType, md);

            return(new OverridableMethod
            {
                Method = method,
                BaseMethod = overridableMethod,
                MethodReference = baseMethodReference
            });
        }