boolean tryDeleteDir(final Path root,
                         final Path dir,
                         final long oldFileTime,
                         final LongConsumer deleteCountConsumer) {
        Objects.requireNonNull(root);
        Objects.requireNonNull(dir);

        if (!Files.isDirectory(root)) {
            throw new IllegalArgumentException(LogUtil.message("root '{}' is not a directory",
                    root.normalize().toAbsolutePath()));
        }
        boolean success = true;
        try {
            final Path canonicalRoot = root.toAbsolutePath().normalize();
            final Path canonicalDir = dir.toAbsolutePath().normalize();
            LOGGER.trace(() -> LogUtil.message(
                    "tryDelete() - canonicalRoot: '{}', canonicalDir: '{}', oldFileTime: {}",
                    canonicalRoot,
                    canonicalDir,
                    Instant.ofEpochMilli(oldFileTime)));

            // No idea why the length condition?
            if (canonicalRoot.toString().length() > 2 && canonicalDir.startsWith(canonicalRoot)) {
                if (Objects.equals(canonicalRoot, canonicalDir)) {
                    LOGGER.trace("tryDelete() - dir: '{}' is the same as root: '{}'", canonicalRoot, canonicalDir);
                    // We have reached root so silently drop out
                } else if (!Files.exists(dir)) {
                    // It is not there (which is what we want), so just carry on recursing
                    // with its parent
                    final boolean wasRecursionSuccess = tryDeleteDir(
                            root, dir.getParent(), oldFileTime, deleteCountConsumer);
                    if (!wasRecursionSuccess) {
                        success = false;
                    }
                } else if (!Files.isDirectory(dir)) {
                    throw new IllegalArgumentException(LogUtil.message("dir '{}' is not a directory", canonicalDir));
                } else if (!Files.isSameFile(root, dir)) { // handles symlinks
                    final long lastModified = Files.getLastModifiedTime(dir).toMillis();

                    if (lastModified < oldFileTime) {
                        // Delete the dir if it is empty
                        try {
                            try {
                                Files.delete(dir);
                                if (deleteCountConsumer != null) {
                                    deleteCountConsumer.accept(1L);
                                }
                                LOGGER.debug("tryDelete() - Successfully deleted empty directory {}", canonicalDir);
                            } catch (NoSuchFileException e) {
                                LOGGER.debug("tryDelete() - Directory not found {}", canonicalDir);
                                // It is not there (which is what we want), so just carry on recursing
                                // with its parent
                            }

                            // Recurse backwards towards the root, using parent as next dir
                            final boolean wasRecursionSuccess = tryDeleteDir(
                                    root, dir.getParent(), oldFileTime, deleteCountConsumer);
                            if (!wasRecursionSuccess) {
                                success = false;
                            }
                        } catch (final DirectoryNotEmptyException e) {
                            LOGGER.debug("tryDelete() - Skipping non-empty dir {}", canonicalDir);
                            // This is an expected case, so swallow and drop out gracefully.
                            // Can't delete it so can't recurse.
                        } catch (final IOException e) {
                            // Some other reason for not being able to delete
                            success = false;
                            LOGGER.error(() -> LogUtil.message("tryDelete() - Failed to delete dir {} - {} - {}",
                                    canonicalDir,
                                    e.getClass().getSimpleName(),
                                    e.getMessage()));
                        }
                    } else {
                        LOGGER.debug(() ->
                                LogUtil.message(
                                        "tryDelete() - Skipping dir that was modified too recently " +
                                                "(lastModified: {} >= oldFileTime: {}) {}",
                                        Instant.ofEpochMilli(lastModified),
                                        Instant.ofEpochMilli(oldFileTime),
                                        canonicalDir));
                    }
                } else {
                    // reached the root so drop out quietly
                    LOGGER.trace("tryDelete() - dir: '{}' is the same directory as root: '{}'",
                            canonicalRoot, canonicalDir);
                }
            } else {
                // If it not then this would carry on deleting
                throw new IllegalArgumentException(LogUtil.message("dir '{}', must be an descendant of root '{}'",
                        canonicalDir, canonicalRoot));
            }
        } catch (final IOException e) {
            success = false;
            LOGGER.error("tryDelete() - Failed to delete dir {}", FileUtil.getCanonicalPath(dir), e);
        }
        return success;
    }
Attempts to delete directory {@code dir} if it is empty and all non-empty
ancestor directories excluding {@code root}. {@code dir} must be a descendant
of {@code root}. Also, it won't delete any directories whose last modified time is >=
oldFileTime.

@param root
@param dir
@param oldFileTime
@return
stroom-data/stroom-data-store-impl-fs/src/main/java/stroom/data/store/impl/fs/FsFileDeleter.java