private DocumentationCommentTriviaSyntax ProcessTag( DocumentationCommentTriviaSyntax documentationNode, IMethodOrAccessorTransformationResult methodTransformResult, string tagName, Func <IMethodSymbol, string> addOrReplace, Predicate <IMethodSymbol> canRemove, bool prepend) { if (addOrReplace == null && canRemove == null) { return(documentationNode); } var methodSymbol = methodTransformResult.AnalyzationResult.Symbol; var tagContent = addOrReplace?.Invoke(methodSymbol); var removeTag = canRemove?.Invoke(methodSymbol); var tagNode = documentationNode.Content.OfType <XmlElementSyntax>() .FirstOrDefault(o => o.StartTag.Name.ToString() == tagName); if (!string.IsNullOrEmpty(tagContent)) { var indent = methodTransformResult.LeadingWhitespaceTrivia.ToFullString(); var eol = methodTransformResult.EndOfLineTrivia.ToFullString(); var tagComment = CreateTagContent(tagName, tagContent, indent, eol); // When prepending a new tag before an existing tag we have to add the indentation at the end otherwise on start if (prepend && tagNode == null && documentationNode.Content.Any()) { var lastComment = tagComment.Content.Last(); tagComment = tagComment.ReplaceNode(lastComment, lastComment .WithTrailingTrivia(lastComment.GetTrailingTrivia() .Add(methodTransformResult.LeadingWhitespaceTrivia))); } else { var startComment = tagComment.Content.First(); tagComment = tagComment.ReplaceNode(startComment, startComment .WithLeadingTrivia(DocumentationCommentExterior($"{indent}///"))); } if (tagNode != null) { documentationNode = documentationNode.ReplaceNode(tagNode, tagComment.Content.OfType <XmlElementSyntax>().First()); } else { documentationNode = documentationNode.WithContent(prepend ? documentationNode.Content.InsertRange(0, tagComment.Content) : documentationNode.Content.AddRange(tagComment.Content)); } } else if (removeTag == true && tagNode != null) { // We need to remove the "///" XmlText and the tag itself var index = documentationNode.Content.IndexOf(tagNode); documentationNode = documentationNode.RemoveNode(tagNode, SyntaxRemoveOptions.KeepNoTrivia); documentationNode = documentationNode.RemoveNode(documentationNode.Content[index - 1], SyntaxRemoveOptions.KeepNoTrivia); } return(documentationNode); }