TreeRewriteRule implements TreeRewriter<V>, Serializable { @Override public int rewrite(final TreeNode<V> tree, final int limit) { requireNonNull(tree); int rewritten = 0; Optional<TreeMatchResult<V>> result; do { result = left().matcher(tree).results().findFirst(); result.ifPresent(res -> rewrite(res, tree)); rewritten += result.isPresent() ? 1 : 0; } while (result.isPresent() && rewritten < limit); return rewritten; } TreeRewriteRule(
		final TreePattern<V> left,
		final TreePattern<V> right
	); TreePattern<V> left(); TreePattern<V> right(); TreeRewriteRule<B> map(final Function<? super V, ? extends B> mapper); @Override int rewrite(final TreeNode<V> tree, final int limit); @Override int hashCode(); @Override boolean equals(final Object obj); @Override String toString(); static TreeRewriteRule<V> parse(
		final String rule,
		final Function<? super String, ? extends V> mapper
	); static TreeRewriteRule<String> parse(final String rule);  }
@Test(dataProvider = "trees") public void rewrite(final String treeString, final String rewrittenTreeString) { final TreeNode<String> tree = TreeNode.parse(treeString); TreeRewriter.rewrite(tree, REWRITERS); Assert.assertEquals( tree.toParenthesesString(), TreeNode.parse(rewrittenTreeString).toParenthesesString() ); }