private static IEnumerable <AutoStartupData> AutoStartupDataForAssembly(Assembly assembly)
        {
            foreach (var attributeData in assembly.GetCustomAttributesData())
            {
                if (attributeData.Constructor.DeclaringType == null)
                {
                    continue;
                }
                var attributeTypeName = attributeData.Constructor.DeclaringType.Name;
                if (attributeTypeName != "OwinAutoStartup" && attributeTypeName != "OwinAutoStartupAttribute")
                {
                    continue;
                }

                var data = new AutoStartupData();

                data = attributeData.Constructor.GetParameters().Zip(attributeData.ConstructorArguments, (a, b) => new { a, b }).Aggregate(data, (c, d) => AddValue(c, d.a.Name, d.b.ArgumentType, d.b.Value));

                if (attributeData.NamedArguments != null)
                {
                    data = attributeData.NamedArguments.Aggregate(data, (c, d) => AddValue(c, d.MemberInfo.Name, d.TypedValue.ArgumentType, d.TypedValue.Value));
                }

                if (data != null)
                {
                    yield return(data);
                }
            }
        }
        private static AutoStartupData AddValue(AutoStartupData data, string name, Type type, object value)
        {
            if (data == null)
            {
                return null;
            }

            if (string.Equals(name, "Type", StringComparison.OrdinalIgnoreCase) &&
                type == typeof(Type) &&
                data.Type == null)
            {
                data.Type = (Type)value;
                return data;
            }

            if (string.Equals(name, "MethodName", StringComparison.OrdinalIgnoreCase) &&
                type == typeof(string) &&
                data.MethodName == null)
            {
                data.MethodName = (String)value;
                return data;
            }

            return null;
        }
        private static AutoStartupData AddValue(AutoStartupData data, string name, Type type, object value)
        {
            if (data == null)
            {
                return(null);
            }

            if (string.Equals(name, "Type", StringComparison.OrdinalIgnoreCase) &&
                type == typeof(Type) &&
                data.Type == null)
            {
                data.Type = (Type)value;
                return(data);
            }

            if (string.Equals(name, "MethodName", StringComparison.OrdinalIgnoreCase) &&
                type == typeof(string) &&
                data.MethodName == null)
            {
                data.MethodName = (String)value;
                return(data);
            }

            return(null);
        }
        private static IEnumerable<AutoStartupData> AutoStartupDataForAssembly(Assembly assembly)
        {
            foreach (var attributeData in assembly.GetCustomAttributesData())
            {
                if (attributeData.Constructor.DeclaringType == null)
                {
                    continue;
                }
                var attributeTypeName = attributeData.Constructor.DeclaringType.Name;
                if (attributeTypeName != "OwinAutoStartup" && attributeTypeName != "OwinAutoStartupAttribute")
                {
                    continue;
                }

                var data = new AutoStartupData();

                data = attributeData.Constructor.GetParameters().Zip(attributeData.ConstructorArguments, (a, b) => new { a, b }).Aggregate(data, (c, d) => AddValue(c, d.a.Name, d.b.ArgumentType, d.b.Value));

                if (attributeData.NamedArguments != null)
                {
                    data = attributeData.NamedArguments.Aggregate(data, (c, d) => AddValue(c, d.MemberInfo.Name, d.TypedValue.ArgumentType, d.TypedValue.Value));
                }

                if (data != null)
                {
                    yield return data;
                }
            }
        }