private CompletableFuture<LayerDiffSummary> run(final String path, final NodeRef left, final NodeRef right) { final ObjectId leftTreeId = left == null ? RevTree.EMPTY_TREE_ID : left.getObjectId(); final ObjectId rightTreeId = right == null ? RevTree.EMPTY_TREE_ID : right.getObjectId(); final RevTree leftTree = left == null ? RevTree.EMPTY : leftSource.getTree(leftTreeId); final RevTree rightTree = right == null ? RevTree.EMPTY : rightSource.getTree(rightTreeId); CompletableFuture<DiffObjectCount> diffCount = CompletableFuture.supplyAsync(() -> { DiffObjectCount count = command(DiffCount.class).setOldTree(leftTree) .setNewTree(rightTree).setLeftSource(leftSource).setRightSource(rightSource) .call(); return count; }); CompletableFuture<org.locationtech.geogig.plumbing.diff.DiffSummary<BoundingBox, BoundingBox>> diffBounds; diffBounds = CompletableFuture.supplyAsync(() -> { DiffSummary<BoundingBox, BoundingBox> boundsDiff; boundsDiff = command(DiffBounds.class).setOldVersion(leftTree).setNewVersion(rightTree) .setLeftSource(leftSource).setRightSource(rightSource).call(); return boundsDiff; }); return diffCount.thenCombine(diffBounds, (count, bounds) -> toSummary(path, leftTree, rightTree, count, bounds)); }