@Override
    public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
        if(file.isRoot()) {
            return PathAttributes.EMPTY;
        }
        final Region region = regionService.lookup(file);
        try {
            if(containerService.isContainer(file)) {
                final ContainerInfo info = session.getClient().getContainerInfo(region,
                        containerService.getContainer(file).getName());
                final PathAttributes attributes = new PathAttributes();
                attributes.setSize(info.getTotalSize());
                attributes.setRegion(info.getRegion().getRegionId());
                return attributes;
            }
            final ObjectMetadata metadata;
            try {
                try {
                    metadata = session.getClient().getObjectMetaData(region,
                            containerService.getContainer(file).getName(), containerService.getKey(file));
                }
                catch(GenericException e) {
                    throw new SwiftExceptionMappingService().map("Failure to read attributes of {0}", e, file);
                }
            }
            catch(NotfoundException e) {
                if(file.isDirectory()) {
                    // Directory placeholder file may be missing. Still return empty attributes when we find children
                    try {
                        new SwiftObjectListService(session).list(file, new CancellingListProgressListener());
                    }
                    catch(ListCanceledException l) {
                        // Found common prefix
                        return PathAttributes.EMPTY;
                    }
                    catch(NotfoundException n) {
                        throw e;
                    }
                    // Common prefix only
                    return PathAttributes.EMPTY;
                }
                // Try to find pending large file upload
                final Write.Append append = new SwiftLargeObjectUploadFeature(session, regionService, new SwiftWriteFeature(session, regionService)).append(file, new TransferStatus());
                if(append.append) {
                    return new PathAttributes().withSize(append.offset);
                }
                throw e;
            }
            if(file.isDirectory()) {
                if(!StringUtils.equals(SwiftDirectoryFeature.DIRECTORY_MIME_TYPE, metadata.getMimeType())) {
                    throw new NotfoundException(String.format("File %s has set MIME type %s but expected %s",
                            file.getAbsolute(), metadata.getMimeType(), SwiftDirectoryFeature.DIRECTORY_MIME_TYPE));
                }
            }
            if(file.isFile()) {
                if(StringUtils.equals(SwiftDirectoryFeature.DIRECTORY_MIME_TYPE, metadata.getMimeType())) {
                    throw new NotfoundException(String.format("File %s has set MIME type %s",
                            file.getAbsolute(), metadata.getMimeType()));
                }
            }
            return this.toAttributes(metadata);
        }
        catch(GenericException e) {
            throw new SwiftExceptionMappingService().map("Failure to read attributes of {0}", e, file);
        }
        catch(IOException e) {
            throw new DefaultIOExceptionMappingService().map("Failure to read attributes of {0}", e, file);
        }
    }
@Test
    public void testFind() throws Exception {
        final Path container = new Path("test.cyberduck.ch", EnumSet.of(Path.Type.directory, Path.Type.volume));
        container.attributes().setRegion("IAD");
        final String name = new AlphanumericRandomStringService().random();
        final Path test = new SwiftTouchFeature(session, new SwiftRegionService(session)).touch(
                new Path(container, String.format("%s-", name), EnumSet.of(Path.Type.file)), new TransferStatus());
        final SwiftAttributesFinderFeature f = new SwiftAttributesFinderFeature(session);
        final PathAttributes attributes = f.find(test);
        assertEquals(0L, attributes.getSize());
        assertEquals(EnumSet.of(Path.Type.file), test.getType());
        assertNull(attributes.getETag());
        assertEquals("d41d8cd98f00b204e9800998ecf8427e", attributes.getChecksum().hash);
        assertEquals(attributes.getModificationDate(), new SwiftObjectListService(session).list(container, new DisabledListProgressListener())
                .find(new DefaultPathPredicate(test)).attributes().getModificationDate());
        assertNotEquals(-1L, attributes.getModificationDate());
        // Test wrong type
        try {
            f.find(new Path(container, name, EnumSet.of(Path.Type.directory)));
            fail();
        }
        catch(NotfoundException e) {
            // Expected
        }
        try {
            f.find(new Path(container, String.format("%s-", name), EnumSet.of(Path.Type.directory)));
            fail();
        }
        catch(NotfoundException e) {
            // Expected
        }
        new SwiftDeleteFeature(session).delete(Collections.singletonList(test), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }