/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *
 *******************************************************************************/
package org.eclipse.dltk.core.tests.buildpath;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuildpathAttribute;
import org.eclipse.dltk.core.IBuildpathContainer;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IModelElementDelta;
import org.eclipse.dltk.core.IModelMarker;
import org.eclipse.dltk.core.IModelStatus;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.internal.environment.LocalEnvironment;
import org.eclipse.dltk.core.tests.model.AbstractModelTests;
import org.eclipse.dltk.core.tests.model.ModelTestsPlugin;
import org.eclipse.dltk.core.tests.model.ModifyingResourceTests;
import org.eclipse.dltk.core.tests.util.Util;
import org.eclipse.dltk.internal.core.ArchiveProjectFragment;
import org.eclipse.dltk.internal.core.BuildpathEntry;
import org.eclipse.dltk.internal.core.ScriptProject;
import org.eclipse.dltk.utils.CorePrinter;

import junit.framework.Test;

public class BuildpathTests extends ModifyingResourceTests {

	private static final String[] TEST_NATURE = new String[] {
			"org.eclipse.dltk.core.tests.testnature" };

	private static final String BUILDPATH_PRJ_0 = "Buildpath0";

	private static final String BUILDPATH_PRJ_1 = "Buildpath1";

	private static final String BUILDPATH_PRJ_2 = "Buildpath2";

	private static final String BUILDPATH_PRJ_4 = "Buildpath4";

	public class TestContainer implements IBuildpathContainer {
		IPath path;

		IBuildpathEntry[] entries;

		TestContainer(IPath path, IBuildpathEntry[] entries) {
			this.path = path;
			this.entries = entries;
		}

		@Override
		public IPath getPath() {
			return this.path;
		}

		@Override
		public IBuildpathEntry[] getBuildpathEntries() {
			return this.entries;
		}

		@Override
		public String getDescription() {
			return this.path.toString();
		}

		@Override
		public int getKind() {
			return 0;
		}

	}

	public BuildpathTests(String name) {
		super(ModelTestsPlugin.PLUGIN_NAME, name);
	}

	public static Test suite() {
		return new Suite(BuildpathTests.class);
	}

	@Override
	public void setUpSuite() throws Exception {
		super.setUpSuite();
		setUpScriptProject("ModelMembers");

		setUpScriptProject(BUILDPATH_PRJ_0);
		setUpScriptProject(BUILDPATH_PRJ_1);
		setUpScriptProject("p1");
		setUpScriptProject("p2");
	}

	private void assertEncodeDecodeEntry(String projectName,
			String expectedEncoded, IBuildpathEntry entry) {
		IScriptProject project = getScriptProject(projectName);
		String encoded = project.encodeBuildpathEntry(entry);
		assertSourceEquals("Unexpected encoded entry", expectedEncoded,
				encoded);
		IBuildpathEntry decoded = project.decodeBuildpathEntry(encoded);
		assertEquals("Unexpected decoded entry", entry, decoded);
	}

	protected void assertStatus(String expected, IStatus status) {
		String actual = status.getMessage();
		if (!expected.equals(actual)) {
			// System.out.print(Util.displayString(actual, 2));
			// System.out.println(",");
		}
		assertEquals(expected, actual);
	}

	protected void assertStatus(String message, String expected,
			IStatus status) {
		String actual = status.getMessage();
		if (!expected.equals(actual)) {
			// System.out.print(Util.displayString(actual, 2));
			// System.out.println(",");
		}
		assertEquals(message, expected, actual);
	}

	protected File createFile(File parent, String name, String content)
			throws IOException {
		File file = new File(parent, name);
		try (FileOutputStream out = new FileOutputStream(file)) {
			out.write(content.getBytes());
		}
		/*
		 * Need to change the time stamp to realize that the file has been
		 * modified
		 */
		file.setLastModified(System.currentTimeMillis() + 2000);
		return file;
	}

	protected File createFolder(File parent, String name) {
		File file = new File(parent, name);
		file.mkdirs();
		return file;
	}

	protected int numberOfCycleMarkers(IScriptProject scriptProject)
			throws CoreException {
		IMarker[] markers = scriptProject.getProject().findMarkers(
				IModelMarker.BUILDPATH_PROBLEM_MARKER, false,
				IResource.DEPTH_ZERO);
		int result = 0;
		for (int i = 0, length = markers.length; i < length; i++) {
			IMarker marker = markers[i];
			String cycleAttr = (String) marker
					.getAttribute(IModelMarker.CYCLE_DETECTED);
			if (cycleAttr != null && cycleAttr.equals("true")) { //$NON-NLS-1$
				result++;
			}
		}
		return result;
	}

	protected int numberOfBuildpathProblems(IScriptProject scriptProject)
			throws CoreException {
		IMarker[] markers = scriptProject.getProject().findMarkers(
				IModelMarker.BUILDPATH_PROBLEM_MARKER, false,
				IResource.DEPTH_ZERO);
		return markers.length;
	}

	@Override
	public void tearDownSuite() throws Exception {
		deleteProject("ModelMembers");
		deleteProject(BUILDPATH_PRJ_0);
		deleteProject(BUILDPATH_PRJ_1);
		deleteProject("p1");
		deleteProject("p2");
		super.tearDownSuite();
	}

	public void test001() throws ModelException {
		ScriptProject project = (ScriptProject) getScriptProject(
				BUILDPATH_PRJ_0);
		assertNotNull(project);
		IBuildpathEntry entrys[] = project.getRawBuildpath();
		assertEquals(3, entrys.length);
		assertEquals(IBuildpathEntry.BPE_SOURCE, entrys[0].getEntryKind());
		assertEquals(IBuildpathEntry.BPE_PROJECT, entrys[1].getEntryKind());
		assertEquals(IBuildpathEntry.BPE_SOURCE, entrys[2].getEntryKind());
		IModelElement[] children = project.getChildren();
		assertEquals("Sould be 2 accessible project fragments", 2,
				children.length);
		assertTrue(children[0] instanceof IProjectFragment);
		assertTrue(children[1] instanceof IProjectFragment);
		IProjectFragment fr0 = (IProjectFragment) children[0];
		IProjectFragment fr1 = (IProjectFragment) children[1];

		children = fr0.getChildren();
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof IScriptFolder);
		IModelElement[] folderChildren = ((IScriptFolder) children[0])
				.getChildren();
		assertEquals(2, folderChildren.length);
		assertTrue(folderChildren[0] instanceof ISourceModule);
		assertEquals("X.txt",
				((ISourceModule) (folderChildren[0])).getElementName());
		assertEquals("X2.txt",
				((ISourceModule) (folderChildren[1])).getElementName());
		assertTrue(folderChildren[1] instanceof ISourceModule);

		children = fr1.getChildren();
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof IScriptFolder);
		folderChildren = ((IScriptFolder) children[0]).getChildren();
		assertEquals(1, folderChildren.length);
		assertTrue(folderChildren[0] instanceof ISourceModule);
		assertEquals("X3.txt",
				((ISourceModule) (folderChildren[0])).getElementName());
	}

	public void test002() throws ModelException {
		ScriptProject project = (ScriptProject) getScriptProject(
				BUILDPATH_PRJ_0);
		ScriptProject project2 = (ScriptProject) getScriptProject(
				BUILDPATH_PRJ_1);
		assertNotNull(project);
		IProjectFragment fragments[] = project.getProjectFragments();
		IBuildpathEntry entrys[] = project.getResolvedBuildpath();

		// CorePrinter cPrinter = new CorePrinter(System.out);
		// System.out.println("Project 1 model:");
		// project.printNode(cPrinter);
		// cPrinter.flush();
		// System.out.println("Project 2 model:");
		// project2.printNode(cPrinter);
		// cPrinter.flush();
	}

	/**
	 * Testie container test
	 *
	 * @throws ModelException
	 */
	public void test003() throws ModelException {
		ScriptProject project = (ScriptProject) getScriptProject(
				BUILDPATH_PRJ_0);
		ScriptProject project2 = (ScriptProject) getScriptProject(
				BUILDPATH_PRJ_1);
		assertNotNull(project);
		IProjectFragment fragments[] = project.getProjectFragments();
		IBuildpathEntry entrys[] = project.getResolvedBuildpath();

		// CorePrinter cPrinter = new CorePrinter(System.out);
		// System.out.println("Project 1 model:");
		// project.printNode(cPrinter);
		// cPrinter.flush();
		// System.out.println("Project 2 model:");
		// project2.printNode(cPrinter);
		// cPrinter.flush();
	}

	/**
	 * Library BuildpathEntry test
	 *
	 * @throws Exception
	 */
	public void test004() throws Exception {
		try {
			setUpScriptProject(BUILDPATH_PRJ_2);
			IScriptProject project = getScriptProject(BUILDPATH_PRJ_2);
			assertNotNull(project);
			IBuildpathEntry entrys[] = project.getRawBuildpath();
			assertEquals(1, entrys.length);
			assertEquals(IBuildpathEntry.BPE_LIBRARY, entrys[0].getEntryKind());
			IProjectFragment[] fragments = project.getProjectFragments();
			assertEquals(1, fragments.length);
			assertTrue(fragments[0] instanceof ArchiveProjectFragment);
			IProjectFragment fragment = fragments[0];
			IModelElement[] elements = fragment.getChildren();

			// System.out.println("Model:");
			CorePrinter printer = new CorePrinter(System.out);
			((ScriptProject) project).printNode(printer);
			printer.flush();
		} finally {
			deleteProject(BUILDPATH_PRJ_2);
		}
	}

	/**
	 * External folder Library BuildpathEntry test
	 *
	 * @throws Exception
	 */
	public void test005() throws Exception {
		try {
			URL url = ModelTestsPlugin.getDefault().getBundle()
					.getEntry("workspace/Buildpath3");
			URL res = FileLocator.resolve(url);
			IPath filePath = new Path(res.getFile());
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			IEnvironment env = LocalEnvironment.getInstance();
			newCP[originalCP.length] = DLTKCore.newExtLibraryEntry(
					EnvironmentPathUtils.getFullPath(env, filePath));

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus("OK", status);

			proj.setRawBuildpath(newCP, null);

			IProjectFragment[] fragments = proj.getProjectFragments();
			assertEquals(2, fragments.length);
			// System.out.println("Model:");
			CorePrinter printer = new CorePrinter(System.out, true);
			((ScriptProject) proj).printNode(printer);
			printer.flush();

		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	public void test006() throws Exception {
		try {
			URL url = ModelTestsPlugin.getDefault().getBundle()
					.getEntry("/workspace/Buildpath3");
			URL res = FileLocator.resolve(url);

			IPath localPath = new Path("Testie")
					.append(res.getFile().substring(1));
			IPath contPath = localPath;
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newContainerEntry(contPath);

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus("OK", status);

			proj.setRawBuildpath(newCP, null);

			IProjectFragment[] fragments = proj.getProjectFragments();
			assertEquals(2, fragments.length);

			// System.out.println("Model:");
			CorePrinter printer = new CorePrinter(System.out, true);
			((ScriptProject) proj).printNode(printer);
			printer.flush();
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/*
	 * Ensures that a source Buildpath entry can be encoded and decoded.
	 */
	public void testEncodeDecodeEntry01() {
		assertEncodeDecodeEntry("P",
				"<buildpathentry kind=\"src\" path=\"src\"/>\n",
				DLTKCore.newSourceEntry(new Path("/P/src")));
	}

	/*
	 * Ensures that a source Buildpath entry with all possible attributes can be
	 * encoded and decoded.
	 */
	public void testEncodeDecodeEntry02() {
		assertEncodeDecodeEntry("P",
				"<buildpathentry excluding=\"**/X.java\" including=\"**/Y.java\" kind=\"src\" path=\"src\">\n"
						+ "	<attributes>\n"
						+ "		<attribute name=\"attrName\" value=\"some value\"/>\n"
						+ "	</attributes>\n" + "</buildpathentry>\n",
				DLTKCore.newSourceEntry(new Path("/P/src"),
						new IPath[] { new Path("**/Y.java") },
						new IPath[] { new Path("**/X.java") },
						new IBuildpathAttribute[] {
								DLTKCore.newBuildpathAttribute("attrName",
										"some value") }));
	}

	/*
	 * Ensures that a project Buildpath entry can be encoded and decoded.
	 */
	public void testEncodeDecodeEntry03() {
		assertEncodeDecodeEntry("P1",
				"<buildpathentry kind=\"prj\" path=\"/P2\"/>\n",
				DLTKCore.newProjectEntry(new Path("/P2")));
	}

	/**
	 * Ensures that adding an empty Buildpath container generates the correct
	 * deltas.
	 */
	public void testEmptyContainer() throws CoreException {
		try {
			IScriptProject proj = createScriptProject("P", TEST_NATURE, null);

			startDeltas();

			// create container
			DLTKCore.setBuildpathContainer(new Path("container/default"),
					new IScriptProject[] { proj },
					new IBuildpathContainer[] {
							new TestContainer(new Path("container/default"),
									new IBuildpathEntry[] {}) },
					null);

			// set P's Buildpath with this container
			IBuildpathEntry container = DLTKCore
					.newContainerEntry(new Path("container/default"), true);
			proj.setRawBuildpath(new IBuildpathEntry[] { container }, null);

			assertDeltas("Unexpected delta",
					"P[*]: {CONTENT | BUILDPATH CHANGED}\n"
							+ "	ResourceDelta(/P/.buildpath)[*]");
		} finally {
			stopDeltas();
			AbstractModelTests.deleteProject("P");
		}
	}

	/*
	 * Ensures that a non existing source folder cannot be put on the Buildpath.
	 * (regression test for bug 66512 Invalid Buildpath entry not rejected)
	 */
	public void testInvalidSourceFolder() throws CoreException {
		try {
			createScriptProject("P1i", TEST_NATURE, new String[] { "" });
			IScriptProject proj = createScriptProject("P2i", TEST_NATURE,
					new String[] { "" }, new String[] { "/P1i/src1/src2" });
			assertMarkers("Unexpected markers",
					"Illegal path for required project: '/P1i/src1/src2' in project P2i",
					proj);
		} finally {
			deleteProject("P1i");
			deleteProject("P2i");
		}
	}

	/**
	 * Should detect duplicate entries on the Buildpath
	 */
	public void testBuildpathValidation01() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = newCP[0];

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should have detected duplicate entries on the buildpath",
					"Build path contains duplicate entry: \'src\' for project P",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	public void testBuildpathLibraryValidation01() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("Pv0", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			IEnvironment env = LocalEnvironment.getInstance();
			IPath libPath = EnvironmentPathUtils.getFullPath(env,
					new Path("/opt2"));
			newCP[originalCP.length] = DLTKCore.newExtLibraryEntry(libPath);

			IModelStatus status = BuildpathEntry.validateBuildpathEntry(proj,
					newCP[originalCP.length], false);

			assertStatus("should detect not pressent folders",
					"Required library cannot denote external folder or archive: \'"
							+ EnvironmentPathUtils.getLocalPath(libPath)
									.toString()
							+ "\' for project Pv0",
					status);
		} finally {
			AbstractModelTests.deleteProject("Pv0");
		}
	}

	/**
	 * Should detect nested source folders on the Buildpath
	 */
	public void testBuildpathValidation02() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"));

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);
			assertStatus(
					"should have detected nested source folders on the buildpath",
					"Cannot nest \'P/src\' inside \'P\'. To enable the nesting exclude \'src/\' from \'P\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should detect library folder nested inside source folder on the Buildpath
	 */
	public void testBuildpathValidation03() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore
					.newLibraryEntry(new Path("/P/src/lib"));

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should have detected library folder nested inside source folder on the Buildpath",
					"Cannot nest \'P/src/lib\' inside \'P/src\'. To enable the nesting exclude \'lib/\' from \'P/src\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	public void testClasspathValidation04() throws CoreException {

		IScriptProject[] p = null;
		try {

			p = new IScriptProject[] {
					this.createScriptProject("P0var", TEST_NATURE,
							new String[] { "src0" }),
					this.createScriptProject("P1var", TEST_NATURE,
							new String[] { "src1" }), };

			DLTKCore.setBuildpathVariable("var", new Path("/P1var"), null);

			IBuildpathEntry[] newBuildpath = new IBuildpathEntry[] {
					DLTKCore.newSourceEntry(new Path("/P0var/src0")),
					DLTKCore.newVariableEntry(new Path("var/src1")), };

			// validate Buildpath
			IModelStatus status = BuildpathEntry.validateBuildpath(p[0],
					newBuildpath);
			assertStatus(
					"should not detect external source folder through a variable on the buildpath",
					"OK", status);

		} finally {
			AbstractModelTests.deleteProject("P0var");
			AbstractModelTests.deleteProject("P1var");
		}
	}

	public void testBuildpathValidation05() throws CoreException {

		IScriptProject[] p = null;
		try {

			p = new IScriptProject[] {
					this.createScriptProject("P0v", TEST_NATURE,
							new String[] { "src0", "src1" }),
					this.createScriptProject("P1v", TEST_NATURE,
							new String[] { "src1" }), };

			DLTKCore.setBuildpathContainer(new Path("container/default"),
					new IScriptProject[] { p[0] },
					new IBuildpathContainer[] { new TestContainer(
							new Path("container/default"),
							new IBuildpathEntry[] { DLTKCore
									.newSourceEntry(new Path("/P0v/src0")) }) },
					null);

			IBuildpathEntry[] newBuildpath = new IBuildpathEntry[] {
					DLTKCore.newSourceEntry(new Path("/P0v/src1")),
					DLTKCore.newContainerEntry(
							new Path("container/default")), };

			// validate Buildpath
			IModelStatus status = BuildpathEntry.validateBuildpath(p[0],
					newBuildpath);
			assertStatus(
					"should not have detected external source folder through a container on the Buildpath",
					"OK", status);

			// validate Buildpath entry
			status = BuildpathEntry.validateBuildpathEntry(p[0],
					newBuildpath[1], true);
			assertStatus(
					"should have detected external source folder through a container on the Buildpath",
					"Invalid buildpath container: \'container/default\' in project P0v",
					status);

		} finally {
			AbstractModelTests.deleteProject("P0v");
			AbstractModelTests.deleteProject("P1v");
		}
	}

	public void testBuildpathValidation06() throws CoreException {

		IScriptProject[] p = null;
		try {

			p = new IScriptProject[] { this.createScriptProject("P0",
					TEST_NATURE, new String[] { "src" }), };

			// validate Buildpath entry
			IBuildpathEntry[] newBuildpath = new IBuildpathEntry[] {
					DLTKCore.newSourceEntry(new Path("/P0")),
					DLTKCore.newSourceEntry(new Path("/P0/src")), };

			IModelStatus status = BuildpathEntry.validateBuildpath(p[0],
					newBuildpath);
			assertStatus("should have detected nested source folder",
					"Cannot nest \'P0/src\' inside \'P0\'. To enable the nesting exclude \'src/\' from \'P0\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P0");
		}
	}

	/**
	 * Should allow nested source folders on the Buildpath as long as the outer
	 * folder excludes the inner one.
	 */
	public void testBuildpathValidation07() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"),
					new IPath[] { new Path("src/") });

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should have allowed nested source folders with exclusion on the buildpath",
					"OK", status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should allow a nested binary folder in a source folder on the buildpath
	 * as long as the outer folder excludes the inner one.
	 */
	public void testBuildpathValidation08() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] {});
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"),
					new IPath[] { new Path("lib/") });

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should have allowed nested lib folders with exclusion on the buildpath",
					"OK", status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should not allow nested source folders on the Buildpath if exclusion
	 * filter has no trailing slash.
	 */
	public void testBuildpathValidation15() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"),
					new IPath[] { new Path("**/src") });

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"End exclusion filter \'src\' with / to fully exclude \'P/src\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should not allow exclusion patterns if project preference disallow them
	 */
	public void testBuildpathValidation21() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] {});
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(
					new Path("/P/src"), new IPath[] { new Path("**/src") });

			Map<String, String> options = new Hashtable<>(5);
			options.put(DLTKCore.CORE_ENABLE_BUILDPATH_EXCLUSION_PATTERNS,
					DLTKCore.DISABLED);
			proj.setOptions(options);
			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"Inclusion or exclusion patterns are disabled in project P, cannot selectively include or exclude from entry: \'src\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * 33207 - Reject output folder that coincidate with distinct source folder
	 * but 36465 - Unable to create multiple source folders when not using bin
	 * for output default output scenarii is still tolerated
	 */
	public void testBuildpathValidation23() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] {});
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 2];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P/"),
					new IPath[] { new Path("src/") },
					BuildpathEntry.EXCLUDE_NONE);
			newCP[originalCP.length + 1] = DLTKCore.newSourceEntry(
					new Path("/P/src"), new IPath[0],
					BuildpathEntry.EXCLUDE_NONE);

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"Cannot nest 'P/src' inside 'P/'. To enable the nesting exclude 'src/' from 'P/'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should not allow nested source folders on the buildpath if the outer
	 * folder includes the inner one.
	 */
	public void testBuildpathValidation34() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"),
					new IPath[] { new Path("src/") }, new IPath[0], null);

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should not have allowed nested source folders with inclusion on the buildpath",
					"Cannot nest \'P/src\' inside \'P\'. To enable the nesting exclude \'src/\' from \'P\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should allow nested source folders on the buildpath if inclusion filter
	 * has no trailing slash.
	 */
	public void testBuildpathValidation36() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"),
					new IPath[] { new Path("**/src") }, new Path[0], null);

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus("OK", status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Should not allow inclusion patterns if project preference disallow them
	 */
	public void testBuildpathValidation37() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] {});
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(
					new Path("/P/src"), new IPath[] { new Path("**/src") },
					new Path[0], null);

			Map<String, String> options = new Hashtable<>(5);
			options.put(DLTKCore.CORE_ENABLE_BUILDPATH_EXCLUSION_PATTERNS,
					DLTKCore.DISABLED);
			proj.setOptions(options);
			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"Inclusion or exclusion patterns are disabled in project P, cannot selectively include or exclude from entry: \'src\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/*
	 * Should detect nested source folders on the buildpath and indicate the
	 * preference if disabled (regression test for bug 122615 validate buildpath
	 * propose to exlude a source folder even though exlusion patterns are
	 * disabled)
	 */
	public void testBuildpathValidation42() throws CoreException {
		try {
			IScriptProject proj = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			proj.setOption(DLTKCore.CORE_ENABLE_BUILDPATH_EXCLUSION_PATTERNS,
					DLTKCore.DISABLED);
			IBuildpathEntry[] originalCP = proj.getRawBuildpath();

			IBuildpathEntry[] newCP = new IBuildpathEntry[originalCP.length
					+ 1];
			System.arraycopy(originalCP, 0, newCP, 0, originalCP.length);
			newCP[originalCP.length] = DLTKCore.newSourceEntry(new Path("/P"));

			IModelStatus status = BuildpathEntry.validateBuildpath(proj, newCP);

			assertStatus(
					"should have detected nested source folders on the buildpath",
					"Cannot nest \'P/src\' inside \'P\'. To allow the nesting enable use of exclusion patterns in the preferences of project \'P\' and exclude \'src/\' from \'P\'",
					status);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Setting the buildpath with two entries specifying the same path should
	 * fail.
	 */
	public void testBuildpathWithDuplicateEntries() throws CoreException {
		try {
			IScriptProject project = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] cp = project.getRawBuildpath();
			IBuildpathEntry[] newCp = new IBuildpathEntry[cp.length * 2];
			System.arraycopy(cp, 0, newCp, 0, cp.length);
			System.arraycopy(cp, 0, newCp, cp.length, cp.length);
			try {
				project.setRawBuildpath(newCp, null);
			} catch (ModelException jme) {
				return;
			}
			assertTrue(
					"Setting the buildpath with two entries specifying the same path should fail",
					false);
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Adding an entry to the buildpath for a project that does not exist should
	 * not break the model. The buildpath should contain the entry, but the root
	 * should not appear in the children.
	 */
	public void testBuildpathWithNonExistentProjectEntry()
			throws CoreException {
		try {
			IScriptProject project = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalPath = project.getRawBuildpath();
			IProjectFragment[] originalRoots = project.getProjectFragments();

			IBuildpathEntry[] newPath = new IBuildpathEntry[originalPath.length
					+ 1];
			System.arraycopy(originalPath, 0, newPath, 0, originalPath.length);

			IBuildpathEntry newEntry = DLTKCore
					.newProjectEntry(new Path("/NoProject"), false);
			newPath[originalPath.length] = newEntry;

			project.setRawBuildpath(newPath, null);

			IBuildpathEntry[] getPath = project.getRawBuildpath();
			assertTrue("should be the same length",
					getPath.length == newPath.length);
			for (int i = 0; i < getPath.length; i++) {
				assertTrue("entries should be the same",
						getPath[i].equals(newPath[i]));
			}

			IProjectFragment[] newRoots = project.getProjectFragments();
			assertTrue("Should be the same number of roots",
					originalRoots.length == newRoots.length);
			for (int i = 0; i < newRoots.length; i++) {
				assertTrue("roots should be the same",
						originalRoots[i].equals(newRoots[i]));
			}
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Adding an entry to the buildpath for a folder that does not exist should
	 * not break the model. The buildpath should contain the entry, but the root
	 * should not appear in the children.
	 */
	public void testBuildpathWithNonExistentSourceEntry() throws CoreException {
		try {
			IScriptProject project = this.createScriptProject("P", TEST_NATURE,
					new String[] { "src" });
			IBuildpathEntry[] originalPath = project.getRawBuildpath();
			IProjectFragment[] originalRoots = project.getProjectFragments();

			IBuildpathEntry[] newPath = new IBuildpathEntry[originalPath.length
					+ 1];
			System.arraycopy(originalPath, 0, newPath, 0, originalPath.length);

			IBuildpathEntry newEntry = DLTKCore
					.newSourceEntry(new Path("/P/moreSource"));
			newPath[originalPath.length] = newEntry;

			project.setRawBuildpath(newPath, null);

			IBuildpathEntry[] getPath = project.getRawBuildpath();
			assertTrue("should be the same length",
					getPath.length == newPath.length);
			for (int i = 0; i < getPath.length; i++) {
				assertTrue("entries should be the same",
						getPath[i].equals(newPath[i]));
			}

			IProjectFragment[] newRoots = project.getProjectFragments();
			assertTrue("Should be the same number of roots",
					originalRoots.length == newRoots.length);
			for (int i = 0; i < newRoots.length; i++) {
				assertTrue("roots should be the same",
						originalRoots[i].equals(newRoots[i]));
			}
		} finally {
			AbstractModelTests.deleteProject("P");
		}
	}

	/**
	 * Ensure that missing projects are properly reported.
	 */
	public void testMissingProjectReport1() throws CoreException {
		final String name1 = "p1miss";
		final String name2 = "p2miss";
		try {
			IScriptProject p1 = createScriptProject(name1, TEST_NATURE,
					new String[] { "" });
			assertEquals(0, numberOfBuildpathProblems(p1));
			IScriptProject p2 = createScriptProject(name2, TEST_NATURE,
					new String[] { "" });
			assertEquals(0, numberOfBuildpathProblems(p2));
			// Add dependency
			IBuildpathEntry[] originalP2CP = p2.getRawBuildpath();
			// Add P1 as a prerequesite of P2
			int length = originalP2CP.length;
			IBuildpathEntry[] newCP = new IBuildpathEntry[length + 1];
			System.arraycopy(originalP2CP, 0, newCP, 0, length);
			newCP[length] = DLTKCore
					.newProjectEntry(p1.getProject().getFullPath(), false);
			p2.setRawBuildpath(newCP, null);
			waitForAutoBuild(); // wait for markers to be created
			assertEquals(0, numberOfBuildpathProblems(p1));
			assertEquals(0, numberOfBuildpathProblems(p2));
			p1.getProject().close(new NullProgressMonitor());
			waitForAutoBuild(); // wait for markers to be created
			assertEquals(1, numberOfBuildpathProblems(p2));
		} finally {
			deleteProjects(new String[] { name1, name2 });
		}
	}

	/**
	 * Ensure that missing projects are properly reported.
	 */
	public void testMissingProjectReport2() throws CoreException, IOException {
		final String name1 = "miss1";
		final String name2 = "miss2";
		try {
			IScriptProject p2 = setUpScriptProject(name2);
			waitForAutoBuild();
			assertEquals(1, numberOfBuildpathProblems(p2));
			IScriptProject p1 = setUpScriptProject(name1);
			waitForAutoBuild();
			assertEquals(0, numberOfBuildpathProblems(p1));
			assertEquals(0, numberOfBuildpathProblems(p2));
		} finally {
			deleteProjects(new String[] { name1, name2 });
		}
	}

	/**
	 * Ensure that cycle are properly reported.
	 */
	public void testCycleReport() throws CoreException {

		try {
			IScriptProject p1 = this.createScriptProject("p1_", TEST_NATURE,
					new String[] { "" });
			IScriptProject p2 = this.createScriptProject("p2_", TEST_NATURE,
					new String[] { "" });
			IScriptProject p3 = this.createScriptProject("p3_", TEST_NATURE,
					new String[] { "" }, new String[] { "/p2_" });

			// Ensure no cycle reported
			IScriptProject[] projects = { p1, p2, p3 };
			int cycleMarkerCount = 0;
			for (int i = 0; i < projects.length; i++) {
				cycleMarkerCount += this.numberOfCycleMarkers(projects[i]);
			}
			assertTrue("Should have no cycle markers", cycleMarkerCount == 0);

			// Add cycle
			IBuildpathEntry[] originalP1CP = p1.getRawBuildpath();
			IBuildpathEntry[] originalP2CP = p2.getRawBuildpath();

			// Add P1 as a prerequesite of P2
			int length = originalP2CP.length;
			IBuildpathEntry[] newCP = new IBuildpathEntry[length + 1];
			System.arraycopy(originalP2CP, 0, newCP, 0, length);
			newCP[length] = DLTKCore
					.newProjectEntry(p1.getProject().getFullPath(), false);
			p2.setRawBuildpath(newCP, null);

			// Add P3 as a prerequesite of P1
			length = originalP1CP.length;
			newCP = new IBuildpathEntry[length + 1];
			System.arraycopy(originalP1CP, 0, newCP, 0, length);
			newCP[length] = DLTKCore
					.newProjectEntry(p3.getProject().getFullPath(), false);
			p1.setRawBuildpath(newCP, null);

			waitForAutoBuild(); // wait for cycle markers to be created
			cycleMarkerCount = 0;
			for (int i = 0; i < projects.length; i++) {
				cycleMarkerCount += numberOfCycleMarkers(projects[i]);
			}
			assertEquals(
					"Unexpected number of projects involved in a buildpath cycle",
					3, cycleMarkerCount);

		} finally {
			// cleanup
			deleteProjects(new String[] { "p1_", "p2_", "p3_" });
		}
	}

	public void testScriptFolderExclude() throws CoreException {
		try {
			// create
			final IScriptProject project = createScriptProject("A_",
					TEST_NATURE, new String[] { "" });
			project.getProject().getFolder("src").create(true, true, null);
			// find folder & test it
			final IScriptFolder folder = project
					.findScriptFolder(new Path("/A_/src"));
			assertNotNull(folder);
			assertTrue(folder.exists());
			// change buildpath
			final IBuildpathEntry entry1 = DLTKCore
					.newSourceEntry(new Path("/A_/src"));
			final IBuildpathEntry entry2 = DLTKCore.newSourceEntry(
					new Path("/A_"), new IPath[0],
					new IPath[] { new Path("src/") });
			project.setRawBuildpath(new IBuildpathEntry[] { entry1, entry2 },
					null);
			// test folder after change
			assertFalse(folder.exists());
		} finally {
			deleteProject("A_");
		}
	}

	/**
	 * Setting the buildpath to empty should result in no entries, and a delta
	 * with removed roots.
	 */
	public void testEmptyBuildpath() throws CoreException {
		IScriptProject project = this.createScriptProject("P", TEST_NATURE,
				new String[] { "" });
		try {
			startDeltas();
			setBuildpath(project, new IBuildpathEntry[] {});
			IBuildpathEntry[] cp = project.getRawBuildpath();
			assertTrue("buildpath should have no entries", cp.length == 0);

			// ensure the deltas are correct
			assertDeltas("Unexpected delta",
					"P[*]: {CHILDREN | CONTENT | BUILDPATH CHANGED | RESOLVED BUILDPATH CHANGED}\n"
							+ "	<project root>[*]: {REMOVED FROM BUILDPATH}\n"
							+ "	ResourceDelta(/P/.buildpath)[*]");
		} finally {
			stopDeltas();
			AbstractModelTests.deleteProject("P");
		}
	}

	/*
	 * Ensures that a source folder that contains character that must be encoded
	 * can be written. (regression test for bug
	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=70193)
	 */
	public void testEncoding() throws CoreException {
		try {
			createScriptProject("P", TEST_NATURE, new String[] { "src\u3400" });
			IFile file = getFile("/P/.buildpath");
			String encodedContents = new String(
					org.eclipse.dltk.internal.core.util.Util
							.getResourceContentsAsCharArray(file, "UTF-8"));
			encodedContents = Util
					.convertToIndependantLineDelimiter(encodedContents);
			assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
					+ "<buildpath>\n"
					+ "	<buildpathentry kind=\"src\" path=\"src\u3400\"/>\n"
					+ "</buildpath>\n", encodedContents);
		} finally {
			deleteProject("P");
		}
	}

	/**
	 * Tests the cross project Buildpath setting
	 */
	public void testBuildpathCrossProject() throws CoreException {
		IScriptProject project = this.createScriptProject("P1c", TEST_NATURE,
				new String[] { "" });
		this.createScriptProject("P2c", TEST_NATURE, new String[] {});
		try {
			startDeltas();
			IProjectFragment oldRoot = getProjectFragment("P1c", "");
			IBuildpathEntry projectEntry = DLTKCore
					.newProjectEntry(new Path("/P2c"), false);
			IBuildpathEntry[] newBuildpath = new IBuildpathEntry[] {
					projectEntry };
			project.setRawBuildpath(newBuildpath, null);
			project.getProjectFragments();
			IModelElementDelta removedDelta = getDeltaFor(oldRoot, true);
			assertDeltas("Unexpected delta",
					"<project root>[*]: {REMOVED FROM BUILDPATH}",
					removedDelta);
		} finally {
			stopDeltas();
			this.deleteProjects(new String[] { "P1c", "P2c" });
		}
	}

	public void testGetProjectFragmentByResource()
			throws CoreException, IOException {
		try {
			setUpScriptProject(BUILDPATH_PRJ_4);
			String folderName = "library";
			IModelElement element = DLTKCore.create(getWorkspaceRoot()
					.getFolder(new Path(BUILDPATH_PRJ_4 + "/" + folderName)));
			assertNotNull(element);
			assertEquals(IModelElement.PROJECT_FRAGMENT,
					element.getElementType());
			assertEquals(folderName, element.getElementName());
		} finally {
			deleteProject(BUILDPATH_PRJ_4);
		}
	}
}
