internal ConfigurationProperty(PropertyInfo info)
        {
            Debug.Assert(info != null, "info != null");

            // Bellow are the attributes we handle
            TypeConverterAttribute          attribConverter = null;
            ConfigurationPropertyAttribute  attribProperty  = null;
            ConfigurationValidatorAttribute attribValidator = null;

            // Compatability attributes
            // If the approprite data is provided in the ConfigPropAttribute then the one bellow will be ignored
            DescriptionAttribute  attribStdDescription = null;
            DefaultValueAttribute attribStdDefault     = null;

            TypeConverter typeConverter          = null;
            ConfigurationValidatorBase validator = null;

            // Find the interesting attributes in the collection
            foreach (Attribute attribute in Attribute.GetCustomAttributes(info))
            {
                if (attribute is TypeConverterAttribute)
                {
                    attribConverter = (TypeConverterAttribute)attribute;
                    typeConverter   = TypeUtil.CreateInstanceRestricted <TypeConverter>(info.DeclaringType, attribConverter.ConverterTypeName);
                }
                else if (attribute is ConfigurationPropertyAttribute)
                {
                    attribProperty = (ConfigurationPropertyAttribute)attribute;
                }
                else if (attribute is ConfigurationValidatorAttribute)
                {
                    // There could be more then one validator attribute specified on a property
                    // Currently we consider this an error since it's too late to fix it for whidbey
                    // but the right thing to do is to introduce new validator type ( CompositeValidator ) that is a list of validators and executes
                    // them all

                    if (validator != null)
                    {
                        throw new ConfigurationErrorsException(SR.GetString(SR.Validator_multiple_validator_attributes, info.Name));
                    }

                    attribValidator = (ConfigurationValidatorAttribute)attribute;
                    attribValidator.SetDeclaringType(info.DeclaringType);
                    validator = attribValidator.ValidatorInstance;
                }
                else if (attribute is DescriptionAttribute)
                {
                    attribStdDescription = (DescriptionAttribute)attribute;
                }
                else if (attribute is DefaultValueAttribute)
                {
                    attribStdDefault = (DefaultValueAttribute)attribute;
                }
            }

            Type propertyType = info.PropertyType;

            // Collections need some customization when the collection attribute is present
            if (typeof(ConfigurationElementCollection).IsAssignableFrom(propertyType))
            {
                ConfigurationCollectionAttribute attribCollection =
                    Attribute.GetCustomAttribute(info,
                                                 typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute;

                // If none on the property - see if there is an attribute on the collection type itself
                if (attribCollection == null)
                {
                    attribCollection =
                        Attribute.GetCustomAttribute(propertyType,
                                                     typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute;
                }
                if (attribCollection != null)
                {
                    if (attribCollection.AddItemName.IndexOf(',') == -1)
                    {
                        _addElementName = attribCollection.AddItemName;
                    }
                    _removeElementName = attribCollection.RemoveItemName;
                    _clearElementName  = attribCollection.ClearItemsName;
                }
            }

            // This constructor shouldnt be invoked if the reflection info is not for an actual config property
            Debug.Assert(attribProperty != null, "attribProperty != null");

            ConstructorInit(attribProperty.Name,
                            info.PropertyType,
                            attribProperty.Options,
                            validator,
                            typeConverter);

            // Figure out the default value
            InitDefaultValueFromTypeInfo(attribProperty, attribStdDefault);

            // Get the description
            if ((attribStdDescription != null) && !string.IsNullOrEmpty(attribStdDescription.Description))
            {
                _description = attribStdDescription.Description;
            }
        }