/** * Canonicalize an ordered set of exceptions. In the canonical form, none of the RVVExceptions * have any received versions. * * @param exceptions * @return The canonicalized set of exceptions. */ protected List<RVVException> canonicalExceptions(List<RVVException> exceptions) { LinkedList<RVVException> canon = new LinkedList<RVVException>(); if (exceptions != null) { // Iterate through the set of exceptions for (RVVException exception : exceptions) { if (exception.isEmpty()) { canon.add(exception); } else { long previous = exception.previousVersion; // Iterate through the set of received versions for this exception int insertAt = canon.size(); for (ReceivedVersionsIterator it = exception.receivedVersionsIterator(); it.hasNext(); ) { Long received = it.next(); // If we find a gap between the previous received version and the // next received version, add an exception. if (received != previous + 1) { canon.add(insertAt, RVVException.createException(previous, received)); } // move the previous reference previous = received; } // if there is a gap between the last received version and the next // version, add an exception // this also handles the case where the RVV has no received versions, // because previous==exception.previousVersion in that case. if (exception.nextVersion != previous + 1) { canon.add(insertAt, RVVException.createException(previous, exception.nextVersion)); } } } } return canon; }