/*******************************************************************************
 * Copyright (c) 2005, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.Serializable;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.jpt.utility.Filter;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.CompositeIterator;
import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 * TODO
 */
public class Classpath
	implements Serializable
{
	/** The entries in the classpath */
	private final Entry[] entries;

	private static final long serialVersionUID = 1L;


	// ********** static methods **********

	// ***** factory methods for "standard" classpaths *****

	/**
	 * Return the Java "boot" classpath. This includes rt.jar.
	 */
	public static Classpath bootClasspath() {
		return new Classpath(System.getProperty("sun.boot.class.path"));
	}
	
	/**
	 * Return a "virtual classpath" that contains all the jars
	 * that would be used by the Java Extension Mechanism.
	 */
	public static Classpath javaExtensionClasspath() {
		File[] dirs = javaExtensionDirectories();
		List<String> jarFileNames = new ArrayList<String>();
		for (File dir : dirs) {
			if (dir.isDirectory()) {
				addJarFileNamesTo(dir, jarFileNames);
			}
		}
		return new Classpath(jarFileNames);
	}

	/**
	 * Return the Java "system" classpath.
	 */
	public static Classpath javaClasspath() {
		return new Classpath(System.getProperty("java.class.path"));
	}

	/**
	 * Return the unretouched "complete" classpath.
	 * This includes the boot classpath, the Java Extension
	 * Mechanism classpath, and the normal "system" classpath.
	 */
	public static Classpath completeClasspath() {
		return new Classpath(new Classpath[] {
				bootClasspath(),
				javaExtensionClasspath(),
				javaClasspath()
		});
	}

	/**
	 * Return a classpath that contains the location of the specified class.
	 */
	public static Classpath classpathFor(Class<?> javaClass) {
		return new Classpath(locationFor(javaClass));
	}


	// ***** file => class *****

	/**
	 * Convert a relative file name to a class name; this will work for
	 * any file that has a single extension beyond the base
	 * class name.
	 * e.g. "java/lang/String.class" is converted to "java.lang.String"
	 * e.g. "java/lang/String.java" is converted to "java.lang.String"
	 */
	public static String convertToClassName(String classFileName) {
		String className = FileTools.stripExtension(classFileName);
		// do this for archive entry names
		className = className.replace('/', '.');
		// do this for O/S-specific file names
		if (File.separatorChar != '/') {
			className = className.replace(File.separatorChar, '.');
		}
		return className;
	}

	/**
	 * Convert a file to a class name;
	 * e.g. File(java/lang/String.class) is converted to "java.lang.String"
	 */
	public static String convertToClassName(File classFile) {
		return convertToClassName(classFile.getPath());
	}

	/**
	 * Convert a relative file name to a class;
	 * e.g. "java/lang/String.class" is converted to java.lang.String.class
	 */
	public static Class<?> convertToClass(String classFileName) throws ClassNotFoundException {
		return Class.forName(convertToClassName(classFileName));
	}

	/**
	 * Convert a relative file to a class;
	 * e.g. File(java/lang/String.class) is converted to java.lang.String.class
	 */
	public static Class<?> convertToClass(File classFile) throws ClassNotFoundException {
		return convertToClass(classFile.getPath());
	}


	// ***** class => JAR entry *****

	/**
	 * Convert a class name to an archive entry name base;
	 * e.g. "java.lang.String" is converted to "java/lang/String"
	 */
	public static String convertToArchiveEntryNameBase(String className) {
		return className.replace('.', '/');
	}
	
	/**
	 * Convert a class to an archive entry name base;
	 * e.g. java.lang.String.class is converted to "java/lang/String"
	 */
	public static String convertToArchiveEntryNameBase(Class<?> javaClass) {
		return convertToArchiveEntryNameBase(javaClass.getName());
	}
	
	/**
	 * Convert a class name to an archive class file entry name;
	 * e.g. "java.lang.String" is converted to "java/lang/String.class"
	 */
	public static String convertToArchiveClassFileEntryName(String className) {
		return convertToArchiveEntryNameBase(className) + ".class";
	}
	
	/**
	 * Convert a class to an archive class file entry name;
	 * e.g. java.lang.String.class is converted to "java/lang/String.class"
	 */
	public static String convertToArchiveClassFileEntryName(Class<?> javaClass) {
		return convertToArchiveClassFileEntryName(javaClass.getName());
	}
	

	// ***** class => file (.class or .java) *****

	/**
	 * Convert a class name to a file name base for the current O/S;
	 * e.g. "java.lang.String" is converted to "java/lang/String" on Unix
	 * and "java\\lang\\String" on Windows
	 */
	public static String convertToFileNameBase(String className) {
		return className.replace('.', File.separatorChar);
	}
	
	/**
	 * Convert a class to a file name base for the current O/S;
	 * e.g. java.lang.String.class is converted to "java/lang/String" on Unix
	 * and "java\\lang\\String" on Windows
	 */
	public static String convertToFileNameBase(Class<?> javaClass) {
		return convertToFileNameBase(javaClass.getName());
	}
	
	/**
	 * Convert a class name to a class file name for the current O/S;
	 * e.g. "java.lang.String" is converted to "java/lang/String.class" on Unix
	 * and "java\\lang\\String.class" on Windows
	 */
	public static String convertToClassFileName(String className) {
		return convertToFileNameBase(className) + ".class";
	}
	
	/**
	 * Convert a class to a class file name for the current O/S;
	 * e.g. java.lang.String.class is converted to "java/lang/String.class" on Unix
	 * and "java\\lang\\String.class" on Windows
	 */
	public static String convertToClassFileName(Class<?> javaClass) {
		return convertToClassFileName(javaClass.getName());
	}
	
	/**
	 * Convert a class name to a class file for the current O/S;
	 * e.g. "java.lang.String" is converted to File(java/lang/String.class)
	 */
	public static File convertToClassFile(String className) {
		return new File(convertToClassFileName(className));
	}
	
	/**
	 * Convert a class to a class file for the current O/S;
	 * e.g. java.lang.String.class is converted to File(java/lang/String.class)
	 */
	public static File convertToClassFile(Class<?> javaClass) {
		return convertToClassFile(javaClass.getName());
	}
	
	/**
	 * Convert a class name to a java file name for the current O/S;
	 * e.g. "java.lang.String" is converted to "java/lang/String.java" on Unix
	 * and "java\\lang\\String.java" on Windows
	 */
	public static String convertToJavaFileName(String className) {
		return convertToFileNameBase(className) + ".java";
	}

	/**
	 * Convert a class to a java file name for the current O/S;
	 * e.g. java.lang.String.class is converted to "java/lang/String.java" on Unix
	 * and "java\\lang\\String.java" on Windows
	 */
	public static String convertToJavaFileName(Class<?> javaClass) {
		return convertToJavaFileName(javaClass.getName());
	}

	/**
	 * Convert a class name to a java file for the current O/S;
	 * e.g. "java.lang.String" is converted to File(java/lang/String.java)
	 */
	public static File convertToJavaFile(String className) {
		return new File(convertToJavaFileName(className));
	}

	/**
	 * Convert a class to a java file for the current O/S;
	 * e.g. java.lang.String.class is converted to File(java/lang/String.java)
	 */
	public static File convertToJavaFile(Class<?> javaClass) {
		return convertToJavaFile(javaClass.getName());
	}


	// ***** class => resource *****

	/**
	 * Convert a class to a resource name;
	 * e.g. java.lang.String.class is converted to "/java/lang/String.class".
	 */
	public static String convertToResourceName(Class<?> javaClass) {
		return '/' + convertToArchiveClassFileEntryName(javaClass);
	}

	/**
	 * Convert a class to a resource;
	 * e.g. java.lang.String.class is converted to
	 * URL(jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class).
	 */
	public static URL convertToResource(Class<?> javaClass) {
		return javaClass.getResource(convertToResourceName(javaClass));
	}


	// ***** utilities *****

	/**
	 * Return whether the specified file is an archive file;
	 * i.e. its name ends with ".zip" or ".jar"
	 */
	public static boolean fileNameIsArchive(String fileName) {
		String ext = FileTools.extension(fileName).toLowerCase();
		return ext.equals(".jar") || ext.equals(".zip");
	}
	
	/**
	 * Return whether the specified file is an archive file;
	 * i.e. its name ends with ".zip" or ".jar"
	 */
	public static boolean fileIsArchive(File file) {
		return fileNameIsArchive(file.getName());
	}
	
	/**
	 * Return what should be the fully-qualified file name
	 * for the JRE runtime JAR;
	 * e.g. "C:\jdk1.4.2_04\jre\lib\rt.jar".
	 */
	public static String rtJarName() {
		return locationFor(java.lang.Object.class);
	}
	
	/**
	 * Return the location from where the specified class was loaded.
	 */
	public static String locationFor(Class<?> javaClass) {
		URL url = convertToResource(javaClass);
		String path;
		try {
			path = FileTools.buildFile(url).getPath();
		} catch (URISyntaxException ex) {
			throw new RuntimeException(ex);
		}
		String protocol = url.getProtocol().toLowerCase();
		if (protocol.equals("jar")) {
			// if the class is in a JAR, the URL will look something like this:
			//     jar:file:/C:/jdk/1.4.2_04/jre/lib/rt.jar!/java/lang/String.class
			return path.substring(0, path.indexOf('!'));
		} else if (protocol.equals("file")) {
			// if the class is in a directory, the URL will look something like this:
			//     file:/C:/dev/main/mwdev/class/org/eclipse/dali/utility/Classpath.class
			return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1);
		} else if (protocol.equals("bundleresource")) {
			// if the class is in a bundle resource (Eclipse?), the URL will look something like this:
			//     bundleresource://43/org/eclipse/dali/utility/Classpath.class
			return path.substring(0, path.length() - convertToClassFileName(javaClass).length() - 1);
		}

		throw new IllegalStateException(url.toString());
	}
	
	/**
	 * Return the directories used by the Java Extension Mechanism.
	 */
	public static File[] javaExtensionDirectories() {
		return convertToFiles(javaExtensionDirectoryNames());
	}

	/**
	 * Return the directory names used by the Java Extension Mechanism.
	 */
	public static String[] javaExtensionDirectoryNames() {
		return System.getProperty("java.ext.dirs").split(File.pathSeparator);
	}


	// ***** internal *****

	private static File[] convertToFiles(String[] fileNames) {
		File[] files = new File[fileNames.length];
		for (int i = fileNames.length; i-- > 0; ) {
			files[i] = new File(fileNames[i]);
		}
		return files;
	}

	private static void addJarFileNamesTo(File dir, List<String> jarFileNames) {
		File[] jarFiles = jarFilesIn(dir);
		for (File jarFile : jarFiles) {
			jarFileNames.add(FileTools.canonicalFile(jarFile).getPath());
		}
	}

	private static File[] jarFilesIn(File directory) {
		return directory.listFiles(jarFileFilter());
	}

	private static FileFilter jarFileFilter() {
		return new FileFilter() {
			public boolean accept(File file) {
				return FileTools.extension(file.getName()).toLowerCase().equals(".jar");
			}
		};
	}


	// ********** constructors **********

	/**
	 * Construct a classpath with the specified entries.
	 */
	private Classpath(Entry[] entries) {
		super();
		this.entries = entries;
	}

	/**
	 * Construct a classpath with the specified entries.
	 */
	public Classpath(String[] fileNames) {
		this(buildEntries(fileNames));
	}

	/**
	 * Skip empty file names because they will end up expanding to the current
	 * working directory, which is not what we want. Empty file names actually
	 * occur with some frequency; such as when the classpath has been built up
	 * dynamically with too many separators. For example:
	 *     "C:\dev\foo.jar;;C:\dev\bar.jar"
	 * will be parsed into three file names:
	 *     { "C:\dev\foo.jar", "", "C:\dev\bar.jar" }
	 */
	private static Entry[] buildEntries(String[] fileNames) {
		List<Entry> entries = new ArrayList<Entry>();
		for (String fileName : fileNames) {
			if ((fileName != null) && (fileName.length() != 0)) {
				entries.add(new Entry(fileName));
			}
		}
		return entries.toArray(new Entry[entries.size()]);
	}

	/**
	 * Construct a classpath with the specified path.
	 */
	public Classpath(String path) {
		this(path.split(File.pathSeparator));
	}

	/**
	 * Construct a classpath with the specified entries.
	 */
	public Classpath(List<String> fileNames) {
		this(fileNames.toArray(new String[fileNames.size()]));
	}

	/**
	 * Consolidate the specified classpaths into a single classpath.
	 */
	public Classpath(Classpath[] classpaths) {
		this(consolidateEntries(classpaths));
	}

	private static Entry[] consolidateEntries(Classpath[] classpaths) {
		List<Entry> entries = new ArrayList<Entry>();
		for (Classpath classpath : classpaths) {
			CollectionTools.addAll(entries, classpath.entries());
		}
		return entries.toArray(new Entry[entries.size()]);
	}


	// ********** public API **********

	/**
	 * Return the classpath's entries.
	 */
	public Entry[] entries() {
		return this.entries;
	}

	/**
	 * Return the classpath's path.
	 */
	public String path() {
		Entry[] localEntries = this.entries;
		int max = localEntries.length - 1;
		if (max == -1) {
			return "";
		}
		StringBuilder sb = new StringBuilder(2000);
		// stop one short of the end of the array
		for (int i = 0; i < max; i++) {
			sb.append(localEntries[i].fileName());
			sb.append(File.pathSeparatorChar);
		}
		sb.append(localEntries[max].fileName());
		return sb.toString();
	}

	/**
	 * Search the classpath for the specified (unqualified) file
	 * and return its entry. Return null if an entry is not found.
	 * For example, you could use this method to find the entry
	 * for "rt.jar" or "toplink.jar".
	 */
	public Entry entryForFileNamed(String shortFileName) {
		Entry[] localEntries = this.entries;
		for (Entry entry : localEntries) {
			if (entry.file().getName().equals(shortFileName)) {
				return entry;
			}
		}
		return null;
	}

	/**
	 * Return the first entry file in the classpath
	 * that contains the specified class.
	 * Return null if an entry is not found.
	 */
	public Entry entryForClassNamed(String className) {
		String relativeClassFileName = convertToClassFileName(className);
		String archiveEntryName = convertToArchiveClassFileEntryName(className);
		Entry[] localEntries = this.entries;
		for (Entry entry : localEntries) {
			if (entry.contains(relativeClassFileName, archiveEntryName)) {
				return entry;
			}
		}
		return null;
	}

	/**
	 * Return the names of all the classes discovered on the classpath,
	 * with duplicates removed.
	 */
	public String[] classNames() {
		return this.classNames(Filter.Null.<String>instance());
	}

	/**
	 * Return the names of all the classes discovered on the classpath
	 * and accepted by the specified filter, with duplicates removed.
	 */
	public String[] classNames(Filter<String> filter) {
		Collection<String> classNames = new HashSet<String>(10000);
		this.addClassNamesTo(classNames, filter);
		return classNames.toArray(new String[classNames.size()]);
	}

	/**
	 * Add the names of all the classes discovered on the classpath
	 * to the specified collection.
	 */
	public void addClassNamesTo(Collection<String> classNames) {
		this.addClassNamesTo(classNames, Filter.Null.<String>instance());
	}

	/**
	 * Add the names of all the classes discovered on the classpath
	 * and accepted by the specified filter to the specified collection.
	 */
	public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) {
		Entry[] localEntries = this.entries;
		for (Entry entry : localEntries) {
			entry.addClassNamesTo(classNames, filter);
		}
	}

	/**
	 * Return the names of all the classes discovered on the classpath.
	 * Just a bit more performant than #classNames().
	 */
	public Iterator<String> classNamesStream() {
		return this.classNamesStream(Filter.Null.<String>instance());
	}

	/**
	 * Return the names of all the classes discovered on the classpath
	 * that are accepted by the specified filter.
	 * Just a bit more performant than #classNames(Filter).
	 */
	public Iterator<String> classNamesStream(Filter<String> filter) {
		return new CompositeIterator<String>(this.entryClassNamesStreams(filter));
	}

	private Iterator<Iterator<String>> entryClassNamesStreams(final Filter<String> filter) {
		return new TransformationIterator<Entry, Iterator<String>>(new ArrayIterator<Entry>(this.entries)) {
			@Override
			protected Iterator<String> transform(Entry entry) {
				return entry.classNamesStream(filter);
			}
		};
	}

	/**
	 * Return a "compressed" version of the classpath with its
	 * duplicate entries eliminated.
	 */
	public Classpath compressed() {
		return new Classpath(CollectionTools.removeDuplicateElements(this.entries));
	}

	/**
	 * Convert the classpath to an array of URLs
	 * (that can be used to instantiate a URLClassLoader).
	 */
	public URL[] urls() {
		Entry[] localEntries = this.entries;
		int len = localEntries.length;
		URL[] urls = new URL[len];
		for (int i = 0; i < len; i++) {
			urls[i] = localEntries[i].url();
		}
		return urls;
	}

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.path());
	}


	// ********** inner class **********

	/**
	 * TODO
	 */
	public static class Entry implements Serializable {
		private final String fileName;
		private final File file;
		private final File canonicalFile;

		private static final long serialVersionUID = 1L;

		Entry(String fileName) {
			super();
			if ((fileName == null) || (fileName.length() == 0)) {
				throw new IllegalArgumentException("'fileName' must be non-empty");
			}
			this.fileName = fileName;
			this.file = new File(fileName);
			this.canonicalFile = FileTools.canonicalFile(this.file);
		}

		public String fileName() {
			return this.fileName;
		}

		public File file() {
			return this.file;
		}

		public File canonicalFile() {
			return this.canonicalFile;
		}

		public String canonicalFileName() {
			return this.canonicalFile.getAbsolutePath();
		}

		@Override
		public boolean equals(Object o) {
			if ( ! (o instanceof Entry)) {
				return false;
			}
			return ((Entry) o).canonicalFile.equals(this.canonicalFile);
		}

		@Override
		public int hashCode() {
			return this.canonicalFile.hashCode();
		}

		/**
		 * Return the entry's "canonical" URL.
		 */
		public URL url() {
			try {
				return this.canonicalFile.toURL();
			} catch (IOException ex) {
				throw new RuntimeException(ex);
			}
		}

		/**
		 * Return whether the entry contains the specified class.
		 */
		public boolean contains(Class<?> javaClass) {
			return this.contains(javaClass.getName());
		}

		/**
		 * Return whether the entry contains the specified class.
		 */
		public boolean contains(String className) {
			return this.contains(convertToClassFileName(className), convertToArchiveClassFileEntryName(className));
		}

		/**
		 * Return whether the entry contains either the specified relative
		 * class file or the specified archive entry.
		 * Not the prettiest signature, but it's internal....
		 */
		boolean contains(String relativeClassFileName, String archiveEntryName) {
			if ( ! this.canonicalFile.exists()) {
				return false;
			}
			if (this.canonicalFile.isDirectory() && (new File(this.canonicalFile, relativeClassFileName)).exists()) {
				return true;
			}
			return (fileIsArchive(this.canonicalFile) && this.archiveContainsEntry(archiveEntryName));
		}

		/**
		 * Return whether the entry's archive contains the specified entry.
		 */
		private boolean archiveContainsEntry(String zipEntryName) {
			ZipFile zipFile = null;
			ZipEntry zipEntry = null;
			try {
				zipFile = new ZipFile(this.canonicalFile);
				zipEntry = zipFile.getEntry(zipEntryName);
			} catch (IOException ex) {
				// something is wrong, leave the entry null
			} finally {
				try {
					if (zipFile != null) {
						zipFile.close();
					}
				} catch (IOException ex) {
					zipEntry = null;	// something is wrong, clear out the entry
				}
			}
			return zipEntry != null;
		}

		/**
		 * Return the names of all the classes discovered in the entry.
		 */
		public String[] classNames() {
			return this.classNames(Filter.Null.<String>instance());
		}

		/**
		 * Return the names of all the classes discovered in the entry
		 * and accepted by the specified filter.
		 */
		public String[] classNames(Filter<String> filter) {
			Collection<String> classNames = new ArrayList<String>(2000);
			this.addClassNamesTo(classNames, filter);
			return classNames.toArray(new String[classNames.size()]);
		}

		/**
		 * Add the names of all the classes discovered in the entry
		 * to the specified collection.
		 */
		public void addClassNamesTo(Collection<String> classNames) {
			this.addClassNamesTo(classNames, Filter.Null.<String>instance());
		}

		/**
		 * Add the names of all the classes discovered in the entry
		 * and accepted by the specified filter to the specified collection.
		 */
		public void addClassNamesTo(Collection<String> classNames, Filter<String> filter) {
			if (this.canonicalFile.exists()) {
				if (this.canonicalFile.isDirectory()) {
					this.addClassNamesForDirectoryTo(classNames, filter);
				} else if (fileIsArchive(this.canonicalFile)) {
					this.addClassNamesForArchiveTo(classNames, filter);
				}
			}
		}

		/**
		 * Add the names of all the classes discovered
		 * under the entry's directory and accepted by
		 * the specified filter to the specified collection.
		 */
		private void addClassNamesForDirectoryTo(Collection<String> classNames, Filter<String> filter) {
			int start = this.canonicalFile.getAbsolutePath().length() + 1;
			for (Iterator<File> stream = this.classFilesForDirectory(); stream.hasNext(); ) {
				String className = convertToClassName(stream.next().getAbsolutePath().substring(start));
				if (filter.accept(className)) {
					classNames.add(className);
				}
			}
		}

		/**
		 * Return an iterator on all the class files discovered
		 * under the entry's directory.
		 */
		private Iterator<File> classFilesForDirectory() {
			return new FilteringIterator<File, File>(FileTools.filesInTree(this.canonicalFile)) {
				@Override
				protected boolean accept(File next) {
					return Entry.this.fileNameMightBeForClassFile(next.getName());
				}
			};
		}

		/**
		 * Add the names of all the classes discovered
		 * in the entry's archive file and accepted by the
		 * specified filter to the specified collection.
		 */
		private void addClassNamesForArchiveTo(Collection<String> classNames, Filter<String> filter) {
			ZipFile zipFile = null;
			try {
				zipFile = new ZipFile(this.canonicalFile);
			} catch (IOException ex) {
				return;
			}
			for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) {
				ZipEntry zipEntry = stream.nextElement();
				String zipEntryName = zipEntry.getName();
				if (this.fileNameMightBeForClassFile(zipEntryName)) {
					String className = convertToClassName(zipEntryName);
					if (filter.accept(className)) {
						classNames.add(className);
					}
				}
			}
			try {
				zipFile.close();
			} catch (IOException ex) {
				return;
			}
		}

		/**
		 * Return whether the specified file might be a Java class file.
		 * The file name must at least end with ".class" and contain no spaces.
		 * (Neither class names nor package names may contain spaces.)
		 * Whether it actually is a class file will need to be determined by
		 * a class loader.
		 */
		boolean fileNameMightBeForClassFile(String name) {
			return FileTools.extension(name).toLowerCase().equals(".class")
					&& (name.indexOf(' ') == -1);
		}

		/**
		 * Return the names of all the classes discovered on the classpath.
		 * Just a bit more performant than #classNames().
		 */
		public Iterator<String> classNamesStream() {
			return this.classNamesStream(Filter.Null.<String>instance());
		}

		/**
		 * Return the names of all the classes discovered on the classpath
		 * that are accepted by the specified filter.
		 * Just a bit more performant than #classNames(Filter).
		 */
		public Iterator<String> classNamesStream(Filter<String> filter) {
			if (this.canonicalFile.exists()) {
				if (this.canonicalFile.isDirectory()) {
					return this.classNamesForDirectory(filter);
				}
				if (fileIsArchive(this.canonicalFile)) {
					return this.classNamesForArchive(filter);
				}
			}
			return EmptyIterator.instance();
		}

		/**
		 * Return the names of all the classes discovered
		 * under the entry's directory and accepted by
		 * the specified filter.
		 */
		private Iterator<String> classNamesForDirectory(Filter<String> filter) {
			return new FilteringIterator<String, String>(this.classNamesForDirectory(), filter);
		}

		/**
		 * Transform the class files to class names.
		 */
		private Iterator<String> classNamesForDirectory() {
			final int start = this.canonicalFile.getAbsolutePath().length() + 1;
			return new TransformationIterator<File, String>(this.classFilesForDirectory()) {
				@Override
				protected String transform(File f) {
					return convertToClassName(f.getAbsolutePath().substring(start));
				}
			};
		}

		/**
		 * Return the names of all the classes discovered
		 * in the entry's archive file and accepted by the
		 * specified filter.
		 */
		private Iterator<String> classNamesForArchive(Filter<String> filter) {
			// we can't simply wrap iterators here because we need to close the archive file...
			ZipFile zipFile = null;
			try {
				zipFile = new ZipFile(this.canonicalFile);
			} catch (IOException ex) {
				return EmptyIterator.instance();
			}
			Collection<String> classNames = new HashSet<String>(zipFile.size());
			for (Enumeration<? extends ZipEntry> stream = zipFile.entries(); stream.hasMoreElements(); ) {
				ZipEntry zipEntry = stream.nextElement();
				String zipEntryName = zipEntry.getName();
				if (this.fileNameMightBeForClassFile(zipEntryName)) {
					String className = convertToClassName(zipEntryName);
					if (filter.accept(className)) {
						classNames.add(className);
					}
				}
			}
			try {
				zipFile.close();
			} catch (IOException ex) {
				return EmptyIterator.instance();
			}
			return classNames.iterator();
		}

	}

}
