private void ParseWithTag <T>(Element element, Result <T> result, string[] lines, int linePosition) { var lineValueExtractor = _lineValueExtractorFactory.Get(element.LineValueExtractorType); var continueParsing = true; for (var i = linePosition; i < lines.Length; i++) { var tagValue = lineValueExtractor.Extract(lines[i], element); if (!tagValue.IsFound || string.IsNullOrEmpty(tagValue.Value)) { result.Errors.Add($"Line {i} does not contain any valid tag."); return; } if (tagValue.Value != element.Tag) { var tagElement = GetTagObject(element, lines[i], lineValueExtractor); if (tagElement != null) { var listPropertyInfo = result.Content.Last().GetType().GetProperty(tagElement.Name); if (listPropertyInfo.GetValue(result.Content.Last()) == null) { listPropertyInfo.SetValue(result.Content.Last(), Activator.CreateInstance(listPropertyInfo.PropertyType)); } ParseWithTag(element, tagElement, result.Content.Last(), listPropertyInfo, result, lines, lineValueExtractor, ref i, ref continueParsing); if (!continueParsing) { return; } continue; } result.Errors.Add($"Line {i} does not contain any valid tag."); return; } var newObject = (T)Activator.CreateInstance(typeof(T)); result.Content.Add(newObject); var propertyElements = element.Elements.Where(child => child.ElementType == ElementType.Property).ToList(); foreach (var propertyElement in propertyElements) { var propertyValue = lineValueExtractor.Extract(lines[i], propertyElement, element); if ((!propertyValue.IsFound || string.IsNullOrEmpty(propertyValue.Value)) && propertyElement.Required) { result.Errors.Add($"Property {propertyElement.Name} is missing at Line {i}."); } else { var propertyInfo = typeof(T).GetProperty(propertyElement.Name, BindingFlags.Public | BindingFlags.Instance); var isSet = _valueSetter.Set(propertyInfo, propertyValue.Value, newObject); if (!isSet) { result.Errors.Add($"Value of Property {propertyElement.Name} is not valid at Line {i}."); } } } } }