@Override
    public void setTimestamp(final Path file, final TransferStatus status) throws BackgroundException {
        if(file.isVolume()) {
            log.warn(String.format("Skip setting timestamp for %s", file));
            return;
        }
        final S3MetadataFeature feature = new S3MetadataFeature(session, new S3AccessControlListFeature(session));
        // Copy existing metadata in addition to timestamp
        final PathAttributes attr = new S3AttributesFinderFeature(session, new S3AccessControlListFeature(session)).find(file);
        final Map<String, String> metadata = attr.getMetadata();
        if(status.getModified() != null) {
            final Header header = S3TimestampFeature.toHeader(S3TimestampFeature.METADATA_MODIFICATION_DATE, status.getModified());
            metadata.put(StringUtils.lowerCase(header.getName()), header.getValue());
        }
        if(status.getCreated() != null) {
            final Header header = S3TimestampFeature.toHeader(S3TimestampFeature.METADATA_CREATION_DATE, status.getCreated());
            metadata.put(StringUtils.lowerCase(header.getName()), header.getValue());
        }
        feature.setMetadata(file, status.withMetadata(metadata));
    }
@Test
    public void testFindTimestamp() throws Exception {
        final Path bucket = new Path("versioning-test-eu-central-1-cyberduck", EnumSet.of(Path.Type.volume, Path.Type.directory));
        final TransferStatus status = new TransferStatus();
        final S3AccessControlListFeature acl = new S3AccessControlListFeature(session);
        final Path test = new S3TouchFeature(session, acl).touch(new Path(bucket,
                        new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)),
                status.withCreated(1695159781972L).withModified(1530305150672L));
        final String versionId = test.attributes().getVersionId();
        assertEquals(1530305150000L, status.getResponse().getModificationDate());
        assertEquals(1695159781000L, status.getResponse().getCreationDate());
        final PathAttributes attributes = new S3AttributesFinderFeature(session, acl).find(test);
        assertEquals(1530305150000L, attributes.getModificationDate());
        assertEquals(1695159781000L, attributes.getCreationDate());
        final Map<String, String> metadata = attributes.getMetadata();
        assertEquals(3, metadata.size());
        assertTrue(metadata.containsKey("mtime"));
        assertTrue(metadata.containsKey("btime"));
        assertTrue(metadata.containsKey("Content-Type"));
        final S3TimestampFeature feature = new S3TimestampFeature(session);
        feature.setTimestamp(test, status.withModified(1630305150672L).withCreated(1530305160672L));
        assertNotEquals(versionId, status.getResponse().getVersionId());
        assertEquals("1630305150", status.getResponse().getMetadata().get("mtime"));
        assertEquals("1530305160", status.getResponse().getMetadata().get("btime"));
        final PathAttributes attributesAfterSettingNewTimestamps = new S3AttributesFinderFeature(session, acl).find(test.withAttributes(status.getResponse()));
        assertNotEquals(metadata, attributesAfterSettingNewTimestamps.getMetadata());
        assertEquals("1630305150", attributesAfterSettingNewTimestamps.getMetadata().get("mtime"));
        assertEquals("1530305160", attributesAfterSettingNewTimestamps.getMetadata().get("btime"));
        assertEquals(metadata.size(), attributesAfterSettingNewTimestamps.getMetadata().size());
        assertNotEquals(versionId, attributesAfterSettingNewTimestamps.getVersionId());
        assertEquals(status.getResponse().getVersionId(), attributesAfterSettingNewTimestamps.getVersionId());
        assertEquals(1630305150000L, attributesAfterSettingNewTimestamps.getModificationDate());
        assertEquals(1530305160000L, attributesAfterSettingNewTimestamps.getCreationDate());
        test.attributes().setModificationDate(1630305150000L);
        final Path found = new S3ObjectListService(session, acl, true).list(bucket, new DisabledListProgressListener()).find(new DefaultPathPredicate(test));
        assertEquals(1630305150000L, found.attributes().getModificationDate());
        final Path moved = new S3MoveFeature(session, acl).move(test, new Path(bucket,
                new AlphanumericRandomStringService().random(), EnumSet.of(Path.Type.file)), status, new Delete.DisabledCallback(), new DisabledConnectionCallback());
        assertEquals(1630305150000L, moved.attributes().getModificationDate());
        assertEquals(1630305150000L, new S3AttributesFinderFeature(session, acl).find(moved).getModificationDate());
        new S3DefaultDeleteFeature(session).delete(Collections.singletonList(moved), new DisabledLoginCallback(), new Delete.DisabledCallback());
    }