private int clearAndDecrementPaths(ArrayList<Path> paths, Path basePath, int index,
int count) {
int depth = basePath.getLength();
// Find the index of the first path to clear (inclusive)
Path testPath = new Path(basePath);
testPath.add(index);
int start = ArrayList.binarySearch(paths, testPath, PATH_COMPARATOR);
if (start < 0) {
start = -(start + 1);
}
// Find the index of the last path to clear (exclusive)
testPath.update(depth, index + count);
int end = ArrayList.binarySearch(paths, testPath, PATH_COMPARATOR);
if (end < 0) {
end = -(end + 1);
}
// Clear affected paths
if (end > start) {
paths.remove(start, end - start);
}
// Decrement paths as necessary
int n = paths.getLength();
for (int i = start; i < n; i++) {
Path affectedPath = paths.get(i);
if (!Sequence.Tree.isDescendant(basePath, affectedPath)) {
// All paths from here forward are guaranteed to be unaffected
break;
}
Integer[] elements = affectedPath.toArray();
elements[depth] -= count;
paths.update(i, new ImmutablePath(elements));
}
return (n - start);