//------------------------------------------------------------------------------
// 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.BufferedOutputStream;
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.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

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;
	}
	
	
	/**
	 * Unzips the contents of a zip file to a directory
	 * 
	 * @param zipfile
	 *            source zip file
	 * @param tgtDir
	 *            target directory
	 */
	public static boolean unzip(File srcZipFile, File tgtDir) {
		if (! srcZipFile.exists() || ! tgtDir.exists()) {
			return false;
		}

		if (! tgtDir.isDirectory()) {
			return false;
		}

		try {
			ZipFile zipFile = new ZipFile(srcZipFile);
			Enumeration entries = zipFile.entries();

			while (entries.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				
				File tgtFile = new File(tgtDir, entry.getName());

				if (entry.isDirectory() && ! tgtFile.exists()) {
					tgtFile.mkdirs();
					
				} else {
					File parentFolder = tgtFile.getParentFile();
					if (! parentFolder.exists()) {
						parentFolder.mkdirs();
					}
										
					copyInputStream(zipFile.getInputStream(entry),
							new BufferedOutputStream(new FileOutputStream(
									new File(tgtDir, entry.getName()))));
				}
			}

			zipFile.close();
		} catch (IOException ioe) {
			return false;
		}
		return false;
	}

	private static final void copyInputStream(InputStream in, OutputStream out)
			throws IOException {
		byte[] buffer = new byte[1024];
		int len;

		while ((len = in.read(buffer)) >= 0)
			out.write(buffer, 0, len);

		in.close();
		out.close();
	}
	
}