class TreeWalker {

    protected @Nullable CommandNode<R> map(CommandNode<T> command, @Nullable T source) {
        if (source != null && command.getRequirement() != null && !command.canUse(source)) {
            return null;
        }
        
        var result = mappings.get(command);
        if (result == null) {
            result = mapper.map(command);
            mappings.put(command, result);
            
            redirect(command.getRedirect(), result, source);
            descend(command.getChildren(), result, source);
        }

        return result;
    }

    public  TreeWalker(Mapper<T, R> mapper);

}