class PackagedProgram {

	public static List<File> extractContainedLibraries(URL jarFile) throws ProgramInvocationException {
		try (final JarFile jar = new JarFile(new File(jarFile.toURI()))) {

			final List<JarEntry> containedJarFileEntries = getContainedJarEntries(jar);
			if (containedJarFileEntries.isEmpty()) {
				return Collections.emptyList();
			}

			final List<File> extractedTempLibraries = new ArrayList<>(containedJarFileEntries.size());
			boolean incomplete = true;

			try {
				final Random rnd = new Random();
				final byte[] buffer = new byte[4096];

				for (final JarEntry entry : containedJarFileEntries) {
					// '/' as in case of zip, jar
					// java.util.zip.ZipEntry#isDirectory always looks only for '/' not for File.separator
					final String name = entry.getName().replace('/', '_');
					final File tempFile = copyLibToTempFile(name, rnd, jar, entry, buffer);
					extractedTempLibraries.add(tempFile);
				}

				incomplete = false;
			} finally {
				if (incomplete) {
					deleteExtractedLibraries(extractedTempLibraries);
				}
			}

			return extractedTempLibraries;
		} catch (Throwable t) {
			throw new ProgramInvocationException("Unknown I/O error while extracting contained jar files.", t);
		}
	}

	private  PackagedProgram(
			@Nullable File jarFile,
			List<URL> classpaths,
			@Nullable String entryPointClassName,
			Configuration configuration,
			SavepointRestoreSettings savepointRestoreSettings,
			String... args);

}