/// <summary>
        /// Get the <c>ExcelColumnInfo</c> for all members of a class.
        /// </summary>
        /// <param name="itemType">Type of item being serialised.</param>
        /// <param name="data">The collection of values being serialised. (Not used, provided for use by derived
        /// types.)</param>
        public virtual ExcelColumnInfoCollection GetExcelColumnInfo(Type itemType, IEnumerable<object> data)
        {
            var fields = GetSerialisableMemberNames(itemType, data);
            var properties = GetSerialisablePropertyInfo(itemType, data);

            var fieldInfo = new ExcelColumnInfoCollection();

            // Instantiate field names and fieldInfo lists with serialisable members.
            foreach (var field in fields)
            {
                var propName = field;
                var prop = properties.FirstOrDefault(p => p.Name == propName);

                if (prop == null) continue;

                fieldInfo.Add(new ExcelColumnInfo(field, util.GetAttribute<ExcelColumnAttribute>(prop)));
            }

            PopulateFieldInfoFromMetadata(fieldInfo, itemType, data);

            return fieldInfo;
        }
        /// <summary>
        /// Get the <c>ExcelColumnInfo</c> for all members of a class.
        /// </summary>
        /// <param name="itemType">Type of item being serialised.</param>
        /// <param name="data">The collection of values being serialised. (Not used, provided for use by derived
        /// types.)</param>
        public virtual ExcelColumnInfoCollection GetExcelColumnInfo(Type itemType, object data, string namePrefix = "", bool isComplexColumn = false)
        {
            var fieldInfo = new ExcelColumnInfoCollection();

            if (itemType.Name.StartsWith("Dictionary"))
            {
                var prefix = namePrefix + "_Dict_";
                fieldInfo.Add(new ExcelColumnInfo(prefix, null, new ExcelColumnAttribute(), null));
                return(fieldInfo);
            }


            var fields     = GetSerialisableMemberNames(itemType, data);
            var properties = GetSerialisablePropertyInfo(itemType, data);


            // Instantiate field names and fieldInfo lists with serialisable members.
            foreach (var field in fields)
            {
                var prop = properties.FirstOrDefault(p => p.Name == field);

                if (prop == null)
                {
                    continue;
                }

                Type propertyType = prop.PropertyType;
                if (propertyType.IsGenericType &&
                    propertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    propertyType = propertyType.GetGenericArguments()[0];
                }

                ExcelColumnAttribute attribute = FormatterUtils.GetAttribute <ExcelColumnAttribute>(prop);
                if (attribute != null)
                {
                    string prefix = string.IsNullOrEmpty(namePrefix) == false ? $"{namePrefix}:{prop.Name}" : prop.Name;

                    if (propertyType.Name.StartsWith("List"))
                    {
                        Type typeOfList = FormatterUtils.GetEnumerableItemType(propertyType);

                        //if (FormatterUtils.IsSimpleType(typeOfList))
                        //{
                        //    fieldInfo.Add(new ExcelColumnInfo(prefix, typeOfList, attribute, null));
                        //}
                        //else
                        if (typeOfList.FullName.EndsWith("CustomFieldModel") || typeOfList.Name.StartsWith("OverrideProperty"))
                        {
                            prefix += "_CustomField_";
                            fieldInfo.Add(new ExcelColumnInfo(prefix, null, attribute, null));
                        }
                        else
                        {
                            prefix += "_List_";
                            fieldInfo.Add(new ExcelColumnInfo(prefix, null, attribute, null));

                            //ExcelColumnInfoCollection columnCollection = GetExcelColumnInfo(typeOfList, null, prefix, true);
                            //foreach (var subcolumn in columnCollection)
                            //    fieldInfo.Add(subcolumn);
                        }
                    }
                    else if (propertyType.Name.EndsWith("CustomFieldModel") || propertyType.Name.StartsWith("OverrideProperty"))
                    {
                        prefix += "_CustomField_Single_";
                        fieldInfo.Add(new ExcelColumnInfo(prefix, null, attribute, null));
                    }
                    else if (propertyType.Name.StartsWith("Dictionary"))
                    {
                        prefix += "_Dict_";
                        fieldInfo.Add(new ExcelColumnInfo(prefix, null, attribute, null));
                    }
                    else if (!FormatterUtils.IsSimpleType(propertyType))
                    {
                        ExcelColumnInfoCollection columnCollection = GetExcelColumnInfo(propertyType, null, prefix, true);
                        foreach (var subcolumn in columnCollection)
                        {
                            fieldInfo.Add(subcolumn);
                        }
                    }
                    else
                    {
                        string propertyName = isComplexColumn ? $"{namePrefix}:{field}" : field;
                        string displayName  = propertyName;

                        if (attribute.DoNotUsePropertyName)
                        {
                            attribute.Header = namePrefix;
                        }

                        bool columnAlreadyadded = fieldInfo.Any(a => a.PropertyName == propertyName);
                        if (!columnAlreadyadded)
                        {
                            if (FormatterUtils.IsExcelSupportedType(propertyType))
                            {
                                fieldInfo.Add(new ExcelColumnInfo(propertyName, propertyType, attribute, null));
                            }
                            else
                            {
                                fieldInfo.Add(new ExcelColumnInfo(propertyName, typeof(string), attribute, null));
                            }
                        }
                    }
                }
            }

            PopulateFieldInfoFromMetadata(fieldInfo, itemType, data);

            return(fieldInfo);
        }