public AstNode ReplaceWith(Func <AstNode, AstNode> replaceFunction) { if (replaceFunction == null) { throw new ArgumentNullException("replaceFunction"); } if (parent == null) { throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node"); } AstNode oldParent = parent; AstNode oldSuccessor = nextSibling; Role oldRole = this.Role; Remove(); AstNode replacement = replaceFunction(this); if (oldSuccessor != null && oldSuccessor.parent != oldParent) { throw new InvalidOperationException("replace function changed nextSibling of node being replaced?"); } if (!(replacement == null || replacement.IsNull)) { if (replacement.parent != null) { throw new InvalidOperationException("replace function must return the root of a tree"); } if (!oldRole.IsValid(replacement)) { throw new InvalidOperationException(string.Format("The new node '{0}' is not valid in the role {1}", replacement.GetType().Name, oldRole.ToString())); } if (oldSuccessor != null) { oldParent.InsertChildBeforeUnsafe(oldSuccessor, replacement, oldRole); } else { oldParent.AddChildUnsafe(replacement, oldRole); } } return(replacement); }