/*
 * Java Genetic Algorithm Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
 */
package io.jenetics.ext.util;

import static java.util.Objects.requireNonNull;

import java.util.Comparator;

import io.jenetics.util.Seq;

/**
 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 * @version !__version__!
 * @since !__version__!
 */
public interface MOV<T> {

	public T value();

	public int dimension();

	public default int compareTo(final int index, final T other) {
		return 0;
	}

	public int domination(final T other);

	public default boolean dominates(final T other) {
		return domination(other) > 0;
	}

	public default boolean dominated(final T other) {
		return domination(other) < 0;
	}

	default int rank(final Seq<T> population) {
		domination(population.get(0));
		return 0;
	}

	default int[] distances(final Seq<T> population) {
		return null;
	}

	public static <T> double[] crowdingDistances(
		final Seq<? extends T> front,
		final ComponentComparator<? super T> comparator
	) {

		return null;
	}

	public static MOV<double[]> of(final double[] value) {
		return new DoubleMOV(value);
	}

}

final class DoubleMOV implements MOV<double[]> {

	private final double[] _value;

	DoubleMOV(final double[] value) {
		_value = requireNonNull(value);
	}

	@Override
	public double[] value() {
		return _value;
	}

	@Override
	public int dimension() {
		return _value.length;
	}

	@Override
	public int domination(final double[] other) {
		return 0;
	}
}

@@ -838,20 +838,91 @@
 til.
-Comparator;%0A
+Arrays;%0Aimport java.util.Comparator;%0A%0Aimport io.jenetics.internal.util.IndexSorter;
 %0Aimp
@@ -1702,16 +1702,40 @@
  front,%0A
+%09%09final int dimensions,%0A
 %09%09final 
@@ -1781,30 +1781,744 @@
 or%0A%09) %7B%0A
-%0A%09%09return null
+%09%09final double%5B%5D distances = new double%5Bfront.size()%5D;%0A%0A%09%09if (distances.length %3C 3) %7B%0A%09%09%09Arrays.fill(distances, Double.POSITIVE_INFINITY);%0A%09%09%7D else %7B%0A%09%09%09Arrays.fill(distances, 0);%0A%09%09%09final IndexSorter sorter = IndexSorter.sorter(front.size());%0A%09%09%09final int%5B%5D indexes = new int%5Bfront.size()%5D;%0A%0A%09%09%09for (int i = 0; i %3C dimensions; ++i) %7B%0A%09%09%09%09final int objective = i;%0A%09%09%09%09sorter.sort(%0A%09%09%09%09%09front,%0A%09%09%09%09%09IndexSorter.init(indexes),%0A%09%09%09%09%09(a, b) -%3E comparator.compare(objective, a, b)%0A%09%09%09%09);%0A%0A%09%09%09%09distances%5Bindexes%5B0%5D%5D = Double.POSITIVE_INFINITY;%0A%09%09%09%09distances%5Bindexes%5Bindexes.length - 1%5D%5D = Double.POSITIVE_INFINITY;%0A%0A%09%09%09%09for (int j = 1; j %3C indexes.length - 1; ++j) %7B%0A%09%09%09%09%09distances%5Bindexes%5Bj%5D%5D += 1;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09return distances
 ;%0A%09%7D%0A%0A%09p

Implement 'crowdingDistances' method.