public string[] CombineNodes(XElement xml, Func <NodeBuilder, XElement, List <XNode>, int, string> getElementText) { var nodes = xml.Nodes().ToList(); var nodeBuilder = new NodeBuilder(); var trimWhitespaceLength = GetWhitespaceToTrim(nodes) ?? 0; var spaces = new string(' ', trimWhitespaceLength); for (var i = 0; i < nodes.Count && nodeBuilder.Continue; i++) { if (nodes[i] is XText) { var lines = ((XText)nodes[i]).Value.Split('\n'); lines = lines.SkipWhile(string.IsNullOrEmpty).Reverse().SkipWhile(string.IsNullOrEmpty) .Reverse().ToArray(); for (var j = 0; j < lines.Length; j++) { string l; if (lines[j].StartsWith(spaces)) { l = lines[j].Substring(trimWhitespaceLength); } else { l = lines[j]; } //Is the last line of an expression all spaces? Ignore! if (j == lines.Length - 1) { if (Regex.Match(l, "^ +$").Success) { continue; } } var trimmed = methodConfig.Method.GetValue(l, false); if (Regex.Match(trimmed, "^ +$").Success) { trimmed = string.Empty; } nodeBuilder.Append(trimmed); //If this isn't the last line of text and the next line isn't all just spaces, or there are at least two more lines to go, insert a newline if (NodeTextNeedsNewLine(lines, nodes, nodeBuilder, i, j)) //todo: this is wrong. { nodeBuilder.AppendLine(); } } } if (nodes[i] is XElement) { var elm = (XElement)nodes[i]; nodeBuilder.Append(getElementText(nodeBuilder, elm, nodes, i)); } } return(nodeBuilder.ToString().Split('\n').Select(v => v.TrimEnd('\r')).Reverse().SkipWhile(string.IsNullOrEmpty).Reverse().ToArray()); }