/*******************************************************************************
 * Copyright (c) 2005, 2010 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.common.utility.internal;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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

/**
 * Assorted file tools:
 * - delete entire trees of directories and files
 * - build iterators on entire trees of directories and files
 * - build a temporary directory
 * - "canonize" files
 */
public final class FileTools {

	public static final String USER_HOME_DIRECTORY_NAME = System.getProperty("user.home"); //$NON-NLS-1$
	public static final String USER_TEMPORARY_DIRECTORY_NAME = System.getProperty("java.io.tmpdir"); //$NON-NLS-1$
	public static String DEFAULT_TEMPORARY_DIRECTORY_NAME = "tmpdir"; //$NON-NLS-1$
	public static final String CURRENT_WORKING_DIRECTORY_NAME = System.getProperty("user.dir"); //$NON-NLS-1$

    /** A list of some invalid file name characters.
				: is the filename separator in MacOS and the drive indicator in DOS
				* is a DOS wildcard character
				| is a DOS redirection character
				& is our own escape character
				/ is the filename separator in Unix and the command option tag in DOS
				\ is the filename separator in DOS/Windows and the escape character in Unix
				; is ???
				? is a DOS wildcard character
				[ is ???
				] is ???
				= is ???
				+ is ???
				< is a DOS redirection character
				> is a DOS redirection character
				" is used by DOS to delimit file names with spaces
				, is ???
     */
	public static final char[] INVALID_FILENAME_CHARACTERS = { ':', '*', '|', '&', '/', '\\', ';', '?', '[', ']', '=', '+', '<', '>', '"', ',' };

	/** This encoder will convert strings into valid file names. */
	public static final XMLStringEncoder FILE_NAME_ENCODER = new XMLStringEncoder(INVALID_FILENAME_CHARACTERS);

	/** Windows files that are redirected to devices etc. */
	@SuppressWarnings("nls")
	private static final String[] WINDOWS_RESERVED_FILE_NAMES = {
		"con",
		"aux",
		"com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
		"lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
		"prn",
		"nul"
	};

	/** The default length of a shortened file name. */
	public static final int MAXIMUM_SHORTENED_FILE_NAME_LENGTH = 60;


	// ********** deleting directories **********

	/**
	 * Delete the specified directory and all of its contents.
	 * <em>USE WITH CARE.</em>
	 * File#deleteAll()?
	 */
	public static void deleteDirectory(String directoryName) {
		deleteDirectory(new File(directoryName));
	}
	
	/**
	 * Delete the specified directory and all of its contents.
	 * <em>USE WITH CARE.</em>
	 * File#deleteAll()?
	 */
	public static void deleteDirectory(File directory) {
		deleteDirectoryContents(directory);
		if ( ! directory.delete()) {
			throw new RuntimeException("unable to delete directory: " + directory.getAbsolutePath()); //$NON-NLS-1$
		}
	}
	
	/**
	 * Delete the contents of the specified directory
	 * (but not the directory itself).
	 * <em>USE WITH CARE.</em>
	 * File#deleteFiles()
	 */
	public static void deleteDirectoryContents(String directoryName) {
		deleteDirectoryContents(new File(directoryName));
	}
	
	/**
	 * Delete the contents of the specified directory
	 * (but not the directory itself).
	 * <em>USE WITH CARE.</em>
	 * File#deleteFiles()
	 */
	public static void deleteDirectoryContents(File directory) {
		for (File file : directory.listFiles()) {
			if (file.isDirectory()) {
				deleteDirectory(file);	// recurse through subdirectories
			} else {
				if ( ! file.delete()) {
					throw new RuntimeException("unable to delete file: " + file.getAbsolutePath()); //$NON-NLS-1$
				}
			}
		}
	}
	

	// ********** copying files **********

	/**
	 * Copies the content of the source file to the destination file.
	 * File#copy(File destinationFile)
	 */
	public static void copyToFile(File sourceFile, File destinationFile)
		throws IOException
	{
		FileChannel sourceChannel = new FileInputStream(sourceFile).getChannel();
		FileChannel destinationChannel = new FileOutputStream(destinationFile).getChannel();
		try {
			destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
		} finally {
			sourceChannel.close();
			destinationChannel.close();
		}
	}
	
	/**
	 * Copies the content of the source file to a file by
	 * the same name in the destination directory.
	 * File#copyToDirectory(File destinationDirectory)
	 */
	public static void copyToDirectory(File sourceFile, File destinationDirectory)
		throws IOException
	{
		File destinationFile = new File(destinationDirectory, sourceFile.getName());
		if ( ! destinationFile.exists() && ! destinationFile.createNewFile()) {
			throw new RuntimeException("createNewFile() failed: " + destinationFile); //$NON-NLS-1$
		}
		copyToFile(sourceFile, destinationFile);
	}
	

	// ********** iteratoring over files and directories **********

	/**
	 * Return an iterator on all the files in the specified directory.
	 * The iterator will skip over subdirectories.
	 * File#files()
	 */
	public static Iterator<File> filesIn(String directoryName) {
		return filesIn(new File(directoryName));
	}
	
	/**
	 * Return an iterator on all the files in the specified directory.
	 * The iterator will skip over subdirectories.
	 * File#files()
	 */
	public static Iterator<File> filesIn(File directory) {
		return filesIn(directory.listFiles());
	}
	
	private static Iterator<File> filesIn(File[] files) {
		return new FilteringIterator<File>(new ArrayIterator<File>(files)) {
			@Override
			protected boolean accept(File next) {
				return next.isFile();
			}
		};
	}
	
	/**
	 * Return an iterator on all the subdirectories
	 * in the specified directory.
	 * File#subDirectories()
	 */
	public static Iterator<File> directoriesIn(String directoryName) {
		return directoriesIn(new File(directoryName));
	}
	
	/**
	 * Return an iterator on all the subdirectories
	 * in the specified directory.
	 * File#subDirectories()
	 */
	public static Iterator<File> directoriesIn(File directory) {
		return directoriesIn(directory.listFiles());
	}
	
	private static Iterator<File> directoriesIn(File[] files) {
		return new FilteringIterator<File>(new ArrayIterator<File>(files)) {
			@Override
			protected boolean accept(File next) {
				return next.isDirectory();
			}
		};
	}
	
	/**
	 * Return an iterator on all the files under the specified
	 * directory, recursing into subdirectories.
	 * The iterator will skip over the subdirectories themselves.
	 * File#filesRecurse()
	 */
	public static Iterator<File> filesInTree(String directoryName) {
		return filesInTree(new File(directoryName));
	}
	
	/**
	 * Return an iterator on all the files under the specified
	 * directory, recursing into subdirectories.
	 * The iterator will skip over the subdirectories themselves.
	 * File#filesRecurse()
	 */
	public static Iterator<File> filesInTree(File directory) {
		return filesInTreeAsSet(directory).iterator();
	}

	private static Set<File> filesInTreeAsSet(File directory) {
		Set<File> files = new HashSet<File>(10000);
		addFilesInTreeTo(directory, files);
		return files;
	}

	private static void addFilesInTreeTo(File directory, Collection<File> allFiles) {
		for (File file : directory.listFiles()) {
			if (file.isFile()) {
				allFiles.add(file);
			} else if (file.isDirectory()) {
				addFilesInTreeTo(file, allFiles);
			}
		}
	}

	/**
	 * Return an iterator on all the directories under the specified
	 * directory, recursing into subdirectories.
	 * File#subDirectoriesRecurse()
	 */
	public static Iterator<File> directoriesInTree(String directoryName) {
		return directoriesInTree(new File(directoryName));
	}
	
	/**
	 * Return an iterator on all the directories under the specified
	 * directory, recursing into subdirectories.
	 * File#subDirectoriesRecurse()
	 */
	@SuppressWarnings("unchecked")
	public static Iterator<File> directoriesInTree(File directory) {
		File[] files = directory.listFiles();
		return new CompositeIterator<File>(directoriesIn(files), directoriesInTrees(directoriesIn(files)));
	}
	
	private static Iterator<File> directoriesInTrees(Iterator<File> directories) {
		return new CompositeIterator<File>(
			new TransformationIterator<File, Iterator<File>>(directories) {
				@Override
				protected Iterator<File> transform(File next) {
					return FileTools.directoriesInTree(next);
				}
			}
		);
	}
	

	// ********** short file name manipulation **********

	/**
	 * Strip the extension from the specified file name
	 * and return the result. If the file name has no
	 * extension, it is returned unchanged
	 * File#basePath()
	 */
	public static String stripExtension(String fileName) {
		int index = fileName.lastIndexOf('.');
		if (index == -1) {
			return fileName;
		}
		return fileName.substring(0, index);
	}
	
	/**
	 * Strip the extension from the specified file's name
	 * and return the result. If the file's name has no
	 * extension, it is returned unchanged
	 * File#basePath()
	 */
	public static String stripExtension(File file) {
		return stripExtension(file.getPath());
	}

	/**
	 * Return the extension, including the dot, of the specified file name.
	 * If the file name has no extension, return an empty string.
	 * File#extension()
	 */
	public static String extension(String fileName) {
		int index = fileName.lastIndexOf('.');
		if (index == -1) {
			return ""; //$NON-NLS-1$
		}
		return fileName.substring(index);
	}
	
	/**
	 * Return the extension, including the dot, of the specified file's name.
	 * If the file's name has no extension, return an empty string.
	 * File#extension()
	 */
	public static String extension(File file) {
		return extension(file.getPath());
	}


	// ********** temporary directories **********

	/**
	 * Build and return an empty temporary directory with the specified
	 * name. If the directory already exists, it will be cleared out.
	 * This directory will be a subdirectory of the Java temporary directory,
	 * as indicated by the System property "java.io.tmpdir".
	 */
	public static File emptyTemporaryDirectory(String name) {
		File dir = new File(userTemporaryDirectory(), name);
		if (dir.exists()) {
			deleteDirectoryContents(dir);
		} else {
			mkdirs(dir);
		}
		return dir;
	}

	private static void mkdirs(File dir) {
		if ( ! dir.mkdirs()) {
			throw new RuntimeException("mkdirs() failed: " + dir); //$NON-NLS-1$
		}
	}
	
	/**
	 * Build and return an empty temporary directory with a
	 * name of "tmpdir". If the directory already exists, it will be cleared out.
	 * This directory will be a subdirectory of the Java temporary directory,
	 * as indicated by the System property "java.io.tmpdir".
	 */
	public static File emptyTemporaryDirectory() {
		return emptyTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
	}
	
	/**
	 * Build and return a temporary directory with the specified
	 * name. If the directory already exists, it will be left unchanged;
	 * if it does not already exist, it will be created.
	 * This directory will be a subdirectory of the Java temporary directory,
	 * as indicated by the System property "java.io.tmpdir".
	 */
	public static File temporaryDirectory(String name) {
		File dir = new File(userTemporaryDirectory(), name);
		if ( ! dir.exists()) {
			mkdirs(dir);
		}
		return dir;
	}
	
	/**
	 * Build and return a temporary directory with a name of
	 * "tmpdir". If the directory already exists, it will be left unchanged;
	 * if it does not already exist, it will be created.
	 * This directory will be a subdirectory of the Java temporary directory,
	 * as indicated by the System property "java.io.tmpdir".
	 */
	public static File temporaryDirectory() {
		return temporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
	}
	
	/**
	 * Build and return a *new* temporary directory with the specified
	 * prefix. The prefix will be appended with a number that
	 * is incremented, starting with 1, until a non-pre-existing directory
	 * is found and successfully created. This directory will be a
	 * subdirectory of the Java temporary directory, as indicated by
	 * the System property "java.io.tmpdir".
	 */
	public static File newTemporaryDirectory(String prefix) {
		if ( ! prefix.endsWith(".")) { //$NON-NLS-1$
			prefix = prefix + '.';
		}
		File dir;
		int i = 0;
		do {
			i++;
			dir = new File(userTemporaryDirectory(), prefix + i);
		} while ( ! dir.mkdirs());
		return dir;
	}
	
	/**
	 * Build and return a *new* temporary directory with a
	 * prefix of "tmpdir". This prefix will be appended with a number that
	 * is incremented, starting with 1, until a non-pre-existing directory
	 * is found and successfully created. This directory will be a
	 * subdirectory of the Java temporary directory, as indicated by
	 * the System property "java.io.tmpdir".
	 */
	public static File newTemporaryDirectory() {
		return newTemporaryDirectory(DEFAULT_TEMPORARY_DIRECTORY_NAME);
	}
	

	// ********** resource files **********

	/**
	 * Build and return a file for the specified resource.
	 * The resource name must be fully-qualified, i.e. it cannot be relative
	 * to the package name/directory.
	 * NB: There is a bug in jdk1.4.x the prevents us from getting
	 * a resource that has spaces (or other special characters) in
	 * its name.... (see Sun's Java bug 4466485)
	 */
	public static File resourceFile(String resourceName) throws URISyntaxException {
		if ( ! resourceName.startsWith("/")) { //$NON-NLS-1$
			throw new IllegalArgumentException(resourceName);
		}
		return resourceFile(resourceName, FileTools.class);
	}
	
	/**
	 * Build and return a file for the specified resource.
	 * NB: There is a bug in jdk1.4.x the prevents us from getting
	 * a resource that has spaces (or other special characters) in
	 * its name.... (see Sun's Java bug 4466485)
	 */
	public static File resourceFile(String resourceName, Class<?> javaClass) throws URISyntaxException {
		URL url = javaClass.getResource(resourceName);
		return buildFile(url);
	}
	
	/**
	 * Build and return a file for the specified URL.
	 * NB: There is a bug in jdk1.4.x the prevents us from getting
	 * a resource that has spaces (or other special characters) in
	 * its name.... (see Sun's Java bug 4466485)
	 */
	public static File buildFile(URL url) throws URISyntaxException {
		return buildFile(url.getFile());
	}
	
	/**
	 * Build and return a file for the specified file name.
	 * NB: There is a bug in jdk1.4.x the prevents us from getting
	 * a resource that has spaces (or other special characters) in
	 * its name.... (see Sun's Java bug 4466485)
	 */
	public static File buildFile(String fileName) throws URISyntaxException {
		URI uri = new URI(fileName);
		File file = new File(uri.getPath());
		return file;
	}
	

	// ********** "canonical" files **********

	/**
	 * Convert the specified file into a "canonical" file.
	 */
	public static File canonicalFile(File file) {
		try {
			return file.getCanonicalFile();
		} catch (IOException ioexception) {
			// settle for the absolute file
			return file.getAbsoluteFile();
		}
	}
	
	/**
	 * Build an iterator that will convert the specified files
	 * into "canonical" files.
	 */
	public static Iterator<File> canonicalFiles(Iterator<File> files) {
		return new TransformationIterator<File, File>(files) {
			@Override
			protected File transform(File next) {
				return canonicalFile(next);
			}
		};
	}
	
	/**
	 * Build an iterator that will convert the specified files
	 * into "canonical" files.
	 */
	public static Iterator<File> canonicalFiles(Collection<File> files) {
		return canonicalFiles(files.iterator());
	}
	
	/**
	 * Convert the specified file name into a "canonical" file name.
	 */
	public static String canonicalFileName(String fileName) {
		return canonicalFile(new File(fileName)).getAbsolutePath();
	}
	
	/**
	 * Build an iterator that will convert the specified file names
	 * into "canonical" file names.
	 */
	public static Iterator<String> canonicalFileNames(Iterator<String> fileNames) {
		return new TransformationIterator<String, String>(fileNames) {
			@Override
			protected String transform(String next) {
				return canonicalFileName(next);
			}
		};
	}
	
	/**
	 * Build an iterator that will convert the specified file names
	 * into "canonical" file names.
	 */
	public static Iterator<String> canonicalFileNames(Collection<String> fileNames) {
		return canonicalFileNames(fileNames.iterator());
	}
	

	// ********** file name validation **********

	/**
	 * Return whether the specified file name is invalid.
	 */
	public static boolean fileNameIsInvalid(String filename) {
		return ! fileNameIsValid(filename);
	}

	/**
	 * Return whether the specified file name is valid.
	 */
	public static boolean fileNameIsValid(String filename) {
		int len = filename.length();
		for (int i = 0; i < len; i++) {
			char filenameChar = filename.charAt(i);
			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Convert the illegal characters in the specified file name to
	 * the specified character and return the result.
	 */
	public static String convertToValidFileName(String filename, char replacementChar) {
		int len = filename.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char filenameChar = filename.charAt(i);
			if (ArrayTools.contains(INVALID_FILENAME_CHARACTERS, filenameChar)) {
				sb.append(replacementChar);
			} else {
				sb.append(filenameChar);
			}
		}
		return sb.toString();
	}

	/**
	 * Convert the illegal characters in the specified file name to
	 * periods ('.') and return the result.
	 */
	public static String convertToValidFileName(String filename) {
		return convertToValidFileName(filename, '.');
	}

	/**
	 * Return whether the specified file name is "reserved"
	 * (i.e. it cannot be used for "user" files). Windows reserves
	 * a number of file names (e.g. CON, AUX, PRN).
	 */
	public static boolean fileNameIsReserved(String fileName) {
		// Unix/Linux does not have any "reserved" file names (I think...)
		return Tools.osIsWindows() && ArrayTools.contains(WINDOWS_RESERVED_FILE_NAMES, fileName.toLowerCase());
	}

	/**
	 * Return whether the specified file contains any "reserved"
	 * components.
	 * Windows reserves a number of file names (e.g. CON, AUX, PRN);
	 * and these file names cannot be used for either the names of
	 * files or directories.
	 */
	public static boolean fileHasAnyReservedComponents(File file) {
		File temp = file;
		while (temp != null) {
			if (fileNameIsReserved(temp.getName())) {
				return true;
			}
			temp = temp.getParentFile();
		}
		return false;
	}


	// ********** shortened file names **********

	/**
	 * Return a shorter version of the absolute file name for the specified file.
	 * The shorter version will not be longer than the maximum length.
	 * The first directory (usually the drive letter) and the file name or the
	 * last directory will always be added to the generated string regardless of
	 * the maximum length allowed.
	 */
	public static String shortenFileName(URL url) {
		return shortenFileName(url, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
	}

	/**
	 * Return a shorter version of the absolute file name for the specified file.
	 * The shorter version will not be longer than the maximum length.
	 * The first directory (usually the drive letter) and the file name or the
	 * last directory will always be added to the generated string regardless of
	 * the maximum length allowed.
	 */
	public static String shortenFileName(URL url, int maxLength) {
		File file;
		try {
			file = buildFile(url);
		} catch (URISyntaxException e) {
			file = new File(url.getFile());
		}
		return shortenFileName(file, maxLength);
	}

	/**
	 * Return a shorter version of the absolute file name for the specified file.
	 * The shorter version will not be longer than the maximum length.
	 * The first directory (usually the drive letter) and the file name or the
	 * last directory will always be added to the generated string regardless of
	 * the maximum length allowed.
	 */
	public static String shortenFileName(File file) {
		return shortenFileName(file, MAXIMUM_SHORTENED_FILE_NAME_LENGTH);
	}

	/**
	 * Return a shorter version of the absolute file name for the specified file.
	 * The shorter version will not be longer than the maximum length.
	 * The first directory (usually the drive letter) and the file name or the
	 * last directory will always be added to the generated string regardless of
	 * the maximum length allowed.
	 */
	public static String shortenFileName(File file, int maxLength) {
		String absoluteFileName = canonicalFile(file).getAbsolutePath();
		if (absoluteFileName.length() <= maxLength) {
			// no need to shorten
			return absoluteFileName;
		}

		// break down the path into its components
		String fs = File.separator;
		String[] paths = absoluteFileName.split('\\' + fs);

		if (paths.length <= 1) {
			// e.g. "C:\"
			return paths[0];
		}

		if (paths.length == 2) {
			// e.g. "C:\MyReallyLongFileName.ext" or "C:\MyReallyLongDirectoryName"
			// return the complete file name since this is a minimum requirement,
			// regardless of the maximum length allowed
			return absoluteFileName;
		}

		StringBuilder sb = new StringBuilder();
		sb.append(paths[0]);		// always add the first directory, which is usually the drive letter

		// Keep the index of insertion into the string buffer
		int insertIndex = sb.length();

		sb.append(fs);
		sb.append(paths[paths.length - 1]);		// append the file name or the last directory

		maxLength -= 4;                      // -4 for "/..."

		int currentLength = sb.length() - 4; // -4 for "/..."
		int leftIndex = 1;                   //  1 to skip the root directory
		int rightIndex = paths.length - 2;   // -1 for the file name or the last directory

		boolean canAddFromLeft = true;
		boolean canAddFromRight = true;

		// Add each directory, the insertion is going in both direction: left and
		// right, once a side can't be added, the other side is still continuing
		// until both can't add anymore
		while (true) {
			if (!canAddFromLeft && !canAddFromRight)
				break;

			if (canAddFromRight) {
				String rightDirectory = paths[rightIndex];
				int rightLength = rightDirectory.length();

				// Add the directory on the right side of the loop
				if (currentLength + rightLength + 1 <= maxLength) {
					sb.insert(insertIndex,     fs);
					sb.insert(insertIndex + 1, rightDirectory);

					currentLength += rightLength + 1;
					rightIndex--;

					// The right side is now overlapping the left side, that means
					// we can't add from the right side anymore
					if (leftIndex >= rightIndex) {
						canAddFromRight = false;
					}
				} else {
					canAddFromRight = false;
				}
			}

			if (canAddFromLeft) {
				String leftDirectory = paths[leftIndex];
				int leftLength = leftDirectory.length();

				// Add the directory on the left side of the loop
				if (currentLength + leftLength + 1 <= maxLength) {
					sb.insert(insertIndex,     fs);
					sb.insert(insertIndex + 1, leftDirectory);

					insertIndex += leftLength + 1;
					currentLength += leftLength + 1;
					leftIndex++;

					// The left side is now overlapping the right side, that means
					// we can't add from the left side anymore
					if (leftIndex >= rightIndex) {
						canAddFromLeft = false;
					}
				} else {
					canAddFromLeft = false;
				}
			}
		}

		if (leftIndex <= rightIndex) {
			sb.insert(insertIndex, fs);
			sb.insert(insertIndex + 1, "..."); //$NON-NLS-1$
		}

		return sb.toString();
	}


	// ********** system properties **********

	/**
	 * Return a file representing the user's home directory.
	 */
	public static File userHomeDirectory() {
		return new File(USER_HOME_DIRECTORY_NAME);
	}
	
	/**
	 * Return a file representing the user's temporary directory.
	 */
	public static File userTemporaryDirectory() {
		return new File(USER_TEMPORARY_DIRECTORY_NAME);
	}
	
	/**
	 * Return a file representing the current working directory.
	 */
	public static File currentWorkingDirectory() {
		return new File(CURRENT_WORKING_DIRECTORY_NAME);
	}
	

	// ********** miscellaneous **********

	/**
	 * Return only the files that fit the filter.
	 * File#files(FileFilter fileFilter)
	 */
	public static Iterator<File> filter(Iterator<File> files, final FileFilter fileFilter) {
		return new FilteringIterator<File>(files) {
			@Override
			protected boolean accept(File next) {
				return fileFilter.accept(next);
			}
		};
	}

	/**
	 * Return a file that is a re-specification of the specified
	 * file, relative to the specified directory.
	 *     Linux/Unix/Mac:
	 *         convertToRelativeFile(/foo/bar/baz.java, /foo)
	 *             => bar/baz.java
	 *     Windows:
	 *         convertToRelativeFile(C:\foo\bar\baz.java, C:\foo)
	 *             => bar/baz.java
	 * The file can be either a file or a directory; the directory
	 * *should* be a directory.
	 * If the file is already relative or it cannot be made relative
	 * to the directory, it will be returned unchanged.
	 * 
	 * NB: This method has been tested on Windows and Linux,
	 * but not Mac (but the Mac is Unix-based these days, so
	 * it shouldn't be a problem...).
	 */
	public static File convertToRelativeFile(final File file, final File dir) {
		// check whether the file is already relative
		if ( ! file.isAbsolute()) {
			return file;		// return unchanged
		}

		File cFile = canonicalFile(file);
		File cDir = canonicalFile(dir);

		// the two are the same directory
		if (cFile.equals(cDir)) {
			return new File("."); //$NON-NLS-1$
		}

		File[] filePathFiles = pathFiles(cFile);
		File[] dirPathFiles = pathFiles(cDir);

		// Windows only (?): the roots are different - e.g. D:\ vs. C:\
		if ( ! dirPathFiles[0].equals(filePathFiles[0])) {
			return file;		// return unchanged
		}

		// at this point we know the root is the same, now find how much is in common
		int i = 0;		// this will point at the first miscompare
		while ((i < dirPathFiles.length) && (i < filePathFiles.length)) {
			if (dirPathFiles[i].equals(filePathFiles[i])) {
				i++;
			} else {
				break;
			}
		}
		// save our current position
		int firstMismatch = i;

		// check whether the file is ABOVE the directory: ../..
		if (firstMismatch == filePathFiles.length) {
			return relativeParentFile(dirPathFiles.length - firstMismatch);
		}

		// build a new file from the path beyond the matching portions
		File diff = new File(filePathFiles[i].getName());
		while (++i < filePathFiles.length) {
			diff = new File(diff, filePathFiles[i].getName());
		}

		// check whether the file is BELOW the directory: subdir1/subdir2/file.ext
		if (firstMismatch == dirPathFiles.length) {
			return diff;
		}

		// the file must be a PEER of the directory: ../../subdir1/subdir2/file.ext
		return new File(relativeParentFile(dirPathFiles.length - firstMismatch), diff.getPath());
	}

	/**
	 * Return a file that is a re-specification of the specified
	 * file, relative to the current working directory.
	 *     Linux/Unix/Mac (CWD = /foo):
	 *         convertToRelativeFile(/foo/bar/baz.java)
	 *             => bar/baz.java
	 *     Windows (CWD = C:\foo):
	 *         convertToRelativeFile(C:\foo\bar\baz.java)
	 *             => bar/baz.java
	 * The file can be either a file or a directory.
	 * If the file is already relative or it cannot be made relative
	 * to the directory, it will be returned unchanged.
	 * 
	 * NB: This method has been tested on Windows and Linux,
	 * but not Mac (but the Mac is Unix-based these days, so
	 * it shouldn't be a problem...).
	 */
	public static File convertToRelativeFile(final File file) {
		return convertToRelativeFile(file, currentWorkingDirectory());
	}

	/**
	 * Return an array of files representing the path to the specified
	 * file. For example:
	 *     C:/foo/bar/baz.txt =>
	 *     { C:/, C:/foo, C:/foo/bar, C:/foo/bar/baz.txt }
	 */
	private static File[] pathFiles(File file) {
		List<File> path = new ArrayList<File>();
		for (File f = file; f != null; f = f.getParentFile()) {
			path.add(f);
		}
		Collections.reverse(path);
		return path.toArray(new File[path.size()]);
	}

	/**
	 * Return a file with the specified (non-zero) number of relative
	 * file names, e.g. xxx(3) => ../../..
	 */
	private static File relativeParentFile(int len) {
		if (len <= 0) {
			throw new IllegalArgumentException("length must be greater than zero: " + len); //$NON-NLS-1$
		}
		File result = new File(".."); //$NON-NLS-1$
		for (int i = len - 1; i-- > 0; ) {
			result = new File(result, ".."); //$NON-NLS-1$
		}
		return result;
	}

	/**
	 * Return a file that is a re-specification of the specified
	 * file, absolute to the specified directory.
	 *     Linux/Unix/Mac:
	 *         convertToAbsoluteFile(bar/baz.java, /foo)
	 *             => /foo/bar/baz.java
	 *     Windows:
	 *         convertToAbsoluteFile(bar/baz.java, C:\foo)
	 *             => C:\foo\bar\baz.java
	 * The file can be either a file or a directory; the directory
	 * *should* be a directory.
	 * If the file is already absolute, it will be returned unchanged.
	 * 
	 * NB: This method has been tested on Windows and Linux,
	 * but not Mac (but the Mac is Unix-based these days, so
	 * it shouldn't be a problem...).
	 */
	public static File convertToAbsoluteFile(final File file, final File dir) {
		// check whether the file is already absolute
		if (file.isAbsolute()) {
			return file;		// return unchanged
		}
		return canonicalFile(new File(dir, file.getPath()));
	}

	/**
	 * Return a file that is a re-specification of the specified
	 * file, absolute to the current working directory.
	 *     Linux/Unix/Mac (CWD = /foo):
	 *         convertToAbsoluteFile(bar/baz.java)
	 *             => /foo/bar/baz.java
	 *     Windows (CWD = C:\foo):
	 *         convertToAbsoluteFile(bar/baz.java)
	 *             => C:\foo\bar\baz.java
	 * The file can be either a file or a directory.
	 * If the file is already absolute, it will be returned unchanged.
	 * 
	 * NB: This method has been tested on Windows and Linux,
	 * but not Mac (but the Mac is Unix-based these days, so
	 * it shouldn't be a problem...).
	 */
	public static File convertToAbsoluteFile(final File file) {
		return convertToAbsoluteFile(file, currentWorkingDirectory());
	}


	// ********** constructor **********

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private FileTools() {
		super();
		throw new UnsupportedOperationException();
	}

}
