public void ReadSections(XElement root)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }

            var sectionsElement = root.Element("Sections");

            if (sectionsElement == null)
            {
                return;
            }

            var sectionElements = from el in sectionsElement.Elements("Section") select el;

            // Loop through the sections
            foreach (var sectionElement in sectionElements)
            {
                CoalesceSection section;
                var             currentSection = new CoalesceSection();
                var             sectionName    = (string)sectionElement.Attribute("name");

                // Make sure the section has a name
                if (sectionName.IsNullOrEmpty())
                {
                    continue;
                }

                var propertyElements = from el in sectionElement.Elements("Property") select el;

                // Loop through the current sections properties
                foreach (var propertyElement in propertyElements)
                {
                    var currentProperty = ReadProperty(propertyElement);
                    CoalesceProperty property;

                    if (currentProperty == null)
                    {
                        continue;
                    }

                    if (!currentSection.TryGetValue(currentProperty.Name, out property))
                    {
                        property = new CoalesceProperty();
                        currentSection.Add(currentProperty.Name, property);
                    }

                    property.AddRange(currentProperty);
                }

                if (!Sections.TryGetValue(sectionName, out section))
                {
                    section = new CoalesceSection();
                    Sections.Add(sectionName, section);
                }

                section.Combine(currentSection);
            }
        }
        public CoalesceProperty ReadProperty(XElement propertyElement)
        {
            if (propertyElement == null)
            {
                throw new ArgumentNullException("propertyElement");
            }

            var propertyName = (string)propertyElement.Attribute("name");

            if (propertyName.IsNullOrWhiteSpace())
            {
                return(null);
            }

            var property = new CoalesceProperty(propertyName);

            if (propertyElement.HasElements)
            {
                var valueElements = from el in propertyElement.Elements("Value") select el;

                // Loop through the current properties values
                foreach (var valueElement in valueElements)
                {
                    var value = valueElement.Value;
                    var type  = (int?)valueElement.Attribute("type");

                    if (!value.IsNullOrWhiteSpace())
                    {
                        value = SpecialCharactersPattern.Replace(value.Trim(), "");
                    }

                    property.Add(new CoalesceValue(value, type));
                }
            }
            else
            {
                var value = propertyElement.Value;
                var type  = (int?)propertyElement.Attribute("type");

                if (!value.IsNullOrWhiteSpace())
                {
                    value = SpecialCharactersPattern.Replace(value.Trim(), "");
                }

                property.Add(new CoalesceValue(value, type));
            }

            return(property);
        }
        public void ReadSections(XElement root)
        {
            if (root == null)
            {
                throw new ArgumentNullException(nameof(root));
            }

            var sectionsElement = root.Element("Sections");

            if (sectionsElement == null)
            {
                return;
            }

            var sectionElements = from el in sectionsElement.Elements("Section") select el;

            // Loop through the sections
            foreach (var sectionElement in sectionElements)
            {
                var currentSection = new CoalesceSection();
                var sectionName    = (string)sectionElement.Attribute("name");

                // Make sure the section has a name
                if (string.IsNullOrEmpty(sectionName))
                {
                    continue;
                }

                var propertyElements = from el in sectionElement.Elements("Property") select el;

                // Loop through the current sections properties
                foreach (var propertyElement in propertyElements)
                {
                    var currentProperty = ReadProperty(propertyElement);

                    if (currentProperty == null)
                    {
                        continue;
                    }

                    if (!currentSection.TryGetValue(currentProperty.Name, out CoalesceProperty property))
                    {
                        property = new CoalesceProperty();
                        currentSection.Add(currentProperty.Name, property);
                    }

                    property.AddRange(currentProperty);
                    //currentSection[currentProperty.Name] = (CoalesceProperty) property.Concat(currentProperty);
                    //properties.Add(property);

                    // If the current section dictionary does not contain the property, add it
                    // Else replace the property with this one

                    /*if (!coalescedSection.ContainsKey(property.Name))
                     * {
                     *      coalescedSection.Add(property.Name, property);
                     * }
                     * else
                     * {
                     *      //coalescedSection[property.Name] = property;
                     *      coalescedSection[property.Name].Combine(property);
                     * }*/
                }

                if (!Sections.TryGetValue(sectionName, out CoalesceSection section))
                {
                    section = new CoalesceSection();
                    Sections.Add(sectionName, section);
                }

                section.Combine(currentSection);

                // If the current asset dictionary does not contain the current section, add it
                // Else replace it with this one

                /*if (!Sections.ContainsKey(sectionName))
                 * {
                 *      Sections.Add(sectionName, currentSection);
                 * }
                 * else
                 * {
                 *      Sections[sectionName].Combine(currentSection);
                 * }*/
            }
        }
        public CoalesceProperty ReadProperty(XElement propertyElement)
        {
            if (propertyElement == null)
            {
                throw new ArgumentNullException(nameof(propertyElement));
            }

            var propertyName = (string)propertyElement.Attribute("name");
            //var optionsString = ((string) propertyElement.Attribute("options")) ?? "";

            // Trim spaces from options
            //optionsString = Regex.Replace(optionsString, @"\s+", "");
            //var options = optionsString.Split(new []{ '|' }, StringSplitOptions.RemoveEmptyEntries);

            // Old, remove eventually
            var ignoreProperty = (bool?)propertyElement.Attribute("ignore") ?? false;

            //var allowDuplicates = (bool?) propertyElement.Attribute("allowDuplicates") ?? false;

            if (ignoreProperty || string.IsNullOrEmpty(propertyName))
            {
                return(null);
            }

            var property = new CoalesceProperty(propertyName);

            if (propertyElement.HasElements)
            {
                var valueElements = from el in propertyElement.Elements("Value") select el;

                // Loop through the current properties values
                foreach (var valueElement in valueElements)
                {
                    var value = valueElement.Value;
                    var type  = (int?)valueElement.Attribute("type");
                    //var ignoreValue = (bool?) valueElement.Attribute("ignore") ?? false;

                    if (!string.IsNullOrEmpty(value))
                    {
                        value = SpecialCharactersPattern.Replace(value.Trim(), "");
                    }

                    property.Add(new CoalesceValue(value, type));

                    /*switch (type)
                     * {
                     *      case -1:
                     *      {
                     *              property.Clear();
                     *              property.Add(new CoalesceValue(value, type));
                     *
                     *              break;
                     *      }
                     *      case 0:
                     *      {
                     *              property.Clear();
                     *              property.Add(new CoalesceValue(value, type));
                     *
                     *              break;
                     *      }
                     *      case 1:
                     *      {
                     *              property.Clear();
                     *              property.Add(new CoalesceValue(value, type));
                     *
                     *              break;
                     *      }
                     *      case 2:
                     *      {
                     *              property.Add(new CoalesceValue(value, type));
                     *
                     *              break;
                     *      }
                     *      case 3:
                     *      {
                     *              if (!property.Any(v => v.Equals(value) && v.ValueType != 4))
                     *              {
                     *                      property.Add(new CoalesceValue(value, type));
                     *              }
                     *
                     *              break;
                     *      }
                     *      case 4:
                     *      {
                     *              property.RemoveAll(v => v.Equals(value));
                     *
                     *              property.Add(new CoalesceValue(value, type));
                     *
                     *              break;
                     *      }
                     * }*/
                }
            }
            else
            {
                var value = propertyElement.Value;
                var type  = (int?)propertyElement.Attribute("type");

                if (!string.IsNullOrEmpty(value))
                {
                    value = SpecialCharactersPattern.Replace(value.Trim(), "");
                }

                property.Add(new CoalesceValue(value, type));
            }

            return(property);
        }
		public void ReadSections(XElement root)
		{
			if (root == null)
			{
				throw new ArgumentNullException(nameof(root));
			}

			var sectionsElement = root.Element("Sections");

			if (sectionsElement == null)
			{
				return;
			}

			var sectionElements = from el in sectionsElement.Elements("Section") select el;

			// Loop through the sections
			foreach (var sectionElement in sectionElements)
			{
				CoalesceSection section;
				var currentSection = new CoalesceSection();
				var sectionName = (string) sectionElement.Attribute("name");
				
				// Make sure the section has a name
				if (sectionName.IsNullOrEmpty())
				{
					continue;
				}

				var propertyElements = from el in sectionElement.Elements("Property") select el;
				
				// Loop through the current sections properties
				foreach (var propertyElement in propertyElements)
				{
					var currentProperty = ReadProperty(propertyElement);
					CoalesceProperty property;

					if (currentProperty == null)
					{
						continue;
					}

					if (!currentSection.TryGetValue(currentProperty.Name, out property))
					{
						property = new CoalesceProperty();
						currentSection.Add(currentProperty.Name, property);
					}

					property.AddRange(currentProperty);
					//currentSection[currentProperty.Name] = (CoalesceProperty) property.Concat(currentProperty);
					//properties.Add(property);

					// If the current section dictionary does not contain the property, add it
					// Else replace the property with this one
					/*if (!coalescedSection.ContainsKey(property.Name))
					{
						coalescedSection.Add(property.Name, property);
					}
					else
					{
						//coalescedSection[property.Name] = property;
						coalescedSection[property.Name].Combine(property);
					}*/
				}

				if (!Sections.TryGetValue(sectionName, out section))
				{
					section = new CoalesceSection();
					Sections.Add(sectionName, section);
				}

				section.Combine(currentSection);

				// If the current asset dictionary does not contain the current section, add it
				// Else replace it with this one
				/*if (!Sections.ContainsKey(sectionName))
				{
					Sections.Add(sectionName, currentSection);
				}
				else
				{
					Sections[sectionName].Combine(currentSection);
				}*/
			}
		}
		public CoalesceProperty ReadProperty(XElement propertyElement)
		{
			if (propertyElement == null)
			{
				throw new ArgumentNullException(nameof(propertyElement));
			}

			var propertyName = (string) propertyElement.Attribute("name");
			//var optionsString = ((string) propertyElement.Attribute("options")) ?? "";

			// Trim spaces from options
			//optionsString = Regex.Replace(optionsString, @"\s+", "");
			//var options = optionsString.Split(new []{ '|' }, StringSplitOptions.RemoveEmptyEntries);

			// Old, remove eventually
			var ignoreProperty = (bool?) propertyElement.Attribute("ignore") ?? false;
			//var allowDuplicates = (bool?) propertyElement.Attribute("allowDuplicates") ?? false;

			if (ignoreProperty || propertyName.IsNullOrWhiteSpace())
			{
				return null;
			}

			var property = new CoalesceProperty(propertyName);

			if (propertyElement.HasElements)
			{
				var valueElements = from el in propertyElement.Elements("Value") select el;

				// Loop through the current properties values
				foreach (var valueElement in valueElements)
				{
					var value = valueElement.Value;
					var type = (int?) valueElement.Attribute("type");
					//var ignoreValue = (bool?) valueElement.Attribute("ignore") ?? false;

					if (!value.IsNullOrWhiteSpace())
					{
						value = SpecialCharactersPattern.Replace(value.Trim(), "");
					}

					property.Add(new CoalesceValue(value, type));

					/*switch (type)
					{
						case -1:
						{
							property.Clear();
							property.Add(new CoalesceValue(value, type));

							break;
						}
						case 0:
						{
							property.Clear();
							property.Add(new CoalesceValue(value, type));

							break;
						}
						case 1:
						{
							property.Clear();
							property.Add(new CoalesceValue(value, type));

							break;
						}
						case 2:
						{
							property.Add(new CoalesceValue(value, type));

							break;
						}
						case 3:
						{
							if (!property.Any(v => v.Equals(value) && v.ValueType != 4))
							{
								property.Add(new CoalesceValue(value, type));
							}

							break;
						}
						case 4:
						{
							property.RemoveAll(v => v.Equals(value));

							property.Add(new CoalesceValue(value, type));

							break;
						}
					}*/
				}
			}
			else
			{
				var value = propertyElement.Value;
				var type = (int?) propertyElement.Attribute("type");

				if (!value.IsNullOrWhiteSpace())
				{
					value = SpecialCharactersPattern.Replace(value.Trim(), "");
				}

				property.Add(new CoalesceValue(value, type));
			}

			return property;
		}