/// <summary>
        /// Finds all members with the given attribute accross the type chain.
        /// </summary>
        /// <param name="targetType">The type on which to search for members.</param>
        /// <param name="attributeType">The attribute that should be present on the members of the type.</param>
        /// <param name="memberFilter">What members should be included in the result.</param>
        /// <param name="bindingFlags">What binding flags should be used for the members.</param>
        /// <returns>The set of members that have the attribute defined.</returns>
        public static IEnumerable <MemberInfo> FindAllMembersWithAttribute(Type targetType, Type attributeType, MemberTypes memberFilter = DefaultMemberTypes, BindingFlags bindingFlags = DefaultBindingFlags)
        {
            IEnumerable <MemberInfo> membersWithAttribute = Enumerable.Empty <MemberInfo>();

            while ((targetType != ObjectType) && (targetType != null))
            {
                membersWithAttribute = membersWithAttribute
                                       .Concat(
                    targetType
                    .GetMembers(bindingFlags | BindingFlags.DeclaredOnly)                               // Because we're going down the type chain anyway, we only get what is defined on this type.
                    .Where(m => memberFilter.HasMemberFlag(m.MemberType) && Attribute.IsDefined(m, attributeType, true)));

                targetType = targetType.BaseType;
            }

            return(membersWithAttribute.Distinct());
        }