private double recalculateDimension(final LayoutConfig layoutConfig,
                                        final int dim,
                                        double pos,
                                        final double size,
                                        final boolean useRemaining) {
        double containerSize = 0;

        if (layoutConfig != null) {
//            Console.log(layoutConfig.toString());
//            Console.log("Preferred size: " +
//                    layoutConfig.getPreferredSize().get(dim) +
//                    " dimension " +
//                    (dim == 0
//                            ? "X"
//                            : "Y"));

            // Get the minimum size in this dimension that this splitter can be
            // to fit its contents.
            final double minSize = getMinRequired(layoutConfig, dim);
            if (useRemaining) {
                containerSize = size;
                containerSize = Math.max(containerSize, minSize);
            } else {
                final double preferredSize = layoutConfig.getPreferredSize().get(dim);
                containerSize = Math.min(preferredSize, size);
                containerSize = Math.max(containerSize, minSize);
            }

            PositionAndSize positionAndSize =
                    positionAndSizeMap.computeIfAbsent(layoutConfig, k -> new PositionAndSize());
            positionAndSize.setPos(dim, pos);
            positionAndSize.setSize(dim, containerSize);

            // Now deal with children if this is split layout data.
            if (layoutConfig instanceof SplitLayoutConfig) {
                final SplitLayoutConfig splitLayoutConfig = (SplitLayoutConfig) layoutConfig;
                double remainingSize = containerSize;

                for (int i = 0; i < splitLayoutConfig.count(); i++) {
                    final LayoutConfig child = splitLayoutConfig.get(i);

                    // See if this is the last child.
                    if (i < splitLayoutConfig.count() - 1) {
                        // Find out what the minimum space is that could be
                        // taken up by layouts after this one.
                        double minRequired = 0;
                        if (splitLayoutConfig.getDimension() == dim) {
                            minRequired = getMinRequired(splitLayoutConfig, dim, i + 1, 1);
                        }
                        final double available = remainingSize - minRequired;

                        final boolean useRest = splitLayoutConfig.getDimension() != dim;
                        final double childSize = recalculateDimension(child, dim, pos, available, useRest);
                        if (splitLayoutConfig.getDimension() == dim) {
                            // Move position for next child and reduce available
                            // size.
                            pos += childSize;
                            remainingSize -= childSize;
                        }

                        // Add data to position a split during layout.
                        final SplitInfo splitInfo = new SplitInfo(splitLayoutConfig, i);
                        positionAndSize = positionAndSizeMap.computeIfAbsent(splitInfo, k -> new PositionAndSize());

                        if (dim == splitLayoutConfig.getDimension()) {
                            positionAndSize.setPos(dim, pos - SPLIT_OFFSET);
                            positionAndSize.setSize(dim, SPLIT_SIZE);
                        } else {
                            positionAndSize.setPos(dim, pos);
                            positionAndSize.setSize(dim, containerSize + SPLIT_SIZE);
                        }

                    } else {
                        // This is the last child so assume rest of available
                        // space.
                        recalculateDimension(child, dim, pos, remainingSize, true);
                    }
                }
            }
        }

        return containerSize;
    }
Tests the supplied layout to see if it is the current mouse target and
returns mouse target if it is.

@param x               The mouse x coordinate.
@param y               The mouse y coordinate.
@param splitter        True if the layout is a splitter. Splitters are targeted
                       outside their rect.
@param layoutConfig    The layout data to test to see if it is a target.
@param positionAndSize The position and size of the layout being tested.
@return The mouse target if the tested layout is the target, else null.
stroom-core-client/src/main/java/stroom/dashboard/client/flexlayout/FlexLayout.java