//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.epf.common.CommonPlugin;

/**
 * Utility class for managing directories and files.
 * 
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 */
public class FileUtil {

	/**
	 * Platform-specific line separator.
	 */
	public static final String LINE_SEP = System.getProperty("line.separator"); //$NON-NLS-1$

	/**
	 * Platform-specific file separator.
	 */
	public static final String FILE_SEP = System.getProperty("file.separator"); //$NON-NLS-1$

	/**
	 * Platform-specific line separator length.
	 */
	public static final int LINE_SEP_LENGTH = LINE_SEP.length();

	/**
	 * UNC path prefix.
	 */
	public static final String UNC_PATH_PREFIX = "\\\\"; //$NON-NLS-1$

	/**
	 * UNC path prefix length.
	 */
	public static final int UNC_PATH_PREFIX_LENGTH = UNC_PATH_PREFIX.length();

	/**
	 * ISO-8859-1 encoding.
	 */
	public static final String ENCODING_ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$

	/**
	 * UTF-8 encoding.
	 */
	public static final String ENCODING_UTF_8 = "UTF-8";//$NON-NLS-1$
	
	private static Map<File, File> copiedFileMap;

	/**
	 * Private constructor to prevent this class from being instantiated. All
	 * methods in this class should be static.
	 */
	private FileUtil() {
	}

	/**
	 * Returns the absolute path for a file or directory.
	 * 
	 * @param file
	 *            a file or directory
	 * @return the absolute path to the file or directory
	 */
	public static String getAbsolutePath(File file) {
		return file.getAbsolutePath().replace('\\', '/');
	}

	/**
	 * Returns the absolute path for a file or directory.
	 * 
	 * @param path
	 *            a path to a file or directory
	 * @return an absolute path to the file or directory
	 */
	public static String getAbsolutePath(String path) {
		return getAbsolutePath(new File(path));
	}

	/**
	 * Returns the absolute path for a URL.
	 * 
	 * @param url
	 *            a URL
	 * @return the absolute path of the URL
	 */
	public static String getAbsolutePath(URL url) {
		String pathName = url.getFile().substring(1);
		String result = NetUtil.decodeUrl(pathName, null);
		return result;
	}

	/**
	 * Returns the parent directory of a path.
	 * 
	 * @param path
	 *            a path name
	 * @return the name of the parent directory
	 */
	public static String getParentDirectory(String path) {
		return (new File(path)).getParent();
	}

	/**
	 * Returns the file name and extension from a path.
	 * 
	 * @param path
	 *            a path name
	 * @return the file name including the file extension
	 */
	public static String getFileName(String path) {
		return getFileName(path, true);
	}

	/**
	 * Returns the file name from a path, with or without the file extension.
	 * 
	 * @param path
	 *            a path name
	 * @param withExtension
	 *            if <code>true</code>, include the file extension in the
	 *            result
	 * @return the file name with or without the file extension
	 */
	public static String getFileName(String path, boolean withExtension) {
		String normalizedPath = path.replace('\\', '/');

		int prefixLength = 0;
		if (normalizedPath.startsWith(NetUtil.FILE_URI_PREFIX)) {
			prefixLength = NetUtil.FILE_URI_PREFIX_LENGTH;
		} else if (normalizedPath.startsWith(NetUtil.HTTP_URI_PREFIX)) {
			prefixLength = NetUtil.HTTP_URI_PREFIX_LENGTH;
		}

		String fileName;
		int index = normalizedPath.lastIndexOf("/"); //$NON-NLS-1$
		if (index < prefixLength) {
			fileName = normalizedPath.substring(prefixLength);
		} else {
			fileName = path.substring(index + 1);
		}

		if (withExtension) {
			return fileName;
		}

		index = fileName.indexOf("."); //$NON-NLS-1$
		return (index > 0) ? fileName.substring(0, index) : fileName;
	}

	/**
	 * Returns the relative path of a path from a base path.
	 * 
	 * @param path
	 *            a path
	 * @param basePath
	 *            the base path
	 * @return a relative path
	 */
	public static String getRelativePathToBase(File path, File basePath) {
		try {
			String dir = path.toURL().toExternalForm();
			String baseDir = basePath.toURL().toExternalForm();
			StringBuffer result = new StringBuffer();
			if (dir.indexOf(baseDir) == 0) {
				String delta = dir.substring(baseDir.length());
				for (int i = 0; i < delta.length(); i++) {
					if (delta.charAt(i) == '/') {
						result.append("../"); //$NON-NLS-1$
					}
				}
			}
			return result.toString();
		} catch (Exception e) {
			return ""; //$NON-NLS-1$
		}
	}

	public static String getRelativePath(File path, File basePath) {
		try {
			String dir = path.toURL().toExternalForm();
			String baseDir = appendSeparator(basePath.toURL().toExternalForm(),
					"/"); //$NON-NLS-1$
			StringBuffer result = new StringBuffer();
			while (dir.indexOf(baseDir) == -1) {
				basePath = basePath.getParentFile();
				baseDir = appendSeparator(basePath.toURL().toExternalForm(),
						"/"); //$NON-NLS-1$
				result.append("../"); //$NON-NLS-1$
			}
			if (dir.indexOf(baseDir) == 0) {
				String delta = dir.substring(baseDir.length());
				result.append(delta);
			}
			return result.toString();
		} catch (Exception e) {
			return ""; //$NON-NLS-1$
		}
	}

	/**
	 * Appends the platform specific path separator to the end of a path.
	 * 
	 * @param path
	 *            a path name
	 * @return the path name appended with the platform specific path separator
	 */
	public static String appendSeparator(String path) {
		return appendSeparator(path, File.separator);
	}

	/**
	 * Appends the given path separator to the end of a path
	 * 
	 * @param path
	 *            a path name
	 * @param separator
	 *            a path separator
	 * @return the path name appended with the given separator
	 */
	public static String appendSeparator(String path, String separator) {
		return path.endsWith(separator) ? path : path + separator;
	}

	/**
	 * Removes the ending path separator from a path.
	 * 
	 * @param path
	 *            a path name
	 * @return the path name minus the platform specific path separator
	 */
	public static String removeSeparator(String path) {
		return path.endsWith(File.separator) ? path.substring(0,
				path.length() - 1) : path;
	}

	/**
	 * Removes the ending path separator from a path.
	 * 
	 * @param path
	 *            a path name
	 * @return the path name minus the path separator "\\" or "/"
	 */
	public static String removeAllSeparator(String path) {
		return path.endsWith("/") || path.endsWith("\\") ? path.substring(0, path.length() - 1) : path; //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Removes the ending path separator from a path.
	 * 
	 * @param path
	 *            a path name
	 * @param separator
	 *            a path separator
	 * @return the path name minus the separator
	 */
	public static String removeSeparator(String path, String separator) {
		return path.endsWith(separator) ? path.substring(0, path.length() - 1)
				: path;
	}

	/**
	 * Replaces the file name with another in a path.
	 * 
	 * @param path
	 *            a path name
	 * @param oldFileName
	 *            the old file name
	 * @param newFileName
	 *            the new file name
	 * @return the new path name with the new file name
	 */
	public static String replaceFileName(String path, String oldFileName,
			String newFileName) {
		int index = path.lastIndexOf(oldFileName);
		return path.substring(0, index) + newFileName;
	}

	/**
	 * Replaces the file extension with another in a path.
	 * 
	 * @param path
	 *            a path name
	 * @param oldFileExt
	 *            rhe old file extension
	 * @param newFileExt
	 *            the new file extension
	 * @return the new path with the new file extension
	 */
	public static String replaceExtension(String path, String oldExt,
			String newExt) {
		int index = path.lastIndexOf(oldExt);
		return path.substring(0, index) + newExt;
	}

	/**
	 * Returns the locale-specific path of a base path.
	 * 
	 * @param path
	 *            a base path name
	 * @param localeStr
	 *            a locale string
	 * @return the locale-specific path
	 */
	public static String getLocalePath(String path, String localeStr) {
		if (StrUtil.isBlank(localeStr)) {
			return path;
		}
		String fileName = getFileName(path);
		return replaceFileName(path, fileName, localeStr + "/" + fileName); //$NON-NLS-1$
	}

	/**
	 * Returns the locale-specific path of a base path.
	 * 
	 * @param path
	 *            a base path name
	 * @param locale
	 *            a locale object
	 * @return the locale-specific path
	 */
	public static String getLocalePath(String path, Locale locale) {
		return locale == null ? path : getLocalePath(path, locale.toString());
	}

	/**
	 * Writes the given text to a text file.
	 * 
	 * @param fileName
	 *            the target file name
	 * @param text
	 *            the text to write
	 * @return <code>true</code> if the given text is written successfully to
	 *         file
	 */
	public static boolean writeFile(String filename, String text) {
		FileWriter writer = null;
		try {
			writer = new FileWriter(filename);
			writer.write(text);
			writer.flush();
		} catch (IOException e) {
		} finally {
			if (writer != null) {
				try {
					writer.close();
					return true;
				} catch (Exception e) {
				}
			}
		}
		return false;
	}

	/**
	 * Write the given text to a file with UTF-8 encoding.
	 * 
	 * @param fileName
	 *            the target file name
	 * @param text
	 *            the text to write
	 * @param append
	 *            if <code>true</code>, append the text to the end of the
	 *            file, if <code>false</code>, override the file
	 * @return <code>true</code> if the given text is written successfully to
	 *         file
	 */
	public static boolean writeUTF8File(String filename, String text) {
		return writeUTF8File(filename, text, false);
	}

	/**
	 * Write the given text to a file with UTF-8 encoding.
	 * 
	 * @param fileName
	 *            the target file name
	 * @param text
	 *            the text to write
	 * @param append
	 *            if <code>true</code>, append the text to the end of the
	 *            file, if <code>false</code>, override the file
	 * @return <code>true</code> if the given text is written successfully to
	 *         file
	 */
	public static boolean writeUTF8File(String filename, String text,
			boolean append) {
		OutputStreamWriter writer = null;
		FileOutputStream fileOut = null;
		try {
			fileOut = new FileOutputStream(filename, append);
			writer = new OutputStreamWriter(fileOut, ENCODING_UTF_8);
			writer.write(text);
			writer.flush();
			fileOut.flush();
		} catch (IOException e) {
			CommonPlugin.getDefault().getLogger().logError(e);
		} finally {
			if (writer != null) {
				try {
					writer.close();
					return true;
				} catch (Exception e) {
				}
			}
			if (fileOut != null) {
				try {
					fileOut.close();
					return true;
				} catch (Exception e) {
				}
			}
		}
		return false;
	}

	/**
	 * Write the content of the given URI to an output stream.
	 * 
	 * @param uri
	 *            the source URI
	 * @param output
	 *            the output stream
	 */
	public static void writeFile(String uri, OutputStream output)
			throws IOException {
		if (uri == null) {
			return;
		}

		InputStream input = null;
		try {
			input = NetUtil.getInputStream(uri);
			int bytesRead;
			byte[] buf = new byte[4096];
			while ((bytesRead = input.read(buf, 0, 4096)) > 0) {
				output.write(buf, 0, bytesRead);
			}
			output.flush();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (Exception e) {
				}
			}
		}
	}

	/**
	 * Write the content of the given URI to a <code>PrintWriter</code>.
	 * 
	 * @param uri
	 *            the source URI
	 * @param writer
	 *            the <code>PrintWriter</code> object
	 */
	public static void writeFile(String uri, PrintWriter pw) throws IOException {
		if (uri == null) {
			return;
		}

		InputStreamReader input = null;
		try {
			input = new InputStreamReader(NetUtil.getInputStream(uri));
			int charsRead;
			char[] buf = new char[4096];
			while ((charsRead = input.read(buf, 0, 4096)) > 0) {
				pw.write(buf, 0, charsRead);
			}
			pw.flush();
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (Exception e) {
				}
			}
		}
	}

	/**
	 * Recursively delete all sub-directories and files in a directory except
	 * for the directory itself.
	 * 
	 * @param dir
	 *            the directory containing the sub-directories and files
	 * @return <code>true</code> if the delete operation is successful
	 */
	public static boolean deleteAllFiles(String dir) {
		boolean ret = true;
		File targetDir = new File(dir);
		File[] files = targetDir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					ret = ret && deleteAllFiles(files[i].getAbsolutePath());
				}
				ret = ret && files[i].delete();
			}
		}

		return ret;
	}

	/**
	 * Recursively delete all sub-directories and files in a directory except
	 * for the directory itself and the specified file.
	 * 
	 * @param dir
	 *            the directory containing the sub-directories and files
	 * @param filesNotToDelete
	 *            a list of files and/or directories that should not be deleted
	 * @return <code>true</code> if delete operation is successful
	 */
	public static boolean deleteAllFiles(String dir, List<File> filesNotToDelete) {
		boolean ret = true;
		File targetDir = new File(dir);
		File[] files = targetDir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (!filesNotToDelete.contains(files[i])) {
					if (files[i].isDirectory()) {
						ret = ret
								&& deleteAllFiles(files[i].getAbsolutePath(),
										filesNotToDelete);
					}
					ret = ret && files[i].delete();
				}
			}
		}

		return ret;
	}

	/**
	 * Copies the content of the source file to the target file. Will overwrite
	 * an existing file if it has write permission
	 * 
	 * @param srcFile
	 *            the source file or path
	 * @param tgtFile
	 *            the target file or path
	 */
	public static boolean copyFile(File srcFile, File tgtFile) {
		Map<File, File> map = getCopiedFileMap();
		File keyFile = null;
		File valFile = null;
		if (map != null) {
			try {
				keyFile = tgtFile.getCanonicalFile();
				valFile = srcFile.getCanonicalFile();
				if (valFile.equals(map.get(keyFile))) {
					return true;
				}
			} catch (Exception e) {
				keyFile = valFile = null;
			}			
		}
				
		try {
			boolean ret = copyfile(srcFile, tgtFile);
			if (map != null && keyFile != null && valFile != null) {
				map.put(keyFile, valFile);
			}
			return ret;
		} catch (IOException ex) {
			CommonPlugin.getDefault().getLogger().logError(ex);
			return false;
		}
	}

	/**
	 * Copies the content of the source file to the target file.
	 * 
	 * @param srcFileName
	 *            the source file name
	 * @param tgtFileName
	 *            the target file name
	 */
	public static boolean copyFile(String srcFileName, String tgtFileName) {
		return copyFile(new File(srcFileName), new File(tgtFileName));
	}

	/**
	 * Copies one file to another.
	 * <p>
	 * If both source and destination are directories, delegates to
	 * copydirectory().
	 * <p>
	 * source must exist and be readable
	 * <p>
	 * cannot copy a directory to a file
	 * <p>
	 * will not copy if timestamps and filesize match, will overwrite otherwise
	 * 
	 * @param source
	 *            the source file
	 * @param dest
	 *            the destination file
	 * @throws IOException
	 *             if an error occurs during the copy operation
	 */
	private static boolean copyfile(File source, File dest) throws IOException {
		if (source.equals(dest))
			// do not copy equal files
			return false;

		if (!source.exists() || !source.canRead()) {
			// source does not exist or can't read
			return false;
		}

		if (dest.exists() && !dest.canWrite()) {
			// dest exists and cannot be written
			return false;
		}

		if (source.isDirectory()) {
			if (dest.isFile()) {
				// can't copy a directory to a file
				return false;
			} else {
				// delegate to copydirectory
				return copydirectory(source, dest);
			}
		} else {
			// source is a file
			if (dest.isDirectory()) {
				String sourceFileName = source.getName();
				return copyfile(source, new File(dest, sourceFileName));
			}
			// both source and dest are files
			boolean needCopy = true;
			if (dest.exists()) {
				needCopy = (dest.lastModified() != source.lastModified())
						|| (dest.length() != source.length());
			}

			if (needCopy) {
				FileInputStream input = null;
				FileOutputStream output = null;

				try {
					input = new FileInputStream(source);
					FileChannel in = input.getChannel();
					if (!dest.exists()) {
						dest.getParentFile().mkdirs();
					}
					output = new FileOutputStream(dest);
					FileChannel out = output.getChannel();
					out.transferFrom(in, 0, source.length());
					dest.setLastModified(source.lastModified());
					return true;
				} finally {
					if (input != null) {
						try {
							input.close();
						} catch (IOException e) {
						}
					}
					if (output != null) {
						try {
							output.close();
						} catch (IOException e) {
						}
					}
				}
			} else {
				// did not copy
				// return true because dest file is same as source
				return true;
			}
		}
	}

	/**
	 * Copies the content of a directory to another directory.
	 * 
	 * @param srcDirName
	 *            the source directory name
	 * @param tgtDirName
	 *            the target directory name
	 */
	public static boolean copyDir(File srcDir, File tgtDir) {
		try {
			return copydirectory(srcDir, tgtDir);
		} catch (IOException ex) {
			CommonPlugin.getDefault().getLogger().logError(ex);
			return false;
		}
	}

	/**
	 * Copies the content of a directory to another directory.
	 * 
	 * @param srcDirName
	 *            the source directory name
	 * @param tgtDirName
	 *            the target directory name
	 */
	public static boolean copyDir(String srcDirName, String tgtDirName) {
		return copyDir(new File(srcDirName), new File(tgtDirName));
	}

	/**
	 * Copies one directory to another - operates ONLY on directories.
	 * <p>
	 * Both source and dest must exist.
	 */
	private static boolean copydirectory(File sourceDir, File destDir)
			throws IOException {
		if (!sourceDir.exists() || !destDir.exists()) {
			return false;
		}

		if (!sourceDir.isDirectory() || !destDir.isDirectory()) {
			return false;
		}

		File[] files = sourceDir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				// calc destination name
				String destName = destDir
						+ File.separator
						+ files[i].getAbsolutePath().substring(
								sourceDir.getAbsolutePath().length() + 1);
				if (files[i].isFile()) {
					// copy the file
					copyfile(files[i], new File(destName));
				} else if (files[i].isDirectory()) {
					// copy directory recursively
					File destFile = new File(destName);
					destFile.mkdirs();
					copydirectory(files[i], destFile);
				}
			}
		}
		return true;
	}

	// for some reason, this guy locks the file, if you try to update the file,
	// got the following exception
	// java.io.FileNotFoundException:
	// (The requested operation cannot be performed on a file with a user-mapped
	// section open)
	// need to handle later
	public static CharBuffer readFile(File file) throws IOException {
		FileInputStream input = null;
		CharBuffer charBuffer = null;
		try {
			input = new FileInputStream(file);
			FileChannel inChannel = input.getChannel();
			int length = (int) inChannel.size();
			MappedByteBuffer byteBuffer = inChannel.map(
					FileChannel.MapMode.READ_ONLY, 0, length);
			Charset charset = Charset.forName(ENCODING_ISO_8859_1);
			CharsetDecoder decoder = charset.newDecoder();
			charBuffer = decoder.decode(byteBuffer);
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
				}
			}
		}
		return charBuffer;
	}

	public static String readInputStream(InputStream input) throws IOException {
		String result = "";  //$NON-NLS-1$
		byte[] readData = new byte[8 * 1024];
		try {
			int bytesRead = 0;
			while ( (bytesRead = input.read(readData)) > 0) {
				result += new String(readData, 0, bytesRead);
			}
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
				}
			}
		}
		return result;
	}

	public static StringBuffer readFile(File file, String encoding)
			throws IOException {

		StringBuffer result = new StringBuffer();
		FileInputStream fis = null;
		InputStreamReader reader = null;
		int size;
		try {
			Charset cs = Charset.forName(encoding);
			CharsetDecoder csd = cs.newDecoder();
			csd.onMalformedInput(CodingErrorAction.REPLACE);
			char[] buffer = new char[1024];
			fis = new FileInputStream(file);
			reader = new InputStreamReader(fis, csd);
			while ((size = reader.read(buffer, 0, 1024)) > 0) {
				result.append(buffer, 0, size);
			}
		} catch (Exception e) {
			// System.out.println(encoding);
			e.printStackTrace();
		} finally {
			if (fis != null) {
				fis.close();
			}

			if (reader != null) {
				reader.close();
			}
		}

		return result;
	}
	
	public static long getSize(File file) {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(file);
			return fis.getChannel().size();			
		}
		catch (IOException e) {
			//
		}
		finally {
			try {
				fis.close();
			}
			catch(Exception e) {
				//
			}
		}
		return -1;
	}

	/**
	 * Uses Java 1.4's FileLock class to test for a file lock
	 * 
	 * @param file
	 * @return
	 */
	public static boolean isFileLocked(File file) {
		boolean isLocked = false;
		FileOutputStream input = null;
		FileLock lock = null;

		if (!file.exists()) {
			return false;
		}
		try {
			input = new FileOutputStream(file);
			FileChannel fileChannel = input.getChannel();

			lock = fileChannel.tryLock();

			if (lock == null)
				isLocked = true;
			else
				lock.release();
		} catch (Exception e) {
			if (e instanceof SecurityException)
				// Can't write to file.
				isLocked = true;
			else if (e instanceof FileNotFoundException)
				isLocked = false;
			else if (e instanceof IOException)
				isLocked = true;
			// OverlappingFileLockException means that this JVM has it locked
			// therefore it is not locked to us
			else if (e instanceof OverlappingFileLockException)
				isLocked = false;
			// Could not get a lock for some other reason.
			else
				isLocked = true;
		} finally {
			if (input != null) {
				try {
					input.close();
				} catch (Exception ex) {
				}
			}
		}
		return isLocked;
	}

	/**
	 * Locks a file for the current JVM. Will create the file if it does not
	 * exist
	 * 
	 * @param file
	 * @return a FileLock object, or null if file could not be locked
	 */
	public static FileLock lockFile(File file) {
		FileOutputStream input = null;
		FileLock lock = null;
		try {
			input = new FileOutputStream(file);
			FileChannel fileChannel = input.getChannel();
			lock = fileChannel.tryLock();

			if (lock.isValid())
				return lock;
		} catch (Exception e) {
			// Could not get a lock for some reason.
			return null;
		} finally {
			try {
				if (input != null && (lock == null || !lock.isValid())) {
					input.close();
				}
			} catch (Exception ex) {
			}
		}
		return null;
	}

	/**
	 * Gets all files in a specified path.
	 * 
	 * @param path
	 *            absolute path of a folder
	 * @param fileList
	 *            a list to collect the files
	 * @param recursive
	 *            if <code>true</code>, find the files in sub folders as well
	 */
	public static void getAllFiles(File path, List<File> fileList,
			boolean recursive) {
		if (path.isDirectory()) {
			File[] files = path.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (files[i].isFile()) {
						fileList.add(files[i]);
					} else if (recursive) {
						getAllFiles(files[i], fileList, recursive);
					}
				}
			}
		}
	}

	/**
	 * Given a directory and extension, returns all files (recursively) whose
	 * extension starts with a given extension.
	 * 
	 * @param file
	 *            a directory
	 * @param extension
	 *            a file extension
	 * @return a colleciton of <code>File</code> with the given extension
	 */
	public static List<File> fileList(File f, String extension) {
		extension = extension.toUpperCase();
		List<File> returnList = new ArrayList<File>();
		try {
			if (f.isDirectory()) {
				String[] flist = f.list();
				for (int i = 0; i < flist.length; ++i) {
					File fc = new File(f.getPath(), flist[i]);
					returnList.addAll(fileList(fc, extension));
				}
			} else {
				if (extension != null) {
					String name = f.getName().toUpperCase();
					if (name.lastIndexOf(".") != -1) //$NON-NLS-1$
						if (name
								.substring(name.lastIndexOf(".") + 1).startsWith(extension)) { //$NON-NLS-1$
							returnList.add(f);
						}
				} else
					returnList.add(f);
			}
		} catch (Exception e) {
			CommonPlugin.getDefault().getLogger().logError(e);
		}
		return returnList;
	}

	/**
	 * Given a directory and extension, returns all files (recursively) whose
	 * extension does not starts with a given extension.
	 * 
	 * @param file
	 *            a directory
	 * @param extension
	 *            a file extension
	 * @return a colleciton of <code>File</code> without the given extension
	 */
	public static List<File> fileListExcludeExt(File f, String extension) {
		List<File> returnList = new ArrayList<File>();
		try {
			if (f.isDirectory()) {
				String[] flist = f.list();
				for (int i = 0; i < flist.length; ++i) {
					File fc = new File(f.getPath(), flist[i]);
					returnList.addAll(fileListExcludeExt(fc, extension));
				}
			} else {
				if (extension != null) {
					String name = f.getName();
					if (name.lastIndexOf(".") != -1) //$NON-NLS-1$
						if (!(name.substring(name.lastIndexOf(".") + 1).startsWith(extension))) { //$NON-NLS-1$
							returnList.add(f);
						}
				} else
					returnList.add(f);
			}
		} catch (Exception e) {
			CommonPlugin.getDefault().getLogger().logError(e);
		}
		return returnList;
	}

	/**
	 * Gets all file paths in the specified path.
	 * 
	 * @param path,
	 *            absolute path of a folder
	 * @param recursive
	 *            if <code>true</code>, find the files in sub folders as well
	 */
	public static ArrayList<String> getAllFileAbsolutePaths(File path,
			boolean recursive) {
		ArrayList<File> files = new ArrayList<File>();
		getAllFiles(path, files, recursive);
		ArrayList<String> paths = new ArrayList<String>();
		for (int i = 0; i < files.size(); i++) {
			String absPath = ((File) files.get(i)).getAbsolutePath();
			paths.add(absPath);
		}
		return paths;
	}

	/**
	 * Moves a file from a directory to another.
	 * <p>
	 * Attempts to rename the file first. If that fails, will copy the
	 * sourceFile to destFile and delete the sourceFile.
	 * 
	 * @param sourceFile
	 *            the source file
	 * @param destFile
	 *            the destination file
	 * @return
	 */
	public static boolean moveFile(File sourceFile, File destFile) {
		try {
			doMoveFile(sourceFile, destFile);
			return true;
		} catch (Exception e) {
			CommonPlugin.getDefault().getLogger().logError(e);
			return false;
		}
	}

	public static void doMoveFile(File sourceFile, File destFile) throws IOException {
		// Try to rename the source file to the destination file.
		if (!sourceFile.renameTo(destFile)) {
			// Try to copy the source file to the destination file and
			// delete
			// the source file.
			copyfile(sourceFile, destFile);
			sourceFile.delete();
		}
	}

	private static Map<File, File> getCopiedFileMap() {
		return copiedFileMap;
	}

	public static void setCopiedFileMap(Map<File, File> copiedFileMap) {
		FileUtil.copiedFileMap = copiedFileMap;
	}
}