private static <A> TreeNode<Op<A>> toTree(
		final TreeNode<Op<A>> root,
		final int index,
		final ISeq<? extends FlatTree<? extends Op<A>, ?>> nodes,
		final int[] offsets,
		final ISeq<? extends Op<A>> terminals,
		final RandomGenerator random
	) {
		if (index < nodes.size()) {
			final FlatTree<? extends Op<A>, ?> node = nodes.get(index);
			final Op<A> op = node.value();

			for (int i  = 0; i < op.arity(); ++i) {
				assert offsets[index] != -1;

				final TreeNode<Op<A>> treeNode = TreeNode.of();
				if (offsets[index] + i < nodes.size()) {
					treeNode.value(nodes.get(offsets[index] + i).value());
				} else {
					treeNode.value(terminals.get(random.nextInt(terminals.size())));
				}

				toTree(
					treeNode,
					offsets[index] + i,
					nodes,
					offsets,
					terminals,
					random
				);
				root.attach(treeNode);
			}
		}

		return root;
	}
Creates a valid program tree from the given flattened sequence of
op nodes. The given {@code operations} and {@code termination} nodes are
used for <em>repairing</em> the program tree, if necessary.

@param nodes the flattened, possible corrupt, program tree
@param terminals the usable non-terminal operation nodes to use for
       reparation
@param <A> the operation argument type
@return a new valid program tree build from the flattened program tree
@throws NullPointerException if one of the arguments is {@code null}
@throws IllegalArgumentException if the {@code nodes} sequence is empty
jenetics.prog/src/main/java/io/jenetics/prog/op/Program.java