class DefaultPackageInfo implements PackageInfo {

    public static @Nullable PackageInfo read(@NotNull File file) throws IOException {
        DefaultPackageInfo info = new DefaultPackageInfo(null, null, PackageType.MIXED);
        if (!file.exists()) {
            throw new FileNotFoundException("Could not find file " + file);
        }
        if (file.isDirectory()) {
            for (File directoryFile : FileUtils.listFiles(file, new NameFileFilter(new String[] { "MANIFEST.MF", Constants.PROPERTIES_XML, Constants.FILTER_XML}),
                    new SuffixFileFilter(new String[] { Constants.META_INF, Constants.VAULT_DIR }))) {
                try (InputStream input = new BufferedInputStream(new FileInputStream(directoryFile))) {
                    info = readFromInputStream(new File(file.toURI().relativize(directoryFile.toURI()).getPath()), input, info);
                    // bail out as soon as all info was found
                    if (info.getId() != null && info.getFilter() != null) {
                        break;
                    }
                }

            }
            if (info.getId() == null || info.getFilter() == null) {
                return null;
            } else {
                return info;
            }
        } else if (file.getName().endsWith(".zip")) {
            // try to derive from vault-work?
            try (ZipFile zip = new ZipFile(file)) {
                Enumeration<? extends ZipEntry> entries = zip.entries();
                while (entries.hasMoreElements()) {
                    ZipEntry e = entries.nextElement();
                    try (InputStream input = zip.getInputStream(e)) {
                        info = readFromInputStream(new File(e.getName()), input, info);
                        // bail out as soon as all info was found
                        if (info.getId() != null && info.getFilter() != null) {
                            break;
                        }
                    }
                }
            }
            if (info.getId() == null || info.getFilter() == null) {
                return null;
            } else {
                return info;
            }
        } else {
            throw new IOException("Only metadata from zip files could be extracted but the given file is not a zip:" + file);
        }
    }

    public  DefaultPackageInfo(PackageId id, WorkspaceFilter filter, PackageType packageType);

}