gt: 						return name.endsWith(".jar") & !name.endsWith("-src.jar");
context: /*******************************************************************************
   * Copyright (c) 2000, 2014 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 API and implementation
   *     Nina Rinskaya
   *     		Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=172820.
   *******************************************************************************/
  package org.eclipse.jdt.core.tests.util;
  
  import java.io.*;
  import java.net.ServerSocket;
  import java.util.*;
  import java.util.zip.*;
  
  import org.eclipse.core.resources.IContainer;
  import org.eclipse.core.resources.IResource;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.core.runtime.Status;
  import org.eclipse.jdt.core.JavaCore;
  import org.eclipse.jdt.core.compiler.CategorizedProblem;
  import org.eclipse.jdt.core.compiler.IProblem;
  import org.eclipse.jdt.internal.compiler.CompilationResult;
  import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
  import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
  import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public class Util {
  	// Trace for delete operation
  	/*
  	 * Maximum time wasted repeating delete operations while running JDT/Core tests.
  	 */
  	private static int DELETE_MAX_TIME = 0;
  	/**
  	 * Trace deletion operations while running JDT/Core tests.
  	 */
  	public static boolean DELETE_DEBUG = false;
  	/**
  	 * Maximum of time in ms to wait in deletion operation while running JDT/Core tests.
  	 * Default is 10 seconds. This number cannot exceed 1 minute (ie. 60000).
  	 * <br>
  	 * To avoid too many loops while waiting, the ten first ones are done waiting
  	 * 10ms before repeating, the ten loops after are done waiting 100ms and
  	 * the other loops are done waiting 1s...
  	 */
  	public static int DELETE_MAX_WAIT = 10000;
  
  	private static final boolean DEBUG = false;
  	/**
  	 * Initially, output directory was located in System.getProperty("java.io.tmpdir")+"\comptest".
  	 * To allow user to run several compiler tests at the same time, main output directory
  	 * is now located in a sub-directory of "comptest" which name is "run."+<code>System.currentMilliseconds</code>.
  	 *
  	 * @see #DELAY_BEFORE_CLEAN_PREVIOUS
  	 */
  	private final static String OUTPUT_DIRECTORY;
  	/**
  	 * Let user specify the delay in hours before output directories are removed from file system
  	 * while starting a new test run. Default value is 2 hours.
  	 * <p>
  	 * Note that this value may be a float and so have time less than one hour.
  	 * If value is 0 or negative, then all previous run directories will be removed...
  	 *
  	 * @see #OUTPUT_DIRECTORY
  	 */
  	private final static String DELAY_BEFORE_CLEAN_PREVIOUS = System.getProperty("delay");
  	/*
  	 * Static initializer to clean directories created while running previous test suites.
  	 */
  	static {
  		// Get delay for cleaning sub-directories
  		long millisecondsPerHour = 1000L * 3600L;
  		long delay = millisecondsPerHour * 2; // default is to keep previous run directories for 2 hours
  		try {
  			if (DELAY_BEFORE_CLEAN_PREVIOUS != null) {
  				float hours = Float.parseFloat(DELAY_BEFORE_CLEAN_PREVIOUS);
  				delay = (int) (millisecondsPerHour * hours);
  			}
  		}
  		catch (NumberFormatException nfe) {
  			// use default
  		}
  
  		// Get output directory root from system properties
  		String container = System.getProperty("jdt.test.output_directory");
  		if (container == null){
  			container = System.getProperty("java.io.tmpdir");
  		}
  		if (container == null) {
  			container = "."; // use current directory
  		}
  
  		// Get file for root directory
  		if (Character.isLowerCase(container.charAt(0)) && container.charAt(1) == ':') {
  			container = Character.toUpperCase(container.charAt(0)) + container.substring(1);
  		}
  		File dir = new File(new File(container), "comptest");
  
  		// If root directory already exists, clean it
  		if (dir.exists()) {
  			long now = System.currentTimeMillis();
  			if ((now - dir.lastModified()) > delay) {
  				// remove all directory content
  				flushDirectoryContent(dir);
  			} else {
  				// remove only old sub-dirs
  				File[] testDirs = dir.listFiles();
  				for (int i=0,l=testDirs.length; i<l; i++) {
  					if (testDirs[i].isDirectory()) {
  						if ((now - testDirs[i].lastModified()) > delay) {
  							delete(testDirs[i]);
  						}
  					}
  				}
  			}
  		}
  
  		// Computed test run directory name based on current time
  		File dateDir = new File(dir, "run."+System.currentTimeMillis());
  		String pathDir = null;
  		try {
  			pathDir = dateDir.getCanonicalPath();
  		} catch (IOException e) {
  			pathDir = dateDir.getAbsolutePath();
  		}
  		OUTPUT_DIRECTORY = pathDir;
  	}
  
  	public static void appendProblem(StringBuffer problems, IProblem problem, char[] source, int problemCount) {
  		problems.append(problemCount + (problem.isError() ? ". ERROR" : problem.isWarning() ? ". WARNING" : ". INFO"));
  		problems.append(" in " + new String(problem.getOriginatingFileName()));
  		if (source != null) {
  			problems.append(((DefaultProblem)problem).errorReportSource(source));
  		}
  		problems.append("\n");
  		problems.append(problem.getMessage());
  		problems.append("\n");
  	}
  
  	public static CompilationUnit[] compilationUnits(String[] testFiles) {
  		int length = testFiles.length / 2;
  		CompilationUnit[] result = new CompilationUnit[length];
  		int index = 0;
  		for (int i = 0; i < length; i++) {
  			result[i] = new CompilationUnit(testFiles[index + 1].toCharArray(), testFiles[index], null);
  			index += 2;
  		}
  		return result;
  	}
  	public static String[] concatWithClassLibs(String[] classpaths, boolean inFront) {
  		String[] classLibs = getJavaClassLibs();
  		if (classpaths == null) return classLibs;
  		final int classLibsLength = classLibs.length;
  		final int classpathsLength = classpaths.length;
  		String[] defaultClassPaths = new String[classLibsLength + classpathsLength];
  		if (inFront) {
  			System.arraycopy(classLibs, 0, defaultClassPaths, classpathsLength, classLibsLength);
  			System.arraycopy(classpaths, 0, defaultClassPaths, 0, classpathsLength);
  		} else {
  			System.arraycopy(classLibs, 0, defaultClassPaths, 0, classLibsLength);
  			System.arraycopy(classpaths, 0, defaultClassPaths, classLibsLength, classpathsLength);
  		}
  		for (int i = 0; i < classpathsLength; i++) {
  			File file = new File(classpaths[i]);
  			if (!file.exists()) {
  				file.mkdirs();
  			}
  		}
  		return defaultClassPaths;
  	}
  	public static String[] concatWithClassLibs(String classpath, boolean inFront) {
  		String[] classLibs = getJavaClassLibs();
  		final int length = classLibs.length;
  		File dir = new File(classpath);
  		if (!dir.exists())
  			dir.mkdirs();
  		String[] defaultClassPaths = new String[length + 1];
  		if (inFront) {
  			System.arraycopy(classLibs, 0, defaultClassPaths, 1, length);
  			defaultClassPaths[0] = classpath;
  		} else {
  			System.arraycopy(classLibs, 0, defaultClassPaths, 0, length);
  			defaultClassPaths[length] = classpath;
  		}
  		return defaultClassPaths;
  	}
  	public static String convertToIndependantLineDelimiter(String source) {
  		if (source == null) return "";
  		if (source.indexOf('\n') == -1 && source.indexOf('\r') == -1) return source;
  		StringBuffer buffer = new StringBuffer();
  		for (int i = 0, length = source.length(); i < length; i++) {
  			char car = source.charAt(i);
  			if (car == '\r') {
  				buffer.append('\n');
  				if (i < length-1 && source.charAt(i+1) == '\n') {
  					i++; // skip \n after \r
  				}
  			} else {
  				buffer.append(car);
  			}
  		}
  		return buffer.toString();
  	}
  	/**
  	 * Copy the given source (a file or a directory that must exists) to the given destination (a directory that must exists).
  	 */
  	public static void copy(String sourcePath, String destPath) {
  		sourcePath = toNativePath(sourcePath);
  		destPath = toNativePath(destPath);
  		File source = new File(sourcePath);
  		if (!source.exists()) return;
  		File dest = new File(destPath);
  		if (!dest.exists()) return;
  		if (source.isDirectory()) {
  			String[] files = source.list();
  			if (files != null) {
  				for (int i = 0; i < files.length; i++) {
  					String file = files[i];
  					File sourceFile = new File(source, file);
  					if (sourceFile.isDirectory()) {
  						File destSubDir = new File(dest, file);
  						destSubDir.mkdir();
  						copy(sourceFile.getPath(), destSubDir.getPath());
  					} else {
  						copy(sourceFile.getPath(), dest.getPath());
  					}
  				}
  			}
  		} else {
  			FileInputStream in = null;
  			FileOutputStream out = null;
  			try {
  				in = new FileInputStream(source);
  				File destFile = new File(dest, source.getName());
  				if (destFile.exists()) {
  					if (!Util.delete(destFile)) {
  						throw new IOException(destFile + " is in use");
  					}
  				}
  				out = new FileOutputStream(destFile);
  				int bufferLength = 1024;
  				byte[] buffer = new byte[bufferLength];
  				int read = 0;
  				while (read != -1) {
  					read = in.read(buffer, 0, bufferLength);
  					if (read != -1) {
  						out.write(buffer, 0, read);
  					}
  				}
  			} catch (IOException e) {
  				throw new Error(e.toString());
  			} finally {
  				if (in != null) {
  					try {
  						in.close();
  					} catch (IOException e) {
  					}
  				}
  				if (out != null) {
  					try {
  						out.close();
  					} catch (IOException e) {
  					}
  				}
  			}
  		}
  	}
  	public static void createFile(String path, String contents) throws IOException {
  		FileOutputStream output = new FileOutputStream(path);
  		try {
  			output.write(contents.getBytes());
  		} finally {
  			output.close();
  		}
  	}
  	public static void createSourceZip(String[] pathsAndContents, String zipPath) throws IOException {
  		String sourcesPath = getOutputDirectory() + File.separator + "sources";
  		createSourceDir(pathsAndContents, sourcesPath);
  		zip(new File(sourcesPath), zipPath);
  	}
  
  	public static void createSourceDir(String[] pathsAndContents, String sourcesPath) throws IOException {
  		flushDirectoryContent(new File(sourcesPath));
  		for (int i = 0, length = pathsAndContents.length; i < length; i+=2) {
  			String sourcePath = sourcesPath + File.separator + pathsAndContents[i];
  			File sourceFile = new File(sourcePath);
  			sourceFile.getParentFile().mkdirs();
  			createFile(sourcePath, pathsAndContents[i+1]);
  		}
  	}
  	/**
  	 * Delete a file or directory and insure that the file is no longer present
  	 * on file system. In case of directory, delete all the hierarchy underneath.
  	 *
  	 * @param file The file or directory to delete
  	 * @return true iff the file was really delete, false otherwise
  	 */
  	public static boolean delete(File file) {
  		// flush all directory content
  		if (file.isDirectory()) {
  			flushDirectoryContent(file);
  		}
  		// remove file
  		file.delete();
  		if (isFileDeleted(file)) {
  			return true;
  		}
  		return waitUntilFileDeleted(file);
  	}
  	/**
  	 * Delete a file or directory and insure that the file is no longer present
  	 * on file system. In case of directory, delete all the hierarchy underneath.
  	 *
  	 * @param resource The resource to delete
  	 * @return true iff the file was really delete, false otherwise
  	 */
  	public static IStatus delete(IResource resource) {
  		IStatus status = null;
  		try {
  			resource.delete(true, null);
  			if (isResourceDeleted(resource)) {
  				return Status.OK_STATUS;
  			}
  		} catch (CoreException e) {
  			status = e.getStatus();
  		}
  		boolean deleted = waitUntilResourceDeleted(resource);
  		if (deleted) {
  			return Status.OK_STATUS;
  		}
  		if (status != null) {
  			return status;
  		}
  		return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, "Cannot delete resource "+resource);
  	}
  	/**
  	 * Delete a file or directory and insure that the file is no longer present
  	 * on file system. In case of directory, delete all the hierarchy underneath.
  	 *
  	 * @param path The path of the file or directory to delete
  	 * @return true iff the file was really delete, false otherwise
  	 */
  	public static boolean delete(String path) {
  		return delete(new File(path));
  	}
  	/**
  	 * Generate a display string from the given String.
  	 * @param inputString the given input string
  	 *
  	 * Example of use: [org.eclipse.jdt.core.tests.util.Util.displayString("abc\ndef\tghi")]
  	 */
  	public static String displayString(String inputString){
  		return displayString(inputString, 0);
  	}
  	/**
  	 * Generate a display string from the given String.
  	 * It converts:
  	 * <ul>
  	 * <li>\t to \t</li>
  	 * <li>\r to \\r</li>
  	 * <li>\n to \n</li>
  	 * <li>\b to \\b</li>
  	 * <li>\f to \\f</li>
  	 * <li>\" to \\\"</li>
  	 * <li>\' to \\'</li>
  	 * <li>\\ to \\\\</li>
  	 * <li>All other characters are unchanged.</li>
  	 * </ul>
  	 * This method doesn't convert \r\n to \n.
  	 * <p>
  	 * Example of use:
  	 * <o>
  	 * <li>
  	 * <pre>
  	 * input string = "abc\ndef\tghi",
  	 * indent = 3
  	 * result = "\"\t\t\tabc\\n" +
  	 * 			"\t\t\tdef\tghi\""
  	 * </pre>
  	 * </li>
  	 * <li>
  	 * <pre>
  	 * input string = "abc\ndef\tghi\n",
  	 * indent = 3
  	 * result = "\"\t\t\tabc\\n" +
  	 * 			"\t\t\tdef\tghi\\n\""
  	 * </pre>
  	 * </li>
  	 * <li>
  	 * <pre>
  	 * input string = "abc\r\ndef\tghi\r\n",
  	 * indent = 3
  	 * result = "\"\t\t\tabc\\r\\n" +
  	 * 			"\t\t\tdef\tghi\\r\\n\""
  	 * </pre>
  	 * </li>
  	 * </ol>
  	 * </p>
  	 *
  	 * @param inputString the given input string
  	 * @param indent number of tabs are added at the begining of each line.
  	 *
  	 * @return the displayed string
  	 */
  	public static String displayString(String inputString, int indent) {
  		return displayString(inputString, indent, false);
  	}
  	public static String displayString(String inputString, int indent, boolean shift) {
  		if (inputString == null)
  			return "null";
  		int length = inputString.length();
  		StringBuffer buffer = new StringBuffer(length);
  		java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(inputString, "\n\r", true);
  		for (int i = 0; i < indent; i++) buffer.append("\t");
  		if (shift) indent++;
  		buffer.append("\"");
  		while (tokenizer.hasMoreTokens()){
  
  			String token = tokenizer.nextToken();
  			if (token.equals("\r")) {
  				buffer.append("\\r");
  				if (tokenizer.hasMoreTokens()) {
  					token = tokenizer.nextToken();
  					if (token.equals("\n")) {
  						buffer.append("\\n");
  						if (tokenizer.hasMoreTokens()) {
  							buffer.append("\" + \n");
  							for (int i = 0; i < indent; i++) buffer.append("\t");
  							buffer.append("\"");
  						}
  						continue;
  					}
  					buffer.append("\" + \n");
  					for (int i = 0; i < indent; i++) buffer.append("\t");
  					buffer.append("\"");
  				} else {
  					continue;
  				}
  			} else if (token.equals("\n")) {
  				buffer.append("\\n");
  				if (tokenizer.hasMoreTokens()) {
  					buffer.append("\" + \n");
  					for (int i = 0; i < indent; i++) buffer.append("\t");
  					buffer.append("\"");
  				}
  				continue;
  			}
  
  			StringBuffer tokenBuffer = new StringBuffer();
  			for (int i = 0; i < token.length(); i++){
  				char c = token.charAt(i);
  				switch (c) {
  				case '\r' :
  					tokenBuffer.append("\\r");
  					break;
  				case '\n' :
  					tokenBuffer.append("\\n");
  					break;
  				case '\b' :
  					tokenBuffer.append("\\b");
  					break;
  				case '\t' :
  					tokenBuffer.append("\t");
  					break;
  				case '\f' :
  					tokenBuffer.append("\\f");
  					break;
  				case '\"' :
  					tokenBuffer.append("\\\"");
  					break;
  				case '\'' :
  					tokenBuffer.append("\\'");
  					break;
  				case '\\' :
  					tokenBuffer.append("\\\\");
  					break;
  				default :
  					tokenBuffer.append(c);
  				}
  			}
  			buffer.append(tokenBuffer.toString());
  		}
  		buffer.append("\"");
  		return buffer.toString();
  	}
  	/**
  	 * Reads the content of the given source file.
  	 * Returns null if enable to read given source file.
  	 *
  	 * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContent("c:/temp/X.java")]
  	 */
  	public static String fileContent(String sourceFilePath) {
  		File sourceFile = new File(sourceFilePath);
  		if (!sourceFile.exists()) {
  			if (DEBUG) System.out.println("File " + sourceFilePath + " does not exists.");
  			return null;
  		}
  		if (!sourceFile.isFile()) {
  			if (DEBUG) System.out.println(sourceFilePath + " is not a file.");
  			return null;
  		}
  		StringBuffer sourceContentBuffer = new StringBuffer();
  		FileInputStream input = null;
  		try {
  			input = new FileInputStream(sourceFile);
  		} catch (FileNotFoundException e) {
  			return null;
  		}
  		try {
  			int read;
  			do {
  				read = input.read();
  				if (read != -1) {
  					sourceContentBuffer.append((char)read);
  				}
  			} while (read != -1);
  			input.close();
  		} catch (IOException e) {
  			e.printStackTrace();
  			return null;
  		} finally {
  			try {
  				input.close();
  			} catch (IOException e2) {
  			}
  		}
  		return sourceContentBuffer.toString();
  	}
  
  	/**
  	 * Reads the content of the given source file and converts it to a display string.
  	 *
  	 * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContentToDisplayString("c:/temp/X.java", 0)]
  	 */
  	public static String fileContentToDisplayString(String sourceFilePath, int indent, boolean independantLineDelimiter) {
  		String sourceString = fileContent(sourceFilePath);
  		if (independantLineDelimiter) {
  			sourceString = convertToIndependantLineDelimiter(sourceString);
  		}
  		return displayString(sourceString, indent);
  	}
  	/**
  	 * Reads the content of the given source file, converts it to a display string.
  	 * If the destination file path is not null, writes the result to this file.
  	 * Otherwise writes it to the console.
  	 *
  	 * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContentToDisplayString("c:/temp/X.java", 0, null)]
  	 */
  	public static void fileContentToDisplayString(String sourceFilePath, int indent, String destinationFilePath, boolean independantLineDelimiter) {
  		String displayString = fileContentToDisplayString(sourceFilePath, indent, independantLineDelimiter);
  		if (destinationFilePath == null) {
  			System.out.println(displayString);
  			return;
  		}
  		writeToFile(displayString, destinationFilePath);
  	}
  	/**
  	 * Flush content of a given directory (leaving it empty),
  	 * no-op if not a directory.
  	 */
  	public static void flushDirectoryContent(File dir) {
  		File[] files = dir.listFiles();
  		if (files == null) return;
  		for (int i = 0, max = files.length; i < max; i++) {
  			delete(files[i]);
  		}
  	}
  	private static Map getCompileOptions(String compliance) {
  		Map options = new HashMap();
  		options.put(CompilerOptions.OPTION_Compliance, compliance);
  		options.put(CompilerOptions.OPTION_Source, compliance);
  		options.put(CompilerOptions.OPTION_TargetPlatform, compliance);
  		// Ignore options with new defaults (since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=76530)
  		options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE);
  		options.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE);
  		options.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE);
  		options.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.IGNORE);
  		options.put(CompilerOptions.OPTION_ReportTypeParameterHiding, CompilerOptions.IGNORE);
  		options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
  		options.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE);
  		return options;
  	}
  	/**
  	 * Returns the next available port number on the local host.
  	 */
  	public static int getFreePort() {
  		ServerSocket socket = null;
  		try {
  			socket = new ServerSocket(0);
  			return socket.getLocalPort();
  		} catch (IOException e) {
  			// ignore
  		} finally {
  			if (socket != null) {
  				try {
  					socket.close();
  				} catch (IOException e) {
  					// ignore
  				}
  			}
  		}
  		return -1;
  	}
  	/**
  	 * Search the user hard-drive for a Java class library.
  	 * Returns null if none could be found.
  	 */
  	public static String[] getJavaClassLibs() {
  		// check bootclasspath properties for Sun, JRockit and Harmony VMs
  		String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
  		if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
  			// IBM J9 VMs
  			bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$
  			if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
  				// Harmony using IBM VME
  				bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$
  			}
  		}
  		String[] jars = null;
  		if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) {
  			StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator);
  			final int size = tokenizer.countTokens();
  			jars = new String[size];
  			int i = 0;
  			while (tokenizer.hasMoreTokens()) {
  				final String fileName = toNativePath(tokenizer.nextToken());
  				if (new File(fileName).exists()) {
  					jars[i] = fileName;
  					i++;
  				}
  			}
  			if (size != i) {
  				// resize
  				System.arraycopy(jars, 0, (jars = new String[i]), 0, i);
  			}
  		} else {
  			String jreDir = getJREDirectory();
  			final String osName = System.getProperty("os.name");
  			if (jreDir == null) {
  				return new String[] {};
  			}
  			if (osName.startsWith("Mac")) {
  				return new String[] {
  						toNativePath(jreDir + "/../Classes/classes.jar")
  				};
  			}
  			final String vmName = System.getProperty("java.vm.name");
  			if ("J9".equals(vmName)) {
  				return new String[] {
  						toNativePath(jreDir + "/lib/jclMax/classes.zip")
  				};
  			}
  			String[] jarsNames = null;
  			ArrayList paths = new ArrayList();
  			if ("DRLVM".equals(vmName)) {
  				FilenameFilter jarFilter = new FilenameFilter() {
  					@Override
  					public boolean accept(File dir, String name) {
  