private void firstWalk(final TreeNode v, final TreeNode leftSibling) {
        if (tree.isLeaf(v)) {
            // No need to set prelim(v) to 0 as the getter takes care of this.

            final TreeNode w = leftSibling;
            if (w != null) {
                // v has left sibling

                setPrelim(v, getPrelim(w) + getDistance(v, w));
            }

        } else {
            // v is not a leaf

            TreeNode defaultAncestor = tree.getFirstChild(v);
            TreeNode previousChild = null;
            for (final TreeNode w : tree.getChildren(v)) {
                firstWalk(w, previousChild);
                defaultAncestor = apportion(w, defaultAncestor, previousChild, v);
                previousChild = w;
            }
            executeShifts(v);
            final double midpoint = (getPrelim(tree.getFirstChild(v)) + getPrelim(tree.getLastChild(v))) / 2.0;
            final TreeNode w = leftSibling;
            if (w != null) {
                // v has left sibling

                setPrelim(v, getPrelim(w) + getDistance(v, w));
                setMod(v, getPrelim(v) - midpoint);

            } else {
                // v has no left sibling

                setPrelim(v, midpoint);
            }
        }
    }
In difference to the original algorithm we also pass in the leftSibling
(see {@link #apportion(Object, Object, Object, Object)} for a
motivation).

@param v
@param leftSibling [nullable] the left sibling v, if there is any
stroom-core-client-widget/src/main/java/stroom/widget/htree/client/treelayout/AbegoTreeLayout.java