public static Collection<String> listToplevelClassNamesForURI(URI uri) {
		final Collection<String> rval = new ArrayList<String>();

		// Ensure we have a proper cache entry ...
		// getCacheEntry();

		// Disabled: Not really necessary, is it? And not storing/retrieving
		// these items
		// makes the cache file smaller and saves several ms (~200) loading and
		// storing it
		// if (this.cacheEntry.classesValid) { return this.cacheEntry.classes; }

		try {
			final JarURLConnection connection = (JarURLConnection) new URI("jar:" + uri + "!/")
			        .toURL().openConnection();
			final JarFile jarFile = connection.getJarFile();

			final Enumeration<JarEntry> entries = jarFile.entries();

			while (entries.hasMoreElements()) {
				final JarEntry entry = entries.nextElement();

				// We only search for class file entries
				if (entry.isDirectory()) {
					continue;
				}
				if (!entry.getName().endsWith(".class")) {
					continue;
				}

				String name = entry.getName();
				name = name.replaceAll("/", ".");

				// Remove trailing .class
				if (name.endsWith("class")) {
					name = name.substring(0, name.length() - 6);
				}

				// Disabled: Not really necessary, is it? And not
				// storing/retrieving these items
				// makes the cache file smaller and saves several ms (~200)
				// loading and storing it
				// Only store something if we have a cache entry
				// if (this.cacheEntry != null)
				// this.cacheEntry.classes.add(name);

				rval.add(name);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}

		return rval;
	}