private static <T extends Element<U>, U> int getNextLocation(State<T, U> state, int classification) {
		int location = state.currInsertIndex[classification];

		int classLowerBound = getLowerBound(state, classification);
		if (location < classLowerBound) {
			/* If the current class is full, we should re-classify in the direction of the cycle leader.
			 * This way, if our neighbors are also full, they will also re-classify towards the cycle leader,
			 * until the cycle leader is reached, ending the cycle.
			 */
			if (location >= state.cycleLeaderIndex) {
				--state.currInsertIndex[classification];

				// Shrink lower neighbor(s).
				int currClass = classification;
				int prevClass = classification - 1;

				while ((prevClass >= 0) && (state.classUpperBounds[prevClass] > state.currInsertIndex[currClass])) {
					state.classUpperBounds[prevClass] = state.currInsertIndex[currClass];
					if (state.currInsertIndex[prevClass] > state.classUpperBounds[prevClass]) {
						state.currInsertIndex[prevClass] = state.classUpperBounds[prevClass];
					}
					--prevClass;
					--currClass;
				}

			} else if (location < state.cycleLeaderIndex) {
				++state.classUpperBounds[classification];
				location = state.classUpperBounds[classification];

				// Shrink upper neighbor(s).
				int currClass = classification;
				int nextClass = classification + 1;
				while ((nextClass < state.numClasses) && (state.currInsertIndex[nextClass] < state.classUpperBounds[currClass])) {
					state.currInsertIndex[nextClass] = state.classUpperBounds[currClass];
					if (state.currInsertIndex[nextClass] > state.classUpperBounds[nextClass]) {
						state.classUpperBounds[nextClass] = state.currInsertIndex[nextClass];
					}
					++currClass;
					++nextClass;
				}
			}

		} else {
			--state.currInsertIndex[classification];
		}

		return location;
	}