@Override
    public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
        if(file.isRoot()) {
            return delegate.find(file, listener);
        }
        if(cache.isValid(file.getParent())) {
            final AttributedList<Path> list = cache.get(file.getParent());
            final Path found = list.find(new ListFilteringFeature.ListFilteringPredicate(sensitivity, file));
            if(null != found) {
                if(log.isDebugEnabled()) {
                    log.debug(String.format("Return cached attributes %s for %s", found.attributes(), file));
                }
                return found.attributes();
            }
            if(log.isDebugEnabled()) {
                log.debug(String.format("Cached directory listing does not contain %s", file));
            }
            throw new NotfoundException(file.getAbsolute());
        }
        final CachingListProgressListener caching = new CachingListProgressListener(cache);
        try {
            final PathAttributes attr = delegate.find(file, new ProxyListProgressListener(listener, caching));
            caching.cache();
            return attr;
        }
        catch(NotfoundException e) {
            caching.cache();
            throw e;
        }
    }
@Test
    public void testFindWithDefaultExist() throws Exception {
        final PathCache cache = new PathCache(1);
        final Path directory = new Path("/", EnumSet.of(Path.Type.directory));
        final Path file = new Path(directory, "f", EnumSet.of(Path.Type.file));
        final CachingAttributesFinderFeature feature = new CachingAttributesFinderFeature(Protocol.Case.sensitive, cache,
                new DefaultAttributesFinderFeature(new NullSession(new Host(new TestProtocol())) {
                    @Override
                    public AttributedList<Path> list(final Path directory, final ListProgressListener listener) throws ConnectionCanceledException {
                        final Path f = new Path(directory, "f", EnumSet.of(Path.Type.file));
                        listener.chunk(directory, new AttributedList<>(Collections.singletonList(f)));
                        return new AttributedList<>(Collections.singletonList(f));
                    }
                }));
        assertNotNull(feature.find(file, new DisabledListProgressListener()));
        assertNotSame(file.attributes(), feature.find(file, new DisabledListProgressListener()));
        assertEquals(file.attributes(), feature.find(file, new DisabledListProgressListener()));
        assertEquals(1, cache.size());
        assertTrue(cache.isCached(directory));
        assertTrue(cache.get(directory).contains(file));
    }