@Override
    public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
        try {
            final EueApiClient client = new EueApiClient(session);
            final UiFsModel response;
            final String resourceId = fileid.getFileId(file);
            switch(resourceId) {
                case EueResourceIdProvider.ROOT:
                case EueResourceIdProvider.TRASH:
                    response = new ListResourceAliasApi(client).resourceAliasAliasGet(resourceId,
                            null, file.attributes().getETag(), null, null, null, null,
                            Collections.singletonList(OPTION_WIN_32_PROPS), null);
                    break;
                default:
                    response = new ListResourceApi(client).resourceResourceIdGet(resourceId,
                            null, file.attributes().getETag(), null, null, null, null,
                            Collections.singletonList(OPTION_WIN_32_PROPS), null);
                    break;
            }
            switch(response.getUifs().getResourceType()) {
                case "aliascontainer":
                case "container":
                    if(file.isFile()) {
                        throw new NotfoundException(file.getAbsolute());
                    }
                    break;
                default:
                    if(file.isDirectory()) {
                        throw new NotfoundException(file.getAbsolute());
                    }
                    break;
            }
            final PathAttributes attr = this.toAttributes(response.getUifs(), response.getUiwin32(),
                    EueShareFeature.findShareForResource(session.userShares(), resourceId));
            if(client.getResponseHeaders().containsKey(HttpHeaders.ETAG)) {
                attr.setETag(StringUtils.remove(client.getResponseHeaders().get(HttpHeaders.ETAG).stream().findFirst().orElse(null), '"'));
            }
            return attr;
        }
        catch(ApiException e) {
            switch(e.getCode()) {
                case HttpStatus.SC_NOT_MODIFIED:
                    if(log.isDebugEnabled()) {
                        log.debug(String.format("No changes for file %s with ETag %s", file, file.attributes().getETag()));
                    }
                    return file.attributes();
            }
            throw new EueExceptionMappingService().map("Failure to read attributes of {0}", e, file);
        }
    }
@Test
    public void testChangeETagPropagatingToRoot() throws Exception {
        final EueResourceIdProvider fileid = new EueResourceIdProvider(session);
        final EueAttributesFinderFeature feature = new EueAttributesFinderFeature(session, fileid);
        final String rootEtag = feature.find(new Path("/", EnumSet.of(Path.Type.directory))).getETag();
        assertNotNull(rootEtag);
        final long rootModificationDate = feature.find(new Path("/", EnumSet.of(Path.Type.directory))).getModificationDate();
        final Path firstlevel = new EueDirectoryFeature(session, fileid).mkdir(new Path(new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus());
        final String firstLevelEtag = feature.find(firstlevel).getETag();
        final Long firstLevelRevision = feature.find(firstlevel).getRevision();
        assertNull(firstLevelRevision);
        final long firstLevelModificationDate = feature.find(firstlevel).getModificationDate();
        assertNotNull(firstLevelEtag);
        final Path secondlevel = new EueDirectoryFeature(session, fileid).mkdir(new Path(firstlevel, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus());
        final String secondLevelEtag = feature.find(secondlevel).getETag();
        assertNotNull(secondLevelEtag);
        final Path secondlevelSibling = new EueDirectoryFeature(session, fileid).mkdir(new Path(firstlevel, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.directory)), new TransferStatus());
        assertNotNull(secondlevelSibling);
        final Path file = new EueTouchFeature(session, fileid).touch(new Path(secondlevel, new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), new TransferStatus());
        final String secondLevelSiblingEtag = feature.find(secondlevelSibling).getETag();
        assertNotEquals(secondLevelEtag, feature.find(secondlevel).getETag());
        assertNotEquals(firstLevelEtag, feature.find(firstlevel).getETag());
        assertNull(feature.find(firstlevel).getRevision());
        assertEquals(firstLevelModificationDate, feature.find(firstlevel).getModificationDate(), 0L);
        assertNotEquals(rootEtag, feature.find(new Path("/", EnumSet.of(Path.Type.directory))).getETag());
        assertNotEquals(rootModificationDate, feature.find(new Path("/", EnumSet.of(Path.Type.directory))).getModificationDate());
        new EueDeleteFeature(session, fileid).delete(Arrays.asList(firstlevel, secondlevel), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }