code: private <A> void crossover(
  		final MSeq<Chromosome<G>> c1,
  		final MSeq<Chromosome<G>> c2,
  		final int index
  	) {
  		@SuppressWarnings("unchecked")
  		final TreeNode<A> tree1 = (TreeNode<A>)TreeNode.ofTree(c1.get(index).getGene());
  		@SuppressWarnings("unchecked")
  		final TreeNode<A> tree2 = (TreeNode<A>)TreeNode.ofTree(c2.get(index).getGene());
  
  		crossover(tree1, tree2);
  
  		final FlatTreeNode<A> flat1 = FlatTreeNode.of(tree1);
  		final FlatTreeNode<A> flat2 = FlatTreeNode.of(tree2);
  
  		@SuppressWarnings("unchecked")
  		final TreeGene<A, ?> template = (TreeGene<A, ?>)c1.get(0).getGene();
  
  		final ISeq<G> genes1 = flat1.map(tree -> gene(template, tree));
  		final ISeq<G> genes2 = flat2.map(tree -> gene(template, tree));
  
  		c1.set(index, c1.get(index).newInstance(genes1));
  		c2.set(index, c2.get(index).newInstance(genes2));
  	}
docs: the abstract "crossover" method usually don't have to do additional casts.