/// <summary>Creates a converter for a property on a class based on the type specified by ConverterType OR ou can
        /// dynamically create a converter based on the property information passed into the method.</summary>
        /// <param name="theClassType">The class were the property resides so that it can be named to help the user
        /// find the particular property in question if they have more than class decorated with converter attributes.</param>
        /// <param name="propInfo">Property information about the property that this attribute was on.</param>
        /// <param name="defaultFactory">The default type converter factory.</param>
        /// <returns>A converter or null if one is not specified.</returns>
        public virtual ICsvConverter CreateConverterForProperty(Type theClassType, PropertyInfo propInfo,
                                                                IDefaultTypeConverterFactory defaultFactory)
        {
            // If no converter type was specified by the user, use a default converter based on the property's type.
            if (this.ConverterType == null)
            {
                ConverterType = defaultFactory.FindConverterType(propInfo.PropertyType);
            }

            string errorMessage = GetErrorMessageForCreateConverterForProperty(theClassType, propInfo);

            var oneTypeConverter = ConverterType.HelpCreateAndCastToInterface <ICsvConverter>(errorMessage);

            oneTypeConverter.Initialize(this, defaultFactory);

            return(oneTypeConverter);
        }
        /// <summary>Creates a converter for a property on a class based on the type specified by ConverterType OR you can
        /// dynamically create a converter based on the property information passed into the method.</summary>
        /// <param name="theClassType">The class were the property resides so that it can be named to help the user
        /// find the particular property in question if they have more than class decorated with converter attributes.</param>
        /// <param name="defaultFactory">The default type converter factory.</param>
        /// <returns>A converter</returns>
        public virtual ICsvConverter CreateConverterForClass(Type theClassType, IDefaultTypeConverterFactory defaultFactory)
        {
            // When decorating a class with this attribute, you MUST specify a target property type!
            if (TargetPropertyType == null)
            {
                throw new ArgumentException($"The {theClassType.Name} class specified an attribute that inherits from " +
                                            $" {nameof(CsvConverterAttribute)}, but a {nameof(TargetPropertyType)} was NOT specified.");
            }

            if (IsColumnIndexSpecified())
            {
                throw new CsvConverterAttributeException($"The {theClassType.Name} class has a class level attribute " +
                                                         $"that inherits {nameof(CsvConverterAttribute)} that is specifying a ColumnIndex.  You can only " +
                                                         $"specify ColumnIndex if the attribute is on the property!");
            }

            if (AreAltColumnNamesSpecified())
            {
                throw new CsvConverterAttributeException($"The {theClassType.Name} class has a class level attribute " +
                                                         $"that inherits {nameof(CsvConverterAttribute)} that is specifying a AltColumnNames.  You can only " +
                                                         $"specify AltColumnNames if the attribute is on the property!");
            }

            if (IsColumnNameSpecified())
            {
                throw new CsvConverterAttributeException($"The {theClassType.Name} class has a class level attribute " +
                                                         $"that inherits {nameof(CsvConverterAttribute)} that is specifying a ColumnName.  You can only " +
                                                         $"specify ColumnName if the attribute is on the property!");
            }


            // If no converter type was specified by the user, use a default converter base on the target property type.
            if (ConverterType == null)
            {
                ConverterType = defaultFactory.FindConverterType(this.TargetPropertyType);
            }

            string errorMessage = GetErrorMessageForCreateConverterForClass(theClassType);

            var oneTypeConverter = ConverterType.HelpCreateAndCastToInterface <ICsvConverter>(errorMessage);

            oneTypeConverter.Initialize(this, defaultFactory);

            return(oneTypeConverter);
        }