@Override
    public PathAttributes find(final Path file, final ListProgressListener listener) throws BackgroundException {
        if(file.isRoot()) {
            return PathAttributes.EMPTY;
        }
        try {
            if(containerService.isContainer(file)) {
                final Storage.Buckets.Get request = session.getClient().buckets().get(containerService.getContainer(file).getName());
                if(containerService.getContainer(file).attributes().getCustom().containsKey(GoogleStorageAttributesFinderFeature.KEY_REQUESTER_PAYS)) {
                    request.setUserProject(session.getHost().getCredentials().getUsername());
                }
                return this.toAttributes(request.execute());
            }
            else {
                final Storage.Objects.Get get = session.getClient().objects().get(
                        containerService.getContainer(file).getName(), containerService.getKey(file));
                if(containerService.getContainer(file).attributes().getCustom().containsKey(GoogleStorageAttributesFinderFeature.KEY_REQUESTER_PAYS)) {
                    get.setUserProject(session.getHost().getCredentials().getUsername());
                }
                final VersioningConfiguration versioning = null != session.getFeature(Versioning.class) ? session.getFeature(Versioning.class).getConfiguration(
                        containerService.getContainer(file)
                ) : VersioningConfiguration.empty();
                if(versioning.isEnabled()) {
                    if(StringUtils.isNotBlank(file.attributes().getVersionId())) {
                        get.setGeneration(Long.parseLong(file.attributes().getVersionId()));
                    }
                }
                final PathAttributes attributes;
                try {
                    attributes = this.toAttributes(get.execute());
                }
                catch(IOException e) {
                    if(file.isDirectory()) {
                        final BackgroundException failure = new GoogleStorageExceptionMappingService().map("Failure to read attributes of {0}", e, file);
                        if(failure instanceof NotfoundException) {
                            if(log.isDebugEnabled()) {
                                log.debug(String.format("Search for common prefix %s", file));
                            }
                            // File may be marked as placeholder but no placeholder file exists. Check for common prefix returned.
                            try {
                                new GoogleStorageObjectListService(session).list(file, new CancellingListProgressListener(), String.valueOf(Path.DELIMITER), 1, VersioningConfiguration.empty());
                            }
                            catch(ListCanceledException l) {
                                // Found common prefix
                                return PathAttributes.EMPTY;
                            }
                            catch(NotfoundException n) {
                                throw e;
                            }
                            // Found common prefix
                            return PathAttributes.EMPTY;
                        }
                    }
                    throw e;
                }
                if(versioning.isEnabled()) {
                    // Determine if latest version
                    try {
                        // Duplicate if not latest version
                        final Storage.Objects.Get request = session.getClient().objects().get(
                                containerService.getContainer(file).getName(), containerService.getKey(file));
                        if(containerService.getContainer(file).attributes().getCustom().containsKey(GoogleStorageAttributesFinderFeature.KEY_REQUESTER_PAYS)) {
                            request.setUserProject(session.getHost().getCredentials().getUsername());
                        }
                        final String latest = this.toAttributes(request.execute()).getVersionId();
                        if(null != latest) {
                            attributes.setDuplicate(!latest.equals(attributes.getVersionId()));
                        }
                    }
                    catch(IOException e) {
                        // Noncurrent versions only appear in requests that explicitly call for object versions to be included
                        final BackgroundException failure = new GoogleStorageExceptionMappingService().map("Failure to read attributes of {0}", e, file);
                        if(failure instanceof NotfoundException) {
                            // The latest version is a delete marker
                            attributes.setDuplicate(true);
                        }
                        else {
                            throw failure;
                        }
                    }
                }
                return attributes;
            }
        }
        catch(IOException e) {
            throw new GoogleStorageExceptionMappingService().map("Failure to read attributes of {0}", e, file);
        }
    }
@Test
    public void testFindBucket() throws Exception {
        final Path container = new Path("cyberduck-test-eu", EnumSet.of(Path.Type.directory, Path.Type.volume));
        final PathAttributes attributes = new GoogleStorageAttributesFinderFeature(session).find(container);
        assertNotSame(PathAttributes.EMPTY, attributes);
        assertEquals(-1L, attributes.getSize());
        assertNotNull(attributes.getRegion());
        assertNotNull(attributes.getETag());
        assertEquals(attributes, new GoogleStorageBucketListService(session).list(new Path("/", EnumSet.of(Path.Type.directory, Path.Type.volume)),
                new DisabledListProgressListener()).find(new SimplePathPredicate(container)).attributes());
    }