/// <summary>
        /// Constructs the implementations for all normal methods.
        /// </summary>
        /// <param name="pipeline">The implementation pipeline that consumes the methods.</param>
        /// <param name="classType">The base class of the type to generate methods for.</param>
        /// <param name="interfaceTypes">The interfaces where the methods originate.</param>
        private void ConstructMethods
        (
            [NotNull] ImplementationPipeline pipeline,
            [NotNull] Type classType,
            [NotNull] params Type[] interfaceTypes
        )
        {
            var symbolTransformer = SymbolTransformer.Default;
            var methods           = new List <PipelineWorkUnit <IntrospectiveMethodInfo> >();

            foreach (var interfaceType in interfaceTypes)
            {
                foreach (var method in interfaceType.GetIntrospectiveMethods(true))
                {
                    var targetMethod = method;

                    // Skip any property accessor methods
                    if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
                    {
                        continue;
                    }

                    // Skip methods with a managed implementation in the base class
                    var baseClassMethod = classType.GetIntrospectiveMethod
                                          (
                        method.Name,
                        method.ParameterTypes.ToArray()
                                          );

                    if (!(baseClassMethod is null))
                    {
                        if (!baseClassMethod.IsAbstract)
                        {
                            continue;
                        }

                        targetMethod = baseClassMethod;
                    }

                    var definition = pipeline.GenerateDefinitionFromSignature(targetMethod);
                    methods.Add
                    (
                        new PipelineWorkUnit <IntrospectiveMethodInfo>
                        (
                            definition,
                            symbolTransformer.GetTransformedSymbol(interfaceType, definition),
                            Options
                        )
                    );
                }
            }

            pipeline.ConsumeMethodDefinitions(methods);
        }
        /// <summary>
        /// Constructs the implementations for all normal methods.
        /// </summary>
        /// <param name="pipeline">The implementation pipeline that consumes the methods.</param>
        /// <param name="classType">The base class of the type to generate methods for.</param>
        /// <param name="interfaceTypes">The interfaces where the methods originate.</param>
        private void ConstructMethods
        (
            [NotNull] ImplementationPipeline pipeline,
            [NotNull] Type classType,
            [NotNull, ItemNotNull] params Type[] interfaceTypes
        )
        {
            var constructedMethods = new List <IntrospectiveMethodInfo>();

            var symbolTransformer = SymbolTransformer.Default;
            var methods           = new List <PipelineWorkUnit <IntrospectiveMethodInfo> >();

            foreach (var interfaceType in interfaceTypes)
            {
                foreach (var method in interfaceType.GetIntrospectiveMethods(true))
                {
                    var targetMethod = method;

                    // Skip any property accessor methods
                    if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
                    {
                        continue;
                    }

                    // Skip methods that were already constructed - happens with inherited interfaces and multiple
                    // identical definitions
                    var existingMethod = constructedMethods.FirstOrDefault(m => m.HasSameSignatureAs(method));
                    if (!(existingMethod is null))
                    {
                        if (existingMethod.HasSameNativeEntrypointAs(targetMethod))
                        {
                            pipeline.TargetType.DefineMethodOverride
                            (
                                existingMethod.GetWrappedMember(),
                                targetMethod.GetWrappedMember()
                            );

                            continue;
                        }
                    }

                    // Skip methods with a managed implementation in the base class
                    var baseClassMethod = classType.GetIntrospectiveMethod
                                          (
                        method.Name,
                        method.ParameterTypes.ToArray()
                                          );

                    if (!(baseClassMethod is null))
                    {
                        if (!baseClassMethod.IsAbstract)
                        {
                            continue;
                        }
                    }

                    // If we have an existing method at this point, this new method must be created as an explicit
                    // interface implementation. Therefore, we override the method name.
                    IntrospectiveMethodInfo definition;
                    if (!(existingMethod is null))
                    {
                        definition = pipeline.GenerateDefinitionFromSignature
                                     (
                            targetMethod,
                            baseClassMethod,
                            $"{interfaceType.Name}.{targetMethod.Name}"
                                     );
                    }