internal static CustomAttributeBuilder GetAttributeBuilder(Attribute attribute)
        {
            AttributeBuilderInfo constructionInfo = GetAttributeBuilderInfo(attribute);

            var namedProperties     = constructionInfo.Properties.Keys.ToArray();
            var namedPropertyValues = constructionInfo.Properties.Values.ToArray();

            return(new CustomAttributeBuilder(constructionInfo.Constructor, constructionInfo.ConstructorArgs, namedProperties, namedPropertyValues));
        }
        internal static AttributeBuilderInfo GetAttributeBuilderInfo(Attribute attribute)
        {
            IDictionary <string, object> attributeData = GetAttributeData(attribute);
            Dictionary <string, object>  attributeDataCaseInsensitive = new Dictionary <string, object>(attributeData, StringComparer.OrdinalIgnoreCase);
            Type attributeType = attribute.GetType();

            // Pick the ctor with the longest parameter list where all parameters are matched.
            int             longestMatch = -1;
            ConstructorInfo bestCtor     = null;
            Dictionary <PropertyInfo, object> propertiesToSet = null;

            object[] constructorArgs = null;
            var      ctors           = attributeType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);

            foreach (var currCtor in ctors)
            {
                var      currCtorParams      = currCtor.GetParameters();
                int      len                 = currCtorParams.Length;
                object[] currConstructorArgs = new object[len];

                bool hasAllParameters = true;
                for (int i = 0; i < len; i++)
                {
                    var    p     = currCtorParams[i];
                    object value = null;
                    if (!attributeDataCaseInsensitive.TryGetValue(p.Name, out value) || value == null)
                    {
                        hasAllParameters = false;
                        break;
                    }

                    currConstructorArgs[i] = value;
                }

                if (hasAllParameters)
                {
                    if (len > longestMatch)
                    {
                        propertiesToSet = new Dictionary <PropertyInfo, object>();

                        // Set any remaining property values
                        foreach (var prop in attributeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                        {
                            if (!prop.CanWrite || !prop.GetSetMethod(/*nonPublic*/ true).IsPublic ||
                                Nullable.GetUnderlyingType(prop.PropertyType) != null)
                            {
                                continue;
                            }

                            object objValue = null;
                            if (attributeDataCaseInsensitive.TryGetValue(prop.Name, out objValue))
                            {
                                propertiesToSet.Add(prop, objValue);
                            }
                        }

                        bestCtor        = currCtor;
                        constructorArgs = currConstructorArgs;
                        longestMatch    = len;
                    }
                }
            }

            if (bestCtor == null)
            {
                // error!!!
                throw new InvalidOperationException("Can't figure out which ctor to call.");
            }

            AttributeBuilderInfo info = new AttributeBuilderInfo
            {
                Constructor     = bestCtor,
                ConstructorArgs = constructorArgs,
                Properties      = propertiesToSet
            };

            return(info);
        }
        internal static AttributeBuilderInfo GetAttributeBuilderInfo(Attribute attribute)
        {
            IDictionary<string, object> attributeData = GetAttributeData(attribute);
            Dictionary<string, object> attributeDataCaseInsensitive = new Dictionary<string, object>(attributeData, StringComparer.OrdinalIgnoreCase);
            Type attributeType = attribute.GetType();

            // Pick the ctor with the longest parameter list where all parameters are matched.
            int longestMatch = -1;
            ConstructorInfo bestCtor = null;
            Dictionary<PropertyInfo, object> propertiesToSet = null;
            object[] constructorArgs = null;
            var ctors = attributeType.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
            foreach (var currCtor in ctors)
            {
                var currCtorParams = currCtor.GetParameters();
                int len = currCtorParams.Length;
                object[] currConstructorArgs = new object[len];

                bool hasAllParameters = true;
                for (int i = 0; i < len; i++)
                {
                    var p = currCtorParams[i];
                    object value = null;
                    if (!attributeDataCaseInsensitive.TryGetValue(p.Name, out value) || value == null)
                    {
                        hasAllParameters = false;
                        break;
                    }

                    currConstructorArgs[i] = value;
                }

                if (hasAllParameters)
                {
                    if (len > longestMatch)
                    {
                        propertiesToSet = new Dictionary<PropertyInfo, object>();

                        // Set any remaining property values
                        foreach (var prop in attributeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                        {
                            if (!prop.CanWrite || !prop.GetSetMethod(/*nonPublic*/ true).IsPublic ||
                                Nullable.GetUnderlyingType(prop.PropertyType) != null)
                            {
                                continue;
                            }

                            object objValue = null;
                            if (attributeDataCaseInsensitive.TryGetValue(prop.Name, out objValue))
                            {
                                propertiesToSet.Add(prop, objValue);
                            }
                        }

                        bestCtor = currCtor;
                        constructorArgs = currConstructorArgs;
                        longestMatch = len;
                    }
                }
            }

            if (bestCtor == null)
            {
                // error!!!
                throw new InvalidOperationException("Can't figure out which ctor to call.");
            }

            AttributeBuilderInfo info = new AttributeBuilderInfo
            {
                Constructor = bestCtor,
                ConstructorArgs = constructorArgs,
                Properties = propertiesToSet
            };

            return info;
        }