/*******************************************************************************
 * Copyright (c) 2007, 2013 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
 *******************************************************************************/
package org.eclipse.pde.api.tools.internal.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.jdt.launching.environments.ExecutionEnvironmentDescription;
import org.eclipse.jface.text.IDocument;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.api.tools.internal.FilterStore;
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
import org.eclipse.pde.api.tools.internal.builder.BuildState;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.Factory;
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
import org.eclipse.pde.api.tools.internal.provisional.IRequiredComponentDescription;
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
import org.eclipse.pde.api.tools.internal.provisional.comparator.DeltaVisitor;
import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot;
import org.eclipse.pde.api.tools.internal.search.SkippedComponent;
import org.objectweb.asm.Opcodes;
import org.osgi.framework.Version;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * A Utility class to use for API tools
 *
 * @since 1.0.0
 */
public final class Util {

	public static final String DOT_TGZ = ".tgz"; //$NON-NLS-1$
	public static final String DOT_TAR_GZ = ".tar.gz"; //$NON-NLS-1$
	public static final String DOT_JAR = ".jar"; //$NON-NLS-1$
	public static final String DOT_ZIP = ".zip"; //$NON-NLS-1$

	public static final char VERSION_SEPARATOR = '(';

	/**
	 * Class that runs a build in the workspace or the given project
	 */
	private static final class BuildJob extends Job {
		private final IProject[] fProjects;
		private int fBuildType;

		/**
		 * Constructor
		 *
		 * @param name
		 * @param project
		 */
		BuildJob(String name, IProject[] projects) {
			this(name, projects, IncrementalProjectBuilder.FULL_BUILD);
		}

		BuildJob(String name, IProject[] projects, int buildType) {
			super(name);
			fProjects = projects;
			this.fBuildType = buildType;
		}

		@Override
		public boolean belongsTo(Object family) {
			return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
		}

		/**
		 * Returns if this build job is covered by another build job
		 *
		 * @param other
		 * @return true if covered by another build job, false otherwise
		 */
		public boolean isCoveredBy(BuildJob other) {
			if (other.fProjects == null) {
				return true;
			}
			if (this.fProjects != null) {
				for (int i = 0, max = this.fProjects.length; i < max; i++) {
					if (!other.contains(this.fProjects[i])) {
						return false;
					}
				}
				return true;
			}
			return false;
		}

		public boolean contains(IProject project) {
			if (project == null) {
				return false;
			}
			for (IProject fProject : this.fProjects) {
				if (project.equals(fProject)) {
					return true;
				}
			}
			return false;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			synchronized (getClass()) {
				if (monitor.isCanceled()) {
					return Status.CANCEL_STATUS;
				}
				// cancelBuild(ResourcesPlugin.FAMILY_AUTO_BUILD);
				cancelBuild(ResourcesPlugin.FAMILY_MANUAL_BUILD);
			}
			try {
				if (fProjects != null) {
					SubMonitor localmonitor = SubMonitor.convert(monitor, UtilMessages.Util_0, fProjects.length);
					for (IProject currentProject : fProjects) {
						if (this.fBuildType == IncrementalProjectBuilder.FULL_BUILD) {
							BuildState.setLastBuiltState(currentProject, null);
						}
						localmonitor.subTask(NLS.bind(UtilMessages.Util_5, currentProject.getName()));
						if (ResourcesPlugin.getWorkspace().isAutoBuilding()) {
							currentProject.touch(null);
						} else {
							currentProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, localmonitor.split(1));
						}
					}
				}
			} catch (CoreException e) {
				return new Status(e.getStatus().getSeverity(), ApiPlugin.PLUGIN_ID, ApiPlugin.INTERNAL_ERROR, UtilMessages.Util_builder_errorMessage, e);
			} catch (OperationCanceledException e) {
				return Status.CANCEL_STATUS;
			} finally {
				monitor.done();
			}
			return Status.OK_STATUS;
		}

		private void cancelBuild(Object jobfamily) {
			Job[] buildJobs = Job.getJobManager().find(jobfamily);
			for (Job curr : buildJobs) {
				if (curr != this && curr instanceof BuildJob) {
					BuildJob job = (BuildJob) curr;
					if (job.isCoveredBy(this)) {
						curr.cancel(); // cancel all other build jobs of our
										// kind
					}
				}
			}
		}
	}

	public static final String EMPTY_STRING = "";//$NON-NLS-1$
	public static final String DEFAULT_PACKAGE_NAME = EMPTY_STRING;
	public static final String MANIFEST_NAME = "MANIFEST.MF"; //$NON-NLS-1$

	public static final String DOT_CLASS_SUFFIX = ".class"; //$NON-NLS-1$
	public static final String DOT_JAVA_SUFFIX = ".java"; //$NON-NLS-1$

	/**
	 * Constant representing the default size to read from an input stream
	 */
	private static final int DEFAULT_READING_SIZE = 8192;

	private static final String JAVA_LANG_OBJECT = "java.lang.Object"; //$NON-NLS-1$
	private static final String JAVA_LANG_RUNTIMEEXCEPTION = "java.lang.RuntimeException"; //$NON-NLS-1$
	public static final String LINE_DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$

	public static final String UNKNOWN_ELEMENT_KIND = "UNKNOWN_ELEMENT_KIND"; //$NON-NLS-1$

	public static final String UNKNOWN_FLAGS = "UNKNOWN_FLAGS"; //$NON-NLS-1$
	public static final String UNKNOWN_KIND = "UNKNOWN_KIND"; //$NON-NLS-1$
	public static final String UNKNOWN_VISIBILITY = "UNKNOWN_VISIBILITY"; //$NON-NLS-1$
	public static final String ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$
	public static final String REGULAR_EXPRESSION_START = "R:"; //$NON-NLS-1$

	// 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.
	 */
	private static boolean DELETE_DEBUG = false;
	/**
	 * Maximum of time in milliseconds to wait in deletion operation while
	 * running JDT/Core tests. Default is 10 seconds. This number cannot exceed
	 * 1 minute (i.e. 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...
	 */
	private static int DELETE_MAX_WAIT = 10000;

	public static final IPath MANIFEST_PROJECT_RELATIVE_PATH = new Path(JarFile.MANIFEST_NAME);

	public static final String ORG_ECLIPSE_SWT = "org.eclipse.swt"; //$NON-NLS-1$

	/**
	 * Throws an exception with the given message and underlying exception.
	 *
	 * @param message error message
	 * @param exception underlying exception, or <code>null</code>
	 * @throws CoreException
	 */
	private static void abort(String message, Throwable exception) throws CoreException {
		IStatus status = new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, message, exception);
		throw new CoreException(status);
	}

	/**
	 * Appends a property to the given string buffer with the given key and
	 * value in the format "key=value\n".
	 *
	 * @param buffer buffer to append to
	 * @param key key
	 * @param value value
	 */
	private static void appendProperty(StringBuffer buffer, String key, String value) {
		buffer.append(key);
		buffer.append('=');
		buffer.append(value);
		buffer.append('\n');
	}

	/**
	 * Collects all of the deltas from the given parent delta
	 *
	 * @param delta
	 * @return
	 */
	public static List<IDelta> collectAllDeltas(IDelta delta) {
		final List<IDelta> list = new ArrayList<>();
		delta.accept(new DeltaVisitor() {
			@Override
			public void endVisit(IDelta localDelta) {
				if (localDelta.getChildren().length == 0) {
					list.add(localDelta);
				}
				super.endVisit(localDelta);
			}
		});
		return list;
	}

	/**
	 * Collects files into the collector array list
	 *
	 * @param root the root to collect the files from
	 * @param collector the collector to place matches into
	 * @param fileFilter the filter for files or <code>null</code> to accept all
	 *            files
	 */
	private static void collectAllFiles(File root, ArrayList<File> collector, FileFilter fileFilter) {
		File[] files = root.listFiles(fileFilter);
		for (final File currentFile : files) {
			if (currentFile.isDirectory()) {
				collectAllFiles(currentFile, collector, fileFilter);
			} else {
				collector.add(currentFile);
			}
		}
	}

	/**
	 * Returns all of the API projects in the workspace
	 *
	 * @return all of the API projects in the workspace or <code>null</code> if
	 *         there are none.
	 */
	public static IProject[] getApiProjects() {
		IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		ArrayList<IProject> temp = new ArrayList<>();
		IProject project = null;
		for (IProject allProject : allProjects) {
			project = allProject;
			if (project.isAccessible()) {
				try {
					if (project.hasNature(org.eclipse.pde.api.tools.internal.provisional.ApiPlugin.NATURE_ID)) {
						temp.add(project);
					}
				} catch (CoreException e) {
				}
			}
		}
		IProject[] projects = null;
		if (temp.size() != 0) {
			projects = new IProject[temp.size()];
			temp.toArray(projects);
		}
		return projects;
	}

	/**
	 * Returns all of the API projects in the workspace
	 *
	 * @param sourcelevel
	 * @return all of the API projects in the workspace or <code>null</code> if
	 *         there are none.
	 */
	public static IProject[] getApiProjectsMinSourceLevel(String sourcelevel) {
		IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		ArrayList<IProject> temp = new ArrayList<>();
		IProject project = null;
		for (IProject allProject : allProjects) {
			project = allProject;
			if (project.isAccessible()) {
				try {
					if (project.hasNature(org.eclipse.pde.api.tools.internal.provisional.ApiPlugin.NATURE_ID)) {
						IJavaProject jp = JavaCore.create(project);
						String src = jp.getOption(JavaCore.COMPILER_SOURCE, true);
						if (src != null && src.compareTo(sourcelevel) >= 0) {
							temp.add(project);
						}
					}
				} catch (CoreException e) {
				}
			}
		}
		IProject[] projects = null;
		if (temp.size() != 0) {
			projects = new IProject[temp.size()];
			temp.toArray(projects);
		}
		return projects;
	}

	/**
	 * Copies the given file to the new file
	 *
	 * @param file
	 * @param newFile
	 * @return if the copy succeeded
	 */
	public static boolean copy(File file, File newFile) {
		byte[] bytes = null;
		BufferedInputStream inputStream = null;
		try {
			inputStream = new BufferedInputStream(new FileInputStream(file));
			bytes = Util.getInputStreamAsByteArray(inputStream, -1);
		} catch (FileNotFoundException e) {
			ApiPlugin.log(e);
		} catch (IOException e) {
			ApiPlugin.log(e);
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					ApiPlugin.log(e);
				}
			}
		}
		if (bytes != null) {
			BufferedOutputStream outputStream = null;
			try {
				outputStream = new BufferedOutputStream(new FileOutputStream(newFile));
				outputStream.write(bytes);
				outputStream.flush();
			} catch (FileNotFoundException e) {
				ApiPlugin.log(e);
			} catch (IOException e) {
				ApiPlugin.log(e);
			} finally {
				if (outputStream != null) {
					try {
						outputStream.close();
					} catch (IOException e) {
						// ignore
					}
				}
			}
			return true;
		}
		return false;
	}

	/**
	 * Creates an EE file for the given JRE and specified EE id
	 *
	 * @param jre
	 * @param eeid
	 * @return
	 * @throws IOException
	 */
	public static File createEEFile(IVMInstall jre, String eeid) throws IOException {
		String string = Util.generateEEContents(jre, eeid);
		File eeFile = createTempFile("eed", ".ee"); //$NON-NLS-1$ //$NON-NLS-2$
		FileOutputStream outputStream = null;
		try {
			outputStream = new FileOutputStream(eeFile);
			outputStream.write(string.getBytes(IApiCoreConstants.UTF_8));
		} finally {
			if (outputStream != null) {
				outputStream.close();
			}
		}
		return eeFile;
	}

	/**
	 * Returns whether the objects are equal, accounting for either one being
	 * <code>null</code>.
	 *
	 * @param o1
	 * @param o2
	 * @return whether the objects are equal, or both are <code>null</code>
	 */
	public static boolean equalsOrNull(Object o1, Object o2) {
		if (o1 == null) {
			return o2 == null;
		}
		return o1.equals(o2);
	}

	/**
	 * Returns an execution environment description for the given VM.
	 *
	 * @param vm JRE to create an definition for
	 * @return an execution environment description for the given VM
	 * @throws IOException if unable to generate description
	 */
	public static String generateEEContents(IVMInstall vm, String eeId) throws IOException {
		StringBuffer buffer = new StringBuffer();
		appendProperty(buffer, ExecutionEnvironmentDescription.JAVA_HOME, vm.getInstallLocation().getCanonicalPath());
		StringBuffer paths = new StringBuffer();
		LibraryLocation[] libraryLocations = JavaRuntime.getLibraryLocations(vm);
		for (int i = 0; i < libraryLocations.length; i++) {
			LibraryLocation lib = libraryLocations[i];
			paths.append(lib.getSystemLibraryPath().toOSString());
			if (i < (libraryLocations.length - 1)) {
				paths.append(File.pathSeparatorChar);
			}
		}
		appendProperty(buffer, ExecutionEnvironmentDescription.BOOT_CLASS_PATH, paths.toString());
		appendProperty(buffer, ExecutionEnvironmentDescription.CLASS_LIB_LEVEL, eeId);
		return buffer.toString();
	}

	/**
	 * Returns an array of all of the files from the given root that are
	 * accepted by the given file filter. If the file filter is null all files
	 * within the given root are returned.
	 *
	 * @param root
	 * @param fileFilter
	 * @return the list of files from within the given root
	 */
	public static File[] getAllFiles(File root, FileFilter fileFilter) {
		ArrayList<File> files = new ArrayList<>();
		if (root.isDirectory()) {
			collectAllFiles(root, files, fileFilter);
			File[] result = new File[files.size()];
			files.toArray(result);
			return result;
		}
		return null;
	}

	/**
	 * Returns a build job that will perform a full build on the given projects.
	 *
	 * If <code>projects</code> are null, then an AssertionFailedException is
	 * thrown
	 *
	 * @param projects the projects to build
	 * @return the build job
	 * @throws AssertionFailedException if the given projects are null
	 */
	public static Job getBuildJob(final IProject[] projects) {
		Assert.isNotNull(projects);
		Job buildJob = new BuildJob(UtilMessages.Util_4, projects);
		buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
		buildJob.setUser(true);
		return buildJob;
	}

	/**
	 * Returns a build job that will return the build that corresponds to the
	 * given build kind on the given projects.
	 *
	 * If <code>projects</code> are null, then an AssertionFailedException is
	 * thrown
	 *
	 * @param projects the projects to build
	 * @param buildKind the given build kind
	 * @return the build job
	 * @throws AssertionFailedException if the given projects are null
	 */
	public static Job getBuildJob(final IProject[] projects, int buildKind) {
		Assert.isNotNull(projects);
		Job buildJob = new BuildJob(UtilMessages.Util_4, projects, buildKind);
		buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
		buildJob.setUser(true);
		return buildJob;
	}

	/**
	 * Returns a result of searching the given components for class file with
	 * the given type name.
	 *
	 * @param components API components to search or <code>null</code> if none
	 * @param typeName type to search for
	 * @return class file or <code>null</code> if none found
	 */
	public static IApiTypeRoot getClassFile(IApiComponent[] components, String typeName) {
		if (components == null) {
			return null;
		}
		for (IApiComponent apiComponent : components) {
			if (apiComponent != null) {
				try {
					IApiTypeRoot classFile = apiComponent.findTypeRoot(typeName);
					if (classFile != null) {
						return classFile;
					}
				} catch (CoreException e) {
					// ignore
				}
			}
		}
		return null;
	}

	/**
	 * Return a string that represents the element type of the given delta.
	 * Returns {@link #UNKNOWN_ELEMENT_KIND} if the element type cannot be
	 * determined.
	 *
	 * @param delta the given delta
	 * @return a string that represents the element type of the given delta.
	 */
	public static String getDeltaElementType(IDelta delta) {
		return getDeltaElementType(delta.getElementType());
	}

	/**
	 * Returns a text representation of a marker severity level
	 *
	 * @param severity
	 * @return text of a marker severity level
	 */
	public static String getSeverity(int severity) {
		switch (severity) {
			case IMarker.SEVERITY_ERROR: {
				return "ERROR"; //$NON-NLS-1$
			}
			case IMarker.SEVERITY_INFO: {
				return "INFO"; //$NON-NLS-1$
			}
			case IMarker.SEVERITY_WARNING: {
				return "WARNING"; //$NON-NLS-1$
			}
			default: {
				return "UNKNOWN_SEVERITY"; //$NON-NLS-1$
			}
		}
	}

	/**
	 * Return an int value that represents the given element type Returns -1 if
	 * the element type cannot be determined.
	 *
	 * @param elementType the given element type
	 * @return an int that represents the given element type constant.
	 */
	public static int getDeltaElementTypeValue(String elementType) {
		Class<IDelta> IDeltaClass = IDelta.class;
		try {
			Field field = IDeltaClass.getField(elementType);
			return field.getInt(null);
		} catch (SecurityException e) {
			// ignore
		} catch (IllegalArgumentException e) {
			// ignore
		} catch (NoSuchFieldException e) {
			// ignore
		} catch (IllegalAccessException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * Return a string that represents the given element type Returns
	 * {@link #UNKNOWN_ELEMENT_KIND} if the element type cannot be determined.
	 *
	 * @param elementType the given element type
	 * @return a string that represents the given element type.
	 */
	public static String getDeltaElementType(int elementType) {
		switch (elementType) {
			case IDelta.ANNOTATION_ELEMENT_TYPE:
				return "ANNOTATION_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.INTERFACE_ELEMENT_TYPE:
				return "INTERFACE_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.ENUM_ELEMENT_TYPE:
				return "ENUM_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.API_COMPONENT_ELEMENT_TYPE:
				return "API_COMPONENT_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.API_BASELINE_ELEMENT_TYPE:
				return "API_BASELINE_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.CONSTRUCTOR_ELEMENT_TYPE:
				return "CONSTRUCTOR_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.METHOD_ELEMENT_TYPE:
				return "METHOD_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.FIELD_ELEMENT_TYPE:
				return "FIELD_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.CLASS_ELEMENT_TYPE:
				return "CLASS_ELEMENT_TYPE"; //$NON-NLS-1$
			case IDelta.TYPE_PARAMETER_ELEMENT_TYPE:
				return "TYPE_PARAMETER_ELEMENT_TYPE"; //$NON-NLS-1$
			default:
				break;
		}
		return UNKNOWN_ELEMENT_KIND;
	}

	/**
	 * Return a string that represents the given flags Returns
	 * {@link #UNKNOWN_FLAGS} if the flags cannot be determined.
	 *
	 * @param flags the given delta's flags
	 * @return a string that represents the given flags.
	 */
	public static String getDeltaFlagsName(int flags) {
		switch (flags) {
			case IDelta.ABSTRACT_TO_NON_ABSTRACT:
				return "ABSTRACT_TO_NON_ABSTRACT"; //$NON-NLS-1$
			case IDelta.ANNOTATION_DEFAULT_VALUE:
				return "ANNOTATION_DEFAULT_VALUE"; //$NON-NLS-1$
			case IDelta.API_COMPONENT:
				return "API_COMPONENT"; //$NON-NLS-1$
			case IDelta.ARRAY_TO_VARARGS:
				return "ARRAY_TO_VARARGS"; //$NON-NLS-1$
			case IDelta.CHECKED_EXCEPTION:
				return "CHECKED_EXCEPTION"; //$NON-NLS-1$
			case IDelta.CLASS_BOUND:
				return "CLASS_BOUND"; //$NON-NLS-1$
			case IDelta.CLINIT:
				return "CLINIT"; //$NON-NLS-1$
			case IDelta.CONSTRUCTOR:
				return "CONSTRUCTOR"; //$NON-NLS-1$
			case IDelta.CONTRACTED_SUPERINTERFACES_SET:
				return "CONTRACTED_SUPERINTERFACES_SET"; //$NON-NLS-1$
			case IDelta.DECREASE_ACCESS:
				return "DECREASE_ACCESS"; //$NON-NLS-1$
			case IDelta.ENUM_CONSTANT:
				return "ENUM_CONSTANT"; //$NON-NLS-1$
			case IDelta.EXECUTION_ENVIRONMENT:
				return "EXECUTION_ENVIRONMENT"; //$NON-NLS-1$
			case IDelta.EXPANDED_SUPERINTERFACES_SET:
				return "EXPANDED_SUPERINTERFACES_SET"; //$NON-NLS-1$
			case IDelta.FIELD:
				return "FIELD"; //$NON-NLS-1$
			case IDelta.FIELD_MOVED_UP:
				return "FIELD_MOVED_UP"; //$NON-NLS-1$
			case IDelta.FINAL_TO_NON_FINAL:
				return "FINAL_TO_NON_FINAL"; //$NON-NLS-1$
			case IDelta.FINAL_TO_NON_FINAL_NON_STATIC:
				return "FINAL_TO_NON_FINAL_NON_STATIC"; //$NON-NLS-1$
			case IDelta.FINAL_TO_NON_FINAL_STATIC_CONSTANT:
				return "FINAL_TO_NON_FINAL_STATIC_CONSTANT"; //$NON-NLS-1$
			case IDelta.FINAL_TO_NON_FINAL_STATIC_NON_CONSTANT:
				return "FINAL_TO_NON_FINAL_STATIC_NON_CONSTANT"; //$NON-NLS-1$
			case IDelta.INCREASE_ACCESS:
				return "INCREASE_ACCESS"; //$NON-NLS-1$
			case IDelta.INTERFACE_BOUND:
				return "INTERFACE_BOUND"; //$NON-NLS-1$
			case IDelta.METHOD:
				return "METHOD"; //$NON-NLS-1$
			case IDelta.METHOD_MOVED_UP:
				return "METHOD_MOVED_UP"; //$NON-NLS-1$
			case IDelta.METHOD_WITH_DEFAULT_VALUE:
				return "METHOD_WITH_DEFAULT_VALUE"; //$NON-NLS-1$
			case IDelta.METHOD_WITHOUT_DEFAULT_VALUE:
				return "METHOD_WITHOUT_DEFAULT_VALUE"; //$NON-NLS-1$
			case IDelta.NATIVE_TO_NON_NATIVE:
				return "NATIVE_TO_NON_NATIVE"; //$NON-NLS-1$
			case IDelta.NON_ABSTRACT_TO_ABSTRACT:
				return "NON_ABSTRACT_TO_ABSTRACT"; //$NON-NLS-1$
			case IDelta.NON_FINAL_TO_FINAL:
				return "NON_FINAL_TO_FINAL"; //$NON-NLS-1$
			case IDelta.NON_NATIVE_TO_NATIVE:
				return "NON_NATIVE_TO_NATIVE"; //$NON-NLS-1$
			case IDelta.NON_STATIC_TO_STATIC:
				return "NON_STATIC_TO_STATIC"; //$NON-NLS-1$
			case IDelta.NON_SYNCHRONIZED_TO_SYNCHRONIZED:
				return "NON_SYNCHRONIZED_TO_SYNCHRONIZED"; //$NON-NLS-1$
			case IDelta.NON_TRANSIENT_TO_TRANSIENT:
				return "NON_TRANSIENT_TO_TRANSIENT"; //$NON-NLS-1$
			case IDelta.OVERRIDEN_METHOD:
				return "OVERRIDEN_METHOD"; //$NON-NLS-1$
			case IDelta.STATIC_TO_NON_STATIC:
				return "STATIC_TO_NON_STATIC"; //$NON-NLS-1$
			case IDelta.SUPERCLASS:
				return "SUPERCLASS"; //$NON-NLS-1$
			case IDelta.SYNCHRONIZED_TO_NON_SYNCHRONIZED:
				return "SYNCHRONIZED_TO_NON_SYNCHRONIZED"; //$NON-NLS-1$
			case IDelta.TYPE_CONVERSION:
				return "TYPE_CONVERSION"; //$NON-NLS-1$
			case IDelta.TRANSIENT_TO_NON_TRANSIENT:
				return "TRANSIENT_TO_NON_TRANSIENT"; //$NON-NLS-1$
			case IDelta.TYPE:
				return "TYPE"; //$NON-NLS-1$
			case IDelta.TYPE_ARGUMENTS:
				return "TYPE_ARGUMENTS"; //$NON-NLS-1$
			case IDelta.TYPE_MEMBER:
				return "TYPE_MEMBER"; //$NON-NLS-1$
			case IDelta.TYPE_PARAMETER:
				return "TYPE_PARAMETER"; //$NON-NLS-1$
			case IDelta.TYPE_PARAMETER_NAME:
				return "TYPE_PARAMETER_NAME"; //$NON-NLS-1$
			case IDelta.TYPE_PARAMETERS:
				return "TYPE_PARAMETERS"; //$NON-NLS-1$
			case IDelta.TYPE_VISIBILITY:
				return "TYPE_VISIBILITY"; //$NON-NLS-1$
			case IDelta.UNCHECKED_EXCEPTION:
				return "UNCHECKED_EXCEPTION"; //$NON-NLS-1$
			case IDelta.VALUE:
				return "VALUE"; //$NON-NLS-1$
			case IDelta.VARARGS_TO_ARRAY:
				return "VARARGS_TO_ARRAY"; //$NON-NLS-1$
			case IDelta.RESTRICTIONS:
				return "RESTRICTIONS"; //$NON-NLS-1$
			case IDelta.API_TYPE:
				return "API_TYPE"; //$NON-NLS-1$
			case IDelta.NON_VOLATILE_TO_VOLATILE:
				return "NON_VOLATILE_TO_VOLATILE"; //$NON-NLS-1$
			case IDelta.VOLATILE_TO_NON_VOLATILE:
				return "VOLATILE_TO_NON_VOLATILE"; //$NON-NLS-1$
			case IDelta.MINOR_VERSION:
				return "MINOR_VERSION"; //$NON-NLS-1$
			case IDelta.MAJOR_VERSION:
				return "MAJOR_VERSION"; //$NON-NLS-1$
			case IDelta.API_FIELD:
				return "API_FIELD"; //$NON-NLS-1$
			case IDelta.API_METHOD:
				return "API_METHOD"; //$NON-NLS-1$
			case IDelta.API_CONSTRUCTOR:
				return "API_CONSTRUCTOR"; //$NON-NLS-1$
			case IDelta.API_ENUM_CONSTANT:
				return "API_ENUM_CONSTANT"; //$NON-NLS-1$
			case IDelta.API_METHOD_WITH_DEFAULT_VALUE:
				return "API_METHOD_WITH_DEFAULT_VALUE"; //$NON-NLS-1$
			case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE:
				return "API_METHOD_WITHOUT_DEFAULT_VALUE"; //$NON-NLS-1$
			case IDelta.TYPE_ARGUMENT:
				return "TYPE_ARGUMENT"; //$NON-NLS-1$
			case IDelta.SUPER_INTERFACE_WITH_METHODS:
				return "SUPER_INTERFACE_WITH_METHODS"; //$NON-NLS-1$
			case IDelta.REEXPORTED_API_TYPE:
				return "REEXPORTED_API_TYPE"; //$NON-NLS-1$
			case IDelta.REEXPORTED_TYPE:
				return "REEXPORTED_TYPE"; //$NON-NLS-1$
			case IDelta.METHOD_MOVED_DOWN:
				return "METHOD_MOVED_DOWN"; //$NON-NLS-1$
			case IDelta.DEPRECATION:
				return "DEPRECATION"; //$NON-NLS-1$
			default:
				break;
		}
		return UNKNOWN_FLAGS;
	}

	/**
	 * Return a string that represents the kind of the given delta. Returns
	 * {@link #UNKNOWN_KIND} if the kind cannot be determined.
	 *
	 * @param delta the given delta
	 * @return a string that represents the kind of the given delta.
	 */
	public static String getDeltaKindName(IDelta delta) {
		return getDeltaKindName(delta.getKind());
	}

	/**
	 * Return a string that represents the given kind. Returns
	 * {@link #UNKNOWN_KIND} if the kind cannot be determined.
	 *
	 * @param delta the given kind
	 * @return a string that represents the given kind.
	 */
	public static String getDeltaKindName(int kind) {
		switch (kind) {
			case IDelta.ADDED:
				return "ADDED"; //$NON-NLS-1$
			case IDelta.CHANGED:
				return "CHANGED"; //$NON-NLS-1$
			case IDelta.REMOVED:
				return "REMOVED"; //$NON-NLS-1$
			default:
				break;
		}
		return UNKNOWN_KIND;
	}

	/**
	 * Returns the preference key for the given element type, the given kind and
	 * the given flags.
	 *
	 * @param elementType the given element type (retrieved using
	 *            {@link IDelta#getElementType()}
	 * @param kind the given kind (retrieved using {@link IDelta#getKind()}
	 * @param flags the given flags (retrieved using {@link IDelta#getFlags()}
	 * @return the preference key for the given element type, the given kind and
	 *         the given flags.
	 */
	public static String getDeltaPrefererenceKey(int elementType, int kind, int flags) {
		StringBuffer buffer = new StringBuffer(Util.getDeltaElementType(elementType));
		buffer.append('_').append(Util.getDeltaKindName(kind));
		if (flags != -1) {
			buffer.append('_');
			switch (flags) {
				case IDelta.API_FIELD:
					buffer.append(Util.getDeltaFlagsName(IDelta.FIELD));
					break;
				case IDelta.API_ENUM_CONSTANT:
					buffer.append(Util.getDeltaFlagsName(IDelta.ENUM_CONSTANT));
					break;
				case IDelta.API_CONSTRUCTOR:
					buffer.append(Util.getDeltaFlagsName(IDelta.CONSTRUCTOR));
					break;
				case IDelta.API_METHOD:
					buffer.append(Util.getDeltaFlagsName(IDelta.METHOD));
					break;
				case IDelta.API_METHOD_WITH_DEFAULT_VALUE:
					if (kind == IDelta.REMOVED) {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD));
					} else {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITH_DEFAULT_VALUE));
					}
					break;
				case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE:
					if (kind == IDelta.REMOVED) {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD));
					} else {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITHOUT_DEFAULT_VALUE));
					}
					break;
				case IDelta.METHOD_WITH_DEFAULT_VALUE:
					if (kind == IDelta.REMOVED) {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD));
					} else {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITH_DEFAULT_VALUE));
					}
					break;
				case IDelta.METHOD_WITHOUT_DEFAULT_VALUE:
					if (kind == IDelta.REMOVED) {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD));
					} else {
						buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITHOUT_DEFAULT_VALUE));
					}
					break;
				default:
					buffer.append(Util.getDeltaFlagsName(flags));
			}
		}
		return String.valueOf(buffer);
	}

	/**
	 * Returns the details of the API delta as a string
	 *
	 * @param delta
	 * @return the details of the delta as a string
	 */
	public static String getDetail(IDelta delta) {
		StringBuffer buffer = new StringBuffer();
		switch (delta.getElementType()) {
			case IDelta.CLASS_ELEMENT_TYPE:
				buffer.append("class"); //$NON-NLS-1$
				break;
			case IDelta.ANNOTATION_ELEMENT_TYPE:
				buffer.append("annotation"); //$NON-NLS-1$
				break;
			case IDelta.INTERFACE_ELEMENT_TYPE:
				buffer.append("interface"); //$NON-NLS-1$
				break;
			case IDelta.API_COMPONENT_ELEMENT_TYPE:
				buffer.append("api component"); //$NON-NLS-1$
				break;
			case IDelta.API_BASELINE_ELEMENT_TYPE:
				buffer.append("api baseline"); //$NON-NLS-1$
				break;
			case IDelta.METHOD_ELEMENT_TYPE:
				buffer.append("method"); //$NON-NLS-1$
				break;
			case IDelta.CONSTRUCTOR_ELEMENT_TYPE:
				buffer.append("constructor"); //$NON-NLS-1$
				break;
			case IDelta.ENUM_ELEMENT_TYPE:
				buffer.append("enum"); //$NON-NLS-1$
				break;
			case IDelta.FIELD_ELEMENT_TYPE:
				buffer.append("field"); //$NON-NLS-1$
				break;
			default:
				break;
		}
		buffer.append(' ');
		switch (delta.getKind()) {
			case IDelta.ADDED:
				buffer.append("added"); //$NON-NLS-1$
				break;
			case IDelta.REMOVED:
				buffer.append("removed"); //$NON-NLS-1$
				break;
			case IDelta.CHANGED:
				buffer.append("changed"); //$NON-NLS-1$
				break;
			default:
				buffer.append("unknown kind"); //$NON-NLS-1$
				break;
		}
		buffer.append(' ').append(getDeltaFlagsName(delta.getFlags())).append(' ').append(delta.getTypeName()).append("#").append(delta.getKey()); //$NON-NLS-1$
		return String.valueOf(buffer);
	}

	/**
	 * Returns the {@link IDocument} for the specified {@link ICompilationUnit}
	 *
	 * @param cu
	 * @return the {@link IDocument} for the specified {@link ICompilationUnit}
	 * @throws CoreException
	 */
	public static IDocument getDocument(ICompilationUnit cu) throws CoreException {
		if (cu.getOwner() == null) {
			IFile file = (IFile) cu.getResource();
			if (file.exists()) {
				ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager();
				IPath path = cu.getPath();
				bufferManager.connect(path, LocationKind.IFILE, new NullProgressMonitor());
				try {
					return bufferManager.getTextFileBuffer(path, LocationKind.IFILE).getDocument();
				} finally {
					bufferManager.disconnect(path, LocationKind.IFILE, null);
				}
			}
		}
		return new org.eclipse.jface.text.Document(cu.getSource());
	}

	/**
	 * Returns the OSGi profile properties corresponding to the given execution
	 * environment id, or <code>null</code> if none.
	 *
	 * @param eeId OSGi profile identifier
	 *
	 * @return the corresponding properties or <code>null</code> if none
	 */
	public static Properties getEEProfile(String eeId) {
		String profileName = eeId + ".profile"; //$NON-NLS-1$
		InputStream stream = Util.class.getResourceAsStream("profiles/" + profileName); //$NON-NLS-1$
		if (stream != null) {
			try {
				Properties profile = new Properties();
				profile.load(stream);
				return profile;
			} catch (IOException e) {
				ApiPlugin.log(e);
			} finally {
				try {
					stream.close();
				} catch (IOException e) {
					ApiPlugin.log(e);
				}
			}
		}
		return null;
	}

	/**
	 * Returns the number of fragments for the given version value, -1 if the
	 * format is unknown. The version is formed like: [optional plug-in name]
	 * major.minor.micro.qualifier.
	 *
	 * @param version the given version value
	 * @return the number of fragments for the given version value or -1 if the
	 *         format is unknown
	 * @throws IllegalArgumentException if version is null
	 */
	public static final int getFragmentNumber(String version) {
		if (version == null) {
			throw new IllegalArgumentException("The given version should not be null"); //$NON-NLS-1$
		}
		int index = version.indexOf(' ');
		char[] charArray = version.toCharArray();
		int length = charArray.length;
		if (index + 1 >= length) {
			return -1;
		}
		int counter = 1;
		for (int i = index + 1; i < length; i++) {
			switch (charArray[i]) {
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					continue;
				case '.':
					counter++;
					break;
				default:
					return -1;
			}
		}
		return counter;
	}

	public static IMember getIMember(IDelta delta, IJavaProject javaProject) {
		String typeName = delta.getTypeName();
		if (typeName == null) {
			return null;
		}
		IType type = null;
		try {
			type = javaProject.findType(typeName.replace('$', '.'));
		} catch (JavaModelException e) {
			// ignore
		}
		if (type == null) {
			return null;
		}
		String key = delta.getKey();
		switch (delta.getElementType()) {
			case IDelta.FIELD_ELEMENT_TYPE: {
				IField field = type.getField(key);
				if (field.exists()) {
					return field;
				}
			}
				break;
			case IDelta.CLASS_ELEMENT_TYPE:
			case IDelta.ANNOTATION_ELEMENT_TYPE:
			case IDelta.INTERFACE_ELEMENT_TYPE:
			case IDelta.ENUM_ELEMENT_TYPE:
				// we report the marker on the type
				switch (delta.getKind()) {
					case IDelta.ADDED:
						switch (delta.getFlags()) {
							case IDelta.FIELD:
							case IDelta.ENUM_CONSTANT:
								IField field = type.getField(key);
								if (field.exists()) {
									return field;
								}
								break;
							case IDelta.METHOD_WITH_DEFAULT_VALUE:
							case IDelta.METHOD_WITHOUT_DEFAULT_VALUE:
							case IDelta.METHOD:
							case IDelta.CONSTRUCTOR:
								return getMethod(type, key);
							case IDelta.TYPE_MEMBER:
								IType type2 = type.getType(key);
								if (type2.exists()) {
									return type2;
								}
								break;
							default:
								break;
						}
						break;
					case IDelta.REMOVED:
						switch (delta.getFlags()) {
							case IDelta.API_FIELD:
							case IDelta.API_ENUM_CONSTANT:
								IField field = type.getField(key);
								if (field.exists()) {
									return field;
								}
								break;
							case IDelta.API_METHOD_WITH_DEFAULT_VALUE:
							case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE:
							case IDelta.API_METHOD:
							case IDelta.API_CONSTRUCTOR:
								return getMethod(type, key);
							default:
								break;
						}
						break;
					default:
						break;
				}
				return type;
			case IDelta.METHOD_ELEMENT_TYPE:
			case IDelta.CONSTRUCTOR_ELEMENT_TYPE: {
				return getMethod(type, key);
			}
			case IDelta.API_COMPONENT_ELEMENT_TYPE:
				return type;
			default:
				break;
		}
		return null;
	}

	private static IMember getMethod(IType type, String key) {
		boolean isGeneric = false;
		int indexOfTypeVariable = key.indexOf('<');
		int index = 0;
		if (indexOfTypeVariable == -1) {
			int indexOfParen = key.indexOf('(');
			if (indexOfParen == -1) {
				return null;
			}
			index = indexOfParen;
		} else {
			int indexOfParen = key.indexOf('(');
			if (indexOfParen == -1) {
				return null;
			}
			if (indexOfParen < indexOfTypeVariable) {
				index = indexOfParen;
			} else {
				index = indexOfTypeVariable;
				isGeneric = true;
			}
		}
		String selector = key.substring(0, index);
		String descriptor = key.substring(index, key.length());
		IMethod method = null;
		String signature = descriptor.replace('/', '.');
		String[] parameterTypes = null;
		if (isGeneric) {
			// remove all type variables first
			signature = signature.substring(signature.indexOf('('));
			parameterTypes = Signature.getParameterTypes(signature);
		} else {
			parameterTypes = Signature.getParameterTypes(signature);
		}

		try {
			method = type.getMethod(selector, parameterTypes);
		} catch (IllegalArgumentException e) {
			ApiPlugin.log(e);
		}
		if (method == null) {
			return null;
		}
		if (method.exists()) {
			return method;
		}
		// if the method is not null and it doesn't exist, it might be the
		// default constructor or a constructor in inner type
		if (selector.equals(type.getElementName())) {
			if (parameterTypes.length == 0) {
				return null;
			}
			// Perhaps a constructor on an inner type?
			IJavaElement parent = type.getParent();
			if (parent instanceof IType) {
				String parentTypeSig = Signature.createTypeSignature(((IType) parent).getFullyQualifiedName(), true);
				if (Signatures.matches(parentTypeSig, parameterTypes[0])) {
					IMethod constructor = type.getMethod(selector, Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length));
					try {
						if (constructor.exists() && constructor.isConstructor()) {
							return constructor;
						}
						String contructorSig = Signature.createMethodSignature(Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length), Signature.getReturnType(signature));
						IMethod[] methods = type.findMethods(constructor);
						if (methods != null) {
							if (methods.length == 1 && methods[0].isConstructor()) {
								return methods[0];
							}
							// findMethods() checks simple type names, so
							// it's possible to have multiple matches with
							// different package names
							for (IMethod m : methods) {
								try {
									if (m.isConstructor() && m.getNumberOfParameters() == parameterTypes.length - 1 && Signatures.matchesSignatures(generateBinarySignature(m), contructorSig)) {
										return m;
									}
								} catch (JavaModelException e) {
									// ignore
								}
							}
						}
					} catch (JavaModelException e) {
						// ignore
					}
				}
			}
		}
		// Let JDT have a go
		IMethod[] methods = type.findMethods(method);
		if (methods != null && methods.length == 1) {
			/* exact match found */
			return methods[0];
		}
		if (methods == null || methods.length == 0) {
			/* no methods found: may be due to type erasure */
			try {
				methods = type.getMethods();
			} catch (JavaModelException e) {
				ApiPlugin.log(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, NLS.bind("Unable to retrieve methods for {0}", type.getFullyQualifiedName()), e)); //$NON-NLS-1$
				return null;
			}
		}

		/*
		 * findMethods() checks simple type names, so it's possible to have
		 * multiple matches with different package names. Or we may need to
		 * check with type erasure.
		 */
		for (IMethod m : methods) {
			try {
				if (!m.getElementName().equals(selector) || m.getNumberOfParameters() != parameterTypes.length) {
					continue;
				}
				if (Signatures.matchesSignatures(generateBinarySignature(m), signature)) {
					return m;
				}
			} catch (JavaModelException e) {
				// ignore
			}
		}

		/*
		 * Unclear what circumstances that this could happen, so provide more
		 * information to help understand why
		 */
		StringBuilder sb = new StringBuilder();
		for (IMethod m : methods) {
			sb.append('\n').append(m.getHandleIdentifier());
		}
		ApiPlugin.log(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, NLS.bind(UtilMessages.Util_6, new String[] {
				selector, descriptor }) + sb.toString()));
		// do not default to the enclosing type - see bug 224713
		return null;
	}

	/**
	 * Generate the binary signature for the provided method. This is the
	 * type-erased signature written out to the .class file.
	 *
	 * @param method the method
	 * @return the method signature as would be encoded in a .class file
	 * @throws JavaModelException
	 */
	private static String generateBinarySignature(IMethod method) throws JavaModelException {
		ITypeParameter[] typeTPs = method.getDeclaringType().getTypeParameters();
		ITypeParameter[] methodTPs = method.getTypeParameters();
		if (typeTPs.length == 0 && methodTPs.length == 0) {
			return method.getSignature();
		}
		Map<String, String> lookup = new HashMap<>();
		Stream.concat(Stream.of(typeTPs), Stream.of(methodTPs)).forEach(tp -> {
			try {
				String sigs[] = tp.getBoundsSignatures();
				lookup.put(tp.getElementName(), sigs.length == 1 ? sigs[0] : "Ljava.lang.Object;"); //$NON-NLS-1$
			} catch (JavaModelException e) {
				/* ignore */
			}
		});
		String[] parameterTypes = Stream.of(method.getParameterTypes()).map(p -> expandParameterType(p, lookup)).toArray(String[]::new);
		return Signature.createMethodSignature(parameterTypes, expandParameterType(method.getReturnType(), lookup));
	}

	/**
	 * Rewrite a parameter type signature with type erasure and using the
	 * parameterized type bounds lookup table. For example:
	 * 
	 * <pre>
	 *     expand("QList&lt;QE;&gt;;", {"E" &rarr; "Ljava.lang.Object;"}) = "QList;"
	 *     expand("QE;", {"E" &rarr; "Ljava.lang.Object;"}) = "Ljava.lang.Object;"
	 * </pre>
	 *
	 * @param parameterTypeSig the type signature for a parameter
	 * @param bounds the type bounds as expressed on the method and class
	 * @return a rewritten parameter type signature as would be found in the .class file
	 */
	private static String expandParameterType(String parameterTypeSig, Map<String, String> bounds) {
		String erased = Signature.getTypeErasure(parameterTypeSig);
		if (erased.charAt(0) == Signature.C_UNRESOLVED || erased.charAt(0) == Signature.C_TYPE_VARIABLE) {
			String repl = bounds.get(Signature.getSignatureSimpleName(erased));
			if (repl != null) {
				return repl;
			}
		}
		return erased;
	}

	/**
	 * Returns the given input stream as a byte array
	 *
	 * @param stream the stream to get as a byte array
	 * @param length the length to read from the stream or -1 for unknown
	 * @return the given input stream as a byte array
	 * @throws IOException
	 */
	public static byte[] getInputStreamAsByteArray(InputStream stream, int length) throws IOException {
		byte[] contents;
		if (length == -1) {
			contents = new byte[0];
			int contentsLength = 0;
			int amountRead = -1;
			do {
				// read at least 8K
				int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);
				// resize contents if needed
				if (contentsLength + amountRequested > contents.length) {
					System.arraycopy(contents, 0, contents = new byte[contentsLength + amountRequested], 0, contentsLength);
				}
				// read as many bytes as possible
				amountRead = stream.read(contents, contentsLength, amountRequested);
				if (amountRead > 0) {
					// remember length of contents
					contentsLength += amountRead;
				}
			} while (amountRead != -1);
			// resize contents if necessary
			if (contentsLength < contents.length) {
				System.arraycopy(contents, 0, contents = new byte[contentsLength], 0, contentsLength);
			}
		} else {
			contents = new byte[length];
			int len = 0;
			int readSize = 0;
			while ((readSize != -1) && (len != length)) {
				// See PR 1FMS89U
				// We record first the read size. In this case length is the
				// actual
				// read size.
				len += readSize;
				readSize = stream.read(contents, len, length - len);
			}
		}
		return contents;
	}

	/**
	 * Returns the given input stream's contents as a character array. If a
	 * length is specified (i.e. if length != -1), this represents the number of
	 * bytes in the stream. Note the specified stream is not closed in this
	 * method
	 *
	 * @param stream the stream to get convert to the char array
	 * @param length the length of the input stream, or -1 if unknown
	 * @param encoding the encoding to use when reading the stream
	 * @return the given input stream's contents as a character array.
	 * @throws IOException if a problem occurred reading the stream.
	 */
	public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) throws IOException {
		Charset charset = null;
		try {
			charset = Charset.forName(encoding);
		} catch (IllegalCharsetNameException e) {
			System.err.println("Illegal charset name : " + encoding); //$NON-NLS-1$
			return null;
		} catch (UnsupportedCharsetException e) {
			System.err.println("Unsupported charset : " + encoding); //$NON-NLS-1$
			return null;
		}
		CharsetDecoder charsetDecoder = charset.newDecoder();

		charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
		byte[] contents = getInputStreamAsByteArray(stream, length);
		ByteBuffer byteBuffer = ByteBuffer.allocate(contents.length);
		byteBuffer.put(contents);
		byteBuffer.flip();
		CharBuffer charBuffer = charsetDecoder.decode(byteBuffer);
		charBuffer.compact(); // ensure pay-load starting at 0
		char[] array = charBuffer.array();
		int lengthToBe = charBuffer.position();
		if (array.length > lengthToBe) {
			System.arraycopy(array, 0, (array = new char[lengthToBe]), 0, lengthToBe);
		}
		return array;
	}

	/**
	 * Tries to find the 'MANIFEST.MF' file with in the given project in the
	 * 'META-INF folder'.
	 *
	 * @param currentProject
	 * @return a handle to the manifest file or <code>null</code> if not found
	 */
	public static IResource getManifestFile(IProject currentProject) {
		return currentProject.findMember("META-INF/MANIFEST.MF"); //$NON-NLS-1$
	}

	/**
	 * Returns if the given {@link IMarker} is representing an
	 * {@link org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem}
	 * or not
	 *
	 * @param marker the marker to check
	 * @return true if the marker is for an
	 *         {@link org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem}
	 *         false otherwise
	 * @throws CoreException
	 */
	public static boolean isApiProblemMarker(IMarker marker) {
		return marker.getAttribute(IApiMarkerConstants.API_MARKER_ATTR_ID, -1) > 0;
	}

	/**
	 * Returns a reference type for the given fully qualified type name.
	 *
	 * @param fullyQualifiedName type name
	 * @return reference type
	 */
	public static IReferenceTypeDescriptor getType(String fullyQualifiedName) {
		int index = fullyQualifiedName.lastIndexOf('.');
		String pkg = index == -1 ? DEFAULT_PACKAGE_NAME : fullyQualifiedName.substring(0, index);
		String type = index == -1 ? fullyQualifiedName : fullyQualifiedName.substring(index + 1);
		return Factory.packageDescriptor(pkg).getType(type);
	}

	/**
	 * Returns if the given project is API enabled
	 *
	 * @param project the given project
	 * @return true if the project is API enabled, false otherwise
	 */
	public static boolean isApiProject(IProject project) {
		try {
			return project.hasNature(ApiPlugin.NATURE_ID);
		} catch (CoreException e) {
			return false;
		}
	}

	/**
	 * Returns if the given project is a java project
	 *
	 * @param project the given project
	 * @return <code>true</code> if the project is a java project,
	 *         <code>false</code> otherwise
	 */
	public static boolean isJavaProject(IProject project) {
		try {
			return project.hasNature(JavaCore.NATURE_ID);
		} catch (CoreException e) {
			return false;
		}
	}

	/**
	 * Returns if the given project is API enabled
	 *
	 * @param project the given project
	 * @return <code>true</code> if the project is API enabled,
	 *         <code>false</code> otherwise
	 */
	public static boolean isApiProject(IJavaProject project) {
		if (project != null) {
			return isApiProject(project.getProject());
		}
		return false;
	}

	/**
	 * Returns if the given {@link IApiComponent} is a valid
	 * {@link IApiComponent}
	 *
	 * @param apiComponent the given component
	 * @return true if the given {@link IApiComponent} is valid, false otherwise
	 */
	public static boolean isApiToolsComponent(IApiComponent apiComponent) {
		File file = new File(apiComponent.getLocation());
		if (file.exists()) {
			if (file.isDirectory()) {
				// directory binary bundle
				File apiDescription = new File(file, IApiCoreConstants.API_DESCRIPTION_XML_NAME);
				return apiDescription.exists();
			}
			ZipFile zipFile = null;
			try {
				zipFile = new ZipFile(file);
				return zipFile.getEntry(IApiCoreConstants.API_DESCRIPTION_XML_NAME) != null;
			} catch (ZipException e) {
				// ignore
			} catch (IOException e) {
				// ignore
			} finally {
				try {
					if (zipFile != null) {
						zipFile.close();
					}
				} catch (IOException e) {
					// ignore
				}
			}
		}
		return false;
	}

	/**
	 * Returns if the specified file name is an archive name. A name is
	 * considered to be an archive name if it ends with either '.zip' or '.jar'
	 *
	 * @param fileName
	 * @return true if the file name is an archive name false otherwise
	 */
	public static boolean isArchive(String fileName) {
		return isZipJarFile(fileName) || isTGZFile(fileName);
	}

	/**
	 * Returns if the given file name represents a 'standard' archive, where the
	 * name has an extension of *.zip or *.jar
	 *
	 * @param fileName
	 * @return true if the given file name is that of a 'standard' archive,
	 *         false otherwise
	 */
	public static boolean isZipJarFile(String fileName) {
		String normalizedFileName = fileName.toLowerCase();
		return normalizedFileName.endsWith(DOT_ZIP) || normalizedFileName.endsWith(DOT_JAR);
	}

	/**
	 * Returns if the given file name represents a G-zip file name, where the
	 * name has an extension of *.tar.gz or *.tgz
	 *
	 * @param fileName
	 * @return true if the given file name is that of a G-zip archive, false
	 *         otherwise
	 */
	public static boolean isTGZFile(String fileName) {
		String normalizedFileName = fileName.toLowerCase();
		return normalizedFileName.endsWith(DOT_TAR_GZ) || normalizedFileName.endsWith(DOT_TGZ);
	}

	/**
	 * Returns if the flags are for a class
	 *
	 * @param accessFlags the given access flags
	 * @return
	 */
	public static boolean isClass(int accessFlags) {
		return (accessFlags & (Opcodes.ACC_ENUM | Opcodes.ACC_ANNOTATION | Opcodes.ACC_INTERFACE)) == 0;
	}

	/**
	 * Returns if the specified file name is for a class file. A name is
	 * considered to be a class file if it ends in '.class'
	 *
	 * @param fileName
	 * @return true if the name is for a class file false otherwise
	 */
	public static boolean isClassFile(String fileName) {
		return fileName.toLowerCase().endsWith(DOT_CLASS_SUFFIX);
	}

	public static boolean isDefault(int accessFlags) {
		// none of the private, protected or public bit is set
		return (accessFlags & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0;
	}

	public static final boolean isDifferentVersion(String versionToBeChecked, String referenceVersion) {
		SinceTagVersion sinceTagVersion1 = null;
		SinceTagVersion sinceTagVersion2 = null;
		try {
			sinceTagVersion1 = new SinceTagVersion(versionToBeChecked);
			sinceTagVersion2 = new SinceTagVersion(referenceVersion);
		} catch (IllegalArgumentException e) {
			// We cannot compare the two versions as their format is unknown
			// TODO (olivier) should we report these as malformed tags?
			return false;
		}
		Version version1 = sinceTagVersion1.getVersion();
		Version version2 = sinceTagVersion2.getVersion();
		if (version1.getMajor() != version2.getMajor()) {
			return true;
		}
		if (version1.getMinor() != version2.getMinor()) {
			return true;
		}
		if (version1.getMicro() != version2.getMicro()) {
			return true;
		}
		return false;
	}

	/**
	 * Returns if the specified file name is for a java source file. A name is
	 * considered to be a java source file if it ends in '.java'
	 *
	 * @param fileName
	 * @return true if the name is for a java source file, false otherwise
	 */
	public static boolean isJavaFileName(String fileName) {
		return fileName.toLowerCase().endsWith(DOT_JAVA_SUFFIX);
	}

	/**
	 * Returns if the given name is {@link java.lang.Object}
	 *
	 * @param name
	 * @return true if the name is java.lang.Object, false otherwise
	 */
	public static boolean isJavaLangObject(String name) {
		return name != null && name.equals(JAVA_LANG_OBJECT);
	}

	/**
	 * Return if the name is {@link java.lang.RuntimeException}
	 *
	 * @param name
	 * @return true if the name is java.lang.RuntimeException, false otherwise
	 */
	public static boolean isJavaLangRuntimeException(String name) {
		return name != null && name.equals(JAVA_LANG_RUNTIMEEXCEPTION);
	}

	public static boolean isVisible(int modifiers) {
		return Flags.isProtected(modifiers) || Flags.isPublic(modifiers);
	}

	public static boolean isBinaryProject(IProject project) {
		return org.eclipse.pde.internal.core.WorkspaceModelManager.isBinaryProject(project);
	}

	/**
	 * Returns a new XML document.
	 *
	 * @return document
	 * @throws CoreException if unable to create a new document
	 */
	public static Document newDocument() throws CoreException {
		DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = null;
		try {
			docBuilder = dfactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			abort("Unable to create new XML document.", e); //$NON-NLS-1$
		}
		Document doc = docBuilder.newDocument();
		return doc;
	}

	/**
	 * Parses the given string representing an XML document, returning its root
	 * element.
	 *
	 * @param document XML document as a string
	 * @return the document's root element
	 * @throws CoreException if unable to parse the document
	 */
	public static Element parseDocument(String document) throws CoreException {
		Element root = null;
		InputStream stream = null;
		try {
			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			parser.setErrorHandler(new DefaultHandler());
			stream = new ByteArrayInputStream(document.getBytes(IApiCoreConstants.UTF_8));
			root = parser.parse(stream).getDocumentElement();
		} catch (ParserConfigurationException e) {
			abort("Unable to parse XML document.", e); //$NON-NLS-1$
		} catch (FactoryConfigurationError e) {
			abort("Unable to parse XML document.", e); //$NON-NLS-1$
		} catch (SAXException e) {
			abort("Unable to parse XML document.", e); //$NON-NLS-1$
		} catch (IOException e) {
			abort("Unable to parse XML document.", e); //$NON-NLS-1$
		} finally {
			try {
				if (stream != null) {
					stream.close();
				}
			} catch (IOException e) {
				abort("Unable to parse XML document.", e); //$NON-NLS-1$
			}
		}
		return root;
	}

	/**
	 * Save the given contents into the given file. The file parent folder must
	 * exist.
	 *
	 * @param file the given file target
	 * @param contents the given contents
	 * @throws IOException if an IOException occurs while saving the file
	 */
	public static void saveFile(File file, String contents) throws IOException {
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(file));
			writer.write(contents);
			writer.flush();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					// ignore
				}
			}
		}
	}

	/**
	 * Returns the contents of the given file as a string, or <code>null</code>
	 *
	 * @param file the file to get the contents for
	 * @return the contents of the file as a {@link String} or <code>null</code>
	 */
	public static String getFileContentAsString(File file) {
		String contents = null;
		FileInputStream stream = null;
		try {
			stream = new FileInputStream(file);
			char[] array = getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8);
			contents = new String(array);
		} catch (IOException ioe) {
			ApiPlugin.log(ioe);
		} finally {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					// ignore
				}
			}
		}
		return contents;
	}

	/**
	 * Returns the given string as an {@link InputStream}. It is up to the
	 * caller to close the new stream.
	 *
	 * @param string the string to convert
	 * @return the {@link InputStream} for the given string
	 */
	public static InputStream getInputStreamFromString(String string) {
		try {
			return new ByteArrayInputStream(string.getBytes(IApiCoreConstants.UTF_8));
		} catch (UnsupportedEncodingException uee) {
			ApiPlugin.log(uee);
		}
		return null;
	}

	/**
	 * Serializes the given XML document into a UTF-8 string.
	 *
	 * @param document XML document to serialize
	 * @return a string representing the given document
	 * @throws CoreException if unable to serialize the document
	 */
	public static String serializeDocument(Document document) throws CoreException {
		try {
			ByteArrayOutputStream s = new ByteArrayOutputStream();
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer();
			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
			transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); //$NON-NLS-1$ //$NON-NLS-2$
			DOMSource source = new DOMSource(document);
			StreamResult outputTarget = new StreamResult(s);
			transformer.transform(source, outputTarget);
			return s.toString(IApiCoreConstants.UTF_8);
		} catch (TransformerException e) {
			abort("Unable to serialize XML document.", e); //$NON-NLS-1$
		} catch (IOException e) {
			abort("Unable to serialize XML document.", e); //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * Unzip the contents of the given zip in the given directory (create it if
	 * it doesn't exist)
	 */
	public static void unzip(String zipPath, String destDirPath) throws IOException {
		InputStream zipIn = new FileInputStream(zipPath);
		byte[] buf = new byte[8192];
		File destDir = new File(destDirPath);
		ZipInputStream zis = new ZipInputStream(new BufferedInputStream(zipIn));
		BufferedOutputStream outputStream = null;
		try {
			ZipEntry zEntry;
			while ((zEntry = zis.getNextEntry()) != null) {
				// if it is empty directory, create it
				if (zEntry.isDirectory()) {
					new File(destDir, zEntry.getName()).mkdirs();
					continue;
				}
				// if it is a file, extract it
				String filePath = zEntry.getName();
				int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$
				String fileDir = ""; //$NON-NLS-1$
				if (lastSeparator >= 0) {
					fileDir = filePath.substring(0, lastSeparator);
				}
				// create directory for a file
				new File(destDir, fileDir).mkdirs();
				// write file
				File outFile = new File(destDir, filePath);
				outputStream = new BufferedOutputStream(new FileOutputStream(outFile));
				int n = 0;
				while ((n = zis.read(buf)) >= 0) {
					outputStream.write(buf, 0, n);
				}
				outputStream.close();
			}
		} catch (IOException ioe) {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException ioe2) {
				}
			}
		} finally {
			try {
				zipIn.close();
				zis.close();
			} catch (IOException ioe) {
			}
		}
	}

	/**
	 * Unzip the contents of the given zip in the given directory (create it if
	 * it doesn't exist)
	 */
	public static void guntar(String zipPath, String destDirPath) throws TarException, IOException {
		TarFile tarFile = new TarFile(zipPath);
		Enumeration<?> entries = tarFile.entries();
		byte[] buf = new byte[8192];
		for (; entries.hasMoreElements();) {
			TarEntry zEntry;
			while ((zEntry = (TarEntry) entries.nextElement()) != null) {
				// if it is empty directory, create it
				if (zEntry.getFileType() == TarEntry.DIRECTORY) {
					new File(destDirPath, zEntry.getName()).mkdirs();
					continue;
				}
				// if it is a file, extract it
				String filePath = zEntry.getName();
				int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$
				String fileDir = ""; //$NON-NLS-1$
				if (lastSeparator >= 0) {
					fileDir = filePath.substring(0, lastSeparator);
				}
				// create directory for a file
				new File(destDirPath, fileDir).mkdirs();
				// write file
				File outFile = new File(destDirPath, filePath);
				BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFile));
				int n = 0;
				InputStream inputStream = tarFile.getInputStream(zEntry);
				BufferedInputStream stream = new BufferedInputStream(inputStream);
				while ((n = stream.read(buf)) >= 0) {
					outputStream.write(buf, 0, n);
				}
				outputStream.close();
				stream.close();
			}
		}
	}

	/**
	 * Gets the .ee file supplied to run tests based on system property.
	 *
	 * @return
	 */
	public static File getEEDescriptionFile() {
		// generate a fake 1.6 ee file
		File fakeEEFile = null;
		PrintWriter writer = null;
		try {
			fakeEEFile = createTempFile("eefile", ".ee"); //$NON-NLS-1$ //$NON-NLS-2$
			writer = new PrintWriter(new BufferedWriter(new FileWriter(fakeEEFile)));
			writer.print("-Djava.home="); //$NON-NLS-1$
			writer.println(System.getProperty("java.home")); //$NON-NLS-1$
			writer.print("-Dee.bootclasspath="); //$NON-NLS-1$
			writer.println(getJavaClassLibsAsString());
			writer.println("-Dee.language.level=1.6"); //$NON-NLS-1$
			writer.println("-Dee.class.library.level=JavaSE-1.6"); //$NON-NLS-1$
			writer.flush();
		} catch (IOException e) {
			// ignore
		} finally {
			if (writer != null) {
				writer.close();
			}
		}
		return fakeEEFile;
	}

	/**
	 * Creates a new file in the users' <code>temp</code> directory
	 *
	 * @param prefix
	 * @param suffix
	 * @return a new temp file
	 * @throws IOException
	 * @since 1.1
	 */
	public static File createTempFile(String prefix, String suffix) throws IOException {
		File file = File.createTempFile(prefix, suffix);
		file.deleteOnExit();
		FileManager.getManager().recordTempFileRoot(file.getCanonicalPath());
		return file;
	}

	/**
	 * @return a string representation of all of the libraries from the bootpath
	 *         of the current default system VM.
	 */
	public static String getJavaClassLibsAsString() {
		String[] libs = Util.getJavaClassLibs();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0, max = libs.length; i < max; i++) {
			if (i > 0) {
				buffer.append(File.pathSeparatorChar);
			}
			buffer.append(libs[i]);
		}
		return String.valueOf(buffer);
	}

	/**
	 * @return an array of the library names from the bootpath of the current
	 *         default system VM
	 */
	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 = System.getProperty("java.home"); //$NON-NLS-1$
			final String osName = System.getProperty("os.name"); //$NON-NLS-1$
			if (jreDir == null) {
				return new String[] {};
			}
			if (osName.startsWith("Mac")) { //$NON-NLS-1$
				return new String[] { toNativePath(jreDir + "/../Classes/classes.jar") //$NON-NLS-1$
				};
			}
			final String vmName = System.getProperty("java.vm.name"); //$NON-NLS-1$
			if ("J9".equals(vmName)) { //$NON-NLS-1$
				return new String[] { toNativePath(jreDir + "/lib/jclMax/classes.zip") //$NON-NLS-1$
				};
			}
			String[] jarsNames = null;
			ArrayList<String> paths = new ArrayList<>();
			if ("DRLVM".equals(vmName)) { //$NON-NLS-1$
				FilenameFilter jarFilter = (dir, name) -> name.endsWith(DOT_JAR) & !name.endsWith("-src.jar"); //$NON-NLS-1$
				jarsNames = new File(jreDir + "/lib/boot/").list(jarFilter); //$NON-NLS-1$
				addJarEntries(jreDir + "/lib/boot/", jarsNames, paths); //$NON-NLS-1$
			} else {
				jarsNames = new String[] { "/lib/vm.jar", //$NON-NLS-1$
						"/lib/rt.jar", //$NON-NLS-1$
						"/lib/core.jar", //$NON-NLS-1$
						"/lib/security.jar", //$NON-NLS-1$
						"/lib/xml.jar", //$NON-NLS-1$
						"/lib/graphics.jar" //$NON-NLS-1$
				};
				addJarEntries(jreDir, jarsNames, paths);
			}
			jars = new String[paths.size()];
			paths.toArray(jars);
		}
		return jars;
	}

	/**
	 * Makes the given path a path using native path separators as returned by
	 * File.getPath() and trimming any extra slash.
	 */
	public static String toNativePath(String path) {
		String nativePath = path.replace('\\', File.separatorChar).replace('/', File.separatorChar);
		return nativePath.endsWith("/") || nativePath.endsWith("\\") ? //$NON-NLS-1$ //$NON-NLS-2$
		nativePath.substring(0, nativePath.length() - 1) : nativePath;
	}

	private static void addJarEntries(String jreDir, String[] jarNames, ArrayList<String> paths) {
		for (String jarName : jarNames) {
			final String currentName = jreDir + jarName;
			File f = new File(currentName);
			if (f.exists()) {
				paths.add(toNativePath(currentName));
			}
		}
	}

	/**
	 * 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) {
		if (!file.exists()) {
			return true;
		}
		// flush all directory content
		if (file.isDirectory()) {
			flushDirectoryContent(file);
		}
		// remove file
		file.delete();
		if (isFileDeleted(file)) {
			return true;
		}
		return waitUntilFileDeleted(file);
	}

	public static void flushDirectoryContent(File dir) {
		File[] files = dir.listFiles();
		if (files == null) {
			return;
		}
		for (File file : files) {
			delete(file);
		}
	}

	/**
	 * Wait until the file is _really_ deleted on file system.
	 *
	 * @param file Deleted file
	 * @return true if the file was finally deleted, false otherwise
	 */
	private static boolean waitUntilFileDeleted(File file) {
		int count = 0;
		int delay = 10; // ms
		int maxRetry = DELETE_MAX_WAIT / delay;
		int time = 0;
		while (count < maxRetry) {
			try {
				count++;
				Thread.sleep(delay);
				time += delay;
				if (time > DELETE_MAX_TIME) {
					DELETE_MAX_TIME = time;
				}
				if (DELETE_DEBUG) {
					System.out.print('.');
				}
				if (file.exists()) {
					if (file.delete()) {
						// SUCCESS
						return true;
					}
				}
				if (isFileDeleted(file)) {
					// SUCCESS
					return true;
				}
				// Increment waiting delay exponentially
				if (count >= 10 && delay <= 100) {
					count = 1;
					delay *= 10;
					maxRetry = DELETE_MAX_WAIT / delay;
					if ((DELETE_MAX_WAIT % delay) != 0) {
						maxRetry++;
					}
				}
			} catch (InterruptedException ie) {
				break; // end loop
			}
		}
		System.err.println();
		System.err.println("	!!! ERROR: " + file + " was never deleted even after having waited " + DELETE_MAX_TIME + "ms!!!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		System.err.println();
		return false;
	}

	/**
	 * Returns whether a file is really deleted or not. Does not only rely on
	 * {@link File#exists()} method but also look if it's not in its parent
	 * children {@link #getParentChildFile(File)}.
	 *
	 * @param file The file to test if deleted
	 * @return true if the file does not exist and was not found in its parent
	 *         children.
	 */
	public static boolean isFileDeleted(File file) {
		return !file.exists() && getParentChildFile(file) == null;
	}

	/**
	 * Returns the parent's child file matching the given file or null if not
	 * found.
	 *
	 * @param file The searched file in parent
	 * @return The parent's child matching the given file or null if not found.
	 */
	private static File getParentChildFile(File file) {
		File parent = file.getParentFile();
		if (parent == null || !parent.exists()) {
			return null;
		}
		File[] files = parent.listFiles();
		if (files == null) {
			return null;
		}
		int length = files == null ? 0 : files.length;
		if (length > 0) {
			for (int i = 0; i < length; i++) {
				if (files[i] == file) {
					return files[i];
				} else if (files[i].equals(file)) {
					return files[i];
				} else if (files[i].getPath().equals(file.getPath())) {
					return files[i];
				}
			}
		}
		return null;
	}

	/**
	 * Turns the given array of strings into a {@link HashSet}
	 *
	 * @param values
	 * @return a new {@link HashSet} of the string array
	 */
	public static Set<String> convertAsSet(String[] values) {
		Set<String> set = new HashSet<>();
		if (values != null && values.length != 0) {
			for (String value : values) {
				set.add(value);
			}
		}
		return set;
	}

	/**
	 * Returns an identifier for the given API component including its version
	 * identifier (component id + '(' + major + . + minor + . + micro + ')' )
	 *
	 * @param component API component
	 * @return API component + version identifier
	 */
	public static String getDeltaComponentVersionsId(IApiComponent component) {
		StringBuffer buffer = new StringBuffer(component.getSymbolicName());
		String version = component.getVersion();
		// remove the qualifier part
		if (version != null) {
			buffer.append(Util.VERSION_SEPARATOR);
			try {
				Version version2 = new Version(version);
				buffer.append(version2.getMajor()).append('.').append(version2.getMinor()).append('.').append(version2.getMicro());
			} catch (IllegalArgumentException e) {
				// the version string doesn't follow the Eclipse pattern
				// we keep the version as is
				buffer.append(version);
			}
			buffer.append(')');
		}
		return String.valueOf(buffer);
	}

	/**
	 * Returns an identifier for the given API component including its version
	 * identifier (component id + _ + major + _ + minor + _ + micro)
	 *
	 * @param component API component
	 * @return API component + version identifier
	 */
	public static String getComponentVersionsId(IApiComponent component) {
		StringBuffer buffer = new StringBuffer(component.getSymbolicName());
		String version = component.getVersion();
		// remove the qualifier part
		if (version != null) {
			buffer.append('_');
			try {
				Version version2 = new Version(version);
				buffer.append(version2.getMajor()).append('.').append(version2.getMinor()).append('.').append(version2.getMicro());
			} catch (IllegalArgumentException e) {
				// the version string doesn't follow the Eclipse pattern
				// we keep the version as is
				buffer.append(version);
			}
		}
		return String.valueOf(buffer);
	}

	public static String getDescriptorName(IApiType descriptor) {
		String typeName = descriptor.getName();
		int index = typeName.lastIndexOf('$');
		if (index != -1) {
			return typeName.replace('$', '.');
		}
		return typeName;
	}

	public static String getDeltaArgumentString(IDelta delta) {
		String[] arguments = delta.getArguments();
		switch (delta.getFlags()) {
			case IDelta.TYPE_MEMBER:
			case IDelta.TYPE:
				return arguments[0];
			case IDelta.METHOD:
			case IDelta.CONSTRUCTOR:
			case IDelta.ENUM_CONSTANT:
			case IDelta.METHOD_WITH_DEFAULT_VALUE:
			case IDelta.METHOD_WITHOUT_DEFAULT_VALUE:
			case IDelta.FIELD:
				return arguments[1];
			case IDelta.INCREASE_ACCESS:
				switch (delta.getElementType()) {
					case IDelta.FIELD_ELEMENT_TYPE:
					case IDelta.METHOD_ELEMENT_TYPE:
					case IDelta.CONSTRUCTOR_ELEMENT_TYPE:
						return arguments[1];
					default:
						return arguments[0];
				}
			default:
				break;
		}
		return EMPTY_STRING;
	}

	/**
	 * Returns the string representation of the {@link IApiElement} type
	 *
	 * @param type
	 * @return the string of the {@link IApiElement} type
	 */
	public static String getApiElementType(int type) {
		switch (type) {
			case IApiElement.API_TYPE_CONTAINER:
				return "API_TYPE_CONTAINER"; //$NON-NLS-1$
			case IApiElement.API_TYPE_ROOT:
				return "API_TYPE_ROOT"; //$NON-NLS-1$
			case IApiElement.BASELINE:
				return "BASELINE"; //$NON-NLS-1$
			case IApiElement.COMPONENT:
				return "COMPONENT"; //$NON-NLS-1$
			case IApiElement.FIELD:
				return "FIELD"; //$NON-NLS-1$
			case IApiElement.METHOD:
				return "METHOD"; //$NON-NLS-1$
			case IApiElement.TYPE:
				return "TYPE"; //$NON-NLS-1$
			default:
				return "UNKNOWN"; //$NON-NLS-1$
		}
	}

	public static boolean isConstructor(String referenceMemberName) {
		return Arrays.equals(ConstantPool.Init, referenceMemberName.toCharArray());
	}

	public static boolean isManifest(IPath path) {
		return MANIFEST_PROJECT_RELATIVE_PATH.equals(path);
	}

	public static void touchCorrespondingResource(IProject project, IResource resource, String typeName) {
		if (typeName != null && typeName != FilterStore.GLOBAL) {
			if (Util.isManifest(resource.getProjectRelativePath())) {
				try {
					IJavaProject javaProject = JavaCore.create(project);
					IType findType = javaProject.findType(typeName);
					if (findType != null) {
						ICompilationUnit compilationUnit = findType.getCompilationUnit();
						if (compilationUnit != null) {
							IResource cuResource = compilationUnit.getResource();
							if (cuResource != null) {
								cuResource.touch(null);
							}
						}
					}
				} catch (JavaModelException e) {
					ApiPlugin.log(e);
				} catch (CoreException e) {
					ApiPlugin.log(e);
				}
			} else {
				try {
					resource.touch(null);
				} catch (CoreException e) {
					ApiPlugin.log(e);
				}
			}
		}
	}

	public static String getTypeNameFromMarker(IMarker marker) {
		return marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_TYPE_NAME, null);
	}

	public static IApiComponent[] getReexportedComponents(IApiComponent component) {
		try {
			IRequiredComponentDescription[] requiredComponents = component.getRequiredComponents();
			int length = requiredComponents.length;
			if (length != 0) {
				List<IApiComponent> reexportedComponents = null;
				IApiBaseline baseline = component.getBaseline();
				for (int i = 0; i < length; i++) {
					IRequiredComponentDescription description = requiredComponents[i];
					if (description.isExported()) {
						String id = description.getId();
						IApiComponent reexportedComponent = baseline.getApiComponent(id);
						if (reexportedComponent != null) {
							if (reexportedComponents == null) {
								reexportedComponents = new ArrayList<>();
							}
							reexportedComponents.add(reexportedComponent);
						}
					}
				}
				if (reexportedComponents == null || reexportedComponents.size() == 0) {
					return null;
				}
				return reexportedComponents.toArray(new IApiComponent[reexportedComponents.size()]);
			}
		} catch (CoreException e) {
			ApiPlugin.log(e);
		}
		return null;
	}

	/**
	 * Returns the {@link IResource} to create markers on when building. If the
	 * {@link IType} is <code>null</code> or the type cannot be located (does
	 * not exist) than the MANIFEST.MF will be returned. <code>null</code> can
	 * be returned in the case that the project does not have a manifest file.
	 *
	 * @param project the project to look in for the {@link IResource}
	 * @param type the type we are looking for the resource for, or
	 *            <code>null</code>
	 * @return the {@link IResource} associated with the given {@link IType} or
	 *         the MANIFEST.MF file, or <code>null</code> if the project does
	 *         not have a manifest
	 */
	public static IResource getResource(IProject project, IType type) {
		try {
			if (type != null) {
				ICompilationUnit unit = type.getCompilationUnit();
				if (unit != null) {
					IResource resource = unit.getCorrespondingResource();
					if (resource != null && resource.exists()) {
						return resource;
					}
				}
			}
		} catch (JavaModelException e) {
			ApiPlugin.log(e);
		}
		return getManifestFile(project);
	}

	/**
	 * Default comparator that orders {@link IApiComponent} by their ID
	 */
	public static final Comparator<Object> componentsorter = (o1, o2) -> {
		if (o1 instanceof IApiComponent && o2 instanceof IApiComponent) {
			return ((IApiComponent) o1).getSymbolicName().compareTo(((IApiComponent) o2).getSymbolicName());
		}
		if (o1 instanceof SkippedComponent && o2 instanceof SkippedComponent) {
			return ((SkippedComponent) o1).getComponentId().compareTo(((SkippedComponent) o2).getComponentId());
		}
		if (o1 instanceof String && o2 instanceof String) {
			return ((String) o1).compareTo((String) o2);
		}
		return -1;
	};

	/**
	 * Initializes the exclude set with regex support. The API baseline is used
	 * to determine which bundles should be added to the list when processing
	 * regex expressions.
	 *
	 * @param location
	 * @param baseline
	 * @return the list of bundles to be excluded
	 * @throws CoreException if the location does not describe a includes file
	 *             or an IOException occurs
	 */
	public static FilteredElements initializeRegexFilterList(String location, IApiBaseline baseline, boolean debug) throws CoreException {
		FilteredElements excludedElements = new FilteredElements();
		if (location != null) {
			File file = new File(location);
			InputStream stream = null;
			char[] contents = null;
			try {
				stream = new BufferedInputStream(new FileInputStream(file));
				contents = getInputStreamAsCharArray(stream, -1, ISO_8859_1);
			} catch (FileNotFoundException e) {
				abort(NLS.bind(UtilMessages.Util_couldNotFindFilterFile, location), e);
			} catch (IOException e) {
				abort(NLS.bind(UtilMessages.Util_problemWithFilterFile, location), e);
			} finally {
				if (stream != null) {
					try {
						stream.close();
					} catch (IOException e) {
					}
				}
			}
			if (contents != null) {
				LineNumberReader reader = new LineNumberReader(new StringReader(new String(contents)));
				String line = null;
				try {
					while ((line = reader.readLine()) != null) {
						line = line.trim();
						if (line.startsWith("#") || line.length() == 0) { //$NON-NLS-1$
							continue;
						}
						if (line.startsWith(REGULAR_EXPRESSION_START)) {
							if (baseline != null) {
								Util.collectRegexIds(line, excludedElements, baseline.getApiComponents(), debug);
							}
						} else {
							excludedElements.addExactMatch(line);
						}
					}
				} catch (IOException e) {
					abort(NLS.bind(UtilMessages.Util_problemWithFilterFile, location), e);
				} finally {
					try {
						reader.close();
					} catch (IOException e) {
					}
				}
			}
		}
		return excludedElements;
	}

	/**
	 * Collects the set of component ids that match a given regex in the exclude
	 * file
	 *
	 * @param line
	 * @param list
	 * @param components
	 */
	public static void collectRegexIds(String line, FilteredElements excludedElements, IApiComponent[] components, boolean debug) throws CoreException {
		if (line.startsWith(REGULAR_EXPRESSION_START)) {
			String componentname = line;
			// regular expression
			componentname = componentname.substring(2);
			Pattern pattern = null;
			try {
				if (debug) {
					System.out.println("Pattern to match : " + componentname); //$NON-NLS-1$
				}
				pattern = Pattern.compile(componentname);
				String componentid = null;
				for (IApiComponent component : components) {
					componentid = component.getSymbolicName();
					if (pattern.matcher(componentid).matches()) {
						if (debug) {
							System.out.println(componentid + " matched the pattern " + componentname); //$NON-NLS-1$
						}
						excludedElements.addPartialMatch(componentid);
					} else if (debug) {
						System.out.println(componentid + " didn't match the pattern " + componentname); //$NON-NLS-1$
					}
				}
			} catch (PatternSyntaxException e) {
				abort(NLS.bind(UtilMessages.comparison_invalidRegularExpression, componentname), e);
			}
		}
	}

	/**
	 * Default comparator that orders {@link File}s by their name
	 */
	public static final Comparator<Object> filesorter = (o1, o2) -> {
		if (o1 instanceof File && o2 instanceof File) {
			return ((File) o1).getName().compareTo(((File) o2).getName());
		}
		return 0;
	};

	/**
	 * Returns true if the given {@link IApiType} is API or not, where API is
	 * defined as having API visibility in an API description and having either
	 * the public of protected Java flag set
	 *
	 * @param visibility
	 * @param typeDescriptor
	 * @return true if the given type is API, false otherwise
	 */
	public static boolean isAPI(int visibility, IApiType typeDescriptor) {
		int access = typeDescriptor.getModifiers();
		return VisibilityModifiers.isAPI(visibility) && (Flags.isPublic(access) || Flags.isProtected(access));
	}

	/**
	 * Simple method to walk an array and call <code>toString()</code> on each
	 * of the entries. Does not descend into sub-collections.
	 *
	 * @param array the array
	 * @return the comma-separated string representation of the the array
	 * @since 1.0.3
	 */
	public static String deepToString(Object[] array) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < array.length; i++) {
			buffer.append(array[i].toString());
			if (i < array.length - 1) {
				buffer.append(',');
			}
		}
		return buffer.toString();
	}
}
