public static ProxyZipSnapshot of(final Path zipFilePath) {
            final List<Path> paths = new ArrayList<>();
            final Map<Path, Item<String>> basePathToDataMap = new HashMap<>();
            final Map<Path, Item<String>> basePathToContextMap = new HashMap<>();
            final Map<Path, Item<String>> basePathToManifestMap = new HashMap<>();
            final Map<Path, Item<AttributeMap>> basePathToMetaMap = new HashMap<>();

            ZipUtil.forEachEntry(zipFilePath, (zipFile, entry) -> {
                final Path path = Path.of(entry.getName());
                final FileName fileName = FileName.parse(entry.getName());
                final Path basePath = Path.of(fileName.getBaseName());
                final String ext = fileName.getExtension();

                if (StroomZipFileType.CONTEXT.hasExtension(path)) {
                    final var prevVal = basePathToContextMap.put(
                            basePath,
                            new Item<>(path, ZipUtil.getEntryContent(zipFile, entry)));
                    if (prevVal != null) {
                        throw new RuntimeException("Duplicate context entry for basePath " + basePath);
                    }
                } else if (StroomZipFileType.MANIFEST.hasExtension(path)) {
                    final var prevVal = basePathToManifestMap.put(
                            basePath,
                            new Item<>(path, ZipUtil.getEntryContent(zipFile, entry)));
                    if (prevVal != null) {
                        throw new RuntimeException("Duplicate manifest entry for basePath " + basePath);
                    }
                } else if (StroomZipFileType.META.hasExtension(path)) {
                    try {
                        try (InputStream inputStream = zipFile.getInputStream(entry)) {
                            final AttributeMap attributeMap = new AttributeMap();
                            AttributeMapUtil.read(inputStream, attributeMap);
                            final var prevVal = basePathToMetaMap.put(basePath, new Item<>(path, attributeMap));
                            if (prevVal != null) {
                                throw new RuntimeException("Duplicate meta entry for basePath " + basePath);
                            }
                        }
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                } else if (StroomZipFileType.DATA.hasExtension(path)
                           || !path.getFileName().toString().contains(".")) {
                    // Also allow entries with no extension
                    final var prevVal = basePathToDataMap.put(
                            basePath,
                            new Item<>(path, ZipUtil.getEntryContent(zipFile, entry)));
                    if (prevVal != null) {
                        throw new RuntimeException("Duplicate data entry for basePath " + basePath);
                    }
                } else {
                    throw new RuntimeException("Unexpected entry: " + path);
                }
                paths.add(Path.of(entry.getName()));
            });

            final List<Path> basePaths = Stream.of(
                            basePathToDataMap,
                            basePathToContextMap,
                            basePathToManifestMap,
                            basePathToMetaMap)
                    .map(Map::keySet)
                    .flatMap(Set::stream)
                    .distinct()
                    .sorted()
                    .toList();

            final List<ItemGroup> itemGroups = basePaths.stream()
                    .map(basePath ->
                            new ItemGroup(
                                    basePath,
                                    basePathToDataMap.get(basePath),
                                    basePathToContextMap.get(basePath),
                                    basePathToMetaMap.get(basePath),
                                    basePathToManifestMap.get(basePath)))
                    .toList();

            return new ProxyZipSnapshot(paths, itemGroups);
        }
Create a {@link ProxyZipSnapshot} of the supplied zip file path.
This assumes the zip is a proxy zip containing entries with extensions .dat/.meta/.mf/.ctx
stroom-proxy/stroom-proxy-app/src/test/java/stroom/proxy/app/handler/TestDataUtil.java