Generic version of the algorithm.