public static <T> InvertibleCodec<ISeq<T>, EnumGene<T>>
	ofPermutation(final ISeq<? extends T> alleles) {
		if (alleles.isEmpty()) {
			throw new IllegalArgumentException(
				"Empty allele array is not allowed."
			);
		}

		final Map<T, EnumGene<T>> genes =
			IntStream.range(0, alleles.length())
				.mapToObj(i -> EnumGene.<T>of(i, alleles))
				.collect(Collectors.toMap(EnumGene::allele, identity()));

		return InvertibleCodec.of(
			Genotype.of(new PermutationChromosome<>(ISeq.of(genes.values()))),
			gt -> gt.chromosome().stream()
				.map(EnumGene::allele)
				.collect(ISeq.toISeq()),
			val -> Genotype.of(
				new PermutationChromosome<>(
					val.stream()
						.map(genes::get)
						.collect(ISeq.toISeq())
				)
			)
		);
	}
Create a permutation {@link InvertibleCodec} with the given alleles.

@param alleles the alleles of the permutation
@param <T> the allele type
@return a new permutation {@code Codec}
@throws IllegalArgumentException if the given allele array is empty
@throws NullPointerException if one of the alleles is {@code null}
jenetics/src/main/java/io/jenetics/engine/Codecs.java