/*******************************************************************************
 * Copyright (c) 2005, 2018 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.core;

import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

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.Assert;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IAccessRule;
import org.eclipse.dltk.core.IBuildpathAttribute;
import org.eclipse.dltk.core.IBuildpathContainer;
import org.eclipse.dltk.core.IBuildpathContainerExtension2;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IModelStatus;
import org.eclipse.dltk.core.IModelStatusConstants;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.internal.compiler.env.AccessRule;
import org.eclipse.dltk.internal.compiler.env.AccessRuleSet;
import org.eclipse.dltk.internal.core.util.Messages;
import org.eclipse.dltk.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;

public class BuildpathEntry implements IBuildpathEntry {
	public static final String TAG_BUILDPATH = "buildpath"; //$NON-NLS-1$
	public static final String TAG_BUILDPATHENTRY = "buildpathentry"; //$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_EXTERNAL = "external"; //$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_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_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_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$
	/**
	 * Describes the kind of project fragment found on this buildpath entry -
	 * either K_BINARY or K_SOURCE
	 */
	private int contentKind;
	/**
	 * Describes the kind of buildpath entry - one of BPE_PROJECT, BPE_SOURCE or
	 * BPE_CONTAINER
	 */
	private int entryKind;
	/**
	 * The meaning of the path of a buildpath entry depends on its entry kind:
	 * <ul>
	 * <li>Source code in the current project (<code>BPE_SOURCE</code>) - The
	 * path associated with this entry is the absolute path to the root
	 * folder.</li>
	 * <li>A required project (<code>BPE_PROJECT</code>) - the path of the entry
	 * denotes the path to the corresponding project resource.</li>
	 * <li>A container entry (<code>BPE_CONTAINER</code>) - the first segment of
	 * the path is denoting the unique container identifier (for which a
	 * <code>BuildpathContainerInitializer</code> could be registered), and the
	 * remaining segments are used as additional hints for resolving the
	 * container entry to an actual <code>IBuildpathContainer</code>.</li>
	 */
	private 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 static final BuildpathEntry[] NO_ENTRIES = new BuildpathEntry[0];
	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 = {};
	/**
	 * The export flag
	 */
	boolean isExported;

	/**
	 * Describes the path to the source archive/folder associated with this
	 * classpath entry, or <code>null</code> if this buildpath entry has no
	 * source attachment.
	 * <p>
	 * Only library and variable buildpath entries may have source attachments.
	 * For library buildpath 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;
	/*
	 * The extra attributes
	 */
	IBuildpathAttribute[] extraAttributes;

	/**
	 * External library extry.
	 */
	private boolean isExternal;

	/**
	 * Creates a build path entry of the specified kind with the given path.
	 *
	 * @param externalLib
	 *            TODO
	 */
	public BuildpathEntry(int contentKind, int entryKind, IPath path,
			boolean isExported, IPath[] inclusionPatterns,
			IPath[] exclusionPatterns,
			org.eclipse.dltk.core.IAccessRule[] accessRules,
			boolean combineAccessRules, IBuildpathAttribute[] extraAttributes,
			boolean externalLib) {
		// if this is external entry, path should be full
		Assert.isLegal(!externalLib || EnvironmentPathUtils.isFull(path) || path
				.segment(0).startsWith(IBuildpathEntry.BUILDPATH_SPECIAL));

		this.contentKind = contentKind;
		this.entryKind = entryKind;
		this.path = path;
		this.isExported = isExported;
		this.inclusionPatterns = inclusionPatterns;
		this.exclusionPatterns = exclusionPatterns;
		this.isExternal = externalLib;
		int length;
		if (accessRules != null && (length = accessRules.length) > 0) {
			AccessRule[] rules = new AccessRule[length];
			System.arraycopy(accessRules, 0, rules, 0, length);
			this.accessRuleSet = new AccessRuleSet(rules,
					getMessageTemplates());
		}
		this.combineAccessRules = combineAccessRules;
		this.extraAttributes = extraAttributes;
		if (inclusionPatterns != INCLUDE_ALL && inclusionPatterns.length > 0) {
			this.fullInclusionPatternChars = UNINIT_PATTERNS;
		}
		if (exclusionPatterns.length > 0) {
			this.fullExclusionPatternChars = UNINIT_PATTERNS;
		}
	}

	@Override
	public IPath getSourceAttachmentPath() {
		return sourceAttachmentPath;
	}

	@Override
	public IPath getSourceAttachmentRootPath() {
		return sourceAttachmentRootPath;
	}

	@Override
	public void setSourceAttachmentPath(IPath sourceAttachmentPath) {
		this.sourceAttachmentPath = sourceAttachmentPath;
	}

	@Override
	public void setSourceAttachmentRootPath(IPath sourceAttachmentRootPath) {
		this.sourceAttachmentRootPath = sourceAttachmentRootPath;
	}

	@Override
	public int getEntryKind() {
		return entryKind;
	}

	@Override
	public IPath[] getExclusionPatterns() {
		return this.exclusionPatterns;
	}

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

	@Override
	public String getExtraAttribute(String name) {
		if (name != null) {
			for (IBuildpathAttribute attribute : extraAttributes) {
				if (name.equals(attribute.getName())) {
					return attribute.getValue();
				}
			}
		}
		return null;
	}

	private String[] getMessageTemplates() {
		ModelManager manager = ModelManager.getModelManager();
		String[] result = new String[AccessRuleSet.MESSAGE_TEMPLATES_LENGTH];
		if (this.entryKind == BPE_PROJECT || this.entryKind == BPE_SOURCE) {
			/*
			 * can be remote source entry when reconciling
			 */
			result[0] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_project,
					new String[] { "{0}", getPath().segment(0) })); //$NON-NLS-1$
			result[1] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_constructor_project,
					new String[] { "{0}", getPath().segment(0) })); //$NON-NLS-1$
			result[2] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_method_project,
					new String[] { "{0}", "{1}", getPath().segment(0) })); //$NON-NLS-1$ //$NON-NLS-2$
			result[3] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_field_project,
					new String[] { "{0}", "{1}", getPath().segment(0) })); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			IPath libPath = getPath();
			Object target = Model.getTarget(
					ResourcesPlugin.getWorkspace().getRoot(), libPath, false);
			String pathString;
			if (target instanceof IFileHandle) {
				pathString = target.toString();
			} else {
				pathString = libPath.makeRelative().toString();
			}

			result[0] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_library,
					new String[] { "{0}", pathString })); //$NON-NLS-1$
			result[1] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_constructor_library,
					new String[] { "{0}", pathString })); //$NON-NLS-1$
			result[2] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_method_library,
					new String[] { "{0}", "{1}", pathString })); //$NON-NLS-1$ //$NON-NLS-2$
			result[3] = manager.intern(Messages.bind(
					org.eclipse.dltk.internal.core.util.Messages.restrictedAccess_field_library,
					new String[] { "{0}", "{1}", pathString })); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return result;
	}

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

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

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

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

	public BuildpathEntry resolvedDotDot(IPath reference) {
		// TODO (alex) port the implementation
		return this;
	}

	public BuildpathEntry[] resolvedChainedLibraries() {
		// TODO (alex) port the implementation
		return NO_ENTRIES;
	}

	/**
	 * 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 IBuildpathEntry.BPE_PROJECT:
				this.rootID = "[PRJ]" + this.path; //$NON-NLS-1$
				break;
			case IBuildpathEntry.BPE_LIBRARY:
				this.rootID = "[LIB]" + this.path; //$NON-NLS-1$
				break;
			case IBuildpathEntry.BPE_SOURCE:
				this.rootID = "[SRC]" + this.path; //$NON-NLS-1$
				break;
			case IBuildpathEntry.BPE_CONTAINER:
				this.rootID = "[CON]" + this.path; //$NON-NLS-1$
				break;
			default:
				this.rootID = ""; //$NON-NLS-1$
				break;
			}
		}
		return this.rootID;
	}

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

	/**
	 * Used to perform export/restriction propagation across referring
	 * projects/containers
	 */
	public BuildpathEntry combineWith(BuildpathEntry referringEntry) {
		if (referringEntry == null)
			return this;
		if (referringEntry.isExported()
				|| referringEntry.getAccessRuleSet() != null) {
			boolean combine = this.entryKind == BPE_SOURCE
					|| referringEntry.combineAccessRules();
			BuildpathEntry newEntry = new BuildpathEntry(getContentKind(),
					getEntryKind(), getPath(),
					referringEntry.isExported() || this.isExported, // duplicate
					// container
					// entry for
					// tagging
					// it as
					// exported
					this.inclusionPatterns, this.exclusionPatterns,
					combine(referringEntry.getAccessRules(), getAccessRules(),
							combine),
					this.combineAccessRules, this.extraAttributes,
					this.isExternal);
			newEntry.setSourceAttachmentPath(getSourceAttachmentPath());
			newEntry.setSourceAttachmentRootPath(getSourceAttachmentRootPath());
			return newEntry;
		}
		// no need to clone
		return this;
	}

	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;
	}

	/**
	 * @see IBuildpathEntry#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 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] = DLTKCore.newAccessRule(accessibleFiles[i],
					IAccessRule.K_ACCESSIBLE);
		}
		for (int i = 0; i < nonAccessibleFilesLength; i++) {
			accessRules[accessibleFilesLength + i] = DLTKCore.newAccessRule(
					nonAccessibleFiles[i], IAccessRule.K_NON_ACCESSIBLE);
		}
		return accessRules;
	}

	/**
	 * Returns a printable representation of this buildpath entry.
	 */
	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append(getPath().toString());
		buffer.append('[');
		switch (getEntryKind()) {
		case IBuildpathEntry.BPE_LIBRARY:
			buffer.append("BPE_LIBRARY"); //$NON-NLS-1$
			break;
		case IBuildpathEntry.BPE_PROJECT:
			buffer.append("BPE_PROJECT"); //$NON-NLS-1$
			break;
		case IBuildpathEntry.BPE_SOURCE:
			buffer.append("BPE_SOURCE"); //$NON-NLS-1$
			break;
		case IBuildpathEntry.BPE_VARIABLE:
			buffer.append("BPE_VARIABLE"); //$NON-NLS-1$
			break;
		case IBuildpathEntry.BPE_CONTAINER:
			buffer.append("BPE_CONTAINER"); //$NON-NLS-1$
			break;
		}
		buffer.append("]["); //$NON-NLS-1$
		switch (getContentKind()) {
		case IProjectFragment.K_BINARY:
			buffer.append("K_BINARY"); //$NON-NLS-1$
			break;
		case IProjectFragment.K_SOURCE:
			buffer.append("K_SOURCE"); //$NON-NLS-1$
			break;
		}
		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 == BPE_PROJECT) {
			buffer.append("[combine access rules:"); //$NON-NLS-1$
			buffer.append(this.combineAccessRules);
			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 AccessRuleSet getAccessRuleSet() {
		return this.accessRuleSet;
	}

	@Override
	public int getContentKind() {
		return contentKind;
	}

	public static IBuildpathEntry elementDecode(Element element,
			IScriptProject 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 != IBuildpathEntry.BPE_VARIABLE
				&& kind != IBuildpathEntry.BPE_CONTAINER
				&& !path.isAbsolute()) {
			path = projectPath.append(path);
		}
		// exported flag (optional)
		boolean isExported = removeAttribute(TAG_EXPORTED, attributes)
				.equals("true"); //$NON-NLS-1$
		boolean isExternal = removeAttribute(TAG_EXTERNAL, 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);
		// 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);
		IBuildpathAttribute[] extraAttributes = decodeExtraAttributes(
				attributeList);
		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 BP entry
		IBuildpathEntry entry = null;
		switch (kind) {
		case IBuildpathEntry.BPE_PROJECT:
			entry = new BuildpathEntry(IProjectFragment.K_SOURCE,
					IBuildpathEntry.BPE_PROJECT, path, isExported,
					BuildpathEntry.INCLUDE_ALL, // inclusion patterns
					BuildpathEntry.EXCLUDE_NONE, // exclusion patterns
					accessRules, combineAccessRestrictions, extraAttributes,
					false);
			break;
		case IBuildpathEntry.BPE_LIBRARY:
			if (isExternal) {
				IPath fullPath = Path.fromPortableString(pathAttr);
				if (!EnvironmentPathUtils.isFull(fullPath)) {
					String environmentId = EnvironmentManager
							.getEnvironmentId(project.getProject());
					if (environmentId != null) {
						path = EnvironmentPathUtils.getFullPath(environmentId,
								path);
					}
				} else {
					path = fullPath;
				}
			}
			entry = DLTKCore.newLibraryEntry(path, accessRules, extraAttributes,
					inclusionPatterns, exclusionPatterns, isExported,
					isExternal);

			break;
		case IBuildpathEntry.BPE_SOURCE:
			// entry = DLTKCore.newSourceEntry(path, inclusionPatterns,
			// exclusionPatterns, extraAttributes);
			String projSegment = path.segment(0);
			if (projSegment != null
					&& projSegment.equals(project.getElementName())) { // this
				// project
				entry = DLTKCore.newSourceEntry(path, inclusionPatterns,
						exclusionPatterns, extraAttributes);
			} else {
				if (path.segmentCount() == 1) {
					// another project
					entry = DLTKCore.newProjectEntry(path, accessRules,
							combineAccessRestrictions, extraAttributes,
							isExported);
				} else {
					// an invalid source folder
					entry = DLTKCore.newSourceEntry(path, inclusionPatterns,
							exclusionPatterns, extraAttributes);
				}
			}
			break;
		case IBuildpathEntry.BPE_VARIABLE:
			entry = DLTKCore.newVariableEntry(path, accessRules,
					extraAttributes, isExported);
			break;
		case IBuildpathEntry.BPE_CONTAINER:
			entry = DLTKCore.newContainerEntry(path, accessRules,
					extraAttributes, isExported);
			break;
		default:
			throw new AssertionFailedException(
					Messages.bind(Messages.buildpath_unknownKind, kindAttr));
		}

		String sourcePath = removeAttribute(TAG_SOURCEPATH, attributes);
		String rootPath = removeAttribute(TAG_ROOTPATH, attributes);
		if (sourcePath.length() > 0) {
			entry.setSourceAttachmentPath(new Path(sourcePath));
			entry.setSourceAttachmentRootPath(new Path(rootPath));
		}
		if (unknownAttributes != null || unknownChildren != null) {
			UnknownXmlElements unknownXmlElements = new UnknownXmlElements();
			unknownXmlElements.attributes = unknownAttributes;
			unknownXmlElements.children = unknownChildren;
			unknownElements.put(path, unknownXmlElements);
		}
		return entry;
	}

	static IBuildpathAttribute[] decodeExtraAttributes(NodeList attributes) {
		if (attributes == null)
			return NO_EXTRA_ATTRIBUTES;
		int length = attributes.getLength();
		if (length == 0)
			return NO_EXTRA_ATTRIBUTES;
		IBuildpathAttribute[] result = new IBuildpathAttribute[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 BuildpathAttribute(name, value);
			}
		}
		if (index != length)
			System.arraycopy(result, 0, result = new IBuildpathAttribute[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( //$NON-NLS-1$
						elementAccessRule.getAttribute(TAG_IGNORE_IF_BETTER));
				result[index++] = new BuildpathAccessRule(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,
			IScriptProject project) {
		ByteArrayOutputStream s = new ByteArrayOutputStream();
		OutputStreamWriter writer;
		try {
			writer = new OutputStreamWriter(s, StandardCharsets.UTF_8); // $NON-NLS-1$
			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(s.toString("UTF8")); //$NON-NLS-1$
		} catch (UnsupportedEncodingException e) {
			// ignore (UTF8 is always supported)
		}
	}

	private static void decodeUnknownNode(Node node, XMLWriter xmlWriter,
			boolean insertNewLine) {
		switch (node.getNodeType()) {
		case Node.ELEMENT_NODE:
			NamedNodeMap attributes = node.getAttributes();
			HashMap parameters = new HashMap();
			for (int i = 0, length = attributes == null ? 0
					: attributes.getLength(); 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;
	}

	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;
		}
	}

	/**
	 * Returns the kind of a <code>ProjectFragment</code> from its
	 * <code>String</code> form.
	 */
	static int kindFromString(String kindStr) {
		if (kindStr.equalsIgnoreCase("prj")) //$NON-NLS-1$
			return IBuildpathEntry.BPE_PROJECT;
		if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$
			return IBuildpathEntry.BPE_VARIABLE;
		if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$
			return IBuildpathEntry.BPE_CONTAINER;
		if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$
			return IBuildpathEntry.BPE_SOURCE;
		if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$
			return IBuildpathEntry.BPE_LIBRARY;
		return -1;
	}

	/**
	 * Returns the XML encoding of the class path.
	 */
	public void elementEncode(XMLWriter writer, IPath projectPath,
			boolean indent, boolean newLine, Map unknownElements) {
		Map<String, String> parameters = new HashMap<>();
		parameters.put(TAG_KIND, kindToString(this.entryKind));
		IPath xmlPath = this.path;
		if (this.entryKind != IBuildpathEntry.BPE_CONTAINER
				&& this.entryKind != IBuildpathEntry.BPE_CONTAINER) {
			// translate to project relative from absolute (unless a device
			// path)
			if (EnvironmentPathUtils.isFull(xmlPath)) {
				xmlPath = EnvironmentPathUtils.getLocalPath(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.isExported) {
			parameters.put(TAG_EXPORTED, "true");//$NON-NLS-1$
		}
		if (this.isExternal) {
			parameters.put(TAG_EXTERNAL, "true");//$NON-NLS-1$
		}
		if (this.sourceAttachmentPath != null) {
			parameters.put(TAG_SOURCEPATH,
					this.sourceAttachmentPath.toString());
		}
		if (this.sourceAttachmentRootPath != null) {
			parameters.put(TAG_ROOTPATH,
					this.sourceAttachmentRootPath.toString());
		}
		encodePatterns(this.inclusionPatterns, TAG_INCLUDING, parameters);
		encodePatterns(this.exclusionPatterns, TAG_EXCLUDING, parameters);
		if (this.entryKind == BPE_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);
			}
		}
		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;
		writer.printTag(TAG_BUILDPATHENTRY, parameters, indent, newLine,
				!hasExtraAttributes && !hasRestrictions
						&& !hasUnknownChildren/*
												 * close tag if no extra
												 * attributes , no restriction
												 * and no unknown children
												 */);
		if (hasExtraAttributes)
			encodeExtraAttributes(writer, indent, newLine);
		if (hasRestrictions)
			encodeAccessRules(writer, indent, newLine);
		if (hasUnknownChildren)
			encodeUnknownChildren(writer, indent, newLine, unknownChildren);
		if (hasUnknownChildren)
			writer.endTag(TAG_BUILDPATHENTRY, indent,
					true/* insert new line */);
		if (hasExtraAttributes || hasRestrictions || hasUnknownChildren)
			writer.endTag(TAG_BUILDPATHENTRY, 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++) {
			IBuildpathAttribute 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 org.eclipse.dltk.compiler.problem.IProblem.ForbiddenReference:
			parameters.put(TAG_KIND, TAG_NON_ACCESSIBLE);
			break;
		case org.eclipse.dltk.compiler.problem.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);
	}

	/**
	 * Returns a <code>String</code> for the kind of a class path entry.
	 */
	static String kindToString(int kind) {
		switch (kind) {
		case IBuildpathEntry.BPE_PROJECT:
			return "prj"; // backward compatibility //$NON-NLS-1$
		case IBuildpathEntry.BPE_SOURCE:
			return "src"; //$NON-NLS-1$
		case IBuildpathEntry.BPE_LIBRARY:
			return "lib"; //$NON-NLS-1$
		case IBuildpathEntry.BPE_VARIABLE:
			return "var"; //$NON-NLS-1$
		case IBuildpathEntry.BPE_CONTAINER:
			return "con"; //$NON-NLS-1$
		default:
			return "unknown"; //$NON-NLS-1$
		}
	}

	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 */);
		}
	}

	/**
	 * Validate a given buildpath for a project, using the following rules:
	 * <ul>
	 * <li>Buildpath entries cannot collide with each other; that is, all entry
	 * paths must be unique. *
	 * <li>A project entry cannot refer to itself directly (that is, a project
	 * cannot prerequisite itself).
	 * <li>Buildpath entries cannot coincidate or be nested in each other.
	 * </ul>
	 *
	 * Note that the buildpath 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 buildpath which has
	 * references to yet non existing projects, folders, ...).
	 * <p>
	 * This validation is intended to anticipate buildpath issues prior to
	 * assigning it to a project. In particular, it will automatically be
	 * performed during the buildpath setting operation (if validation fails,
	 * the buildpath setting will not complete).
	 * <p>
	 *
	 * @param scriptProject
	 *            the given script project
	 * @param rawBuildpath
	 *            a given buildpath
	 * @return a status object with code <code>ModelStatus.VERIFIED_OK</code> if
	 *         the given buildpath are correct, otherwise a status object
	 *         indicating what is wrong with the buildpath
	 */
	public static IModelStatus validateBuildpath(IScriptProject scriptProject,
			IBuildpathEntry[] rawBuildpath) {
		// TODO implement
		IProject project = scriptProject.getProject();
		IPath projectPath = project.getFullPath();
		String projectName = scriptProject.getElementName();
		// tolerate null path, it will be reset to default
		if (rawBuildpath == null) {
			return ModelStatus.VERIFIED_OK;
		}
		int interpreterCount = 0;
		for (int i = 0; i < rawBuildpath.length; ++i) {
			final IBuildpathEntry entry = rawBuildpath[i];
			if (entry.getEntryKind() == BPE_CONTAINER
					&& BuiltinProjectFragment.INTERPRETER_CONTAINER
							.equals(entry.getPath().segment(0))) {
				++interpreterCount;
				if (interpreterCount > 1) {
					return new ModelStatus(IModelStatusConstants.NAME_COLLISION,
							Messages.buildpath_multipleInterpreters);
				}
			}
		}
		final HashSet<IPath> paths = new HashSet<>(rawBuildpath.length);
		for (IBuildpathEntry entry : rawBuildpath) {
			final IPath entryPath = entry.getPath();
			if (!paths.add(entryPath)) {
				String entryPathMsg = projectName.equals(entryPath.segment(0))
						? entryPath.removeFirstSegments(1).toString()
						: EnvironmentPathUtils.getLocalPath(entryPath)
								.makeRelative().toString();
				return new ModelStatus(IModelStatusConstants.NAME_COLLISION,
						Messages.bind(Messages.buildpath_duplicateEntryPath,
								new String[] { entryPathMsg, projectName }));
			}
		}
		// retrieve resolved buildpath
		IBuildpathEntry[] buildpath;
		try {
			buildpath = ((ScriptProject) scriptProject).resolveBuildpath(
					rawBuildpath, false/*
										 * don't use previous session
										 */,
					false/*
							 * don't resolve chained libraries
							 */).resolvedClasspath;
		} catch (ModelException e) {
			return e.getModelStatus();
		}
		int length = buildpath.length;
		// int sourceEntryCount = 0;
		boolean disableExclusionPatterns = DLTKCore.DISABLED
				.equals(scriptProject.getOption(
						DLTKCore.CORE_ENABLE_BUILDPATH_EXCLUSION_PATTERNS,
						true));
		for (int i = 0; i < length; i++) {
			IBuildpathEntry resolvedEntry = buildpath[i];
			if (disableExclusionPatterns && ((resolvedEntry
					.getInclusionPatterns() != null
					&& resolvedEntry.getInclusionPatterns().length > 0)
					|| (resolvedEntry.getExclusionPatterns() != null
							&& resolvedEntry
									.getExclusionPatterns().length > 0))) {
				return new ModelStatus(
						IModelStatusConstants.DISABLED_BP_EXCLUSION_PATTERNS,
						scriptProject, resolvedEntry.getPath());
			}
		}
		// check all entries
		for (int i = 0; i < length; i++) {
			IBuildpathEntry entry = buildpath[i];
			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()
					: EnvironmentPathUtils.getLocalPath(entryPath)
							.makeRelative().toString();
			// boolean external = entry.isExternal();
			// no further check if entry coincidates with project or output
			// location
			if (entryPath.equals(projectPath)) {
				// complain if self-referring project entry
				if (kind == IBuildpathEntry.BPE_PROJECT) {
					return new ModelStatus(IModelStatusConstants.INVALID_PATH,
							Messages.bind(
									Messages.buildpath_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
			IDLTKLanguageToolkit toolkit = DLTKLanguageManager
					.getLanguageToolkit(scriptProject);
			if (kind == IBuildpathEntry.BPE_SOURCE
					|| (kind == IBuildpathEntry.BPE_LIBRARY
							&& !org.eclipse.dltk.compiler.util.Util
									.isArchiveFileName(toolkit,
											entryPath.lastSegment()))) {
				for (int j = 0; j < buildpath.length; j++) {
					IBuildpathEntry otherEntry = buildpath[j];
					if (otherEntry == null)
						continue;
					int otherKind = otherEntry.getEntryKind();
					IPath otherPath = otherEntry.getPath();
					if (entry != otherEntry
							&& (otherKind == IBuildpathEntry.BPE_SOURCE
									|| (otherKind == IBuildpathEntry.BPE_LIBRARY
											&& !org.eclipse.dltk.compiler.util.Util
													.isArchiveFileName(toolkit,
															otherPath
																	.lastSegment())))) {
						char[][] inclusionPatterns, exclusionPatterns;
						if (otherPath.isPrefixOf(entryPath)
								&& !otherPath.equals(entryPath)
								&& !Util.isExcluded(entryPath.append("*"), //$NON-NLS-1$
										inclusionPatterns = ((BuildpathEntry) otherEntry)
												.fullInclusionPatternChars(),
										exclusionPatterns = ((BuildpathEntry) otherEntry)
												.fullExclusionPatternChars(),
										false)) {
							String exclusionPattern = entryPath
									.removeFirstSegments(
											otherPath.segmentCount())
									.segment(0);
							if (Util.isExcluded(entryPath, inclusionPatterns,
									exclusionPatterns, false)) {
								return new ModelStatus(
										IModelStatusConstants.INVALID_BUILDPATH,
										Messages.bind(
												Messages.buildpath_mustEndWithSlash,
												new String[] { exclusionPattern,
														EnvironmentPathUtils
																.getLocalPath(
																		entryPath)
																.makeRelative()
																.toString() }));
							} else {
								if (otherKind == IBuildpathEntry.BPE_SOURCE) {
									exclusionPattern += '/';
									if (!disableExclusionPatterns) {
										return new ModelStatus(
												IModelStatusConstants.INVALID_BUILDPATH,
												Messages.bind(
														Messages.buildpath_cannotNestEntryInEntry,
														new String[] {
																EnvironmentPathUtils
																		.getLocalPath(
																				entryPath)
																		.makeRelative()
																		.toString(),
																EnvironmentPathUtils
																		.getLocalPath(
																				otherEntry
																						.getPath())
																		.makeRelative()
																		.toString(),
																exclusionPattern }));
									} else {
										return new ModelStatus(
												IModelStatusConstants.INVALID_BUILDPATH,
												Messages.bind(
														Messages.buildpath_cannotNestEntryInEntryNoExclusion,
														new String[] {
																EnvironmentPathUtils
																		.getLocalPath(
																				entryPath)
																		.makeRelative()
																		.toString(),
																EnvironmentPathUtils
																		.getLocalPath(
																				otherEntry
																						.getPath())
																		.makeRelative()
																		.toString(),
																exclusionPattern }));
									}
								} else {
									return new ModelStatus(
											IModelStatusConstants.INVALID_BUILDPATH,
											Messages.bind(
													Messages.buildpath_cannotNestEntryInLibrary,
													new String[] {
															EnvironmentPathUtils
																	.getLocalPath(
																			entryPath)
																	.makeRelative()
																	.toString(),
															EnvironmentPathUtils
																	.getLocalPath(
																			otherEntry
																					.getPath())
																	.makeRelative()
																	.toString() }));
								}
							}
						}
					}
				}
			}
		}
		return ModelStatus.VERIFIED_OK;
	}

	/**
	 * Returns a model status describing the problem related to this buildpath
	 * entry if any, a status object with code <code>IStatus.OK</code> if the
	 * entry is fine (that is, if the given buildpath entry denotes a valid
	 * element to be referenced onto a buildpath).
	 *
	 * @param project
	 *            the given script project
	 * @param entry
	 *            the given buildpath entry
	 * @param checkSourceAttachment
	 *            a flag to determine if source attachement should be checked
	 * @param recurseInContainers
	 *            flag indicating whether validation should be applied to
	 *            container entries recursively
	 * @return a model status describing the problem related to this buildpath
	 *         entry if any, a status object with code <code>IStatus.OK</code>
	 *         if the entry is fine
	 */
	public static IModelStatus validateBuildpathEntry(IScriptProject project,
			IBuildpathEntry entry, boolean recurseInContainers) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		IPath path = entry.getPath();
		// Build some common strings for status message
		String projectName = project.getElementName();
		boolean pathStartsWithProject = projectName.equals(path.segment(0));
		String entryPathMsg = pathStartsWithProject
				? path.removeFirstSegments(1).makeRelative().toString()
				: EnvironmentPathUtils.getLocalPath(path).toString();
		switch (entry.getEntryKind()) {
		// container entry check
		case IBuildpathEntry.BPE_CONTAINER:
			if (path != null && path.segmentCount() >= 1) {
				try {
					IBuildpathContainer container = ModelManager
							.getModelManager()
							.getBuildpathContainer(path, project);
					// container retrieval is performing validation check on
					// container entry kinds.
					if (container == null) {
						return new ModelStatus(
								IModelStatusConstants.BP_CONTAINER_PATH_UNBOUND,
								project, path);
					} else if (container == ModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
						// Validate extra attributes
						IBuildpathAttribute[] 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 ModelStatus(
											IModelStatusConstants.NAME_COLLISION,
											Messages.bind(
													Messages.buildpath_duplicateEntryExtraAttribute,
													new String[] { attName,
															entryPathMsg,
															projectName }));
								}
							}
						}
						// don't create a marker if initialization is in
						// progress (case of cp initialization batching)
						return ModelStatus.VERIFIED_OK;
					} else if (container instanceof IBuildpathContainerExtension2) {
						final IModelStatus status = ((IBuildpathContainerExtension2) container)
								.validate();
						if (status != null && !status.isOK()) {
							return status;
						}
					}
					IBuildpathEntry[] containerEntries = container
							.getBuildpathEntries();
					if (containerEntries != null) {
						for (int i = 0, length = containerEntries.length; i < length; i++) {
							IBuildpathEntry containerEntry = containerEntries[i];
							int kind = containerEntry == null ? 0
									: containerEntry.getEntryKind();
							if (containerEntry == null
									|| kind == IBuildpathEntry.BPE_SOURCE
									|| kind == IBuildpathEntry.BPE_CONTAINER) {
								// String description =
								// container.getDescription(project);
								// if (description == null)
								// description = path.makeRelative()
								// .toString();
								return new ModelStatus(
										IModelStatusConstants.INVALID_BP_CONTAINER_ENTRY,
										project, path);
							}
							if (recurseInContainers) {
								IModelStatus containerEntryStatus = validateBuildpathEntry(
										project, containerEntry,
										recurseInContainers);
								if (!containerEntryStatus.isOK()) {
									return containerEntryStatus;
								}
							}
						}
					}
				} catch (ModelException e) {
					return new ModelStatus(e);
				}
			} else {
				return new ModelStatus(IModelStatusConstants.INVALID_BUILDPATH,
						Messages.bind(Messages.buildpath_illegalContainerPath,
								new String[] { entryPathMsg, projectName }));
			}
			break;
		// variable entry check
		case IBuildpathEntry.BPE_VARIABLE:
			if (path.segmentCount() >= 1) {
				try {
					entry = DLTKCore.getResolvedBuildpathEntry(entry);
				} catch (AssertionFailedException e) {
					// Catch the assertion failure and throw java model
					// exception instead
					return new ModelStatus(IModelStatusConstants.INVALID_PATH,
							e.getMessage());
				}
				if (entry == null) {
					return new ModelStatus(
							IModelStatusConstants.BP_VARIABLE_PATH_UNBOUND,
							project, path);
				}

				// get validation status
				IModelStatus status = validateBuildpathEntry(project, entry,
						/* checkSourceAttachment, */recurseInContainers);
				if (!status.isOK())
					return status;
			} else {
				return new ModelStatus(IModelStatusConstants.INVALID_BUILDPATH,
						Messages.bind(Messages.buildpath_illegalVariablePath,
								new String[] { entryPathMsg, projectName }));
			}
			break;
		// library entry check
		case IBuildpathEntry.BPE_LIBRARY:
			if (path.segmentCount() >= 1
					&& path.segment(0)
							.startsWith(IBuildpathEntry.BUILDPATH_SPECIAL)
					&& !path.isAbsolute()) {
				break;
			}
			if (path != null && path.isAbsolute() && !path.isEmpty()) {
				Object target = Model.getTarget(workspaceRoot, path, true);
				// TODO: Add here some library version cheking
				if (!entry.isExternal()) {
					if (target instanceof IResource) {
						IResource resolvedResource = (IResource) target;
						switch (resolvedResource.getType()) {
						case IResource.FILE:
							break;
						case IResource.FOLDER: // internal binary folder
							break;
						}
					} else if (target instanceof IFileHandle) {
						IFileHandle file = (IFileHandle) target;
						if (!file.exists()) {
							return new ModelStatus(
									IModelStatusConstants.INVALID_BUILDPATH,
									Messages.bind(
											Messages.buildpath_illegalLibraryArchive,
											new String[] {
													EnvironmentPathUtils
															.getLocalPath(path)
															.toString(),
													projectName }));
						}
					}
				} else {
					IFileHandle file = EnvironmentPathUtils
							.getFile(entry.getPath());
					if (file == null || !file.exists()) {
						return new ModelStatus(
								IModelStatusConstants.INVALID_BUILDPATH,
								Messages.bind(
										Messages.buildpath_illegalExternalFolder,
										new String[] { EnvironmentPathUtils
												.getLocalPath(path).toString(),
												projectName }));
					}
				}
			} else {
				return new ModelStatus(IModelStatusConstants.INVALID_BUILDPATH,
						Messages.bind(Messages.buildpath_illegalLibraryPath,
								new String[] { entryPathMsg, projectName }));
			}
			break;
		// project entry check
		case IBuildpathEntry.BPE_PROJECT:
			if (path != null && path.isAbsolute() && path.segmentCount() == 1) {
				IProject prereqProjectRsc = workspaceRoot
						.getProject(path.segment(0));
				if (!prereqProjectRsc.exists() || !DLTKLanguageManager
						.hasScriptNature(prereqProjectRsc)) {
					return new ModelStatus(
							IModelStatusConstants.INVALID_BUILDPATH,
							Messages.bind(Messages.buildpath_unboundProject,
									new String[] { path.segment(0),
											projectName }));
				}
				if (!prereqProjectRsc.isOpen()) {
					return new ModelStatus(
							IModelStatusConstants.INVALID_BUILDPATH,
							Messages.bind(Messages.buildpath_closedProject,
									new String[] { path.segment(0) }));
				}
			} else {
				return new ModelStatus(IModelStatusConstants.INVALID_BUILDPATH,
						Messages.bind(Messages.buildpath_illegalProjectPath,
								new String[] { path.toString(), projectName }));
			}
			break;
		// project source folder
		case IBuildpathEntry.BPE_SOURCE:
			if (((entry.getInclusionPatterns() != null
					&& entry.getInclusionPatterns().length > 0)
					|| (entry.getExclusionPatterns() != null
							&& entry.getExclusionPatterns().length > 0))
					&& DLTKCore.DISABLED.equals(project.getOption(
							DLTKCore.CORE_ENABLE_BUILDPATH_EXCLUSION_PATTERNS,
							true))) {
				return new ModelStatus(
						IModelStatusConstants.DISABLED_BP_EXCLUSION_PATTERNS,
						project, path);
			}
			if (path != null && path.isAbsolute() && !path.isEmpty()) {
				IPath projectPath = project.getProject().getFullPath();
				if (!projectPath.isPrefixOf(path)
						|| Model.getTarget(workspaceRoot, path, true) == null) {
					return new ModelStatus(
							IModelStatusConstants.INVALID_BUILDPATH,
							Messages.bind(
									Messages.buildpath_unboundSourceFolder,
									new String[] { entryPathMsg,
											projectName }));
				}
			} else {
				return new ModelStatus(IModelStatusConstants.INVALID_BUILDPATH,
						Messages.bind(
								Messages.buildpath_illegalSourceFolderPath,
								new String[] { entryPathMsg, projectName }));
			}
			break;
		}
		// Validate extra attributes
		IBuildpathAttribute[] 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 ModelStatus(IModelStatusConstants.NAME_COLLISION,
							Messages.bind(
									Messages.buildpath_duplicateEntryExtraAttribute,
									new String[] { attName, entryPathMsg,
											projectName }));
				}
			}
		}
		return ModelStatus.VERIFIED_OK;
	}

	public static IPath resolveDotDot(IPath reference, IPath path) {
		// TODO (alex) port the implementation
		return path;
	}

	/**
	 * 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 equivalent buildpath entry.
	 */
	@Override
	public boolean equals(Object object) {
		if (this == object)
			return true;
		if (object instanceof BuildpathEntry) {
			BuildpathEntry otherEntry = (BuildpathEntry) object;
			if (this.contentKind != otherEntry.getContentKind())
				return false;
			if (this.entryKind != otherEntry.getEntryKind())
				return false;
			if (this.isExported != otherEntry.isExported())
				return false;
			if (this.isExternal != otherEntry.isExternal())
				return false;
			if (!this.path.equals(otherEntry.getPath()))
				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;
			if (!equalAttributes(this.extraAttributes,
					otherEntry.getExtraAttributes()))
				return false;
			return true;
		} else {
			return false;
		}
	}

	private static boolean equalAttributes(
			IBuildpathAttribute[] firstAttributes,
			IBuildpathAttribute[] 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;
	}

	@Override
	public boolean isExternal() {
		return isExternal;
	}

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