/// <summary>
        /// Returns list of Custom Attributes for the specified extendable object with the values prepopulated
        /// </summary>
        /// <param name="extendableObject">The extendable object.</param>
        /// <returns></returns>
        public List <CustomAttributeDetail> BuildModelExtension(IExtendable extendableObject)
        {
            var modelExtension = new List <CustomAttributeDetail>();

            var attributeConfigs = attributeConfigRepository.RetrieveAttributeConfigurationsForType(extendableObject.GetType().Name);

            if (attributeConfigs == null || !attributeConfigs.Any())
            {
                attributeConfigs = attributeConfigRepository.RetrieveAttributeConfigurationsForType(extendableObject.GetType().BaseType.Name);
            }

            if (attributeConfigs == null || !attributeConfigs.Any())
            {
                return(modelExtension);
            }

            foreach (var customAttributeConfig in attributeConfigs)
            {
                var attributeDetail = new CustomAttributeDetail();
                attributeDetail.AttributeKey = customAttributeConfig.AttributeKey;
                attributeDetail.Category     = customAttributeConfig.Category;
                attributeDetail.Type         = customAttributeConfig.CustomAttributeType;
                attributeDetail.Value        = GetAttributeValue(extendableObject, customAttributeConfig);

                if (customAttributeConfig.CustomAttributeType == CustomAttributeType.Selection)
                {
                    var refData = RetrieveSelectionDataForAttribute(customAttributeConfig.AttributeKey);

                    if (refData != null && refData.Any())
                    {
                        attributeDetail.RefData = refData.Select(s =>
                                                                 new SelectListItem
                        {
                            Value    = s.SelectionKey.ToString(),
                            Text     = s.Value,
                            Selected = (attributeDetail.Value != null && s.Id == Convert.ToInt32(attributeDetail.Value))
                        }).ToList();
                    }
                }

                modelExtension.Add(attributeDetail);
            }

            return(modelExtension);
        }
        /// <summary>
        /// Returns a list of unpopulated Custom Attributes for the specified type.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List <CustomAttributeDetail> BuildModelExtension <T>() where T : IExtendable
        {
            var attributeConfigs = attributeConfigRepository.RetrieveAttributeConfigurationsForType(typeof(T).Name);

            var modelExtension = new List <CustomAttributeDetail>();

            if (attributeConfigs == null || !attributeConfigs.Any())
            {
                return(modelExtension);
            }

            foreach (var customAttributeConfig in attributeConfigs)
            {
                var attributeDetail = new CustomAttributeDetail();
                attributeDetail.AttributeKey = customAttributeConfig.AttributeKey;
                attributeDetail.Category     = customAttributeConfig.Category;
                attributeDetail.Type         = customAttributeConfig.CustomAttributeType;
                attributeDetail.Value        = GetAttributeValue(null, customAttributeConfig);

                if (customAttributeConfig.CustomAttributeType == CustomAttributeType.Selection)
                {
                    var refData = RetrieveSelectionDataForAttribute(customAttributeConfig.AttributeKey);

                    if (refData != null && refData.Any())
                    {
                        attributeDetail.RefData = refData.Select(s =>
                                                                 new SelectListItem
                        {
                            Value = s.SelectionKey.ToString(),
                            Text  = s.Value
                        }).ToList();
                    }
                }

                modelExtension.Add(attributeDetail);
            }

            return(modelExtension);
        }
        /// <summary>
        /// This is to handle the issue where the MVC Razor Engine is rendering the values for custom attribute controls as Arrays. Need to determine why this is happening.
        /// </summary>
        /// <param name="customAttributeDetail"></param>
        /// <returns></returns>
        private object ExtractValue(CustomAttributeDetail customAttributeDetail)
        {
            object returnValue = null;

            if (customAttributeDetail.Value != null)
            {
                if (customAttributeDetail.Value.GetType().IsArray)
                {
                    if (customAttributeDetail.Value.GetType() == typeof(string[]) && ((string[])customAttributeDetail.Value).Length == 1)
                    {
                        returnValue = ((string[])customAttributeDetail.Value).First();
                    }
                }
                else
                {
                    returnValue = customAttributeDetail.Value;
                }
            }

            switch (customAttributeDetail.Type)
            {
            case CustomAttributeType.Numeric:
                return(returnValue == null ? default(decimal) : Decimal.Parse(returnValue.ToString(), CultureInfo.InvariantCulture));

            case CustomAttributeType.String:
                return(returnValue == null ? string.Empty : returnValue.ToString());

            case CustomAttributeType.Selection:
                return(returnValue == null ? default(int) : Int32.Parse(returnValue.ToString(), CultureInfo.InvariantCulture));

            case CustomAttributeType.DateTime:
                return(returnValue == null ? default(DateTime) : Convert.ToDateTime(returnValue));
            }

            throw new CustomAttributeException("Unable to extract custom attribute value for attribute {0}", customAttributeDetail.AttributeKey);
        }