private static <V> TreeNode<V> expand(
		final Tree<Decl<V>, ?> template,
		final Map<Var<V>, Tree<V, ?>> vars
	) {
		final Map<Path, Var<V>> paths = template.stream()
			.filter((Tree<Decl<V>, ?> n) -> n.value() instanceof Var)
			.collect(toMap(Tree::childPath, t -> (Var<V>)t.value()));

		final TreeNode<V> tree = TreeNode.ofTree(
			template,
			n -> n instanceof Val<V> val ? val.value() : null
		);

		paths.forEach((path, decl) -> {
			final Tree<? extends V, ?> replacement = vars.get(decl);
			if (replacement != null) {
				tree.replaceAtPath(path, TreeNode.ofTree(replacement));
			} else {
				tree.removeAtPath(path);
			}
		});

		return tree;
	}
Expands {@code this} pattern with the given variable mapping.

@param vars the variables to use for expanding {@code this} pattern
@return the expanded tree pattern
@throws NullPointerException if one of the arguments is {@code null}
@throws IllegalArgumentException if not all needed variables are part
        of the {@code variables} map
jenetics.ext/src/main/java/io/jenetics/ext/rewriting/TreePattern.java