/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 83258 [jar exporter] Deploy java application as executable jar
 *******************************************************************************/
package org.eclipse.jdt.testplugin;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Map;
import java.util.zip.ZipFile;

import org.osgi.framework.Bundle;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Synchronizer;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;

import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameRequestor;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.util.CoreUtility;

import junit.framework.TestCase;


/**
 * Helper methods to set up a IJavaProject.
 */
public class JavaProjectHelper {

	/**
	 * XXX: Flag to enable/disable dummy search to synchronize with indexer. See https://bugs.eclipse.org/391927 .
	 * <p>
	 * 0 if disabled, >0 if enabled.
	 * <p>
	 * If external code increases this counter, then it MUST decrease it again (e.g. in TestSetup's setUp/tearDown).
	 */
	public static int PERFORM_DUMMY_SEARCH= 0;
	
	/**
	 * @deprecated use {@link #RT_STUBS_15}
	 */
	@Deprecated
	public static final IPath RT_STUBS_13= new Path("testresources/rtstubs.jar");
	/**
	 * @deprecated use {@link #JUNIT_SRC_381}
	 */
	@Deprecated
	public static final IPath JUNIT_SRC= new Path("testresources/junit37-noUI-src.zip");

	public static final IPath RT_STUBS_15= new Path("testresources/rtstubs15.jar");
	public static final IPath RT_STUBS_16= new Path("testresources/rtstubs16.jar");
	public static final IPath RT_STUBS_17= new Path("testresources/rtstubs17.jar");
	public static final IPath RT_STUBS_18= new Path("testresources/rtstubs18.jar");
	public static final IPath RT_STUBS_9= new Path("testresources/rtstubs9.jar");
	public static final IPath RT_STUBS_10= new Path("testresources/rtstubs10.jar");
	public static final IPath JUNIT_SRC_381= new Path("testresources/junit381-noUI-src.zip");
	public static final String JUNIT_SRC_ENCODING= "ISO-8859-1";

	public static final IPath MYLIB= new Path("testresources/mylib.jar");
	public static final IPath MYLIB_STDOUT= new Path("testresources/mylib_stdout.jar");
	public static final IPath MYLIB_SIG= new Path("testresources/mylib_sig.jar");
	public static final IPath NLS_LIB= new Path("testresources/nls.jar");

	private static final int MAX_RETRY= 5;
	private static final int RETRY_DELAY= 1000;

	public static final int COUNT_CLASSES_RT_STUBS_15= 661;
	public static final int COUNT_INTERFACES_RT_STUBS_15= 135;

	public static final int COUNT_CLASSES_JUNIT_SRC_381= 76;
	public static final int COUNT_INTERFACES_JUNIT_SRC_381= 8;
	public static final int COUNT_CLASSES_MYLIB= 3;

	/**
	 * If set to <code>true</code> all resources that are
	 * deleted using {@link #delete(IJavaElement)} and that contain mixed
	 * line delimiters will result in a test failure.
	 * <p>
	 * Should be <code>false</code> during normal and Releng test runs
	 * due to performance impact and because the search plug-in gets
	 * loaded which results in a test failure.
	 * </p>
	 */
	private static final boolean ASSERT_NO_MIXED_LINE_DELIMIERS= false;

	/**
	 * Creates a IJavaProject.
	 * @param projectName The name of the project
	 * @param binFolderName Name of the output folder
	 * @return Returns the Java project handle
	 * @throws CoreException Project creation failed
	 */
	public static IJavaProject createJavaProject(String projectName, String binFolderName) throws CoreException {
		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
		IProject project= root.getProject(projectName);
		if (!project.exists()) {
			project.create(null);
		} else {
			project.refreshLocal(IResource.DEPTH_INFINITE, null);
		}

		if (!project.isOpen()) {
			project.open(null);
		}

		IPath outputLocation;
		if (binFolderName != null && binFolderName.length() > 0) {
			IFolder binFolder= project.getFolder(binFolderName);
			if (!binFolder.exists()) {
				CoreUtility.createFolder(binFolder, false, true, null);
			}
			outputLocation= binFolder.getFullPath();
		} else {
			outputLocation= project.getFullPath();
		}

		if (!project.hasNature(JavaCore.NATURE_ID)) {
			addNatureToProject(project, JavaCore.NATURE_ID, null);
		}

		IJavaProject jproject= JavaCore.create(project);

		jproject.setOutputLocation(outputLocation, null);
		jproject.setRawClasspath(new IClasspathEntry[0], null);

		return jproject;
	}

	/**
	 * Creates a Java project with JUnit source and rt.jar from
	 * {@link #addVariableRTJar(IJavaProject, String, String, String)}.
	 *
	 * @param projectName the project name
	 * @param srcContainerName the source container name
	 * @param outputFolderName the output folder name
	 * @return the IJavaProject
	 * @throws CoreException
	 * @throws IOException
	 * @throws InvocationTargetException
	 * @since 3.1
	 */
	public static IJavaProject createJavaProjectWithJUnitSource(String projectName, String srcContainerName, String outputFolderName) throws CoreException, IOException, InvocationTargetException {
		IJavaProject project= createJavaProject(projectName, outputFolderName);

		IPackageFragmentRoot jdk= JavaProjectHelper.addVariableRTJar(project, "JRE_LIB_TEST", null, null);//$NON-NLS-1$
		TestCase.assertNotNull(jdk);

		File junitSrcArchive= JavaTestPlugin.getDefault().getFileInPlugin(JUNIT_SRC_381);
		TestCase.assertTrue(junitSrcArchive != null && junitSrcArchive.exists());

		JavaProjectHelper.addSourceContainerWithImport(project, srcContainerName, junitSrcArchive, JUNIT_SRC_ENCODING);

		return project;
	}

	/**
	 * Sets the compiler options to 9 for the given project.
	 * 
	 * @param project the java project
	 * @since 3.14
	 */
	public static void set9CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		set9CompilerOptions(options);
		project.setOptions(options);
	}

	/**
	 * Sets the compiler options to 10 for the given project.
	 * 
	 * @param project the java project
	 * @since 3.14
	 */
	public static void set10CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		set10CompilerOptions(options);
		project.setOptions(options);
	}

	/**
	 * Sets the compiler options to 1.8 for the given project.
	 * 
	 * @param project the java project
	 * @since 3.10
	 */
	public static void set18CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		set18CompilerOptions(options);
		project.setOptions(options);
	}

	/**
	 * Sets the compiler options to 1.7 for the given project.
	 * @param project the java project
	 */
	public static void set17CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		JavaProjectHelper.set17CompilerOptions(options);
		project.setOptions(options);
	}
	
	/**
	 * Sets the compiler options to 1.6 for the given project.
	 * @param project the java project
	 */
	public static void set16CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		JavaProjectHelper.set16CompilerOptions(options);
		project.setOptions(options);
	}
	
	/**
	 * Sets the compiler options to 1.5 for the given project.
	 * @param project the java project
	 */
	public static void set15CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		JavaProjectHelper.set15CompilerOptions(options);
		project.setOptions(options);
	}

	/**
	 * Sets the compiler options to 1.4 for the given project.
	 * @param project the java project
	 */
	public static void set14CompilerOptions(IJavaProject project) {
		Map<String, String> options= project.getOptions(false);
		JavaProjectHelper.set14CompilerOptions(options);
		project.setOptions(options);
	}


	/**
	 * Sets the compiler options to 9.
	 * 
	 * @param options the compiler options to configure
	 * @since 3.14
	 */
	public static void set9CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_9, options);
	}

	/**
	 * Sets the compiler options to 10.
	 * 
	 * @param options the compiler options to configure
	 * @since 3.14
	 */
	public static void set10CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_10, options);
	}

	/**
	 * Sets the compiler options to 1.8
	 * 
	 * @param options the compiler options to configure
	 * @since 3.10
	 */
	public static void set18CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
	}

	/**
	 * Sets the compiler options to 1.7
	 * @param options The compiler options to configure
	 */
	public static void set17CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options);
	}
	
	/**
	 * Sets the compiler options to 1.6
	 * @param options The compiler options to configure
	 */
	public static void set16CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options);
	}

	/**
	 * Sets the compiler options to 1.5
	 * @param options The compiler options to configure
	 */
	public static void set15CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_5, options);
	}

	/**
	 * Sets the compiler options to 1.4
	 * @param options The compiler options to configure
	 */
	public static void set14CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_4, options);
	}

	/**
	 * Sets the compiler options to 1.3
	 * @param options The compiler options to configure
	 */
	public static void set13CompilerOptions(Map<String, String> options) {
		JavaCore.setComplianceOptions(JavaCore.VERSION_1_3, options);
	}

	/**
	 * Removes an IJavaElement's resource. Retries if deletion failed (e.g. because the indexer
	 * still locks the file).
	 *
	 * @param elem the element to delete
	 * @throws CoreException if operation failed
	 * @see #ASSERT_NO_MIXED_LINE_DELIMIERS
	 */
	public static void delete(final IJavaElement elem) throws CoreException {
		if (ASSERT_NO_MIXED_LINE_DELIMIERS)
			MixedLineDelimiterDetector.assertNoMixedLineDelimiters(elem);

		IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				performDummySearch();
				if (elem instanceof IJavaProject) {
					IJavaProject jproject= (IJavaProject) elem;
					jproject.setRawClasspath(new IClasspathEntry[0], jproject.getProject().getFullPath(), null);
				}
				delete(elem.getResource());
			}
		};
		ResourcesPlugin.getWorkspace().run(runnable, null);
		emptyDisplayLoop();
	}

	/**
	 * Removes a resource. Retries if deletion failed (e.g. because the indexer
	 * still locks the file).
	 * 
	 * @param resource the resource to delete
	 * @throws CoreException if operation failed
	 */
	public static void delete(IResource resource) throws CoreException {
		for (int i= 0; i < MAX_RETRY; i++) {
			try {
				resource.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, null);
				i= MAX_RETRY;
			} catch (CoreException e) {
				if (i == MAX_RETRY - 1) {
					JavaPlugin.log(e);
					throw e;
				}
				try {
					JavaPlugin.log(new IllegalStateException("sleep before retrying JavaProjectHelper.delete() for " + resource.getLocationURI()));
					Thread.sleep(RETRY_DELAY); // give other threads time to close the file
				} catch (InterruptedException e1) {
				}
			}
		}
	}
	
	/**
	 * Removes a package fragment. Retries if deletion failed (e.g. because the indexer
	 * still locks a file).
	 * 
	 * @param pack the package to delete
	 * @throws CoreException if operation failed
	 */
	public static void deletePackage(IPackageFragment pack) throws CoreException {
		for (int i= 0; i < MAX_RETRY; i++) {
			try {
				pack.delete(true, null);
				i= MAX_RETRY;
			} catch (CoreException e) {
				if (i == MAX_RETRY - 1) {
					JavaPlugin.log(e);
					throw e;
				}
				try {
					JavaPlugin.log(new IllegalStateException("sleep before retrying JavaProjectHelper.delete() for package " + pack.getHandleIdentifier()));
					Thread.sleep(RETRY_DELAY); // give other threads time to close the file
				} catch (InterruptedException e1) {
				}
			}
		}
	}

	/**
	 * Removes all files in the project and sets the given classpath
	 * @param jproject The project to clear
	 * @param entries The default class path to set
	 * @throws Exception Clearing the project failed
	 */
	public static void clear(final IJavaProject jproject, final IClasspathEntry[] entries) throws Exception {
		performDummySearch();
		IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				jproject.setRawClasspath(entries, null);

				IResource[] resources= jproject.getProject().members();
				for (int i= 0; i < resources.length; i++) {
					if (!resources[i].getName().startsWith(".")) {
						delete(resources[i]);
					}
				}
			}
		};
		ResourcesPlugin.getWorkspace().run(runnable, null);

		JavaProjectHelper.emptyDisplayLoop();
	}


	public static void mustPerformDummySearch() throws JavaModelException {
		performDummySearch(SearchEngine.createWorkspaceScope(), true);
	}

	public static void mustPerformDummySearch(IJavaElement element) throws JavaModelException {
		performDummySearch(SearchEngine.createJavaSearchScope(new IJavaElement[] { element }), true);
	}
	
	public static void performDummySearch() throws JavaModelException {
		performDummySearch(SearchEngine.createWorkspaceScope(), PERFORM_DUMMY_SEARCH > 0);
	}

	public static void performDummySearch(IJavaElement element) throws JavaModelException {
		performDummySearch(SearchEngine.createJavaSearchScope(new IJavaElement[] { element }), PERFORM_DUMMY_SEARCH > 0);
	}

	private static void performDummySearch(IJavaSearchScope searchScope, boolean doIt) throws JavaModelException {
		/*
		 * Workaround for intermittent test failures. The problem is that the Java indexer
		 * may still be reading a file that has just been created, but a test already tries to delete
		 * the file again.
		 * 
		 * This can theoretically also happen in real life, but it's expected to be very rare,
		 * and there's no good solution for the problem, since the Java indexer should not
		 * take a workspace lock for these files.
		 * 
		 * performDummySearch() was found to be a performance bottleneck, so we've disabled it in most situations.
		 * Use a mustPerformDummySearch() method if you really need it and you can't
		 * use a delete(..) method that retries a few times before failing.
		 */
		if (!doIt)
			return;
		
		new SearchEngine().searchAllTypeNames(
				null,
				SearchPattern.R_EXACT_MATCH,
				"XXXXXXXXX".toCharArray(), // make sure we search a concrete name. This is faster according to Kent
				SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
				IJavaSearchConstants.CLASS,
				searchScope,
				new Requestor(),
				IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
				null);
	}

	/**
	 * Adds a source container to a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName The name of the new source container
	 * @return The handle to the new source container
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName) throws CoreException {
		return addSourceContainer(jproject, containerName, new Path[0]);
	}

	/**
	 * Adds a source container to a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName The name of the new source container
	 * @param exclusionFilters Exclusion filters to set
	 * @return The handle to the new source container
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName, IPath[] exclusionFilters) throws CoreException {
		return addSourceContainer(jproject, containerName, new Path[0], exclusionFilters);
	}

	/**
	 * Adds a source container to a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName The name of the new source container
	 * @param inclusionFilters Inclusion filters to set
	 * @param exclusionFilters Exclusion filters to set
	 * @return The handle to the new source container
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName, IPath[] inclusionFilters, IPath[] exclusionFilters) throws CoreException {
		return addSourceContainer(jproject, containerName, inclusionFilters, exclusionFilters, null);
	}

	/**
	 * Adds a source container to a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName The name of the new source container
	 * @param inclusionFilters Inclusion filters to set
	 * @param exclusionFilters Exclusion filters to set
	 * @param outputLocation The location where class files are written to, <b>null</b> for project output folder
	 * @return The handle to the new source container
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName, IPath[] inclusionFilters, IPath[] exclusionFilters, String outputLocation) throws CoreException {
		return addSourceContainer(jproject, containerName, inclusionFilters, exclusionFilters, outputLocation,
				new IClasspathAttribute[0]);
	}
	/**
	 * Adds a source container to a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName The name of the new source container
	 * @param inclusionFilters Inclusion filters to set
	 * @param exclusionFilters Exclusion filters to set
	 * @param outputLocation The location where class files are written to, <b>null</b> for project output folder
	 * @param attributes The classpath attributes to set
	 * @return The handle to the new source container
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainer(IJavaProject jproject, String containerName, IPath[] inclusionFilters, IPath[] exclusionFilters, String outputLocation, IClasspathAttribute[] attributes) throws CoreException {
		IProject project= jproject.getProject();
		IContainer container= null;
		if (containerName == null || containerName.length() == 0) {
			container= project;
		} else {
			IFolder folder= project.getFolder(containerName);
			if (!folder.exists()) {
				CoreUtility.createFolder(folder, false, true, null);
			}
			container= folder;
		}
		IPackageFragmentRoot root= jproject.getPackageFragmentRoot(container);

		IPath outputPath= null;
		if (outputLocation != null) {
			IFolder folder= project.getFolder(outputLocation);
			if (!folder.exists()) {
				CoreUtility.createFolder(folder, false, true, null);
			}
			outputPath= folder.getFullPath();
		}
		IClasspathEntry cpe= JavaCore.newSourceEntry(root.getPath(), inclusionFilters, exclusionFilters, outputPath, attributes);
		addToClasspath(jproject, cpe);
		return root;
	}

	/**
	 * Adds a source container to a IJavaProject and imports all files contained
	 * in the given ZIP file.
	 * @param jproject The parent project
	 * @param containerName Name of the source container
	 * @param zipFile Archive to import
	 * @param containerEncoding encoding for the generated source container
	 * @return The handle to the new source container
	 * @throws InvocationTargetException Creation failed
	 * @throws CoreException Creation failed
	 * @throws IOException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainerWithImport(IJavaProject jproject, String containerName, File zipFile, String containerEncoding) throws InvocationTargetException, CoreException, IOException {
		return addSourceContainerWithImport(jproject, containerName, zipFile, containerEncoding, new Path[0]);
	}

	/**
	 * Adds a source container to a IJavaProject and imports all files contained
	 * in the given ZIP file.
	 * @param jproject The parent project
	 * @param containerName Name of the source container
	 * @param zipFile Archive to import
	 * @param containerEncoding encoding for the generated source container
	 * @param exclusionFilters Exclusion filters to set
	 * @return The handle to the new source container
	 * @throws InvocationTargetException Creation failed
	 * @throws CoreException Creation failed
	 * @throws IOException Creation failed
	 */
	public static IPackageFragmentRoot addSourceContainerWithImport(IJavaProject jproject, String containerName, File zipFile, String containerEncoding, IPath[] exclusionFilters) throws InvocationTargetException, CoreException, IOException {
		ZipFile file= new ZipFile(zipFile);
		try {
			IPackageFragmentRoot root= addSourceContainer(jproject, containerName, exclusionFilters);
			((IContainer) root.getCorrespondingResource()).setDefaultCharset(containerEncoding, null);
			importFilesFromZip(file, root.getPath(), null);
			return root;
		} finally {
			file.close();
		}
	}

	/**
	 * Removes a source folder from a IJavaProject.
	 * @param jproject The parent project
	 * @param containerName Name of the source folder to remove
	 * @throws CoreException Remove failed
	 */
	public static void removeSourceContainer(IJavaProject jproject, String containerName) throws CoreException {
		IFolder folder= jproject.getProject().getFolder(containerName);
		removeFromClasspath(jproject, folder.getFullPath());
		folder.delete(true, null);
	}

	/**
	 * Adds a library entry to a IJavaProject.
	 * @param jproject The parent project
	 * @param path The path of the library to add
	 * @return The handle of the created root
	 * @throws JavaModelException
	 */
	public static IPackageFragmentRoot addLibrary(IJavaProject jproject, IPath path) throws JavaModelException {
		return addLibrary(jproject, path, null, null);
	}

	/**
	 * Adds a library entry with source attachment to a IJavaProject.
	 * @param jproject The parent project
	 * @param path The path of the library to add
	 * @param sourceAttachPath The source attachment path
	 * @param sourceAttachRoot The source attachment root path
	 * @return The handle of the created root
	 * @throws JavaModelException
	 */
	public static IPackageFragmentRoot addLibrary(IJavaProject jproject, IPath path, IPath sourceAttachPath, IPath sourceAttachRoot) throws JavaModelException {
		IClasspathEntry cpe= JavaCore.newLibraryEntry(path, sourceAttachPath, sourceAttachRoot);
		addToClasspath(jproject, cpe);
		IResource workspaceResource= ResourcesPlugin.getWorkspace().getRoot().findMember(path);
		if (workspaceResource != null) {
			return jproject.getPackageFragmentRoot(workspaceResource);
		}
		return jproject.getPackageFragmentRoot(path.toString());
	}


	/**
	 * Copies the library into the project and adds it as library entry.
	 * @param jproject The parent project
	 * @param jarPath
	 * @param sourceAttachPath The source attachment path
	 * @param sourceAttachRoot The source attachment root path
	 * @return The handle of the created root
	 * @throws IOException
	 * @throws CoreException
	 */
	public static IPackageFragmentRoot addLibraryWithImport(IJavaProject jproject, IPath jarPath, IPath sourceAttachPath, IPath sourceAttachRoot) throws IOException, CoreException {
		IProject project= jproject.getProject();
		IFile newFile= project.getFile(jarPath.lastSegment());
		InputStream inputStream= null;
		try {
			inputStream= new FileInputStream(jarPath.toFile());
			newFile.create(inputStream, true, null);
		} finally {
			if (inputStream != null) {
				try { inputStream.close(); } catch (IOException e) { }
			}
		}
		return addLibrary(jproject, newFile.getFullPath(), sourceAttachPath, sourceAttachRoot);
	}

	/**
	 * Creates and adds a class folder to the class path.
	 * @param jproject The parent project
	 * @param containerName
	 * @param sourceAttachPath The source attachment path
	 * @param sourceAttachRoot The source attachment root path
	 * @return The handle of the created root
	 * @throws CoreException
	 */
	public static IPackageFragmentRoot addClassFolder(IJavaProject jproject, String containerName, IPath sourceAttachPath, IPath sourceAttachRoot) throws CoreException {
		IProject project= jproject.getProject();
		IContainer container= null;
		if (containerName == null || containerName.length() == 0) {
			container= project;
		} else {
			IFolder folder= project.getFolder(containerName);
			if (!folder.exists()) {
				CoreUtility.createFolder(folder, false, true, null);
			}
			container= folder;
		}
		IClasspathEntry cpe= JavaCore.newLibraryEntry(container.getFullPath(), sourceAttachPath, sourceAttachRoot);
		addToClasspath(jproject, cpe);
		return jproject.getPackageFragmentRoot(container);
	}

	/**
	 * Creates and adds a class folder to the class path and imports all files
	 * contained in the given ZIP file.
	 * @param jproject The parent project
	 * @param containerName
	 * @param sourceAttachPath The source attachment path
	 * @param sourceAttachRoot The source attachment root path
	 * @param zipFile
	 * @return The handle of the created root
	 * @throws IOException
	 * @throws CoreException
	 * @throws InvocationTargetException
	 */
	public static IPackageFragmentRoot addClassFolderWithImport(IJavaProject jproject, String containerName, IPath sourceAttachPath, IPath sourceAttachRoot, File zipFile) throws IOException, CoreException, InvocationTargetException {
		ZipFile file= new ZipFile(zipFile);
		try {
			IPackageFragmentRoot root= addClassFolder(jproject, containerName, sourceAttachPath, sourceAttachRoot);
			importFilesFromZip(file, root.getPath(), null);
			return root;
		} finally {
			file.close();
		}
	}

	/**
	 * Adds a library entry pointing to a JRE (stubs only)
	 * and sets the right compiler options.
	 * <p>Currently, the compiler compliance level is 1.5.
	 *
	 * @param jproject target
	 * @return the new package fragment root
	 * @throws CoreException
	 */
	public static IPackageFragmentRoot addRTJar(IJavaProject jproject) throws CoreException {
		return addRTJar15(jproject);
	}

	public static IPackageFragmentRoot addRTJar13(IJavaProject jproject) throws CoreException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_13);

		Map<String, String> options= jproject.getOptions(false);
		JavaProjectHelper.set13CompilerOptions(options);
		jproject.setOptions(options);

		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	public static IPackageFragmentRoot addRTJar15(IJavaProject jproject) throws CoreException, JavaModelException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_15);
		set15CompilerOptions(jproject);
		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	public static IPackageFragmentRoot addRTJar16(IJavaProject jproject) throws CoreException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_16);
		set16CompilerOptions(jproject);
		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	public static IPackageFragmentRoot addRTJar17(IJavaProject jproject) throws CoreException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_17);
		set17CompilerOptions(jproject);
		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	public static IPackageFragmentRoot addRTJar18(IJavaProject jproject) throws CoreException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_18);
		set18CompilerOptions(jproject);
		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	public static IPackageFragmentRoot addRTJar9(IJavaProject jproject) throws CoreException {
		IPath[] rtJarPath= findRtJar(RT_STUBS_9);
		set9CompilerOptions(jproject);
		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
	}

	/**
	 * Adds a variable entry with source attachment to a IJavaProject.
	 * Can return null if variable can not be resolved.
	 * @param jproject The parent project
	 * @param path The variable path
	 * @param sourceAttachPath The source attachment path (variable path)
	 * @param sourceAttachRoot The source attachment root path (variable path)
	 * @return The added package fragment root
	 * @throws JavaModelException
	 */
	public static IPackageFragmentRoot addVariableEntry(IJavaProject jproject, IPath path, IPath sourceAttachPath, IPath sourceAttachRoot) throws JavaModelException {
		IClasspathEntry cpe= JavaCore.newVariableEntry(path, sourceAttachPath, sourceAttachRoot);
		addToClasspath(jproject, cpe);
		IPath resolvedPath= JavaCore.getResolvedVariablePath(path);
		if (resolvedPath != null) {
			return jproject.getPackageFragmentRoot(resolvedPath.toString());
		}
		return null;
	}

	public static IPackageFragmentRoot addVariableRTJar13(IJavaProject jproject, String libVarName, String srcVarName, String srcrootVarName) throws CoreException {
		return addVariableRTJar(jproject, RT_STUBS_13, libVarName, srcVarName, srcrootVarName);
	}

	/**
	 * Adds a variable entry pointing to a current JRE (stubs only)
	 * and sets the compiler compliance level on the project accordingly.
	 * The arguments specify the names of the variables to be used.
	 * Currently, the compiler compliance level is set to 1.5.
	 *
	 * @param jproject the project to add the variable RT JAR
	 * @param libVarName Name of the variable for the library
	 * @param srcVarName Name of the variable for the source attachment. Can be <code>null</code>.
	 * @param srcrootVarName name of the variable for the source attachment root. Can be <code>null</code>.
	 * @return the new package fragment root
	 * @throws CoreException Creation failed
	 */
	public static IPackageFragmentRoot addVariableRTJar(IJavaProject jproject, String libVarName, String srcVarName, String srcrootVarName) throws CoreException {
		return addVariableRTJar(jproject, RT_STUBS_15, libVarName, srcVarName, srcrootVarName);
	}

	/**
	 * Adds a variable entry pointing to a current JRE (stubs only).
	 * The arguments specify the names of the variables to be used.
	 * Clients must not forget to set the right compiler compliance level on the project.
	 *
	 * @param jproject the project to add the variable RT JAR
	 * @param rtStubsPath path to an rt.jar
	 * @param libVarName name of the variable for the library
	 * @param srcVarName Name of the variable for the source attachment. Can be <code>null</code>.
	 * @param srcrootVarName Name of the variable for the source attachment root. Can be <code>null</code>.
	 * @return the new package fragment root
	 * @throws CoreException Creation failed
	 */
	private static IPackageFragmentRoot addVariableRTJar(IJavaProject jproject, IPath rtStubsPath, String libVarName, String srcVarName, String srcrootVarName) throws CoreException {
		IPath[] rtJarPaths= findRtJar(rtStubsPath);
		IPath libVarPath= new Path(libVarName);
		IPath srcVarPath= null;
		IPath srcrootVarPath= null;
		JavaCore.setClasspathVariable(libVarName, rtJarPaths[0], null);
		if (srcVarName != null) {
			IPath varValue= rtJarPaths[1] != null ? rtJarPaths[1] : Path.EMPTY;
			JavaCore.setClasspathVariable(srcVarName, varValue, null);
			srcVarPath= new Path(srcVarName);
		}
		if (srcrootVarName != null) {
			IPath varValue= rtJarPaths[2] != null ? rtJarPaths[2] : Path.EMPTY;
			JavaCore.setClasspathVariable(srcrootVarName, varValue, null);
			srcrootVarPath= new Path(srcrootVarName);
		}
		return addVariableEntry(jproject, libVarPath, srcVarPath, srcrootVarPath);
	}

	/**
	 * Adds a required project entry.
	 * @param jproject Parent project
	 * @param required Project to add to the build path
	 * @throws JavaModelException Creation failed
	 */
	public static void addRequiredProject(IJavaProject jproject, IJavaProject required) throws JavaModelException {
		IClasspathEntry cpe= JavaCore.newProjectEntry(required.getProject().getFullPath());
		addToClasspath(jproject, cpe);
	}

	public static void removeFromClasspath(IJavaProject jproject, IPath path) throws JavaModelException {
		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
		int nEntries= oldEntries.length;
		ArrayList<IClasspathEntry> list= new ArrayList<>(nEntries);
		for (int i= 0 ; i < nEntries ; i++) {
			IClasspathEntry curr= oldEntries[i];
			if (!path.equals(curr.getPath())) {
				list.add(curr);
			}
		}
		IClasspathEntry[] newEntries= list.toArray(new IClasspathEntry[list.size()]);
		jproject.setRawClasspath(newEntries, null);
	}

	public static void addToClasspath(IJavaProject jproject, IClasspathEntry cpe) throws JavaModelException {
		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
		for (int i= 0; i < oldEntries.length; i++) {
			if (oldEntries[i].equals(cpe)) {
				return;
			}
		}
		int nEntries= oldEntries.length;
		IClasspathEntry[] newEntries= new IClasspathEntry[nEntries + 1];
		System.arraycopy(oldEntries, 0, newEntries, 0, nEntries);
		newEntries[nEntries]= cpe;
		jproject.setRawClasspath(newEntries, null);
	}

	/**
	 * @param rtStubsPath the path to the RT stubs
	 * @return a rt.jar (stubs only)
	 * @throws CoreException
	 */
	public static IPath[] findRtJar(IPath rtStubsPath) throws CoreException {
		File rtStubs= JavaTestPlugin.getDefault().getFileInPlugin(rtStubsPath);
		TestCase.assertNotNull(rtStubs);
		TestCase.assertTrue(rtStubs.exists());
		return new IPath[] {
			Path.fromOSString(rtStubs.getPath()),
			null,
			null
		};
	}

	private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
		IProjectDescription description = proj.getDescription();
		String[] prevNatures= description.getNatureIds();
		String[] newNatures= new String[prevNatures.length + 1];
		System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
		newNatures[prevNatures.length]= natureId;
		description.setNatureIds(newNatures);
		proj.setDescription(description, monitor);
	}

	public static void importFilesFromZip(ZipFile srcZipFile, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException {
		ZipFileStructureProvider structureProvider=	new ZipFileStructureProvider(srcZipFile);
		try {
			ImportOperation op= new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, new ImportOverwriteQuery());
			op.run(monitor);
		} catch (InterruptedException e) {
			// should not happen
		}
	}

	/**
	 * Imports resources from <code>bundleSourcePath</code> inside <code>bundle</code> into <code>importTarget</code>.
	 *
	 * @param importTarget the parent container
	 * @param bundle the bundle
	 * @param bundleSourcePath the path to a folder containing resources
	 *
	 * @throws CoreException import failed
	 * @throws IOException import failed
	 */
	public static void importResources(IContainer importTarget, Bundle bundle, String bundleSourcePath) throws CoreException, IOException {
		Enumeration<String> entryPaths= bundle.getEntryPaths(bundleSourcePath);
		while (entryPaths.hasMoreElements()) {
			String path= entryPaths.nextElement();
			IPath name= new Path(path.substring(bundleSourcePath.length()));
			if (path.endsWith("/")) {
				IFolder folder= importTarget.getFolder(name);
				folder.create(false, true, null);
				importResources(folder, bundle, path);
			} else {
				URL url= bundle.getEntry(path);
				IFile file= importTarget.getFile(name);
				file.create(url.openStream(), true, null);
			}
		}
	}

	private static class ImportOverwriteQuery implements IOverwriteQuery {
		@Override
		public String queryOverwrite(String file) {
			return ALL;
		}
	}

	private static class Requestor extends TypeNameRequestor{
	}

	public static void emptyDisplayLoop() {
		boolean showDebugInfo= false;

		Display display= Display.getCurrent();
		if (display != null) {
			if (showDebugInfo) {
				try {
					Synchronizer synchronizer= display.getSynchronizer();
					Field field= Synchronizer.class.getDeclaredField("messageCount");
					field.setAccessible(true);
					System.out.println("Processing " + field.getInt(synchronizer) + " messages in queue");
				} catch (Exception e) {
					// ignore
					System.out.println(e);
				}
			}
			while (display.readAndDispatch()) { /*loop*/ }
		}
	}
}

