public static function fill(Grid $grid, Distribution $distribution, int $maxRetries)
    {
        Assert::assertPositiveInteger($maxRetries, 'maxRetries');

        if ($distribution->getCells() !== ($cells = $grid->rows * $grid->columns)) {
            throw new InvalidArgumentException(
                "Cannot fill distribution {$distribution} ({$distribution->getCells()} cells)"
                . " in a {$grid->rows}x{$grid->columns} grid ({$cells} cells)"
            );
        }

        if ($grid->rows < 2 && $distribution->tall > 0) {
            throw new InvalidArgumentException(
                "Cannot fill distribution {$distribution} in a {$grid->rows}x{$grid->columns} grid: not enough rows."
            );
        }

        if ($grid->columns < 2 && $distribution->wide > 0) {
            throw new InvalidArgumentException(
                "Cannot fill distribution {$distribution} in a {$grid->rows}x{$grid->columns} grid: not enough columns."
            );
        }

        for ($remainingTries = $maxRetries; $remainingTries > 0; $remainingTries -= 1) {
            try {
                return static::tryToFill($grid, $distribution);
            } catch (InvalidArgumentException $e) {
                $grid->empty();
            }
        }
        throw new RuntimeException(
            "Could not fill distribution {$distribution} in a {$grid->rows}x{$grid->columns} grid"
            . " after {$maxRetries} tries."
        );
    }