/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425
 *     Thirumala Reddy Mutchukota <thirumala@google.com> - Avoid optional library classpath entries validation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=412882
 *     Stephan Herrmann - Contribution for
 *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
 *								Bug 462768 - [null] NPE when using linked folder for external annotations
 *                              Bug 465296 - precedence of extra attributes on a classpath container
 *     Karsten Thoms - Bug 532505 - Reduce memory footprint of ClasspathAccessRule
 *******************************************************************************/
package org.eclipse.jdt.internal.core;

import static org.eclipse.jdt.internal.compiler.util.Util.UTF_8;
import static org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IContainer;
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.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaModelStatus;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.AccessRule;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * @see IClasspathEntry
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ClasspathEntry implements IClasspathEntry {

	public static class AssertionFailedException extends RuntimeException {

		private static final long serialVersionUID = -171699380721189572L;

		public AssertionFailedException(String message) {
			super(message);
		}
	}

	public static final String TAG_CLASSPATH = "classpath"; //$NON-NLS-1$
	public static final String TAG_CLASSPATHENTRY = "classpathentry"; //$NON-NLS-1$
	public static final String TAG_REFERENCED_ENTRY = "referencedentry"; //$NON-NLS-1$
	public static final String TAG_OUTPUT = "output"; //$NON-NLS-1$
	public static final String TAG_KIND = "kind"; //$NON-NLS-1$
	public static final String TAG_PATH = "path"; //$NON-NLS-1$
	public static final String TAG_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
	public static final String TAG_ROOTPATH = "rootpath"; //$NON-NLS-1$
	public static final String TAG_EXPORTED = "exported"; //$NON-NLS-1$
	public static final String TAG_INCLUDING = "including"; //$NON-NLS-1$
	public static final String TAG_EXCLUDING = "excluding"; //$NON-NLS-1$
	public static final String TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
	public static final String TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
	public static final String TAG_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
	public static final String TAG_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
	public static final String TAG_COMBINE_ACCESS_RULES = "combineaccessrules"; //$NON-NLS-1$
	public static final String TAG_ACCESS_RULES = "accessrules"; //$NON-NLS-1$
	public static final String TAG_ACCESS_RULE = "accessrule"; //$NON-NLS-1$
	public static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
	public static final String TAG_ACCESSIBLE = "accessible"; //$NON-NLS-1$
	public static final String TAG_NON_ACCESSIBLE = "nonaccessible"; //$NON-NLS-1$
	public static final String TAG_DISCOURAGED = "discouraged"; //$NON-NLS-1$
	public static final String TAG_IGNORE_IF_BETTER = "ignoreifbetter"; //$NON-NLS-1$

	// common index location for all workspaces
	private static String SHARED_INDEX_LOCATION = System.getProperty("jdt.core.sharedIndexLocation"); //$NON-NLS-1$

	/**
	 * Describes the kind of classpath entry - one of
	 * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE or CPE_CONTAINER
	 */
	public int entryKind;

	/**
	 * Describes the kind of package fragment roots found on
	 * this classpath entry - either K_BINARY or K_SOURCE or
	 * K_OUTPUT.
	 */
	public int contentKind;

	/**
	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
	 *	<li>Source code in the current project (<code>CPE_SOURCE</code>) -
	 *      The path associated with this entry is the absolute path to the root folder. </li>
	 *	<li>A binary library in the current project (<code>CPE_LIBRARY</code>) - the path
	 *		associated with this entry is the absolute path to the JAR (or root folder), and
	 *		in case it refers to an external JAR, then there is no associated resource in
	 *		the workbench.
	 *	<li>A required project (<code>CPE_PROJECT</code>) - the path of the entry denotes the
	 *		path to the corresponding project resource.</li>
	 *  <li>A variable entry (<code>CPE_VARIABLE</code>) - the first segment of the path
	 *      is the name of a classpath variable. If this classpath variable
	 *		is bound to the path <it>P</it>, the path of the corresponding classpath entry
	 *		is computed by appending to <it>P</it> the segments of the returned
	 *		path without the variable.</li>
	 *  <li> A container entry (<code>CPE_CONTAINER</code>) - the first segment of the path is denoting
	 *     the unique container identifier (for which a <code>ClasspathContainerInitializer</code> could be
	 * 	registered), and the remaining segments are used as additional hints for resolving the container entry to
	 * 	an actual <code>IClasspathContainer</code>.</li>
	 */
	public IPath path;

	/**
	 * Patterns allowing to include/exclude portions of the resource tree denoted by this entry path.
	 */
	private IPath[] inclusionPatterns;
	private char[][] fullInclusionPatternChars;
	private IPath[] exclusionPatterns;
	private char[][] fullExclusionPatternChars;
	private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$
	public final static ClasspathEntry[] NO_ENTRIES = new ClasspathEntry[0];
	private final static IPath[] NO_PATHS = new IPath[0];
	private final static IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

	private boolean combineAccessRules;

	private String rootID;
	private AccessRuleSet accessRuleSet;


	static class UnknownXmlElements {
		String[] attributes;
		ArrayList children;
	}

	/*
	 * Default inclusion pattern set
	 */
	public final static IPath[] INCLUDE_ALL = {};

	/*
	 * Default exclusion pattern set
	 */
	public final static IPath[] EXCLUDE_NONE = {};

	/*
	 * Default extra attributes
	 */
	public final static IClasspathAttribute[] NO_EXTRA_ATTRIBUTES = {};

	/*
	 * Default access rules
	 */
	public final static IAccessRule[] NO_ACCESS_RULES = {};

	/**
	 * Describes the path to the source archive associated with this
	 * classpath entry, or <code>null</code> if this classpath entry has no
	 * source attachment.
	 * <p>
	 * Only library and variable classpath entries may have source attachments.
	 * For library classpath entries, the result path (if present) locates a source
	 * archive. For variable classpath entries, the result path (if present) has
	 * an analogous form and meaning as the variable path, namely the first segment
	 * is the name of a classpath variable.
	 */
	public IPath sourceAttachmentPath;

	/**
	 * Describes the path within the source archive where package fragments
	 * are located. An empty path indicates that packages are located at
	 * the root of the source archive. Returns a non-<code>null</code> value
	 * if and only if <code>getSourceAttachmentPath</code> returns
	 * a non-<code>null</code> value.
	 */
	public IPath sourceAttachmentRootPath;

	/**
	 * See {@link IClasspathEntry#getReferencingEntry()}
	 */
	public IClasspathEntry referencingEntry;

	/**
	 * Specific output location (for this source entry)
	 */
	public IPath specificOutputLocation;

	/**
	 * A constant indicating an output location.
	 */
	public static final int K_OUTPUT = 10;

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

	/**
	 * The export flag
	 */
	public boolean isExported;

	/**
	 * The extra attributes
	 */
	public IClasspathAttribute[] extraAttributes;

	public ClasspathEntry(
			int contentKind,
			int entryKind,
			IPath path,
			IPath[] inclusionPatterns,
			IPath[] exclusionPatterns,
			IPath sourceAttachmentPath,
			IPath sourceAttachmentRootPath,
			IPath specificOutputLocation,
			boolean isExported,
			IAccessRule[] accessRules,
			boolean combineAccessRules,
			IClasspathAttribute[] extraAttributes) {

		this(	contentKind,
				entryKind,
				path,
				inclusionPatterns,
				exclusionPatterns,
				sourceAttachmentPath,
				sourceAttachmentRootPath,
				specificOutputLocation,
				null,
				isExported,
				accessRules,
				combineAccessRules,
				extraAttributes);
	}

	/**
	 * Creates a class path entry of the specified kind with the given path.
	 */
	public ClasspathEntry(
		int contentKind,
		int entryKind,
		IPath path,
		IPath[] inclusionPatterns,
		IPath[] exclusionPatterns,
		IPath sourceAttachmentPath,
		IPath sourceAttachmentRootPath,
		IPath specificOutputLocation,
		IClasspathEntry referencingEntry,
		boolean isExported,
		IAccessRule[] accessRules,
		boolean combineAccessRules,
		IClasspathAttribute[] extraAttributes) {

		this.contentKind = contentKind;
		this.entryKind = entryKind;
		this.path = path;
		this.inclusionPatterns = inclusionPatterns;
		this.exclusionPatterns = exclusionPatterns;
		this.referencingEntry = referencingEntry;

		int length;
		if (accessRules != null && (length = accessRules.length) > 0) {
			AccessRule[] rules = new AccessRule[length];
			System.arraycopy(accessRules, 0, rules, 0, length);
			byte classpathEntryType;
			String classpathEntryName;
			JavaModelManager manager = JavaModelManager.getJavaModelManager();
			if (this.entryKind == CPE_PROJECT || this.entryKind == CPE_SOURCE) { // can be remote source entry when reconciling
				classpathEntryType = AccessRestriction.PROJECT;
				classpathEntryName = manager.intern(getPath().segment(0));
			} else {
				classpathEntryType = AccessRestriction.LIBRARY;
				Object target = JavaModel.getWorkspaceTarget(path);
				if (target == null) {
					classpathEntryName = manager.intern(path.toOSString());
				} else {
					classpathEntryName = manager.intern(path.makeRelative().toString());
				}
			}
			this.accessRuleSet = new AccessRuleSet(rules, classpathEntryType, classpathEntryName);
		}
//		else { -- implicit!
//			this.accessRuleSet = null;
//		}

		this.combineAccessRules = combineAccessRules;
		this.extraAttributes = extraAttributes.length > 0 ? extraAttributes : NO_EXTRA_ATTRIBUTES;

	    if (inclusionPatterns != INCLUDE_ALL && inclusionPatterns.length > 0) {
			this.fullInclusionPatternChars = UNINIT_PATTERNS;
	    }
	    if (exclusionPatterns.length > 0) {
			this.fullExclusionPatternChars = UNINIT_PATTERNS;
	    }
		this.sourceAttachmentPath = sourceAttachmentPath;
		this.sourceAttachmentRootPath = sourceAttachmentRootPath;
		this.specificOutputLocation = specificOutputLocation;
		this.isExported = isExported;
	}

	@Override
	public boolean combineAccessRules() {
		return this.combineAccessRules;
	}

	/**
	 * Used to perform export/restriction propagation across referring projects/containers.
	 * Also: propagating extraAttributes.
	 */
	public ClasspathEntry combineWith(ClasspathEntry referringEntry) {
		if (referringEntry == null) return this;
		IClasspathAttribute[] referringExtraAttributes = referringEntry.getExtraAttributes();
		if (referringEntry.isExported() || referringEntry.getAccessRuleSet() != null || referringExtraAttributes.length > 0) {
			boolean combine = this.entryKind == CPE_SOURCE || referringEntry.combineAccessRules();
			IClasspathAttribute[] combinedAttributes = this.extraAttributes;
			int lenRefer = referringExtraAttributes.length;
			if (lenRefer > 0) {
				int lenEntry = combinedAttributes.length;
				if (referringEntry.path.isPrefixOf(this.path)) {
					// consider prefix location as less specific, put to back (e.g.: referring to a library via a project):
					System.arraycopy(combinedAttributes, 0, combinedAttributes=new IClasspathAttribute[lenEntry+lenRefer], 0, lenEntry);
					System.arraycopy(referringExtraAttributes, 0, combinedAttributes, lenEntry, lenRefer);
				} else {
					// otherwise consider the referring entry as more specific than the referee:
					System.arraycopy(combinedAttributes, 0, combinedAttributes=new IClasspathAttribute[lenEntry+lenRefer], lenRefer, lenEntry);
					System.arraycopy(referringExtraAttributes, 0, combinedAttributes, 0, lenRefer);
				}
			}
			return new ClasspathEntry(
								getContentKind(),
								getEntryKind(),
								getPath(),
								this.inclusionPatterns,
								this.exclusionPatterns,
								getSourceAttachmentPath(),
								getSourceAttachmentRootPath(),
								getOutputLocation(),
								referringEntry.isExported() || this.isExported, // duplicate container entry for tagging it as exported
								combine(referringEntry.getAccessRules(), getAccessRules(), combine),
								this.combineAccessRules,
								combinedAttributes);
		}
		// no need to clone
		return this;
	}


	public ClasspathEntry withExtraAttributeRemoved(String attrName) {
		IClasspathAttribute[] changedAttributes = Arrays.stream(this.getExtraAttributes())
				.filter(a -> !a.getName().equals(attrName)).toArray(IClasspathAttribute[]::new);
		return new ClasspathEntry(
				this.getContentKind(),
				this.getEntryKind(),
				this.getPath(),
				this.getInclusionPatterns(),
				this.getExclusionPatterns(),
				this.getSourceAttachmentPath(),
				this.getSourceAttachmentRootPath(),
				this.getOutputLocation(),
				this.getReferencingEntry(),
				this.isExported(),
				this.getAccessRules(),
				this.combineAccessRules(),
				changedAttributes);
	}


	private IAccessRule[] combine(IAccessRule[] referringRules, IAccessRule[] rules, boolean combine) {
		if (!combine) return rules;
		if (rules == null || rules.length == 0) return referringRules;

		// concat access rules
		int referringRulesLength = referringRules.length;
		int accessRulesLength = rules.length;
		int rulesLength = referringRulesLength + accessRulesLength;
		IAccessRule[] result = new IAccessRule[rulesLength];
		System.arraycopy(referringRules, 0, result, 0, referringRulesLength);
		System.arraycopy(rules, 0, result, referringRulesLength, accessRulesLength);

		return result;
	}

	static IClasspathAttribute[] decodeExtraAttributes(NodeList attributes) {
		if (attributes == null) return NO_EXTRA_ATTRIBUTES;
		int length = attributes.getLength();
		if (length == 0) return NO_EXTRA_ATTRIBUTES;
		IClasspathAttribute[] result = new IClasspathAttribute[length];
		int index = 0;
		for (int i = 0; i < length; ++i) {
			Node node = attributes.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element attribute = (Element)node;
				String name = attribute.getAttribute(TAG_ATTRIBUTE_NAME);
				if (name == null) continue;
				String value = attribute.getAttribute(TAG_ATTRIBUTE_VALUE);
				if (value == null) continue;
				result[index++] = new ClasspathAttribute(name, value);
			}
		}
		if (index != length)
			System.arraycopy(result, 0, result = new IClasspathAttribute[index], 0, index);
		return result;
	}

	static IAccessRule[] decodeAccessRules(NodeList list) {
		if (list == null) return null;
		int length = list.getLength();
		if (length == 0) return null;
		IAccessRule[] result = new IAccessRule[length];
		int index = 0;
		for (int i = 0; i < length; i++) {
			Node accessRule = list.item(i);
			if (accessRule.getNodeType() == Node.ELEMENT_NODE) {
				Element elementAccessRule = (Element) accessRule;
				String pattern = elementAccessRule.getAttribute(TAG_PATTERN);
				if (pattern == null) continue;
				String tagKind =  elementAccessRule.getAttribute(TAG_KIND);
				int kind;
				if (TAG_ACCESSIBLE.equals(tagKind))
					kind = IAccessRule.K_ACCESSIBLE;
				else if (TAG_NON_ACCESSIBLE.equals(tagKind))
					kind = IAccessRule.K_NON_ACCESSIBLE;
				else if (TAG_DISCOURAGED.equals(tagKind))
					kind = IAccessRule.K_DISCOURAGED;
				else
					continue;
				boolean ignoreIfBetter = "true".equals(elementAccessRule.getAttribute(TAG_IGNORE_IF_BETTER)); //$NON-NLS-1$
				result[index++] = JavaCore.newAccessRule(new Path(pattern), ignoreIfBetter ? kind | IAccessRule.IGNORE_IF_BETTER : kind);
			}
		}
		if (index != length)
			System.arraycopy(result, 0, result = new IAccessRule[index], 0, index);
		return result;
	}

	/**
	 * Decode some element tag containing a sequence of patterns into IPath[]
	 */
	private static IPath[] decodePatterns(NamedNodeMap nodeMap, String tag) {
		String sequence = removeAttribute(tag, nodeMap);
		if (!sequence.equals("")) { //$NON-NLS-1$
			char[][] patterns = CharOperation.splitOn('|', sequence.toCharArray());
			int patternCount;
			if ((patternCount = patterns.length) > 0) {
				IPath[] paths = new IPath[patternCount];
				int index = 0;
				for (int j = 0; j < patternCount; j++) {
					char[] pattern = patterns[j];
					if (pattern.length == 0) continue; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=105581
					paths[index++] = new Path(new String(pattern));
				}
				if (index < patternCount)
					System.arraycopy(paths, 0, paths = new IPath[index], 0, index);
				return paths;
			}
		}
		return null;
	}

	private static void decodeUnknownNode(Node node, StringBuffer buffer, IJavaProject project) {
		StringWriter writer = new StringWriter();
		XMLWriter xmlWriter = new XMLWriter(writer, project, false/*don't print XML version*/);
		decodeUnknownNode(node, xmlWriter, true/*insert new line*/);
		xmlWriter.flush();
		xmlWriter.close();
		buffer.append(writer.toString());
	}

	private static void decodeUnknownNode(Node node, XMLWriter xmlWriter, boolean insertNewLine) {
		switch (node.getNodeType()) {
		case Node.ELEMENT_NODE:
			NamedNodeMap attributes;
			HashMap parameters = null;
			if ((attributes = node.getAttributes()) != null) {
				int length = attributes.getLength();
				if (length > 0) {
					parameters = new HashMap();
					for (int i = 0; i < length; i++) {
						Node attribute = attributes.item(i);
						parameters.put(attribute.getNodeName(), attribute.getNodeValue());
					}
				}
			}
			NodeList children = node.getChildNodes();
			int childrenLength = children.getLength();
			String nodeName = node.getNodeName();
			xmlWriter.printTag(nodeName, parameters, false/*don't insert tab*/, false/*don't insert new line*/, childrenLength == 0/*close tag if no children*/);
			if (childrenLength > 0) {
				for (int i = 0; i < childrenLength; i++) {
					decodeUnknownNode(children.item(i), xmlWriter, false/*don't insert new line*/);
				}
				xmlWriter.endTag(nodeName, false/*don't insert tab*/, insertNewLine);
			}
			break;
		case Node.TEXT_NODE:
			String data = ((Text) node).getData();
			xmlWriter.printString(data, false/*don't insert tab*/, false/*don't insert new line*/);
			break;
		}
	}

	/*
	 * Returns a char based representation of the exclusions patterns full path.
	 */
	public char[][] fullExclusionPatternChars() {

		if (this.fullExclusionPatternChars == UNINIT_PATTERNS) {
			int length = this.exclusionPatterns.length;
			this.fullExclusionPatternChars = new char[length][];
			IPath prefixPath = this.path.removeTrailingSeparator();
			for (int i = 0; i < length; i++) {
				this.fullExclusionPatternChars[i] =
					prefixPath.append(this.exclusionPatterns[i]).toString().toCharArray();
			}
		}
		return this.fullExclusionPatternChars;
	}

	/*
	 * Returns a char based representation of the exclusions patterns full path.
	 */
	public char[][] fullInclusionPatternChars() {

		if (this.fullInclusionPatternChars == UNINIT_PATTERNS) {
			int length = this.inclusionPatterns.length;
			this.fullInclusionPatternChars = new char[length][];
			IPath prefixPath = this.path.removeTrailingSeparator();
			for (int i = 0; i < length; i++) {
				this.fullInclusionPatternChars[i] =
					prefixPath.append(this.inclusionPatterns[i]).toString().toCharArray();
			}
		}
		return this.fullInclusionPatternChars;
	}

	/**
	 * Returns the XML encoding of the class path.
	 */
	public void elementEncode(XMLWriter writer, IPath projectPath, boolean indent, boolean newLine, Map unknownElements, boolean isReferencedEntry) {
		HashMap parameters = new HashMap();

		parameters.put(TAG_KIND, ClasspathEntry.kindToString(this.entryKind));

		IPath xmlPath = this.path;
		if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) {
			// translate to project relative from absolute (unless a device path)
			if (xmlPath.isAbsolute()) {
				if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
					if (xmlPath.segment(0).equals(projectPath.segment(0))) {
						xmlPath = xmlPath.removeFirstSegments(1);
						xmlPath = xmlPath.makeRelative();
					} else {
						xmlPath = xmlPath.makeAbsolute();
					}
				}
			}
		}
		parameters.put(TAG_PATH, String.valueOf(xmlPath));

		if (this.sourceAttachmentPath != null) {
			xmlPath = this.sourceAttachmentPath;
			// translate to project relative from absolute
			if (this.entryKind != IClasspathEntry.CPE_VARIABLE && projectPath != null && projectPath.isPrefixOf(xmlPath)) {
				if (xmlPath.segment(0).equals(projectPath.segment(0))) {
					xmlPath = xmlPath.removeFirstSegments(1);
					xmlPath = xmlPath.makeRelative();
				}
			}
			parameters.put(TAG_SOURCEPATH, String.valueOf(xmlPath));
		}
		if (this.sourceAttachmentRootPath != null) {
			parameters.put(TAG_ROOTPATH, String.valueOf(this.sourceAttachmentRootPath));
		}
		if (this.isExported) {
			parameters.put(TAG_EXPORTED, "true");//$NON-NLS-1$
		}
		encodePatterns(this.inclusionPatterns, TAG_INCLUDING, parameters);
		encodePatterns(this.exclusionPatterns, TAG_EXCLUDING, parameters);
		if (this.entryKind == CPE_PROJECT && !this.combineAccessRules)
			parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$


		// unknown attributes
		UnknownXmlElements unknownXmlElements = unknownElements == null ? null : (UnknownXmlElements) unknownElements.get(this.path);
		String[] unknownAttributes;
		if (unknownXmlElements != null && (unknownAttributes = unknownXmlElements.attributes) != null)
			for (int i = 0, length = unknownAttributes.length; i < length; i+=2) {
				String tagName = unknownAttributes[i];
				String tagValue = unknownAttributes[i+1];
				parameters.put(tagName, tagValue);
			}

		if (this.specificOutputLocation != null) {
			IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1);
			outputLocation = outputLocation.makeRelative();
			parameters.put(TAG_OUTPUT, String.valueOf(outputLocation));
		}

		boolean hasExtraAttributes = this.extraAttributes.length != 0;
		boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules
		ArrayList unknownChildren = unknownXmlElements != null ? unknownXmlElements.children : null;
		boolean hasUnknownChildren = unknownChildren != null;

		/* close tag if no extra attributes, no restriction and no unknown children */
		String tagName = isReferencedEntry ? TAG_REFERENCED_ENTRY : TAG_CLASSPATHENTRY;
		writer.printTag(
			tagName,
			parameters,
			indent,
			newLine,
			!hasExtraAttributes && !hasRestrictions && !hasUnknownChildren);

		if (hasExtraAttributes)
			encodeExtraAttributes(writer, indent, newLine);

		if (hasRestrictions)
			encodeAccessRules(writer, indent, newLine);

		if (hasUnknownChildren)
			encodeUnknownChildren(writer, indent, newLine, unknownChildren);

		if (hasExtraAttributes || hasRestrictions || hasUnknownChildren)
			writer.endTag(tagName, indent, true/*insert new line*/);
	}

	void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
		writer.startTag(TAG_ATTRIBUTES, indent);
		for (int i = 0; i < this.extraAttributes.length; i++) {
			IClasspathAttribute attribute = this.extraAttributes[i];
			HashMap parameters = new HashMap();
	    	parameters.put(TAG_ATTRIBUTE_NAME, attribute.getName());
			parameters.put(TAG_ATTRIBUTE_VALUE, attribute.getValue());
			writer.printTag(TAG_ATTRIBUTE, parameters, indent, newLine, true);
		}
		writer.endTag(TAG_ATTRIBUTES, indent, true/*insert new line*/);
	}

	void encodeAccessRules(XMLWriter writer, boolean indent, boolean newLine) {

		writer.startTag(TAG_ACCESS_RULES, indent);
		AccessRule[] rules = getAccessRuleSet().getAccessRules();
		for (int i = 0, length = rules.length; i < length; i++) {
			encodeAccessRule(rules[i], writer, indent, newLine);
		}
		writer.endTag(TAG_ACCESS_RULES, indent, true/*insert new line*/);
	}

	private void encodeAccessRule(AccessRule accessRule, XMLWriter writer, boolean indent, boolean newLine) {

		HashMap parameters = new HashMap();
		parameters.put(TAG_PATTERN, new String(accessRule.pattern));

		switch (accessRule.getProblemId()) {
			case IProblem.ForbiddenReference:
				parameters.put(TAG_KIND, TAG_NON_ACCESSIBLE);
				break;
			case IProblem.DiscouragedReference:
				parameters.put(TAG_KIND, TAG_DISCOURAGED);
				break;
			default:
				parameters.put(TAG_KIND, TAG_ACCESSIBLE);
				break;
		}
		if (accessRule.ignoreIfBetter())
			parameters.put(TAG_IGNORE_IF_BETTER, "true"); //$NON-NLS-1$

		writer.printTag(TAG_ACCESS_RULE, parameters, indent, newLine, true);

	}

	private void encodeUnknownChildren(XMLWriter writer, boolean indent, boolean newLine, ArrayList unknownChildren) {
		for (int i = 0, length = unknownChildren.size(); i < length; i++) {
			String child = (String) unknownChildren.get(i);
			writer.printString(child, indent, false/*don't insert new line*/);
		}
	}

	public static IClasspathEntry elementDecode(Element element, IJavaProject project, Map unknownElements) {

		IPath projectPath = project.getProject().getFullPath();
		NamedNodeMap attributes = element.getAttributes();
		NodeList children = element.getChildNodes();
		boolean[] foundChildren = new boolean[children.getLength()];
		String kindAttr = removeAttribute(TAG_KIND, attributes);
		String pathAttr = removeAttribute(TAG_PATH, attributes);

		// ensure path is absolute
		IPath path = new Path(pathAttr);
		int kind = kindFromString(kindAttr);
		if (kind != IClasspathEntry.CPE_VARIABLE && kind != IClasspathEntry.CPE_CONTAINER && !path.isAbsolute()) {
			if (!(path.segmentCount() > 0 && path.segment(0).equals(ClasspathEntry.DOT_DOT))) {
				path = projectPath.append(path);
			}
		}
		// source attachment info (optional)
		IPath sourceAttachmentPath =
			element.hasAttribute(TAG_SOURCEPATH)
			? new Path(removeAttribute(TAG_SOURCEPATH, attributes))
			: null;
		if (kind != IClasspathEntry.CPE_VARIABLE && sourceAttachmentPath != null && !sourceAttachmentPath.isAbsolute()) {
			sourceAttachmentPath = projectPath.append(sourceAttachmentPath);
		}
		IPath sourceAttachmentRootPath =
			element.hasAttribute(TAG_ROOTPATH)
			? new Path(removeAttribute(TAG_ROOTPATH, attributes))
			: null;

		// exported flag (optional)
		boolean isExported = removeAttribute(TAG_EXPORTED, attributes).equals("true"); //$NON-NLS-1$

		// inclusion patterns (optional)
		IPath[] inclusionPatterns = decodePatterns(attributes, TAG_INCLUDING);
		if (inclusionPatterns == null) inclusionPatterns = INCLUDE_ALL;

		// exclusion patterns (optional)
		IPath[] exclusionPatterns = decodePatterns(attributes, TAG_EXCLUDING);
		if (exclusionPatterns == null) exclusionPatterns = EXCLUDE_NONE;

		// access rules (optional)
		NodeList attributeList = getChildAttributes(TAG_ACCESS_RULES, children, foundChildren);
		IAccessRule[] accessRules = decodeAccessRules(attributeList);

		// backward compatibility
		if (accessRules == null) {
			accessRules = getAccessRules(inclusionPatterns, exclusionPatterns);
		}

		// combine access rules (optional)
		boolean combineAccessRestrictions = !removeAttribute(TAG_COMBINE_ACCESS_RULES, attributes).equals("false"); //$NON-NLS-1$

		// extra attributes (optional)
		attributeList = getChildAttributes(TAG_ATTRIBUTES, children, foundChildren);
		IClasspathAttribute[] extraAttributes = decodeExtraAttributes(attributeList);

		// custom output location
		IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(removeAttribute(TAG_OUTPUT, attributes)) : null;

		String[] unknownAttributes = null;
		ArrayList unknownChildren = null;

		if (unknownElements != null) {
			// unknown attributes
			int unknownAttributeLength = attributes.getLength();
			if (unknownAttributeLength != 0) {
				unknownAttributes = new String[unknownAttributeLength*2];
				for (int i = 0; i < unknownAttributeLength; i++) {
					Node attribute = attributes.item(i);
					unknownAttributes[i*2] = attribute.getNodeName();
					unknownAttributes[i*2 + 1] = attribute.getNodeValue();
				}
			}

			// unknown children
			for (int i = 0, length = foundChildren.length; i < length; i++) {
				if (!foundChildren[i]) {
					Node node = children.item(i);
					if (node.getNodeType() != Node.ELEMENT_NODE) continue;
					if (unknownChildren == null)
						unknownChildren = new ArrayList();
					StringBuffer buffer = new StringBuffer();
					decodeUnknownNode(node, buffer, project);
					unknownChildren.add(buffer.toString());
				}
			}
		}

		// recreate the CP entry
		IClasspathEntry entry = null;
		switch (kind) {

			case IClasspathEntry.CPE_PROJECT :
				entry = new ClasspathEntry(
												IPackageFragmentRoot.K_SOURCE,
												IClasspathEntry.CPE_PROJECT,
												path,
												ClasspathEntry.INCLUDE_ALL, // inclusion patterns
												ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
												null, // source attachment
												null, // source attachment root
												null, // specific output folder
												isExported,
												accessRules,
												combineAccessRestrictions,
												extraAttributes);
				break;
			case IClasspathEntry.CPE_LIBRARY :
				entry = JavaCore.newLibraryEntry(
												path,
												sourceAttachmentPath,
												sourceAttachmentRootPath,
												accessRules,
												extraAttributes,
												isExported);
				break;
			case IClasspathEntry.CPE_SOURCE :
				// must be an entry in this project or specify another project
				String projSegment = path.segment(0);
				if (projSegment != null && projSegment.equals(project.getElementName())) { // this project
					entry = JavaCore.newSourceEntry(
												path,
												inclusionPatterns,
												exclusionPatterns,
												outputLocation,
												extraAttributes);
				} else {
					if (path.segmentCount() == 1) {
						// another project
						entry = JavaCore.newProjectEntry(
												path,
												accessRules,
												combineAccessRestrictions,
												extraAttributes,
												isExported);
					} else {
						// an invalid source folder
						entry = JavaCore.newSourceEntry(
												path,
												inclusionPatterns,
												exclusionPatterns,
												outputLocation,
												extraAttributes);
					}
				}
				break;
			case IClasspathEntry.CPE_VARIABLE :
				entry = JavaCore.newVariableEntry(
												path,
												sourceAttachmentPath,
												sourceAttachmentRootPath,
												accessRules,
												extraAttributes,
												isExported);
				break;
			case IClasspathEntry.CPE_CONTAINER :
				entry = JavaCore.newContainerEntry(
												path,
												accessRules,
												extraAttributes,
												isExported);
				break;
			case ClasspathEntry.K_OUTPUT :
				if (!path.isAbsolute()) return null;
				entry = new ClasspathEntry(
												ClasspathEntry.K_OUTPUT,
												IClasspathEntry.CPE_LIBRARY,
												path,
												INCLUDE_ALL,
												EXCLUDE_NONE,
												null, // source attachment
												null, // source attachment root
												null, // custom output location
												false,
												null, // no access rules
												false, // no accessible files to combine
												NO_EXTRA_ATTRIBUTES);
				break;
			default :
				throw new AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr));
		}

		if (unknownAttributes != null || unknownChildren != null) {
			UnknownXmlElements unknownXmlElements = new UnknownXmlElements();
			unknownXmlElements.attributes = unknownAttributes;
			unknownXmlElements.children = unknownChildren;
			unknownElements.put(path, unknownXmlElements);
		}

		return entry;
	}

	/*
	 * Returns whether the given path as a ".." segment
	 */
	public static boolean hasDotDot(IPath path) {
		for (int i = 0, length = path.segmentCount(); i < length; i++) {
			if (DOT_DOT.equals(path.segment(i)))
				return true;
		}
		return false;
	}

	public static NodeList getChildAttributes(String childName, NodeList children, boolean[] foundChildren) {
		for (int i = 0, length = foundChildren.length; i < length; i++) {
			Node node = children.item(i);
			if (childName.equals(node.getNodeName())) {
				foundChildren[i] = true;
				return node.getChildNodes();
			}
		}
		return null;
	}


	private static String removeAttribute(String nodeName, NamedNodeMap nodeMap) {
		Node node = removeNode(nodeName, nodeMap);
		if (node == null)
			return ""; // //$NON-NLS-1$
		return node.getNodeValue();
	}

	private static Node removeNode(String nodeName, NamedNodeMap nodeMap) {
		try {
			return nodeMap.removeNamedItem(nodeName);
		} catch (DOMException e) {
			if (e.code != DOMException.NOT_FOUND_ERR)
				throw e;
			return null;
		}
	}

	/*
	 * Read the Class-Path clause of the manifest of the jar pointed by this path, and return
	 * the corresponding paths.
	 */
	public static IPath[] resolvedChainedLibraries(IPath jarPath) {
		ArrayList result = new ArrayList();
		resolvedChainedLibraries(jarPath, new HashSet(), result);
		if (result.size() == 0)
			return NO_PATHS;
		return (IPath[]) result.toArray(new IPath[result.size()]);
	}

	private static void resolvedChainedLibraries(IPath jarPath, HashSet visited, ArrayList result) {
		if (visited.contains( jarPath))
			return;
		visited.add(jarPath);
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		if (manager.isNonChainingJar(jarPath))
			return;
		List calledFileNames = getCalledFileNames(jarPath);
		if (calledFileNames == null) {
			manager.addNonChainingJar(jarPath);
		} else {
			Iterator calledFilesIterator = calledFileNames.iterator();
			IPath directoryPath = jarPath.removeLastSegments(1);
			while (calledFilesIterator.hasNext()) {
				String calledFileName = (String) calledFilesIterator.next();
				if (!directoryPath.isValidPath(calledFileName)) {
					if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
						Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
					}
				} else {
					IPath calledJar = directoryPath.append(new Path(calledFileName));
					// Ignore if segment count is Zero (https://bugs.eclipse.org/bugs/show_bug.cgi?id=308150)
					if (calledJar.segmentCount() == 0) {
						if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
							Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
						}
						continue;
					}
					resolvedChainedLibraries(calledJar, visited, result);
					result.add(calledJar);
				}
			}
		}
	}

	private static char[] getManifestContents(IPath jarPath) throws CoreException, IOException {
		ZipFile zip = null;
		InputStream inputStream = null;
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		try {
			zip = manager.getZipFile(jarPath);
			ZipEntry manifest = zip.getEntry(TypeConstants.META_INF_MANIFEST_MF);
			if (manifest == null) {
				return null;
			}
			inputStream = zip.getInputStream(manifest);
			char[] chars = getInputStreamAsCharArray(inputStream, UTF_8);
			return chars;
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					// best effort
				}
			}
			manager.closeZipFile(zip);
		}
	}

	private static List getCalledFileNames(IPath jarPath) {
		Object target = JavaModel.getTarget(jarPath, true/*check existence, otherwise the manifest cannot be read*/);
		if (!(target instanceof IFile || target instanceof File))
			return null;

		List calledFileNames = null;
		try {
			char[] manifestContents = getManifestContents(jarPath);
			if (manifestContents == null)
				return null;
			// non-null implies regular file
			ManifestAnalyzer analyzer = new ManifestAnalyzer();
			boolean success = analyzer.analyzeManifestContents(manifestContents);
			calledFileNames = analyzer.getCalledFileNames();
			if (!success || analyzer.getClasspathSectionsCount() == 1 && calledFileNames == null) {
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
					Util.verbose("Invalid Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
				}
				return null;
			} else if (analyzer.getClasspathSectionsCount() > 1) {
				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
					Util.verbose("Multiple Class-Path headers in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
				}
				return null;
			}
		} catch (CoreException | IOException e) {
			// not a zip file
			if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
				Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
				e.printStackTrace();
			}
		}
		return calledFileNames;
	}

	/*
	 * Resolves the ".." in the given path. Returns the given path if it contains no ".." segment.
	 */
	public static IPath resolveDotDot(IPath reference, IPath path) {
		IPath newPath = null;
		IPath workspaceLocation = workspaceRoot.getLocation();
		if (reference == null || workspaceLocation.isPrefixOf(reference)) {
			for (int i = 0, length = path.segmentCount(); i < length; i++) {
				String segment = path.segment(i);
				if (DOT_DOT.equals(segment)) {
					if (newPath == null) {
						if (i == 0) {
							newPath = workspaceLocation;
						} else {
							newPath = path.removeFirstSegments(i);
						}
					} else {
						if (newPath.segmentCount() > 0) {
							newPath = newPath.removeLastSegments(1);
						} else {
							newPath = workspaceLocation;
						}
					}
				} else if (newPath != null) {
					if (newPath.equals(workspaceLocation) && workspaceRoot.getProject(segment).isAccessible()) {
						newPath = new Path(segment).makeAbsolute();
					} else {
						newPath = newPath.append(segment);
					}
				}
			}
		}
		else {
			for (int i = 0, length = path.segmentCount(); i < length; i++) {
				String segment = path.segment(i);
				if (DOT_DOT.equals(segment)) {
					if (newPath == null){
						newPath = reference;
					}
					if (newPath.segmentCount() > 0) {
						newPath = newPath.removeLastSegments(1);
	 				}
				} else if (newPath != null) {
					newPath = newPath.append(segment);
	 			}
			}
		}
		if (newPath == null)
			return path;
		return newPath;
	}

	/**
	 * Encode some patterns into XML parameter tag
	 */
	private static void encodePatterns(IPath[] patterns, String tag, Map parameters) {
		if (patterns != null && patterns.length > 0) {
			StringBuffer rule = new StringBuffer(10);
			for (int i = 0, max = patterns.length; i < max; i++){
				if (i > 0) rule.append('|');
				rule.append(patterns[i]);
			}
			parameters.put(tag, String.valueOf(rule));
		}
	}

	/**
	 * Returns true if the given object is a classpath entry
	 * with equivalent attributes.
	 */
	@Override
	public boolean equals(Object object) {
		if (this == object)
			return true;
		if (object instanceof ClasspathEntry) {
			ClasspathEntry otherEntry = (ClasspathEntry) object;

			if (this.contentKind != otherEntry.getContentKind())
				return false;

			if (this.entryKind != otherEntry.getEntryKind())
				return false;

			if (this.isExported != otherEntry.isExported())
				return false;

			if (!this.path.equals(otherEntry.getPath()))
				return false;

			IPath otherPath = otherEntry.getSourceAttachmentPath();
			if (this.sourceAttachmentPath == null) {
				if (otherPath != null)
					return false;
			} else {
				if (!this.sourceAttachmentPath.equals(otherPath))
					return false;
			}

			otherPath = otherEntry.getSourceAttachmentRootPath();
			if (this.sourceAttachmentRootPath == null) {
				if (otherPath != null)
					return false;
			} else {
				if (!this.sourceAttachmentRootPath.equals(otherPath))
					return false;
			}

			if (!equalPatterns(this.inclusionPatterns, otherEntry.getInclusionPatterns()))
				return false;
			if (!equalPatterns(this.exclusionPatterns, otherEntry.getExclusionPatterns()))
				return false;
			AccessRuleSet otherRuleSet = otherEntry.getAccessRuleSet();
			if (getAccessRuleSet() != null) {
				if (!getAccessRuleSet().equals(otherRuleSet))
					return false;
			} else if (otherRuleSet != null)
				return false;
			if (this.combineAccessRules != otherEntry.combineAccessRules())
				return false;
			otherPath = otherEntry.getOutputLocation();
			if (this.specificOutputLocation == null) {
				if (otherPath != null)
					return false;
			} else {
				if (!this.specificOutputLocation.equals(otherPath))
					return false;
			}
			if (!equalAttributes(this.extraAttributes, otherEntry.getExtraAttributes()))
				return false;
			return true;
		} else {
			return false;
		}
	}

	private static boolean equalAttributes(IClasspathAttribute[] firstAttributes, IClasspathAttribute[] secondAttributes) {
		if (firstAttributes != secondAttributes){
		    if (firstAttributes == null) return false;
			int length = firstAttributes.length;
			if (secondAttributes == null || secondAttributes.length != length)
				return false;
			for (int i = 0; i < length; i++) {
				if (!firstAttributes[i].equals(secondAttributes[i]))
					return false;
			}
		}
		return true;
	}

	private static boolean equalPatterns(IPath[] firstPatterns, IPath[] secondPatterns) {
		if (firstPatterns != secondPatterns){
		    if (firstPatterns == null) return false;
			int length = firstPatterns.length;
			if (secondPatterns == null || secondPatterns.length != length)
				return false;
			for (int i = 0; i < length; i++) {
				// compare toStrings instead of IPaths
				// since IPath.equals is specified to ignore trailing separators
				if (!firstPatterns[i].toString().equals(secondPatterns[i].toString()))
					return false;
			}
		}
		return true;
	}

	/**
	 * @see IClasspathEntry#getAccessRules()
	 */
	@Override
	public IAccessRule[] getAccessRules() {
		if (this.accessRuleSet == null) return NO_ACCESS_RULES;
		AccessRule[] rules = this.accessRuleSet.getAccessRules();
		int length = rules.length;
		if (length == 0) return NO_ACCESS_RULES;
		IAccessRule[] result = new IAccessRule[length];
		System.arraycopy(rules, 0, result, 0, length);
		return result;
	}

	public AccessRuleSet getAccessRuleSet() {
		return this.accessRuleSet;
	}

	/**
	 * @see IClasspathEntry
	 */
	@Override
	public int getContentKind() {
		return this.contentKind;
	}

	/**
	 * @see IClasspathEntry
	 */
	@Override
	public int getEntryKind() {
		return this.entryKind;
	}

	/**
	 * @see IClasspathEntry#getExclusionPatterns()
	 */
	@Override
	public IPath[] getExclusionPatterns() {
		return this.exclusionPatterns;
	}

	@Override
	public IClasspathAttribute[] getExtraAttributes() {
		return this.extraAttributes;
	}

	/**
	 * @see IClasspathEntry#getExclusionPatterns()
	 */
	@Override
	public IPath[] getInclusionPatterns() {
		return this.inclusionPatterns;
	}

	/**
	 * @see IClasspathEntry#getOutputLocation()
	 */
	@Override
	public IPath getOutputLocation() {
		return this.specificOutputLocation;
	}

	/**
	 * @see IClasspathEntry
	 */
	@Override
	public IPath getPath() {
		return this.path;
	}

	/**
	 * @see IClasspathEntry
	 */
	@Override
	public IPath getSourceAttachmentPath() {
		return this.sourceAttachmentPath;
	}

	/**
	 * @see IClasspathEntry
	 */
	@Override
	public IPath getSourceAttachmentRootPath() {
		return this.sourceAttachmentRootPath;
	}

	/**
	 * Internal API: answer the path for external annotations (for null analysis) associated with
	 * the given classpath entry.
	 * Four shapes of paths are supported:
	 * <ol>
	 * <li>relative, variable (VAR/relpath): resolve classpath variable VAR and append relpath</li>
	 * <li>relative, project (relpath): interpret relpath as a relative path within the given project</li>
	 * <li>absolute, workspace (/Proj/relpath): an absolute path in the workspace</li>
	 * <li>absolute, filesystem (/abspath): an absolute path in the filesystem</li>
	 * </ol>
	 * In case of ambiguity, workspace lookup has higher priority than filesystem lookup
	 * (in fact filesystem paths are never validated).
	 *
	 * @param entry classpath entry to work on
	 * @param project project whose classpath we are analysing
	 * @param resolve if true, any workspace-relative paths will be resolved to filesystem paths.
	 * @return a path (in the workspace or filesystem-absolute) or null
	 */
	public static IPath getExternalAnnotationPath(IClasspathEntry entry, IProject project, boolean resolve) {
		String rawAnnotationPath = getRawExternalAnnotationPath(entry);
		if (rawAnnotationPath != null) {
			IPath annotationPath = new Path(rawAnnotationPath);
			if (annotationPath.isAbsolute()) {
				if (!resolve)
					return annotationPath;

				// try Workspace-absolute:
				IResource resource = project.getWorkspace().getRoot().findMember(annotationPath);
				if (resource != null) {
					return resource.getLocation();
				} else if (new File(annotationPath.toOSString()).exists()) { // absolute, not in workspace, must be Filesystem-absolute
					return annotationPath;
				}
				invalidExternalAnnotationPath(project);
			} else {
				// try Variable (always resolved):
				IPath resolved = JavaCore.getResolvedVariablePath(annotationPath);
				if (resolved != null)
					return resolved;

				// Project-relative:
				if (project != null) {
					if (resolve) {
						IResource member = project.findMember(annotationPath);
						if (member != null)
							return member.getLocation();
						invalidExternalAnnotationPath(project);
					} else {
						return new Path(project.getName()).append(annotationPath).makeAbsolute();
					}
				}
			}
		}
		return null;
	}

	/**
	 * Answer the raw external annotation path as specified in .classpath, or null.
	 * @param entry where to look
	 * @return the attached external annotation path, or null.
	 */
	static String getRawExternalAnnotationPath(IClasspathEntry entry) {
		return getExtraAttribute(entry, IClasspathAttribute.EXTERNAL_ANNOTATION_PATH);
	}

	private static void invalidExternalAnnotationPath(IProject project) {
		try {
			IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
			for (int i = 0, l = markers.length; i < l; i++) {
				if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR)
					return; // one marker is enough
			}
		} catch (CoreException ce) {
			return;
		}
		// no buildpath marker yet, trigger validation to create one:
		new ClasspathValidation((JavaProject) JavaCore.create(project)).validate();
	}

	private IJavaModelStatus validateExternalAnnotationPath(IJavaProject javaProject, IPath annotationPath) {
		IProject project = javaProject.getProject();
		if (annotationPath.isAbsolute()) {
			if (project.getWorkspace().getRoot().exists(annotationPath) // workspace absolute
					|| new File(annotationPath.toOSString()).exists())  // file system abolute
			{
				return null;
			}
		} else {
			if (JavaCore.getResolvedVariablePath(annotationPath) != null // variable (relative)
					|| project.exists(annotationPath))					 // project relative
			{
				return null;
			}
		}
		return new JavaModelStatus(IJavaModelStatusConstants.CP_INVALID_EXTERNAL_ANNOTATION_PATH,
				javaProject,
				Messages.bind(Messages.classpath_invalidExternalAnnotationPath,
						new String[] { annotationPath.toString(), project.getName(), this.path.toString()}));
	}

	public static String getExtraAttribute(IClasspathEntry entry, String attributeName) {
		IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
		for (int i = 0, length = extraAttributes.length; i < length; i++) {
			IClasspathAttribute attribute = extraAttributes[i];
			if (attributeName.equals(attribute.getName())) {
				return attribute.getValue();
			}
		}
		return null;
	}

	@Override
	public IClasspathEntry getReferencingEntry() {
		return this.referencingEntry;
	}

	/**
	 * Returns the hash code for this classpath entry
	 */
	@Override
	public int hashCode() {
		return this.path.hashCode();
	}

	/**
	 * @see IClasspathEntry#isExported()
	 */
	@Override
	public boolean isExported() {
		return this.isExported;
	}

	public boolean isOptional() {
		for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
			IClasspathAttribute attribute = this.extraAttributes[i];
			if (IClasspathAttribute.OPTIONAL.equals(attribute.getName()) && "true".equals(attribute.getValue())) //$NON-NLS-1$
				return true;
		}
		return false;
	}
	public boolean isModular() {
		for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
			IClasspathAttribute attribute = this.extraAttributes[i];
			if (IClasspathAttribute.MODULE.equals(attribute.getName()) && "true".equals(attribute.getValue())) //$NON-NLS-1$
				return true;
		}
		return false;
	}

	public String getSourceAttachmentEncoding() {
		for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
			IClasspathAttribute attribute = this.extraAttributes[i];
			if (IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING.equals(attribute.getName()))
				return attribute.getValue();
		}
		return null;
	}

	/**
	 * Returns the kind of a <code>PackageFragmentRoot</code> from its <code>String</code> form.
	 */
	static int kindFromString(String kindStr) {

		if (kindStr.equalsIgnoreCase("prj")) //$NON-NLS-1$
			return IClasspathEntry.CPE_PROJECT;
		if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$
			return IClasspathEntry.CPE_VARIABLE;
		if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$
			return IClasspathEntry.CPE_CONTAINER;
		if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$
			return IClasspathEntry.CPE_SOURCE;
		if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$
			return IClasspathEntry.CPE_LIBRARY;
		if (kindStr.equalsIgnoreCase("output")) //$NON-NLS-1$
			return ClasspathEntry.K_OUTPUT;
		return -1;
	}

	/**
	 * Returns a <code>String</code> for the kind of a class path entry.
	 */
	static String kindToString(int kind) {

		switch (kind) {
			case IClasspathEntry.CPE_PROJECT :
				return "src"; // backward compatibility //$NON-NLS-1$
			case IClasspathEntry.CPE_SOURCE :
				return "src"; //$NON-NLS-1$
			case IClasspathEntry.CPE_LIBRARY :
				return "lib"; //$NON-NLS-1$
			case IClasspathEntry.CPE_VARIABLE :
				return "var"; //$NON-NLS-1$
			case IClasspathEntry.CPE_CONTAINER :
				return "con"; //$NON-NLS-1$
			case ClasspathEntry.K_OUTPUT :
				return "output"; //$NON-NLS-1$
			default :
				return "unknown"; //$NON-NLS-1$
		}
	}

	/*
	 * Backward compatibility: only accessible and non-accessible files are supported.
	 */
	public static IAccessRule[] getAccessRules(IPath[] accessibleFiles, IPath[] nonAccessibleFiles) {
		int accessibleFilesLength = accessibleFiles == null ? 0 : accessibleFiles.length;
		int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0 : nonAccessibleFiles.length;
		int length = accessibleFilesLength + nonAccessibleFilesLength;
		if (length == 0) return null;
		IAccessRule[] accessRules = new IAccessRule[length];
		for (int i = 0; i < accessibleFilesLength; i++) {
			accessRules[i] = JavaCore.newAccessRule(accessibleFiles[i], IAccessRule.K_ACCESSIBLE);
		}
		for (int i = 0; i < nonAccessibleFilesLength; i++) {
			accessRules[accessibleFilesLength + i] = JavaCore.newAccessRule(nonAccessibleFiles[i], IAccessRule.K_NON_ACCESSIBLE);
		}
		return accessRules;
	}

	/**
	 * Returns a printable representation of this classpath entry.
	 */
	@Override
	public String toString() {
		StringBuilder buffer = new StringBuilder();
		Object target = JavaModel.getTarget(getPath(), true);
		if (target instanceof File)
			buffer.append(getPath().toOSString());
		else
			buffer.append(String.valueOf(getPath()));
		buffer.append('[');
		switch (getEntryKind()) {
			case IClasspathEntry.CPE_LIBRARY :
				buffer.append("CPE_LIBRARY"); //$NON-NLS-1$
				break;
			case IClasspathEntry.CPE_PROJECT :
				buffer.append("CPE_PROJECT"); //$NON-NLS-1$
				break;
			case IClasspathEntry.CPE_SOURCE :
				buffer.append("CPE_SOURCE"); //$NON-NLS-1$
				break;
			case IClasspathEntry.CPE_VARIABLE :
				buffer.append("CPE_VARIABLE"); //$NON-NLS-1$
				break;
			case IClasspathEntry.CPE_CONTAINER :
				buffer.append("CPE_CONTAINER"); //$NON-NLS-1$
				break;
		}
		buffer.append("]["); //$NON-NLS-1$
		switch (getContentKind()) {
			case IPackageFragmentRoot.K_BINARY :
				buffer.append("K_BINARY"); //$NON-NLS-1$
				break;
			case IPackageFragmentRoot.K_SOURCE :
				buffer.append("K_SOURCE"); //$NON-NLS-1$
				break;
			case ClasspathEntry.K_OUTPUT :
				buffer.append("K_OUTPUT"); //$NON-NLS-1$
				break;
		}
		buffer.append(']');
		if (getSourceAttachmentPath() != null) {
			buffer.append("[sourcePath:"); //$NON-NLS-1$
			buffer.append(getSourceAttachmentPath());
			buffer.append(']');
		}
		if (getSourceAttachmentRootPath() != null) {
			buffer.append("[rootPath:"); //$NON-NLS-1$
			buffer.append(getSourceAttachmentRootPath());
			buffer.append(']');
		}
		buffer.append("[isExported:"); //$NON-NLS-1$
		buffer.append(this.isExported);
		buffer.append(']');
		IPath[] patterns = this.inclusionPatterns;
		int length;
		if ((length = patterns == null ? 0 : patterns.length) > 0) {
			buffer.append("[including:"); //$NON-NLS-1$
			for (int i = 0; i < length; i++) {
				buffer.append(patterns[i]);
				if (i != length-1) {
					buffer.append('|');
				}
			}
			buffer.append(']');
		}
		patterns = this.exclusionPatterns;
		if ((length = patterns == null ? 0 : patterns.length) > 0) {
			buffer.append("[excluding:"); //$NON-NLS-1$
			for (int i = 0; i < length; i++) {
				buffer.append(patterns[i]);
				if (i != length-1) {
					buffer.append('|');
				}
			}
			buffer.append(']');
		}
		if (this.accessRuleSet != null) {
			buffer.append('[');
			buffer.append(this.accessRuleSet.toString(false/*on one line*/));
			buffer.append(']');
		}
		if (this.entryKind == CPE_PROJECT) {
			buffer.append("[combine access rules:"); //$NON-NLS-1$
			buffer.append(this.combineAccessRules);
			buffer.append(']');
		}
		if (getOutputLocation() != null) {
			buffer.append("[output:"); //$NON-NLS-1$
			buffer.append(getOutputLocation());
			buffer.append(']');
		}
		if ((length = this.extraAttributes == null ? 0 : this.extraAttributes.length) > 0) {
			buffer.append("[attributes:"); //$NON-NLS-1$
			for (int i = 0; i < length; i++) {
				buffer.append(this.extraAttributes[i]);
				if (i != length-1) {
					buffer.append(',');
				}
			}
			buffer.append(']');
		}
		return buffer.toString();
	}

	public ClasspathEntry resolvedDotDot(IPath reference) {
		IPath resolvedPath = resolveDotDot(reference, this.path);
		if (resolvedPath == this.path)
			return this;
		return new ClasspathEntry(
							getContentKind(),
							getEntryKind(),
							resolvedPath,
							this.inclusionPatterns,
							this.exclusionPatterns,
							getSourceAttachmentPath(),
							getSourceAttachmentRootPath(),
							getOutputLocation(),
							this.getReferencingEntry(),
							this.isExported,
							getAccessRules(),
							this.combineAccessRules,
							this.extraAttributes);
	}

	/*
	 * Read the Class-Path clause of the manifest of the jar pointed by this entry, and return
	 * the corresponding library entries.
	 */
	public ClasspathEntry[] resolvedChainedLibraries() {
		IPath[] paths = resolvedChainedLibraries(getPath());
		int length = paths.length;
		if (length == 0)
			return NO_ENTRIES;
		ClasspathEntry[] result = new ClasspathEntry[length];
		for (int i = 0; i < length; i++) {
			// Chained(referenced) libraries can have their own attachment path. Hence, set them to null
			result[i] = new ClasspathEntry(
					getContentKind(),
					getEntryKind(),
					paths[i],
					this.inclusionPatterns,
					this.exclusionPatterns,
					null,
					null,
					getOutputLocation(),
					this,
					this.isExported,
					getAccessRules(),
					this.combineAccessRules,
					NO_EXTRA_ATTRIBUTES);
		}
		return result;
	}

	/**
	 * Answers an ID which is used to distinguish entries during package
	 * fragment root computations
	 */
	public String rootID(){

		if (this.rootID == null) {
			switch(this.entryKind){
				case IClasspathEntry.CPE_LIBRARY :
					this.rootID = "[LIB]"+this.path;  //$NON-NLS-1$
					break;
				case IClasspathEntry.CPE_PROJECT :
					this.rootID = "[PRJ]"+this.path;  //$NON-NLS-1$
					break;
				case IClasspathEntry.CPE_SOURCE :
					this.rootID = "[SRC]"+this.path;  //$NON-NLS-1$
					break;
				case IClasspathEntry.CPE_VARIABLE :
					this.rootID = "[VAR]"+this.path;  //$NON-NLS-1$
					break;
				case IClasspathEntry.CPE_CONTAINER :
					this.rootID = "[CON]"+this.path;  //$NON-NLS-1$
					break;
				default :
					this.rootID = "";  //$NON-NLS-1$
					break;
			}
		}
		return this.rootID;
	}

	/**
	 * @see IClasspathEntry
	 * @deprecated
	 */
	@Override
	public IClasspathEntry getResolvedEntry() {

		return JavaCore.getResolvedClasspathEntry(this);
	}

	/**
	 * This function computes the URL of the index location for this classpath entry. It returns null if the URL is
	 * invalid.
	 */
	public URL getLibraryIndexLocation() {
		switch(getEntryKind()) {
			case IClasspathEntry.CPE_LIBRARY :
				if (SHARED_INDEX_LOCATION != null) {
					try {
						String pathString = getPath().toPortableString();
						CRC32 checksumCalculator = new CRC32();
						checksumCalculator.update(pathString.getBytes());
						String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
						return new URL("file", null, Paths.get(SHARED_INDEX_LOCATION, fileName).toString()); //$NON-NLS-1$
					} catch (MalformedURLException e1) {
						Util.log(e1); // should not happen if protocol known (eg. 'file')
					}
				}
				break;
			case IClasspathEntry.CPE_VARIABLE :
				break;
			default :
				return null;
		}
		if (this.extraAttributes == null) return null;
		for (int i= 0; i < this.extraAttributes.length; i++) {
			IClasspathAttribute attrib= this.extraAttributes[i];
			if (IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
				String value = attrib.getValue();
				try {
					return new URL(value);
				} catch (MalformedURLException e) {
					return null;
				}
			}
		}
		return null;
	}

	public boolean ignoreOptionalProblems() {
		if (this.entryKind == IClasspathEntry.CPE_SOURCE) {
			for (int i = 0; i < this.extraAttributes.length; i++) {
				IClasspathAttribute attrib = this.extraAttributes[i];
				if (IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS.equals(attrib.getName())) {
					return "true".equals(attrib.getValue()); //$NON-NLS-1$
				}
			}
		}
		return false;
	}

	/**
	 * Validate a given classpath and output location for a project, using the following rules:
	 * <ul>
	 *   <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
	 *   <li> The project output location path cannot be null, must be absolute and located inside the project.
	 *   <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
	 *   <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
	 *   <li> Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenario listed below:
	 *      <ul><li> A source folder can coincidate with its own output location, in which case this output can then contain library archives.
	 *                     However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li>
	 *              <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
	 * 			<li> An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output
	 * 					location is excluded from the source folder. </li>
	 *      </ul>
	 * </ul>
	 *
	 *  Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
	 *  in the checking process (this allows to perform a consistency check on a classpath which has references to
	 *  yet non existing projects, folders, ...).
	 *  <p>
	 *  This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
	 *  be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
	 *  <p>
	 * @param javaProject the given java project
	 * @param rawClasspath a given classpath
	 * @param projectOutputLocation a given output location
	 * @return a status object with code <code>IStatus.OK</code> if
	 *		the given classpath and output location are compatible, otherwise a status
	 *		object indicating what is wrong with the classpath or output location
	 */
	public static IJavaModelStatus validateClasspath(IJavaProject javaProject, IClasspathEntry[] rawClasspath, IPath projectOutputLocation) {

		IProject project = javaProject.getProject();
		IPath projectPath= project.getFullPath();
		String projectName = javaProject.getElementName();

		/* validate output location */
		if (projectOutputLocation == null) {
			return new JavaModelStatus(IJavaModelStatusConstants.NULL_PATH);
		}
		if (projectOutputLocation.isAbsolute()) {
			if (!projectPath.isPrefixOf(projectOutputLocation)) {
				return new JavaModelStatus(IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT, javaProject, projectOutputLocation.toString());
			}
		} else {
			return new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, projectOutputLocation);
		}

		boolean hasSource = false;
		boolean hasLibFolder = false;


		// tolerate null path, it will be reset to default
		if (rawClasspath == null)
			return JavaModelStatus.VERIFIED_OK;

		// check duplicate entries on raw classpath only (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=175226 )
		int rawLength = rawClasspath.length;
		HashSet pathes = new HashSet(rawLength);
		for (int i = 0 ; i < rawLength; i++) {
			IPath entryPath = rawClasspath[i].getPath();
			if (!pathes.add(entryPath)){
				String entryPathMsg = projectName.equals(entryPath.segment(0)) ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString();
				return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryPath, new String[] {entryPathMsg, projectName}));
			}
		}

		// retrieve resolved classpath
		IClasspathEntry[] classpath;
		try {
			// don't resolve chained libraries: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=259685
			classpath = ((JavaProject)javaProject).resolveClasspath(rawClasspath, false/*don't use previous session*/, false/*don't resolve chained libraries*/).resolvedClasspath;
		} catch(JavaModelException e){
			return e.getJavaModelStatus();
		}

		int outputCount = 1;
		IPath[] outputLocations	= new IPath[classpath.length+1];
		boolean[] allowNestingInOutputLocations = new boolean[classpath.length+1];
		outputLocations[0] = projectOutputLocation;

		// retrieve and check output locations
		IPath potentialNestedOutput = null; // for error reporting purpose
		int sourceEntryCount = 0;
		boolean disableExclusionPatterns = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, true));
		boolean disableCustomOutputLocations = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, true));
		ArrayList<IClasspathEntry> testSourcesFolders=new ArrayList<>();
		HashSet<IPath> mainOutputLocations=new HashSet<>();
		for (IClasspathEntry resolvedEntry : classpath) {
			if (disableExclusionPatterns &&
			        ((resolvedEntry.getInclusionPatterns() != null && resolvedEntry.getInclusionPatterns().length > 0)
			        || (resolvedEntry.getExclusionPatterns() != null && resolvedEntry.getExclusionPatterns().length > 0))) {
				return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS, javaProject, resolvedEntry.getPath());
			}
			switch(resolvedEntry.getEntryKind()){
				case IClasspathEntry.CPE_SOURCE :
					sourceEntryCount++;
					boolean isTest = resolvedEntry.isTest();
					if(isTest) {
						testSourcesFolders.add(resolvedEntry);
					}

					IPath customOutput;
					if ((customOutput = resolvedEntry.getOutputLocation()) != null) {

						if (disableCustomOutputLocations) {
							return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS, javaProject, resolvedEntry.getPath());
						}
						// ensure custom output is in project
						if (customOutput.isAbsolute()) {
							if (!javaProject.getPath().isPrefixOf(customOutput)) {
								return new JavaModelStatus(IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT, javaProject, customOutput.toString());
							}
						} else {
							return new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, customOutput);
						}
						if(!isTest) {
							mainOutputLocations.add(customOutput);
						}
						// ensure custom output doesn't conflict with other outputs
						// check exact match
						if (Util.indexOfMatchingPath(customOutput, outputLocations, outputCount) != -1) {
							continue; // already found
						}
						// accumulate all outputs, will check nesting once all available (to handle ordering issues)
						outputLocations[outputCount++] = customOutput;
					}
			}
		}
		// check nesting across output locations
		for (int i = 1 /*no check for default output*/ ; i < outputCount; i++) {
			IPath customOutput = outputLocations[i];
			int index;
			// check nesting
			if ((index = Util.indexOfEnclosingPath(customOutput, outputLocations, outputCount)) != -1 && index != i) {
				if (index == 0) {
					// custom output is nested in project's output: need to check if all source entries have a custom
					// output before complaining
					if (potentialNestedOutput == null) potentialNestedOutput = customOutput;
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {customOutput.makeRelative().toString(), outputLocations[index].makeRelative().toString()}));
				}
			}
		}
		// allow custom output nesting in project's output if all source entries have a custom output
		if (sourceEntryCount <= outputCount-1) {
		    allowNestingInOutputLocations[0] = true;
		} else if (potentialNestedOutput != null) {
			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {potentialNestedOutput.makeRelative().toString(), outputLocations[0].makeRelative().toString()}));
		} else {
			if (sourceEntryCount > testSourcesFolders.size()) {
				// if there are source folders with main sources, treat project output location as main output location
				mainOutputLocations.add(outputLocations[0]);
			}
		}
		for (IClasspathEntry resolvedEntry : testSourcesFolders) {
			IPath customOutput;
			if ((customOutput = resolvedEntry.getOutputLocation()) != null) {
				if(mainOutputLocations.contains(customOutput)) {
					return new JavaModelStatus(IJavaModelStatusConstants.TEST_OUTPUT_FOLDER_MUST_BE_SEPARATE_FROM_MAIN_OUTPUT_FOLDERS, javaProject, resolvedEntry.getPath());
				}
			} else {
				if(sourceEntryCount > testSourcesFolders.size()) {
					return new JavaModelStatus(IJavaModelStatusConstants.TEST_SOURCE_REQUIRES_SEPARATE_OUTPUT_LOCATION, javaProject, resolvedEntry.getPath());
				}
			}
		}

		for (IClasspathEntry resolvedEntry : classpath) {
			IPath path = resolvedEntry.getPath();
			int index;
			switch(resolvedEntry.getEntryKind()){

				case IClasspathEntry.CPE_SOURCE :
					hasSource = true;
					if ((index = Util.indexOfMatchingPath(path, outputLocations, outputCount)) != -1){
						allowNestingInOutputLocations[index] = true;
					}
					break;

				case IClasspathEntry.CPE_LIBRARY:
					Object target = JavaModel.getTarget(path, false/*don't check resource existence*/);
					hasLibFolder |= target instanceof IContainer;
					if ((index = Util.indexOfMatchingPath(path, outputLocations, outputCount)) != -1){
						allowNestingInOutputLocations[index] = true;
					}
					break;
			}
		}
		if (!hasSource && !hasLibFolder) { // if no source and no lib folder, then allowed
			for (int i = 0; i < outputCount; i++) allowNestingInOutputLocations[i] = true;
		}

		// check all entries
		for (IClasspathEntry entry : classpath) {
			if (entry == null) continue;
			IPath entryPath = entry.getPath();
			int kind = entry.getEntryKind();

			// no further check if entry coincidates with project or output location
			if (entryPath.equals(projectPath)){
				// complain if self-referring project entry
				if (kind == IClasspathEntry.CPE_PROJECT){
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Messages.bind(Messages.classpath_cannotReferToItself, entryPath.makeRelative().toString()));
				}
				// tolerate nesting output in src if src==prj
				continue;
			}

			// allow nesting source entries in each other as long as the outer entry excludes the inner one
			if (kind == IClasspathEntry.CPE_SOURCE
					|| (kind == IClasspathEntry.CPE_LIBRARY && (JavaModel.getTarget(entryPath, false/*don't check existence*/) instanceof IContainer))) {
				for (IClasspathEntry otherEntry : classpath) {
					if (otherEntry == null) continue;
					int otherKind = otherEntry.getEntryKind();
					IPath otherPath = otherEntry.getPath();
					if (entry != otherEntry
						&& (otherKind == IClasspathEntry.CPE_SOURCE
								|| (otherKind == IClasspathEntry.CPE_LIBRARY
										&& (JavaModel.getTarget(otherPath, false/*don't check existence*/) instanceof IContainer)))) {
						char[][] inclusionPatterns, exclusionPatterns;
						if (otherPath.isPrefixOf(entryPath)
								&& !otherPath.equals(entryPath)
								&& !Util.isExcluded(entryPath.append("*"), inclusionPatterns = ((ClasspathEntry)otherEntry).fullInclusionPatternChars(), exclusionPatterns = ((ClasspathEntry)otherEntry).fullExclusionPatternChars(), false)) { //$NON-NLS-1$
							String exclusionPattern = entryPath.removeFirstSegments(otherPath.segmentCount()).segment(0);
							if (Util.isExcluded(entryPath, inclusionPatterns, exclusionPatterns, false)) {
								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_mustEndWithSlash, new String[] {exclusionPattern, entryPath.makeRelative().toString()}));
							} else {
								if (otherKind == IClasspathEntry.CPE_SOURCE) {
									exclusionPattern += '/';
									if (!disableExclusionPatterns) {
										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInEntry, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern}));
									} else {
										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInEntryNoExclusion, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern}));
									}
								} else {
									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInLibrary, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString()}));
								}
							}
						}
					}
				}
			}

			// prevent nesting output location inside entry unless enclosing is a source entry which explicitly exclude the output location
			char[][] inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
			char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
			for (int j = 0; j < outputCount; j++){
				IPath currentOutput = outputLocations[j];
				if (entryPath.equals(currentOutput)) continue;
				if (entryPath.isPrefixOf(currentOutput)) {
				    if (kind != IClasspathEntry.CPE_SOURCE || !Util.isExcluded(currentOutput, inclusionPatterns, exclusionPatterns, true)) {
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInEntry, new String[] {currentOutput.makeRelative().toString(), entryPath.makeRelative().toString()}));
				    }
				}
			}

			// prevent nesting entry inside output location - when distinct from project or a source folder
			for (int j = 0; j < outputCount; j++){
				if (allowNestingInOutputLocations[j]) continue;
				IPath currentOutput = outputLocations[j];
				if (currentOutput.isPrefixOf(entryPath)) {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInOutput, new String[] {entryPath.makeRelative().toString(), currentOutput.makeRelative().toString()}));
				}
			}
		}
		// ensure that no specific output is coincidating with another source folder (only allowed if matching current source folder)
		// 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate)
		// perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should
		// diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should
		// first complain about missing exclusion pattern
		IJavaModelStatus cachedStatus = null;
		for (IClasspathEntry entry : classpath) {
			if (entry == null) continue;
			IPath entryPath = entry.getPath();
			int kind = entry.getEntryKind();

			// Build some common strings for status message
			boolean isProjectRelative = projectName.equals(entryPath.segment(0));
			String entryPathMsg = isProjectRelative ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString();

			if (kind == IClasspathEntry.CPE_SOURCE) {
				IPath output = entry.getOutputLocation();
				if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output)
				for (IClasspathEntry otherEntry : classpath) {
					if (otherEntry == entry) continue;

					switch (otherEntry.getEntryKind()) {
						case IClasspathEntry.CPE_SOURCE :
							// Bug 287164 : Report errors of overlapping output locations only if the user sets the corresponding preference.
							// The check is required for backward compatibility with bug-fix 36465.
							String option = javaProject.getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true);
							if (otherEntry.getPath().equals(output)
									&& !JavaCore.IGNORE.equals(option)) {
								boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0));
								String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString();
								if (JavaCore.ERROR.equals(option)) {
									return new JavaModelStatus(IStatus.ERROR, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE,
											Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {
											entryPathMsg, otherPathMsg, projectName }));
								}
								if (cachedStatus == null) {
									// Note that the isOK() is being overridden to return true. This is an exceptional scenario
									cachedStatus = new JavaModelStatus(IStatus.OK, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE,
										Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {
										entryPathMsg, otherPathMsg, projectName })){
										@Override
										public boolean isOK() {
											return true;
										}
									};
								}
							}
							break;
						case IClasspathEntry.CPE_LIBRARY :
							if (output != projectOutputLocation && otherEntry.getPath().equals(output)) {
								boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0));
								String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString();
								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName}));
							}
					}
				}
			}
		}

		if (hasSource && testSourcesFolders.size() == 0 && !JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY, true))) {
			for (IClasspathEntry entry : classpath) {
				if (entry == null)
					continue;
				IPath entryPath = entry.getPath();
				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
					if (entryPath.isAbsolute() && entryPath.segmentCount() == 1) {
						IProject prereqProjectRsc = workspaceRoot.getProject(entryPath.segment(0));
						IJavaProject prereqProject = JavaCore.create(prereqProjectRsc);
						boolean hasMain = false;
						boolean hasTest = false;
						try {
							for (IClasspathEntry nested : prereqProject.getRawClasspath()) {
								if (nested.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
									if (nested.isTest()) {
										hasTest = true;
									} else {
										hasMain = true;
									}
									if (hasTest && hasMain)
										break;
								}
							}
						} catch (JavaModelException e) {
							// is reported elsewhere
						}
						if (hasTest && !hasMain) {
							return new JavaModelStatus(IJavaModelStatusConstants.MAIN_ONLY_PROJECT_DEPENDS_ON_TEST_ONLY_PROJECT,
									Messages.bind(Messages.classpath_main_only_project_depends_on_test_only_project,
											new String[] { prereqProject.getElementName() }));
						}
					}
				}
			}
		}

		// NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return
		// a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be
		// inserted before the mentioned code.
		if (cachedStatus != null) return cachedStatus;

		return JavaModelStatus.VERIFIED_OK;
	}

	/**
	 * Returns a Java model status describing the problem related to this classpath entry if any,
	 * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
	 * given classpath entry denotes a valid element to be referenced onto a classpath).
	 *
	 * @param project the given java project
	 * @param entry the given classpath entry
	 * @param checkSourceAttachment a flag to determine if source attachment should be checked
	 * @param referredByContainer flag indicating whether the given entry is referred by a classpath container
	 * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
	 */
	public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment, boolean referredByContainer){
		if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
			JavaModelManager.getJavaModelManager().removeFromInvalidArchiveCache(entry.getPath());
		}
		IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, referredByContainer);
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171136 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=300136
		// Ignore class path errors from optional entries.
		int statusCode = status.getCode();
		if ( (statusCode == IJavaModelStatusConstants.INVALID_CLASSPATH ||
				statusCode == IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND ||
				statusCode == IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND ||
				statusCode == IJavaModelStatusConstants.INVALID_PATH) &&
				((ClasspathEntry) entry).isOptional())
			return JavaModelStatus.VERIFIED_OK;
		return status;
	}

	private static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, IClasspathContainer entryContainer, boolean checkSourceAttachment, boolean referredByContainer){

		IPath path = entry.getPath();

		// Build some common strings for status message
		String projectName = project.getElementName();
		String entryPathMsg = projectName.equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();

		switch(entry.getEntryKind()){

			// container entry check
			case IClasspathEntry.CPE_CONTAINER :
				if (path.segmentCount() >= 1){
					try {
						IJavaModelStatus status = null;
						// Validate extra attributes
						IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
						if (extraAttributes != null) {
							int length = extraAttributes.length;
							HashSet set = new HashSet(length);
							for (int i=0; i<length; i++) {
								String attName = extraAttributes[i].getName();
								if (!set.add(attName)) {
									status = new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
									break;
								}
							}
							if (status == null) {
								String annotationPath = getRawExternalAnnotationPath(entry);
								if (annotationPath != null) {
									status = ((ClasspathEntry) entry).validateExternalAnnotationPath(project, new Path(annotationPath));
									if (status != null)
										return status;
								}
							}
						}
						IClasspathContainer container = JavaModelManager.getJavaModelManager().getClasspathContainer(path, project);
						// container retrieval is performing validation check on container entry kinds.
						if (container == null) {
							if (status != null)
								return status;
							return new JavaModelStatus(IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND, project, path);
						} else if (container == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
							// don't create a marker if initialization is in progress (case of cp initialization batching)
							return JavaModelStatus.VERIFIED_OK;
						}
						IClasspathEntry[] containerEntries = container.getClasspathEntries();
						if (containerEntries != null){
							for (int i = 0, length = containerEntries.length; i < length; i++){
								IClasspathEntry containerEntry = containerEntries[i];
								int kind = containerEntry == null ? 0 : containerEntry.getEntryKind();
								if (containerEntry == null
									|| kind == IClasspathEntry.CPE_SOURCE
									|| kind == IClasspathEntry.CPE_VARIABLE
									|| kind == IClasspathEntry.CPE_CONTAINER){
										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CP_CONTAINER_ENTRY, project, path);
								}
								IJavaModelStatus containerEntryStatus = validateClasspathEntry(project, containerEntry, container, checkSourceAttachment, true/*referred by container*/);
								if (!containerEntryStatus.isOK()){
									return containerEntryStatus;
								}
							}
						}
					} catch(JavaModelException e){
						return new JavaModelStatus(e);
					}
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalContainerPath, new String[] {entryPathMsg, projectName}));
				}
				break;

			// variable entry check
			case IClasspathEntry.CPE_VARIABLE :
				if (path.segmentCount() >= 1){
					try {
						entry = JavaCore.getResolvedClasspathEntry(entry);
					} catch (AssertionFailedException e) {
						// Catch the assertion failure and throw java model exception instead
						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
					}
					if (entry == null){
						return new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, project, path);
					}

					// get validation status
					IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, false/*not referred by container*/);
					if (!status.isOK()) return status;

					// return deprecation status if any
					String variableName = path.segment(0);
					String deprecatedMessage = JavaCore.getClasspathVariableDeprecationMessage(variableName);
					if (deprecatedMessage != null) {
						return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path, deprecatedMessage);
					}
					return status;
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName}));
				}

			// library entry check
			case IClasspathEntry.CPE_LIBRARY :
				path = ClasspathEntry.resolveDotDot(project.getProject().getLocation(), path);

				// do not validate entries from Class-Path: in manifest
				// (these entries are considered optional since the user cannot act on them)
				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=252392

				String containerInfo = null;
				if (entryContainer != null) {
					if (entryContainer instanceof UserLibraryClasspathContainer) {
						containerInfo = Messages.bind(Messages.classpath_userLibraryInfo, new String[] {entryContainer.getDescription()});
					} else {
						containerInfo = Messages.bind(Messages.classpath_containerInfo, new String[] {entryContainer.getDescription()});
					}
				}
				IJavaModelStatus status = validateLibraryEntry(path, project, containerInfo, checkSourceAttachment ? entry.getSourceAttachmentPath() : null, entryPathMsg, ((ClasspathEntry) entry).isOptional());
				if (!status.isOK())
					return status;
				break;

			// project entry check
			case IClasspathEntry.CPE_PROJECT :
				if (path.isAbsolute() && path.segmentCount() == 1) {
					IProject prereqProjectRsc = workspaceRoot.getProject(path.segment(0));
					IJavaProject prereqProject = JavaCore.create(prereqProjectRsc);
					try {
						if (!prereqProjectRsc.exists() || !prereqProjectRsc.hasNature(JavaCore.NATURE_ID)){
							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName}));
						}
						if (!prereqProjectRsc.isOpen()){
							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_closedProject, new String[] {path.segment(0)}));
						}
						if (!JavaCore.IGNORE.equals(project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true))) {
							long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
							long prereqProjectTargetJDK = CompilerOptions.versionToJdkLevel(prereqProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
							if (prereqProjectTargetJDK > projectTargetJDK) {
								return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
										project, path,
										Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel,
												new String[] {
													project.getElementName(),
													CompilerOptions.versionFromJdkLevel(projectTargetJDK),
													path.makeRelative().toString(),
													CompilerOptions.versionFromJdkLevel(prereqProjectTargetJDK)}));
							}
						}
					} catch (CoreException e){
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName}));
					}
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalProjectPath, new String[] {path.toString(), projectName}));
				}
				break;

			// project source folder
			case IClasspathEntry.CPE_SOURCE :
				if (((entry.getInclusionPatterns() != null && entry.getInclusionPatterns().length > 0)
						|| (entry.getExclusionPatterns() != null && entry.getExclusionPatterns().length > 0))
						&& JavaCore.DISABLED.equals(project.getOption(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, true))) {
					return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS, project, path);
				}
				if (entry.getOutputLocation() != null && JavaCore.DISABLED.equals(project.getOption(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, true))) {
					return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS, project, path);
				}
				if (path.isAbsolute() && !path.isEmpty()) {
					IPath projectPath= project.getProject().getFullPath();
					if (!projectPath.isPrefixOf(path) || JavaModel.getTarget(path, true) == null){
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceFolder, new String[] {entryPathMsg, projectName}));
					}
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalSourceFolderPath, new String[] {entryPathMsg, projectName}));
				}
				break;
		}

		// Validate extra attributes
		IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
		if (extraAttributes != null) {
			int length = extraAttributes.length;
			HashSet set = new HashSet(length);
			for (int i=0; i<length; i++) {
				String attName = extraAttributes[i].getName();
				if (!set.add(attName)) {
					return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
				}
			}
		}

		return JavaModelStatus.VERIFIED_OK;
	}

	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=232816, Now we have the facility to include a container
	// name in diagnostics. If the parameter ``container'' is not null, it is used to point to the library
	// more fully.
	private static IJavaModelStatus validateLibraryEntry(IPath path, IJavaProject project, String container, IPath sourceAttachment, String entryPathMsg, boolean isOptionalLibrary) {
		if (path.isAbsolute() && !path.isEmpty()) {
			boolean validateJdkLevelCompatibility = !JavaCore.IGNORE.equals(project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true));
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=412882, avoid validating optional entries
			if (!validateJdkLevelCompatibility && isOptionalLibrary) {
				return JavaModelStatus.VERIFIED_OK;
			}
			Object target = JavaModel.getTarget(path, true);
			if (target == null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=248661
				IPath workspaceLocation = workspaceRoot.getLocation();
				if (workspaceLocation.isPrefixOf(path)) {
					target = JavaModel.getTarget(path.makeRelativeTo(workspaceLocation).makeAbsolute(), true);
				}
			}
			if (target != null && validateJdkLevelCompatibility) {
				long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
				long libraryJDK = Util.getJdkLevel(target);
				if (libraryJDK != 0 && libraryJDK > projectTargetJDK) {
					if (container != null) {
						return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
								project, path,
								Messages.bind(Messages.classpath_incompatibleLibraryJDKLevelInContainer,
										new String [] {
											project.getElementName(),
											CompilerOptions.versionFromJdkLevel(projectTargetJDK),
											path.makeRelative().toString(),
											container,
											CompilerOptions.versionFromJdkLevel(libraryJDK)}));
					} else {
						return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
								project, path,
								Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel,
										new String[] {
											project.getElementName(),
											CompilerOptions.versionFromJdkLevel(projectTargetJDK),
											path.makeRelative().toString(),
											CompilerOptions.versionFromJdkLevel(libraryJDK)}));
					}
				}
			}
			if (isOptionalLibrary) {
				return JavaModelStatus.VERIFIED_OK;
			}
			if (target instanceof IResource){
				IResource resolvedResource = (IResource) target;
				switch(resolvedResource.getType()){
					case IResource.FILE :
						if (sourceAttachment != null
							&& !sourceAttachment.isEmpty()
							&& JavaModel.getTarget(sourceAttachment, true) == null){
							if (container != null) {
								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toString(), container}));
							} else {
								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), project.getElementName()}));
							}
						}
						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042
						// Validate the contents of the archive
						IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg);
						if (status != JavaModelStatus.VERIFIED_OK)
							return status;
						break;
					case IResource.FOLDER :	// internal binary folder
						if (sourceAttachment != null
							&& !sourceAttachment.isEmpty()
							&& JavaModel.getTarget(sourceAttachment, true) == null){
							if (container != null) {
								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toString(), container}));
							} else {
								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), project.getElementName()}));
							}
						}
				}
			} else if (target instanceof File){
				File file = JavaModel.getFile(target);
				if (file == null) {
					if (container != null) {
						return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolderInContainer, new String[] {path.toOSString(), container}));
					} else {
						return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolder, new String[] {path.toOSString(), project.getElementName()}));
					}
				} else {
					if (sourceAttachment != null
							&& !sourceAttachment.isEmpty()
							&& JavaModel.getTarget(sourceAttachment, true) == null){
						if (container != null) {
							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toOSString(), container}));
						} else {
							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toOSString(), project.getElementName()}));
						}
					}
					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042
					// Validate the contents of the archive
					if(file.isFile()) {
						IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg);
						if (status != JavaModelStatus.VERIFIED_OK)
							return status;
					}
				}
			} else {
				boolean isExternal = path.getDevice() != null || !ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)).exists();
				if (isExternal) {
					if (container != null) {
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibraryInContainer, new String[] {path.toOSString(), container}));
					} else {
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {path.toOSString(), project.getElementName()}));
					}
				} else {
					if (entryPathMsg == null)
						entryPathMsg = 	project.getElementName().equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();
					if (container!= null) {
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibraryInContainer, new String[] {entryPathMsg, container}));
					} else {
						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {entryPathMsg, project.getElementName()}));
					}
				}
			}
		} else {
			if (entryPathMsg == null)
				entryPathMsg = 	project.getElementName().equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();
				if (container != null) {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryPathInContainer, new String[] {entryPathMsg, container}));
				} else {
					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryPath, new String[] {entryPathMsg, project.getElementName()}));
				}
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	private static IJavaModelStatus validateLibraryContents(IPath path, IJavaProject project, String entryPathMsg) {
		JavaModelManager manager = JavaModelManager.getJavaModelManager();
		try {
			manager.verifyArchiveContent(path);
		} catch (CoreException e) {
			if (e.getStatus().getMessage() == Messages.status_IOException) {
				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(
						Messages.classpath_archiveReadError,
						new String[] {entryPathMsg, project.getElementName()}));
			}
		}
		return JavaModelStatus.VERIFIED_OK;
	}

	/*
	 * For testing shared index location in JavaIndexTests only
	 */
	public static void setSharedIndexLocation(String value, Class<?> clazz) throws IllegalArgumentException{
		if (clazz != null && "org.eclipse.jdt.core.tests.model.JavaIndexTests".equals(clazz.getName())) { //$NON-NLS-1$
			SHARED_INDEX_LOCATION = value;
		} else {
			throw new IllegalArgumentException("Cannot set index location for specified test class"); //$NON-NLS-1$
		}
	}
}
