private MemberDiscoverer(ModuleDefinition module, MemberDiscoveryFlags flags)
        {
            _module = module ?? throw new ArgumentNullException(nameof(module));
            _flags  = flags;

            _eventHandlerTypeRef = new TypeReference(
                module,
                module.CorLibTypeFactory.CorLibScope,
                "System",
                nameof(EventHandler));

            _eventHandlerTypeSig = _eventHandlerTypeRef.ToTypeSignature();
        }
        /// <summary>
        /// Performs a traversal on the provided module and collects all member defined in it.
        /// </summary>
        /// <param name="module">The module to traverse.</param>
        /// <param name="flags">Flags indicating which member lists the original order needs to be preserved.</param>
        /// <returns>The collected members.</returns>
        public static MemberDiscoveryResult DiscoverMembersInModule(ModuleDefinition module, MemberDiscoveryFlags flags)
        {
            // Strategy:
            //
            // 1) Collect all members that were present in the original metadata tables, and leave null slots
            //    in the lists when the member was removed from the module, to preserve RIDs of existing members.
            //
            // 2) Do a normal member tree traversal, collect new members, and try to place them in the available
            //    null slots. If that is not possible anymore, just append to the end of the list.
            //
            // 3) Any remaining null slots need to be stuffed with placeholder member definitions. These will be
            //    added to a dummy namespace for placeholder types, and added to a dummy type definition for all
            //    member definitions.

            var context = new MemberDiscoverer(module, flags);

            if (flags != MemberDiscoveryFlags.None)
            {
                context.CollectExistingMembers();
            }

            context.CollectNewlyAddedMembers();

            if (flags != MemberDiscoveryFlags.None)
            {
                context.StuffFreeMemberSlots();
            }

            return(context._result);
        }