/// <summary>
        /// Deserialize a <see cref="DataFieldDescriptor"/>.
        /// </summary>
        /// <param name="element">Deserialized DataFieldDescriptor</param>
        /// <returns></returns>
        public static DataFieldDescriptor FromXml(XElement element)
        {
            if (element.Name != "DataFieldDescriptor")
            {
                throw new ArgumentException("The xml is not correctly formatted");
            }

            Guid       id         = (Guid)element.GetRequiredAttribute("id");
            string     name       = element.GetRequiredAttributeValue("name");
            bool       isNullable = (bool)element.GetRequiredAttribute("isNullable");
            int        position   = (int)element.GetRequiredAttribute("position");
            bool       inherited  = (bool)element.GetRequiredAttribute("inherited");
            XAttribute groupByPriorityAttribute = element.Attribute("groupByPriority");
            XAttribute instanceTypeAttribute    = element.GetRequiredAttribute("instanceType");
            XAttribute storeTypeAttribute       = element.GetRequiredAttribute("storeType");
            XAttribute isReadOnlyAttribute      = element.Attribute("isReadOnly");
            XAttribute newInstanceDefaultFieldValueAttribute = element.Attribute("newInstanceDefaultFieldValue");


            bool isReadOnly      = isReadOnlyAttribute != null && (bool)isReadOnlyAttribute;
            int  groupByPriority = groupByPriorityAttribute != null ? (int)groupByPriorityAttribute : 0;

            XAttribute defaultValueAttribute = element.Attribute("defaultValue");
            XAttribute foreignKeyReferenceTypeNameAttribute = element.Attribute("foreignKeyReferenceTypeName");
            XElement   formRenderingProfileElement          = element.Element("FormRenderingProfile");
            XElement   treeOrderingProfileElement           = element.Element("TreeOrderingProfile");
            XElement   validationFunctionMarkupsElement     = element.Element("ValidationFunctionMarkups");
            XElement   dataUrlProfileElement = element.Element("DataUrlProfile");
            XElement   searchProfileElement  = element.Element(nameof(SearchProfile));



            Type           instanceType = TypeManager.GetType(instanceTypeAttribute.Value);
            StoreFieldType storeType    = StoreFieldType.Deserialize(storeTypeAttribute.Value);

            var dataFieldDescriptor = new DataFieldDescriptor(id, name, storeType, instanceType, inherited)
            {
                IsNullable      = isNullable,
                Position        = position,
                GroupByPriority = groupByPriority,
                IsReadOnly      = isReadOnly
            };

            if (newInstanceDefaultFieldValueAttribute != null)
            {
                dataFieldDescriptor.NewInstanceDefaultFieldValue = newInstanceDefaultFieldValueAttribute.Value;
            }

            if (defaultValueAttribute != null)
            {
                DefaultValue defaultValue = DefaultValue.Deserialize(defaultValueAttribute.Value);
                dataFieldDescriptor.DefaultValue = defaultValue;
            }

            if (foreignKeyReferenceTypeNameAttribute != null)
            {
                string typeName = foreignKeyReferenceTypeNameAttribute.Value;

                typeName = TypeManager.FixLegasyTypeName(typeName);

                dataFieldDescriptor.ForeignKeyReferenceTypeName = typeName;
            }

            if (formRenderingProfileElement != null)
            {
                XAttribute labelAttribute                = formRenderingProfileElement.Attribute("label");
                XAttribute helpTextAttribute             = formRenderingProfileElement.Attribute("helpText");
                XAttribute widgetFunctionMarkupAttribute = formRenderingProfileElement.Attribute("widgetFunctionMarkup");

                var dataFieldFormRenderingProfile = new DataFieldFormRenderingProfile();

                if (labelAttribute != null)
                {
                    dataFieldFormRenderingProfile.Label = labelAttribute.Value;
                }

                if (helpTextAttribute != null)
                {
                    dataFieldFormRenderingProfile.HelpText = helpTextAttribute.Value;
                }

                if (widgetFunctionMarkupAttribute != null)
                {
                    dataFieldFormRenderingProfile.WidgetFunctionMarkup = widgetFunctionMarkupAttribute.Value;
                }

                dataFieldDescriptor.FormRenderingProfile = dataFieldFormRenderingProfile;
            }

            if (dataUrlProfileElement != null)
            {
                int order     = (int)dataUrlProfileElement.GetRequiredAttribute("Order");
                var formatStr = (string)dataUrlProfileElement.Attribute("Format");
                DataUrlSegmentFormat?format = null;

                if (formatStr != null)
                {
                    format = (DataUrlSegmentFormat)Enum.Parse(typeof(DataUrlSegmentFormat), formatStr);
                }

                dataFieldDescriptor.DataUrlProfile = new DataUrlProfile {
                    Order = order, Format = format
                };
            }

            if (searchProfileElement != null)
            {
                Func <string, bool> getAttr = fieldName => (bool)searchProfileElement.GetRequiredAttribute(CamelCase(fieldName));

                dataFieldDescriptor.SearchProfile = new SearchProfile
                {
                    IndexText     = getAttr(nameof(DynamicTypes.SearchProfile.IndexText)),
                    EnablePreview = getAttr(nameof(DynamicTypes.SearchProfile.EnablePreview)),
                    IsFacet       = getAttr(nameof(DynamicTypes.SearchProfile.IsFacet))
                };
            }

            if (treeOrderingProfileElement != null)
            {
                int? orderPriority   = (int?)treeOrderingProfileElement.Attribute("orderPriority");
                bool orderDescending = (bool)treeOrderingProfileElement.Attribute("orderDescending");

                dataFieldDescriptor.TreeOrderingProfile = new DataFieldTreeOrderingProfile
                {
                    OrderPriority   = orderPriority,
                    OrderDescending = orderDescending
                };
            }

            dataFieldDescriptor.ValidationFunctionMarkup = new List <string>();
            if (validationFunctionMarkupsElement != null)
            {
                foreach (XElement validationFunctionMarkupElement in validationFunctionMarkupsElement.Elements("ValidationFunctionMarkup"))
                {
                    string markup = validationFunctionMarkupElement.GetRequiredAttributeValue("markup");

                    dataFieldDescriptor.ValidationFunctionMarkup.Add(markup);
                }
            }

            return(dataFieldDescriptor);
        }
        /// <summary>
        /// Deserialize a <see cref="DataFieldDescriptor"/>.
        /// </summary>
        /// <param name="element">Deserialized DataFieldDescriptor</param>
        /// <returns></returns>
        public static DataFieldDescriptor FromXml(XElement element)
        {
            if (element.Name != "DataFieldDescriptor") throw new ArgumentException("The xml is not correctly formatted");

            Guid id = (Guid)element.GetRequiredAttribute("id");
            string name = element.GetRequiredAttributeValue("name");
            bool isNullable = (bool)element.GetRequiredAttribute("isNullable");
            int position = (int)element.GetRequiredAttribute("position");
            bool inherited = (bool)element.GetRequiredAttribute("inherited");
            XAttribute groupByPriorityAttribute = element.Attribute("groupByPriority");
            XAttribute instanceTypeAttribute = element.GetRequiredAttribute("instanceType");
            XAttribute storeTypeAttribute = element.GetRequiredAttribute("storeType");
            XAttribute isReadOnlyAttribute = element.Attribute("isReadOnly");
            XAttribute newInstanceDefaultFieldValueAttribute = element.Attribute("newInstanceDefaultFieldValue");

            bool isReadOnly = isReadOnlyAttribute != null && (bool) isReadOnlyAttribute;
            int groupByPriority = groupByPriorityAttribute != null ? (int)groupByPriorityAttribute : 0;

            XAttribute defaultValueAttribute = element.Attribute("defaultValue");
            XAttribute foreignKeyReferenceTypeNameAttribute = element.Attribute("foreignKeyReferenceTypeName");
            XElement formRenderingProfileElement = element.Element("FormRenderingProfile");
            XElement treeOrderingProfileElement = element.Element("TreeOrderingProfile");
            XElement validationFunctionMarkupsElement = element.Element("ValidationFunctionMarkups");
            XElement dataUrlProfileElement = element.Element("DataUrlProfile");

            Type instanceType = TypeManager.GetType(instanceTypeAttribute.Value);
            StoreFieldType storeType = StoreFieldType.Deserialize(storeTypeAttribute.Value);

            var dataFieldDescriptor = new DataFieldDescriptor(id, name, storeType, instanceType, inherited)
            {
                IsNullable = isNullable,
                Position = position,
                GroupByPriority = groupByPriority,
                IsReadOnly = isReadOnly
            };

            if (newInstanceDefaultFieldValueAttribute != null)
            {
                dataFieldDescriptor.NewInstanceDefaultFieldValue = newInstanceDefaultFieldValueAttribute.Value;
            }

            if (defaultValueAttribute != null)
            {
                DefaultValue defaultValue = DefaultValue.Deserialize(defaultValueAttribute.Value);
                dataFieldDescriptor.DefaultValue = defaultValue;
            }

            if (foreignKeyReferenceTypeNameAttribute != null)
            {
                string typeName = foreignKeyReferenceTypeNameAttribute.Value;

                typeName = TypeManager.FixLegasyTypeName(typeName);

                dataFieldDescriptor.ForeignKeyReferenceTypeName = typeName;
            }

            if (formRenderingProfileElement != null)
            {
                XAttribute labelAttribute = formRenderingProfileElement.Attribute("label");
                XAttribute helpTextAttribute = formRenderingProfileElement.Attribute("helpText");
                XAttribute widgetFunctionMarkupAttribute = formRenderingProfileElement.Attribute("widgetFunctionMarkup");

                var dataFieldFormRenderingProfile = new DataFieldFormRenderingProfile();

                if (labelAttribute != null)
                {
                    dataFieldFormRenderingProfile.Label = labelAttribute.Value;
                }

                if (helpTextAttribute != null)
                {
                    dataFieldFormRenderingProfile.HelpText = helpTextAttribute.Value;
                }

                if (widgetFunctionMarkupAttribute != null)
                {
                    dataFieldFormRenderingProfile.WidgetFunctionMarkup = widgetFunctionMarkupAttribute.Value;
                }

                dataFieldDescriptor.FormRenderingProfile = dataFieldFormRenderingProfile;
            }

            if (dataUrlProfileElement != null)
            {
                int order = (int)dataUrlProfileElement.GetRequiredAttribute("Order");
                var formatStr = (string)dataUrlProfileElement.Attribute("Format");
                DataUrlSegmentFormat? format = null;

                if (formatStr != null)
                {
                    format = (DataUrlSegmentFormat) Enum.Parse(typeof(DataUrlSegmentFormat), formatStr);
                }

                dataFieldDescriptor.DataUrlProfile = new DataUrlProfile {Order = order, Format = format};
            }

            if (treeOrderingProfileElement != null)
            {
                int? orderPriority = (int?)treeOrderingProfileElement.Attribute("orderPriority");
                bool orderDescending = (bool)treeOrderingProfileElement.Attribute("orderDescending");

                dataFieldDescriptor.TreeOrderingProfile = new DataFieldTreeOrderingProfile
                {
                    OrderPriority = orderPriority,
                    OrderDescending = orderDescending
                };
            }

            dataFieldDescriptor.ValidationFunctionMarkup = new List<string>();
            if (validationFunctionMarkupsElement != null)
            {
                foreach (XElement validationFunctionMarkupElement in validationFunctionMarkupsElement.Elements("ValidationFunctionMarkup"))
                {
                    string markup = validationFunctionMarkupElement.GetRequiredAttributeValue("markup");

                    dataFieldDescriptor.ValidationFunctionMarkup.Add(markup);
                }
            }

            return dataFieldDescriptor;
        }