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

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
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.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
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.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.JSP11TLDNames;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.JSP12TLDNames;
import org.eclipse.jst.jsp.core.internal.contenttype.DeploymentDescriptorPropertyCache;
import org.eclipse.jst.jsp.core.internal.util.DocumentProvider;
import org.eclipse.jst.jsp.core.internal.util.FacetModuleCoreSupport;
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
import org.eclipse.wst.sse.core.internal.util.JarUtilities;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.xml.core.internal.XMLCorePlugin;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalog;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEntry;
import org.eclipse.wst.xml.core.internal.catalog.provisional.INextCatalog;
import org.w3c.dom.Document;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ibm.icu.util.StringTokenizer;

class ProjectDescription {

	class DeltaVisitor implements IResourceDeltaVisitor {
		public boolean visit(IResourceDelta delta) throws CoreException {
			IResource resource = delta.getResource();
			if (resource.getType() == IResource.FILE) {
				if (delta.getKind() == IResourceDelta.CHANGED && (delta.getFlags() == IResourceDelta.ENCODING || delta.getFlags() == IResourceDelta.MARKERS))
					return true;
				if (resource.getName().endsWith(".tld")) { //$NON-NLS-1$
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeTLD(resource);
					}
					else {
						updateTLD(resource, delta.getKind());
					}
				}
				else if (resource.getName().endsWith(".jar")) { //$NON-NLS-1$
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeJAR(resource);
					}
					else {
						updateJAR(resource, delta.getKind());
					}
				}
				else if ("tag".equalsIgnoreCase(resource.getFileExtension()) || "tagx".equalsIgnoreCase(resource.getFileExtension())) { //$NON-NLS-1$ //$NON-NLS-2$
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeTag(resource);
					}
					else {
						updateTag(resource, delta.getKind());
					}
				}
				else if (resource.getName().equals(WEB_XML) && resource.getParent().getName().equals(WEB_INF)) {
					if (delta.getKind() == IResourceDelta.REMOVED) {
						removeWebXML(resource);
					}
					else {
						updateWebXML(resource, delta.getKind());
					}
				}
			}
			return resource.getName().length() != 0 && resource.getName().charAt(0) != '.';
		}
	}

	class Indexer implements IResourceProxyVisitor {
		public boolean visit(IResourceProxy proxy) throws CoreException {
			boolean visitMembers = true;
			if (proxy.getType() == IResource.FILE) {
				if (proxy.getName().endsWith(".tld")) { //$NON-NLS-1$
					updateTLD(proxy.requestResource(), ITaglibIndexDelta.ADDED);
				}
				else if (proxy.getName().endsWith(".jar")) { //$NON-NLS-1$
					updateJAR(proxy.requestResource(), ITaglibIndexDelta.ADDED);
				}
				else if (proxy.getName().endsWith(".tag") || proxy.getName().endsWith(".tagx")) { //$NON-NLS-1$ //$NON-NLS-2$
					updateTagDir(proxy.requestResource().getParent(), ITaglibIndexDelta.ADDED);
					// any folder with these files will create a record for
					// that folder in one pass
					visitMembers = false;
				}
				else if (proxy.getName().equals(WEB_XML) && proxy.requestResource().getParent().getName().equals(WEB_INF)) {
					updateWebXML(proxy.requestResource(), ITaglibIndexDelta.ADDED);
				}
			}
			String name = proxy.getName();
			return name.length() != 0 && name.charAt(0) != '.' && visitMembers;
		}
	}

	static class JarRecord implements IJarRecord {
		boolean has11TLD;
		TaglibInfo info;

		boolean isExported = true;
		boolean isMappedInWebXML;
		IPath location;
		List urlRecords;

		public boolean equals(Object obj) {
			if (!(obj instanceof JarRecord))
				return false;
			return ((JarRecord) obj).location.equals(location) && ((JarRecord) obj).has11TLD == has11TLD && ((JarRecord) obj).info.equals(info);
		}

		public ITaglibDescriptor getDescriptor() {
			return info != null ? info : new TaglibInfo();
		}

		/**
		 * @return Returns the location.
		 */
		public IPath getLocation() {
			return location;
		}

		public int getRecordType() {
			return ITaglibRecord.JAR;
		}

		/**
		 * @return Returns the recommended/default prefix if one was given.
		 */
		public String getShortName() {
			if (info == null)
				return null;
			return info.shortName;
		}

		/**
		 * @return Returns the uri.
		 */
		public String getURI() {
			if (info == null)
				return null;
			return info.uri;
		}

		public List getURLRecords() {
			return urlRecords;
		}

		public String toString() {
			StringBuffer s = new StringBuffer("JarRecord: ");//$NON-NLS-1$ 
			s.append(location);
			if (urlRecords.size() > 0) {
				s.append('\n');//$NON-NLS-1$ 
				for (int i = 0; i < urlRecords.size(); i++) {
					s.append(urlRecords.get(i));
					s.append('\n');//$NON-NLS-1$ 
				}
			}
			return s.toString();
		}
	}

	static class TagDirRecord implements ITagDirRecord {
		TaglibInfo info;
		IPath path;
		// a List holding Strings of .tag and .tagx filenames relative to the
		// tagdir's location
		List tags = new ArrayList(0);

		public boolean equals(Object obj) {
			if (!(obj instanceof TagDirRecord))
				return false;
			return ((TagDirRecord) obj).path.equals(path) && ((TagDirRecord) obj).info.equals(info);
		}

		public ITaglibDescriptor getDescriptor() {
			return info != null ? info : (info = new TaglibInfo());
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jst.jsp.core.taglib.ITagDirRecord#getPath()
		 */
		public IPath getPath() {
			return path;
		}

		public int getRecordType() {
			return ITaglibRecord.TAGDIR;
		}

		/**
		 * @return Returns the tags.
		 */
		public String[] getTagFilenames() {
			return (String[]) tags.toArray(new String[tags.size()]);
		}

		public String toString() {
			return "TagdirRecord: " + path + " <-> " + info.shortName; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * A brief representation of the information in a TLD.
	 */
	static class TaglibInfo implements ITaglibDescriptor {
		// extract only when asked?
		String description = "";
		String displayName = "";
		String jspVersion = "";
		String largeIcon = "";
		String shortName = "";
		String smallIcon = "";
		String tlibVersion = "";
		String uri = "";

		public TaglibInfo() {
			super();
		}

		public boolean equals(Object obj) {
			if (!(obj instanceof TaglibInfo))
				return false;
			return ((TaglibInfo) obj).jspVersion == jspVersion && ((TaglibInfo) obj).description.equals(description) && ((TaglibInfo) obj).largeIcon.equals(largeIcon) && ((TaglibInfo) obj).shortName.equals(shortName) && ((TaglibInfo) obj).smallIcon.equals(smallIcon) && ((TaglibInfo) obj).tlibVersion.equals(tlibVersion) && ((TaglibInfo) obj).uri.equals(uri);
		}

		public String getDescription() {
			return description;
		}

		public String getDisplayName() {
			return displayName;
		}

		public String getJSPVersion() {
			return jspVersion;
		}

		public String getLargeIcon() {
			return largeIcon;
		}

		public String getShortName() {
			return shortName;
		}

		public String getSmallIcon() {
			return smallIcon;
		}

		public String getTlibVersion() {
			return tlibVersion;
		}

		public String getURI() {
			return uri;
		}

		public String toString() {
			return "TaglibInfo|" + shortName + "|" + tlibVersion + "|" + smallIcon + "|" + largeIcon + "|" + jspVersion + "|" + uri + "|" + description; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
		}
	}

	static class TLDRecord implements ITLDRecord {
		TaglibInfo info;
		IPath path;

		public boolean equals(Object obj) {
			if (!(obj instanceof TLDRecord))
				return false;
			return ((TLDRecord) obj).path.equals(path) && ((TLDRecord) obj).getURI().equals(getURI()) && ((TLDRecord) obj).info.equals(info);
		}

		public ITaglibDescriptor getDescriptor() {
			return info != null ? info : new TaglibInfo();
		}

		public IPath getPath() {
			return path;
		}

		public int getRecordType() {
			return ITaglibRecord.TLD;
		}

		public String getShortName() {
			if (info == null)
				return null;
			return info.shortName;
		}

		/**
		 * @return Returns the uri.
		 */
		public String getURI() {
			if (info == null)
				return null;
			return info.uri;
		}

		public String toString() {
			return "TLDRecord: " + getURI() + " <-> " + path; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	static class URLRecord implements IURLRecord {
		String baseLocation;
		TaglibInfo info;
		boolean isExported = true;
		URL url;

		public URLRecord() {
			super();
		}

		public boolean equals(Object obj) {
			if (!(obj instanceof URLRecord))
				return false;
			return ((URLRecord) obj).baseLocation.equals(baseLocation) && ((URLRecord) obj).url.equals(url) && ((URLRecord) obj).info.equals(info);
		}

		public String getBaseLocation() {
			return baseLocation;
		}

		public ITaglibDescriptor getDescriptor() {
			return info != null ? info : new TaglibInfo();
		}

		public int getRecordType() {
			return ITaglibRecord.URL;
		}

		/**
		 * @return Returns the recommended/default prefix if one was given.
		 */
		public String getShortName() {
			if (info == null)
				return null;
			return info.shortName;
		}

		/**
		 * @return Returns the uri.
		 */
		public String getURI() {
			if (info == null)
				return ""; //$NON-NLS-1$
			return info.uri;
		}

		/**
		 * @return Returns the URL.
		 */
		public URL getURL() {
			return url;
		}

		public String toString() {
			return "URLRecord: (exported=" + isExported + ") " + baseLocation + " <-> " + getURI(); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	static class WebXMLRecord {
		TaglibInfo info;
		IPath path;
		List tldRecords = new ArrayList(0);

		public boolean equals(Object obj) {
			if (!(obj instanceof WebXMLRecord))
				return false;
			return ((WebXMLRecord) obj).path.equals(path) && ((WebXMLRecord) obj).info.equals(info);
		}

		/**
		 * @return Returns the recommended/default prefix if one was given.
		 */
		public String getPrefix() {
			if (info == null)
				return null;
			return info.shortName;
		}

		/**
		 * 
		 */
		public List getTLDRecords() {
			return tldRecords;
		}

		/**
		 * @return Returns the webxml.
		 */
		public IPath getWebXML() {
			return path;
		}

		public String toString() {
			StringBuffer s = new StringBuffer("WebXMLRecord: ");//$NON-NLS-1$ 
			s.append(path);
			if (tldRecords.size() > 0) {
				s.append('\n');//$NON-NLS-1$ 
				for (int i = 0; i < tldRecords.size(); i++) {
					s.append(tldRecords.get(i));
					s.append('\n');//$NON-NLS-1$ 
				}
			}
			return s.toString();
		}
	}

	static boolean _debugIndexCreation = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indexcreation")); //$NON-NLS-1$ //$NON-NLS-2$
	static boolean _debugIndexTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indextime")); //$NON-NLS-1$ //$NON-NLS-2$

	private static final String BUILDPATH_DIRTY = "BUILDPATH_DIRTY"; //$NON-NLS-1$
	private static final String BUILDPATH_ENTRIES = "BUILDPATH_ENTRIES"; //$NON-NLS-1$
	private static final String BUILDPATH_PROJECT = "BUILDPATH_PROJECT"; //$NON-NLS-1$
	private static final String SAVE_FORMAT_VERSION = "Tag Library Index 1.0.3"; //$NON-NLS-1$
	private static final String WEB_INF = "WEB-INF"; //$NON-NLS-1$
	private static final IPath WEB_INF_PATH = new Path(WEB_INF);
	private static final String WEB_XML = "web.xml"; //$NON-NLS-1$

	/**
	 * Notes that the build path information is stale. Some operations can now
	 * be skipped until a resolve/getAvailable call is made.
	 */
	boolean fBuildPathIsDirty = false;

	/**
	 * Count of entries on the build path. Primary use case is for classpath
	 * containers that add an entry. Without notification (3.3), we can only
	 * check after-the-fact.
	 */
	int fBuildPathEntryCount = 0;

	/**
	 * A cached copy of all of the records createable from the XMLCatalog.
	 */
	private Collection fCatalogRecords;

	/*
	 * Records active JARs on the classpath. Taglib descriptors should be
	 * usable, but the jars by themselves are not.
	 */
	Hashtable fClasspathJars;

	/**
	 * A set of the projects that are in this project's build path.
	 * Lookups/enumerations will be redirected to the corresponding
	 * ProjectDescription instances
	 */
	Set fClasspathProjects = null;

	// holds references by URI to JARs
	Hashtable fClasspathReferences;

	/*
	 * this table is special in that it holds tables of references according
	 * to local roots
	 */
	Hashtable fImplicitReferences;

	Hashtable fJARReferences;

	IProject fProject;

	private String fSaveStateFilename;

	Hashtable fTagDirReferences;

	Hashtable fTLDReferences;

	IResourceDeltaVisitor fVisitor;
	Hashtable fWebXMLReferences;

	ILock LOCK = Job.getJobManager().newLock();

	private long time0;

	ProjectDescription(IProject project, String saveStateFile) {
		super();
		fProject = project;
		fSaveStateFilename = saveStateFile;

		fClasspathJars = new Hashtable(0);
		fJARReferences = new Hashtable(0);
		fTagDirReferences = new Hashtable(0);
		fTLDReferences = new Hashtable(0);
		fWebXMLReferences = new Hashtable(0);
		fImplicitReferences = new Hashtable(0);
		fClasspathReferences = new Hashtable(0);
		fClasspathProjects = new HashSet();

		restoreReferences();
	}

	private Collection _getJSP11AndWebXMLJarReferences(Collection allJARs) {
		List collection = new ArrayList(allJARs.size());
		Iterator i = allJARs.iterator();
		while (i.hasNext()) {
			JarRecord record = (JarRecord) i.next();
			if (record.has11TLD || record.isMappedInWebXML) {
				collection.add(record);
			}
		}
		return collection;
	}

	/**
	 * Adds the list of known references from this project's build path to the
	 * map, appending any processed projects into the list to avoid
	 * build-path-cycles.
	 * 
	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=142408
	 * 
	 * @param references -
	 *            the map of references to ITaglibRecords
	 * @param projectsProcessed -
	 *            the list of projects already considered
	 * @param exportedOnly -
	 *            Whether to only add references derived from exported build
	 *            path containers. This method calls itself recursively with
	 *            this parameter as false.
	 */
	void addBuildPathReferences(Map references, List projectsProcessed, boolean exportedOnly) {
		ensureUpTodate();

		// Add the build path references that are exported from this project
		Enumeration keys = fClasspathReferences.keys();
		while (keys.hasMoreElements()) {
			Object key = keys.nextElement();
			URLRecord urlRecord = (URLRecord) fClasspathReferences.get(key);
			if (exportedOnly) {
				if (urlRecord.isExported) {
					references.put(key, urlRecord);
				}
			}
			else {
				references.put(key, urlRecord);
			}
		}
		IProject[] buildpathProjects = (IProject[]) fClasspathProjects.toArray(new IProject[fClasspathProjects.size()]);
		for (int i = 0; i < buildpathProjects.length; i++) {
			if (!projectsProcessed.contains(buildpathProjects[i]) && buildpathProjects[i].isAccessible()) {
				projectsProcessed.add(buildpathProjects[i]);
				ProjectDescription description = TaglibIndex.getInstance().createDescription(buildpathProjects[i]);
				description.addBuildPathReferences(references, projectsProcessed, true);

				/*
				 * 199843 (183756) - JSP Validation Cannot Find Tag Library
				 * Descriptor in Referenced Projects
				 * 
				 * Add any TLD records having URI values from projects on the
				 * build path
				 */
				Map[] rootReferences = (Map[]) description.fImplicitReferences.values().toArray(new Map[description.fImplicitReferences.size()]);
				for (int j = 0; j < rootReferences.length; j++) {
					Iterator implicitRecords = rootReferences[j].values().iterator();
					while (implicitRecords.hasNext()) {
						ITaglibRecord record = (ITaglibRecord) implicitRecords.next();
						if (record.getRecordType() == ITaglibRecord.TLD && ((ITLDRecord) record).getURI() != null) {
							references.put(((ITLDRecord) record).getURI(), record);
						}
					}
				}
			}
		}
	}

	/**
	 * Erases all known tables
	 */
	void clear() {
		fClasspathJars = new Hashtable(0);
		fJARReferences = new Hashtable(0);
		fTagDirReferences = new Hashtable(0);
		fTLDReferences = new Hashtable(0);
		fWebXMLReferences = new Hashtable(0);
		fImplicitReferences = new Hashtable(0);
		fClasspathReferences = new Hashtable(0);
	}

	private void closeJarFile(ZipFile file) {
		if (file == null)
			return;
		try {
			file.close();
		}
		catch (IOException ioe) {
			// no cleanup can be done
			Logger.logException("TaglibIndex: Could not close zip file " + file.getName(), ioe); //$NON-NLS-1$
		}
	}

	/**
	 * @param catalogEntry
	 *            a XML catalog entry pointing to a .jar or .tld file
	 * @return a ITaglibRecord describing a TLD contributed to the XMLCatalog
	 *         if one was found at the given location, null otherwise
	 */
	private ITaglibRecord createCatalogRecord(ICatalogEntry catalogEntry) {
		return createCatalogRecord(catalogEntry.getKey(), catalogEntry.getURI());
	}

	/**
	 * @param uri -
	 *            the key value that will become the returned record's "URI"
	 * @param urlString -
	 *            the string indicating where the TLD really is
	 * @return a ITaglibRecord describing a TLD contributed to the XMLCatalog
	 *         if one was found at the given location, null otherwise
	 */
	private ITaglibRecord createCatalogRecord(String uri, String urlString) {
		ITaglibRecord record = null;
		// handle "file:" URLs that point to a .jar file on disk (1.1 mode)
		if (urlString.toLowerCase(Locale.US).endsWith((".jar")) && urlString.startsWith("file:")) { //$NON-NLS-1$ //$NON-NLS-2$
			String fileLocation = null;
			try {
				URL url = new URL(urlString);
				fileLocation = url.getFile();
			}
			catch (MalformedURLException e) {
				// not worth reporting
			}
			if (fileLocation != null) {
				JarRecord jarRecord = createJARRecord(fileLocation);
				String[] entries = JarUtilities.getEntryNames(fileLocation);
				for (int jEntry = 0; jEntry < entries.length; jEntry++) {
					if (entries[jEntry].endsWith(".tld")) { //$NON-NLS-1$
						if (entries[jEntry].equals(JarUtilities.JSP11_TAGLIB)) {
							jarRecord.has11TLD = true;
							InputStream contents = JarUtilities.getInputStream(fileLocation, entries[jEntry]);
							if (contents != null) {
								TaglibInfo info = extractInfo(fileLocation, contents);
								/*
								 * the record's reported URI should match the
								 * catalog entry's "key" so replace the
								 * detected value
								 */
								info.uri = uri;
								jarRecord.info = info;
							}
							try {
								contents.close();
							}
							catch (IOException e) {
							}
						}
					}
				}
				if (jarRecord.has11TLD) {
					if (_debugIndexCreation)
						Logger.log(Logger.INFO, "created catalog record for " + urlString + "@" + jarRecord.getLocation()); //$NON-NLS-1$ //$NON-NLS-2$
					record = jarRecord;
				}

			}
		}
		// The rest are URLs into a plug-in...somewhere
		else {
			URL url = null;
			ByteArrayInputStream cachedContents = null;
			InputStream tldStream = null;
			try {
				url = new URL(urlString);
				URLConnection connection = url.openConnection();
				connection.setDefaultUseCaches(false);
				tldStream = connection.getInputStream();
			}
			catch (Exception e1) {
				Logger.logException("Exception reading TLD contributed to the XML Catalog", e1);
			}

			if (tldStream != null) {
				int c;
				ByteArrayOutputStream buffer = new ByteArrayOutputStream();
				// array dim restriction?
				byte bytes[] = new byte[2048];
				try {
					while ((c = tldStream.read(bytes)) >= 0) {
						buffer.write(bytes, 0, c);
					}
					cachedContents = new ByteArrayInputStream(buffer.toByteArray());
				}
				catch (IOException ioe) {
					// no cleanup can be done
				}
				finally {
					try {
						tldStream.close();
					}
					catch (IOException e) {
					}
				}

				URLRecord urlRecord = null;
				TaglibInfo info = extractInfo(urlString, cachedContents);
				if (info != null) {
					/*
					 * the record's reported URI should match the catalog
					 * entry's "key" so replace the detected value
					 */
					info.uri = uri;
					urlRecord = new URLRecord();
					urlRecord.info = info;
					urlRecord.baseLocation = urlString;
					urlRecord.url = url; //$NON-NLS-1$ //$NON-NLS-2$
				}
				try {
					cachedContents.close();
				}
				catch (IOException e) {
				}
				record = urlRecord;
			}
		}
		return record;
	}

	/**
	 * @param resource
	 * @return
	 */
	private JarRecord createJARRecord(IResource jar) {
		IPath location = jar.getLocation();
		JarRecord jarRecord = null;
		if (location != null) {
			jarRecord = createJARRecord(location.toString());
		}
		else if (jar.getLocationURI() != null) {
			jarRecord = createJARRecord(jar.getLocationURI().toString());
		}
		return jarRecord;
	}

	private JarRecord createJARRecord(String fileLocation) {
		JarRecord record = new JarRecord();
		record.info = new TaglibInfo();
		record.location = new Path(fileLocation);
		record.urlRecords = new ArrayList(0);
		return record;
	}

	/**
	 * @return
	 */
	private TagDirRecord createTagdirRecord(IFolder tagdir) {
		IPath tagdirPath = tagdir.getFullPath();
		TagDirRecord record = new TagDirRecord();
		record.path = tagdir.getFullPath();
		record.info = new TaglibInfo();
		// 8.4.3
		if (tagdir.getName().equals("tags")) //$NON-NLS-1$
			record.info.shortName = "tags"; //$NON-NLS-1$
		else {
			boolean determined = false;
			IPath path = tagdirPath;
			String[] segments = path.segments();
			for (int i = 1; i < segments.length; i++) {
				if (segments[i - 1].equals("WEB-INF") && segments[i].equals("tags")) { //$NON-NLS-1$ //$NON-NLS-2$
					IPath tagdirLocalPath = path.removeFirstSegments(i + 1);
					record.info.shortName = StringUtils.replace(tagdirLocalPath.toString(), "/", "-");
					determined = true;
				}
			}
			if (!determined) {
				record.info.shortName = StringUtils.replace(tagdirPath.toString(), "/", "-");
			}
		}
		// 8.4.3
		record.info.tlibVersion = "1.0";
		record.info.description = "";
		record.info.displayName = "";
		record.info.smallIcon = "";
		record.info.largeIcon = "";

		try {
			IResource[] tagfiles = tagdir.members();
			for (int i = 0; i < tagfiles.length; i++) {
				if (tagfiles[i].getType() != IResource.FILE)
					continue;
				String extension = tagfiles[i].getFileExtension();
				if (extension != null && (extension.equals("tag") || extension.equals("tagx"))) {
					record.tags.add(tagfiles[i].getName());
				}
			}
		}
		catch (CoreException e) {
			Logger.logException(e);
		}

		return record;
	}

	/**
	 * @param resource
	 * @return
	 */
	private TLDRecord createTLDRecord(IResource tld) {
		TLDRecord record = new TLDRecord();
		record.path = tld.getFullPath();
		InputStream contents = null;
		try {
			if (tld.isAccessible()) {
				contents = ((IFile) tld).getContents(true);
				String basePath = tld.getFullPath().toString();
				TaglibInfo info = extractInfo(basePath, contents);
				if (info != null) {
					record.info = info;
				}
			}
		}
		catch (CoreException e) {
			Logger.logException(e);
		}
		finally {
			try {
				if (contents != null) {
					contents.close();
				}
			}
			catch (IOException e) {
				// ignore
			}
		}
		return record;
	}

	private void ensureUpTodate() {
		LOCK.acquire();

		if (!fBuildPathIsDirty) {
			/*
			 * Double-check that the number of build path entries has not
			 * changed. This should cover most cases such as when a library is
			 * added into or removed from a container.
			 */
			try {
				IJavaProject jproject = JavaCore.create(fProject);
				if (jproject != null && jproject.exists()) {
					IClasspathEntry[] entries = jproject.getResolvedClasspath(true);
					fBuildPathIsDirty = (fBuildPathEntryCount != entries.length);
				}
			}
			catch (JavaModelException e) {
				Logger.logException(e);
			}
		}
		if (fBuildPathIsDirty) {
			indexClasspath();
			fBuildPathIsDirty = false;
		}

		LOCK.release();
	}

	private TaglibInfo extractInfo(String basePath, InputStream tldContents) {
		TaglibInfo info = new TaglibInfo();
		if (tldContents != null) {
			DocumentProvider provider = new DocumentProvider();
			provider.setInputStream(tldContents);
			provider.setValidating(false);
			provider.setRootElementName(JSP12TLDNames.TAGLIB);
			provider.setBaseReference(basePath);
			Node child = provider.getRootElement();
			if (child == null || child.getNodeType() != Node.ELEMENT_NODE || !child.getNodeName().equals(JSP12TLDNames.TAGLIB)) {
				return null;
			}
			child = child.getFirstChild();
			while (child != null) {
				if (child.getNodeType() == Node.ELEMENT_NODE) {
					if (child.getNodeName().equals(JSP12TLDNames.URI)) {
						info.uri = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.SHORT_NAME) || child.getNodeName().equals(JSP11TLDNames.SHORTNAME)) {
						info.shortName = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.DESCRIPTION) || child.getNodeName().equals(JSP11TLDNames.INFO)) {
						info.description = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.DISPLAY_NAME)) {
						info.displayName = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.JSP_VERSION) || child.getNodeName().equals(JSP11TLDNames.JSPVERSION)) {
						info.jspVersion = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.TLIB_VERSION) || child.getNodeName().equals(JSP11TLDNames.TLIBVERSION)) {
						info.tlibVersion = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.SMALL_ICON)) {
						info.smallIcon = getTextContents(child);
					}
					else if (child.getNodeName().equals(JSP12TLDNames.LARGE_ICON)) {
						info.largeIcon = getTextContents(child);
					}
				}
				child = child.getNextSibling();
			}
		}
		return info;
	}

	List getAvailableTaglibRecords(IPath path) {
		ensureUpTodate();

		float jspVersion = DeploymentDescriptorPropertyCache.getInstance().getJSPVersion(path);

		LOCK.acquire();

		Collection implicitReferences = new HashSet(getImplicitReferences(path.toString()).values());
		Collection records = new ArrayList(fTLDReferences.size() + fTagDirReferences.size() + fJARReferences.size() + fWebXMLReferences.size());
		records.addAll(fTLDReferences.values());
		if (jspVersion >= 1.1) {
			records.addAll(_getJSP11AndWebXMLJarReferences(fJARReferences.values()));
		}

		if (jspVersion >= 1.2) {
			records.addAll(implicitReferences);

			Map buildPathReferences = new HashMap();
			List projectsProcessed = new ArrayList(fClasspathProjects.size() + 1);
			projectsProcessed.add(fProject);
			addBuildPathReferences(buildPathReferences, projectsProcessed, false);
			records.addAll(buildPathReferences.values());
		}
		if (jspVersion >= 2.0) {
			records.addAll(fTagDirReferences.values());
		}

		records.addAll(getCatalogRecords());

		LOCK.release();

		return new ArrayList(records);
	}

	/**
	 * Provides a stream to a local copy of the input or null if not possible
	 */
	private InputStream getCachedInputStream(ZipFile zipFile, ZipEntry zipEntry) {
		InputStream cache = null;
		if (zipFile != null) {
			if (zipEntry != null) {
				InputStream entryInputStream = null;
				try {
					entryInputStream = zipFile.getInputStream(zipEntry);
				}
				catch (IOException ioExc) {
					Logger.logException("Taglib Index: " + zipFile.getName(), ioExc); //$NON-NLS-1$
				}

				if (entryInputStream != null) {
					int c;
					ByteArrayOutputStream buffer = null;
					if (zipEntry.getSize() > 0) {
						buffer = new ByteArrayOutputStream((int) zipEntry.getSize());
					}
					else {
						buffer = new ByteArrayOutputStream();
					}
					// array dim restriction?
					byte bytes[] = new byte[2048];
					try {
						while ((c = entryInputStream.read(bytes)) >= 0) {
							buffer.write(bytes, 0, c);
						}
						cache = new ByteArrayInputStream(buffer.toByteArray());
					}
					catch (IOException ioe) {
						// no cleanup can be done
					}
					finally {
						try {
							entryInputStream.close();
						}
						catch (IOException e) {
						}
					}
				}
			}
		}

		return cache;
	}

	private Collection getCatalogRecords() {
		if (fCatalogRecords == null) {
			List records = new ArrayList();
			ICatalog defaultCatalog = XMLCorePlugin.getDefault().getDefaultXMLCatalog();
			if (defaultCatalog != null) {
				// Process default catalog
				ICatalogEntry[] entries = defaultCatalog.getCatalogEntries();
				for (int entry = 0; entry < entries.length; entry++) {
					ITaglibRecord record = createCatalogRecord(entries[entry]);
					records.add(record);
				}

				// Process declared OASIS nextCatalogs catalog
				INextCatalog[] nextCatalogs = defaultCatalog.getNextCatalogs();
				for (int nextCatalog = 0; nextCatalog < nextCatalogs.length; nextCatalog++) {
					ICatalog catalog = nextCatalogs[nextCatalog].getReferencedCatalog();
					ICatalogEntry[] entries2 = catalog.getCatalogEntries();
					for (int entry = 0; entry < entries2.length; entry++) {
						String uri = entries2[entry].getURI();
						if (uri != null) {
							uri = uri.toLowerCase(Locale.US);
							if (uri.endsWith((".jar")) || uri.endsWith((".tld"))) {
								ITaglibRecord record = createCatalogRecord(entries2[entry]);
								if (record != null) {
									records.add(record);
								}
							}
						}
					}
				}
			}
			fCatalogRecords = records;
		}
		return fCatalogRecords;
	}

	/**
	 * @return Returns the implicitReferences for the given path
	 */
	Hashtable getImplicitReferences(String path) {
		String localRoot = getLocalRoot(path);
		Hashtable implicitReferences = (Hashtable) fImplicitReferences.get(localRoot);
		if (implicitReferences == null) {
			implicitReferences = new Hashtable(1);
			fImplicitReferences.put(localRoot, implicitReferences);
		}
		return implicitReferences;
	}

	/**
	 * @param basePath
	 * @return the applicable Web context root path, if one exists
	 * @deprecated
	 */
	IPath getLocalRoot(IPath basePath) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

		// existing workspace resources - this is the 93% case
		IResource file = FileBuffers.getWorkspaceFileAtLocation(basePath);

		// Try the base path as a folder first
		if (file == null && basePath.segmentCount() > 1) {
			file = workspaceRoot.getFolder(basePath);
		}
		// If not a folder, then try base path as a file
		if (file != null && !file.exists() && basePath.segmentCount() > 1) {
			file = workspaceRoot.getFile(basePath);
		}

		if (file == null && basePath.segmentCount() == 1) {
			file = workspaceRoot.getProject(basePath.segment(0));
		}

		if (file == null) {
			/*
			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=116529
			 * 
			 * This method produces a less accurate result, but doesn't
			 * require that the file exist yet.
			 */
			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(basePath);
			if (files.length > 0)
				file = files[0];
		}

		while (file != null) {
			/**
			 * Treat any parent folder with a WEB-INF subfolder as a web-app
			 * root
			 */
			IContainer folder = null;
			if ((file.getType() & IResource.FOLDER) != 0) {
				folder = (IContainer) file;
			}
			else {
				folder = file.getParent();
			}
			// getFolder on a workspace root must use a full path, skip
			if (folder != null && (folder.getType() & IResource.ROOT) == 0) {
				IFolder webinf = folder.getFolder(WEB_INF_PATH);
				if (webinf != null && webinf.exists()) {
					return folder.getFullPath();
				}
			}
			file = file.getParent();
		}

		return fProject.getFullPath();
	}

	/**
	 * @param basePath
	 * @return
	 */
	private String getLocalRoot(String basePath) {
		return getLocalRoot(new Path(basePath)).toString();
	}

	private String getTextContents(Node parent) {
		NodeList children = parent.getChildNodes();
		if (children.getLength() == 1) {
			return children.item(0).getNodeValue().trim();
		}
		StringBuffer s = new StringBuffer();
		Node child = parent.getFirstChild();
		while (child != null) {
			if (child.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
				String reference = ((EntityReference) child).getNodeValue();
				if (reference == null && child.getNodeName() != null) {
					reference = "&" + child.getNodeName() + ";"; //$NON-NLS-1$ //$NON-NLS-2$
				}
				if (reference != null) {
					s.append(reference.trim());
				}
			}
			else {
				s.append(child.getNodeValue().trim());
			}
			child = child.getNextSibling();
		}
		return s.toString().trim();
	}

	/**
	 * @return Returns the visitor.
	 */
	IResourceDeltaVisitor getVisitor() {
		if (fVisitor == null) {
			fVisitor = new DeltaVisitor();
		}
		return fVisitor;
	}

	void handleElementChanged(IJavaElementDelta delta) {
		if (fBuildPathIsDirty) {
			return;
		}

		// Logger.log(Logger.INFO_DEBUG, "IJavaElementDelta: " + delta);
		IJavaElement element = delta.getElement();
		if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT && ((IPackageFragmentRoot) element).isArchive()) {
			time0 = System.currentTimeMillis();
			if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT && ((IPackageFragmentRoot) element).isExternal()) {
			}
			String libLocation = null;
			int taglibRecordEventKind = -1;
			if ((delta.getFlags() & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0 || (delta.getFlags() & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) > 0 || (delta.getFlags() & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0) {
				taglibRecordEventKind = ITaglibIndexDelta.ADDED;
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(element.getPath());
				if (file.isAccessible() && file.getLocation() != null)
					libLocation = file.getLocation().toString();
				else
					libLocation = element.getPath().toString();
			}
			if (libLocation != null) {
				boolean fragmentisExported = true;
				try {
					IClasspathEntry rawClasspathEntry = ((IPackageFragmentRoot) element).getRawClasspathEntry();
					/*
					 * null may also be returned for deletions depending on
					 * resource/build path notification order. If it's null,
					 * it's been deleted and whether it's exported won't
					 * really matter
					 */
					if (rawClasspathEntry != null) {
						fragmentisExported = rawClasspathEntry.isExported();
					}
				}
				catch (JavaModelException e) {
					Logger.logException("Problem handling build path entry for " + element.getPath(), e); //$NON-NLS-1$
				}
				if ((delta.getFlags() & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0) {
					fBuildPathEntryCount++;
				}
				else if ((delta.getFlags() & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0) {
					fBuildPathEntryCount--;
				}
				updateClasspathLibrary(libLocation, taglibRecordEventKind, fragmentisExported);
			}
			if (_debugIndexTime)
				Logger.log(Logger.INFO, "processed build path delta for " + fProject.getName() + "(" + element.getPath() + ") in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
	}

	void index() {
		time0 = System.currentTimeMillis();

		fTLDReferences.clear();
		fJARReferences.clear();
		fTagDirReferences.clear();
		fWebXMLReferences.clear();

		try {
			fProject.accept(new Indexer(), 0);
		}
		catch (CoreException e) {
			Logger.logException(e);
		}

		if (_debugIndexTime)
			Logger.log(Logger.INFO, "indexed " + fProject.getName() + " contents in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	void indexClasspath() {
		if (_debugIndexTime)
			time0 = System.currentTimeMillis();
		fClasspathProjects.clear();
		fClasspathReferences.clear();
		fClasspathJars.clear();
		fBuildPathEntryCount = 0;

		IJavaProject javaProject = JavaCore.create(fProject);
		/*
		 * If the Java nature isn't present (or something else is wrong),
		 * don't check the build path.
		 */
		if (javaProject != null && javaProject.exists()) {
			indexClasspath(javaProject);
		}
		// else {
		// Logger.log(Logger.WARNING, "TaglibIndex was asked to index non-Java
		// Project " + fProject.getName()); //$NON-NLS-1$
		// }

		if (_debugIndexTime)
			Logger.log(Logger.INFO, "indexed " + fProject.getName() + " classpath in " + (System.currentTimeMillis() - time0) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/**
	 * @param entry
	 */
	private void indexClasspath(IClasspathEntry entry) {
		switch (entry.getEntryKind()) {
			case IClasspathEntry.CPE_CONTAINER : {
				IClasspathContainer container = (IClasspathContainer) entry;
				IClasspathEntry[] containedEntries = container.getClasspathEntries();
				for (int i = 0; i < containedEntries.length; i++) {
					indexClasspath(containedEntries[i]);
				}
			}
				break;
			case IClasspathEntry.CPE_LIBRARY : {
				/*
				 * Ignore libs in required projects that are not exported
				 */
				IPath libPath = entry.getPath();
				if (!fClasspathJars.containsKey(libPath.toString())) {
					if (libPath.toFile().exists()) {
						updateClasspathLibrary(libPath.toString(), ITaglibIndexDelta.ADDED, entry.isExported());
					}
					else {
						/*
						 * Note: .jars on the classpath inside of the project
						 * will have duplicate entries in the JAR references
						 * table that will e returned to
						 * getAvailableTaglibRecords().
						 */
						IFile libFile = ResourcesPlugin.getWorkspace().getRoot().getFile(libPath);
						if (libFile != null && libFile.exists()) {
							updateClasspathLibrary(libFile.getLocation().toString(), ITaglibIndexDelta.ADDED, entry.isExported());
						}
					}
				}
			}
				break;
			case IClasspathEntry.CPE_PROJECT : {
				/*
				 * We're currently ignoring whether the project exports all of
				 * its build path
				 */
				IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().lastSegment());
				if (project != null) {
					fClasspathProjects.add(project);
				}
			}
				break;
			case IClasspathEntry.CPE_SOURCE :
				break;
			case IClasspathEntry.CPE_VARIABLE : {
				IPath libPath = JavaCore.getResolvedVariablePath(entry.getPath());
				if (libPath != null) {
					File file = libPath.toFile();

					// file in filesystem
					if (file.exists() && !file.isDirectory()) {
						updateClasspathLibrary(libPath.toString(), ITaglibRecordEvent.ADDED, entry.isExported());
					}
					else {
						// workspace file
						IFile jarFile = ResourcesPlugin.getWorkspace().getRoot().getFile(libPath);
						if (jarFile.isAccessible() && jarFile.getType() == IResource.FILE && jarFile.getLocation() != null) {
							String jarPathString = jarFile.getLocation().toString();
							updateClasspathLibrary(jarPathString, ITaglibRecordEvent.ADDED, entry.isExported());
						}
					}
				}
			}
				break;
		}
	}

	/*
	 * private void removeClasspathLibrary(String libraryLocation) { JarRecord
	 * record = (JarRecord) fClasspathJars.remove(libraryLocation); if (record !=
	 * null) { URLRecord[] records = (URLRecord[])
	 * record.getURLRecords().toArray(new URLRecord[0]); for (int i = 0; i <
	 * records.length; i++) {
	 * fClasspathReferences.remove(records[i].getURI()); }
	 * TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record,
	 * ITaglibIndexDelta.REMOVED)); } }
	 */

	/**
	 * @param javaProject
	 */
	private void indexClasspath(IJavaProject javaProject) {
		if (javaProject == null)
			return;

		IProject project = javaProject.getProject();
		if (project.equals(fProject)) {
			try {
				IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
				fBuildPathEntryCount = entries.length;
				for (int i = 0; i < entries.length; i++) {
					indexClasspath(entries[i]);
				}
			}
			catch (JavaModelException e) {
				Logger.logException("Error searching Java Build Path + (" + fProject.getName() + ") for tag libraries", e); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	private String readTextofChild(Node node, String childName) {
		NodeList children = node.getChildNodes();
		for (int i = 0; i < children.getLength(); i++) {
			Node child = children.item(i);
			if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(childName)) {
				return getTextContents(child);
			}
		}
		return ""; //$NON-NLS-1$
	}

	void removeJAR(IResource jar) {
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "removing records for JAR " + jar.getFullPath()); //$NON-NLS-1$
		JarRecord record = (JarRecord) fJARReferences.remove(jar.getFullPath().toString());
		if (record != null) {
			URLRecord[] records = (URLRecord[]) record.getURLRecords().toArray(new URLRecord[0]);
			for (int i = 0; i < records.length; i++) {
				TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, records[i], ITaglibIndexDelta.REMOVED));
				getImplicitReferences(jar.getFullPath().toString()).remove(records[i].getURI());
			}
			if (record.has11TLD) {
				TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.REMOVED));
			}
		}
	}

	void removeTag(IResource resource) {
		TagDirRecord record = (TagDirRecord) fTagDirReferences.get(resource.getParent().getFullPath().toString());
		if (record != null) {
			record.tags.remove(resource.getName());
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.CHANGED));
		}
	}

	void removeTagDir(IResource tagdir) {
		IPath tagdirPath = tagdir.getFullPath();
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "removing record for " + tagdirPath); //$NON-NLS-1$
		ITaglibRecord record = (ITaglibRecord) fTagDirReferences.remove(tagdirPath.toString());
		if (record != null) {
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.REMOVED));
		}
	}

	void removeTLD(IResource tld) {
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "removing record for " + tld.getFullPath()); //$NON-NLS-1$
		TLDRecord record = (TLDRecord) fTLDReferences.remove(tld.getFullPath().toString());
		if (record != null) {
			if (record.getURI() != null) {
				getImplicitReferences(tld.getFullPath().toString()).remove(record.getURI());
			}
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.REMOVED));
		}
	}

	void removeWebXML(IResource webxml) {
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "removing records for " + webxml.getFullPath()); //$NON-NLS-1$
		WebXMLRecord record = (WebXMLRecord) fWebXMLReferences.remove(webxml.getFullPath().toString());
		if (record != null) {
			TLDRecord[] records = (TLDRecord[]) record.getTLDRecords().toArray(new TLDRecord[0]);
			for (int i = 0; i < records.length; i++) {
				if (_debugIndexCreation)
					Logger.log(Logger.INFO, "removed record for " + records[i].getURI() + "@" + records[i].path); //$NON-NLS-1$ //$NON-NLS-2$
				getImplicitReferences(webxml.getFullPath().toString()).remove(records[i].getURI());
				TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, records[i], ITaglibIndexDelta.REMOVED));
			}
		}
	}

	/**
	 * @param basePath
	 * @param reference
	 * @return
	 */
	ITaglibRecord resolve(String basePath, String reference) {
		ensureUpTodate();

		ITaglibRecord record = null;
		String path = null;
		float jspVersion = DeploymentDescriptorPropertyCache.getInstance().getJSPVersion(new Path(basePath));

		/**
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=196177
		 * Support resolution in flexible projects
		 */
		IPath resourcePath = FacetModuleCoreSupport.resolve(new Path(basePath), reference);
		if (resourcePath.segmentCount() > 1) {
			if (resourcePath.toString().toLowerCase(Locale.US).endsWith(".tld")) { //$NON-NLS-1$ 
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(resourcePath);
				if (file.isAccessible()) {
					path = resourcePath.toString();
				}
			}
			else if (resourcePath.toString().toLowerCase(Locale.US).endsWith(".jar")) { //$NON-NLS-1$ 
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(resourcePath);
				if (file.isAccessible()) {
					path = resourcePath.toString();
				}
			}
		}

		LOCK.acquire();

		/**
		 * Workaround for problem in URIHelper; uris starting with '/' are
		 * returned as-is.
		 */
		if (path == null) {
			if (reference.startsWith("/")) { //$NON-NLS-1$
				path = getLocalRoot(basePath) + reference;
			}
			else {
				path = URIHelper.normalize(reference, basePath, getLocalRoot(basePath));
			}
		}

		// order dictated by JSP spec 2.0 section 7.2.3
		record = (ITaglibRecord) fJARReferences.get(path);

		// only if 1.1 TLD was found
		if (jspVersion < 1.1 || (record instanceof JarRecord && !((JarRecord) record).has11TLD)) {
			record = null;
		}
		if (record == null) {
			record = (ITaglibRecord) fTLDReferences.get(path);
		}
		if (record == null && jspVersion >= 1.2) {
			record = (ITaglibRecord) getImplicitReferences(basePath).get(reference);
		}


		if (record == null && jspVersion >= 2.0) {
			record = (ITaglibRecord) fTagDirReferences.get(path);
		}

		if (record == null && jspVersion >= 1.2) {
			record = (ITaglibRecord) fClasspathReferences.get(reference);
		}
		if (record == null && jspVersion >= 1.2) {
			Map buildPathReferences = new HashMap();
			List projectsProcessed = new ArrayList(fClasspathProjects.size() + 1);
			projectsProcessed.add(fProject);
			addBuildPathReferences(buildPathReferences, projectsProcessed, false);
			record = (ITaglibRecord) buildPathReferences.get(reference);
		}

		// Check the XML Catalog
		if (record == null) {
			ICatalog catalog = XMLCorePlugin.getDefault().getDefaultXMLCatalog();
			if (catalog != null) {
				String resolvedString = null;
				try {
					// Check as system reference first
					resolvedString = catalog.resolveSystem(reference);
					// Check as URI
					if (resolvedString == null || resolvedString.trim().length() == 0) {
						resolvedString = catalog.resolveURI(reference);
					}
					// Check as public ID
					if (resolvedString == null || resolvedString.trim().length() == 0) {
						resolvedString = catalog.resolvePublic(reference, basePath);
					}
				}
				catch (Exception e) {
					Logger.logException(e);
				}
				if (resolvedString != null && resolvedString.trim().length() > 0) {
					record = createCatalogRecord(reference, resolvedString);
				}
			}
		}

		/*
		 * If no records were found and no local-root applies, check ALL
		 * of the web.xml files as a fallback
		 */
		if (record == null && fProject.getFullPath().toString().equals(getLocalRoot(basePath))) {
			WebXMLRecord[] webxmls = (WebXMLRecord[]) fWebXMLReferences.values().toArray(new WebXMLRecord[0]);
			for (int i = 0; i < webxmls.length; i++) {
				if (record != null)
					continue;
				record = (ITaglibRecord) getImplicitReferences(webxmls[i].path.toString()).get(reference);
			}
		}
		
		LOCK.release();
				
		return record;
	}

	/**
	 * Restores any saved reference tables
	 */
	private void restoreReferences() {
		final boolean notifyOnRestoration = true;
		if (TaglibIndex.ENABLED) {
			// resources first
			index();
			// now build path

			// ================ test reload time ========================
			boolean restored = false;
			File savedState = new File(fSaveStateFilename);
			if (savedState.exists()) {
				Reader reader = null;
				try {
					time0 = System.currentTimeMillis();
					reader = new InputStreamReader(new BufferedInputStream(new FileInputStream(savedState)), "UTF-16"); //$NON-NLS-1$ 
					// use a string buffer temporarily to reduce string
					// creation
					StringBuffer buffer = new StringBuffer();
					char array[] = new char[2048];
					int charsRead = 0;
					while ((charsRead = reader.read(array)) != -1) {
						if (charsRead > 0) {
							buffer.append(array, 0, charsRead);
						}
					}

					IDocument doc = new org.eclipse.jface.text.Document();
					doc.set(buffer.toString());
					int lines = doc.getNumberOfLines();
					if (lines > 0) {
						IRegion line = doc.getLineInformation(0);
						String lineText = doc.get(line.getOffset(), line.getLength());
						JarRecord libraryRecord = null;
						if (SAVE_FORMAT_VERSION.equals(lineText.trim())) {
							IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

							for (int i = 1; i < lines && !fBuildPathIsDirty; i++) {
								line = doc.getLineInformation(i);
								lineText = doc.get(line.getOffset(), line.getLength());
								StringTokenizer toker = new StringTokenizer(lineText, "|"); //$NON-NLS-1$
								if (toker.hasMoreTokens()) {
									String tokenType = toker.nextToken();
									if ("JAR".equalsIgnoreCase(tokenType)) { //$NON-NLS-1$ //$NON-NLS-2$
										boolean has11TLD = Boolean.valueOf(toker.nextToken()).booleanValue();
										boolean exported = Boolean.valueOf(toker.nextToken()).booleanValue();
										// make the rest the libraryLocation
										String libraryLocation = toker.nextToken();
										while (toker.hasMoreTokens()) {
											libraryLocation = libraryLocation + "|" + toker.nextToken(); //$NON-NLS-1$ //$NON-NLS-2$
										}
										libraryLocation = libraryLocation.trim();
										if (libraryRecord != null && notifyOnRestoration) {
											TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, libraryRecord, ITaglibIndexDelta.ADDED));
										}
										// Create a new JarRecord
										libraryRecord = createJARRecord(libraryLocation);
										libraryRecord.has11TLD = has11TLD;
										libraryRecord.isExported = exported;

										// Add a URLRecord for the 1.1 TLD
										if (has11TLD) {
											InputStream contents = JarUtilities.getInputStream(libraryLocation, JarUtilities.JSP11_TAGLIB);
											if (contents != null) {
												TaglibInfo info = extractInfo(libraryLocation, contents);

												if (info != null && info.uri != null && info.uri.length() > 0) {
													URLRecord urlRecord = new URLRecord();
													urlRecord.info = info;
													urlRecord.isExported = exported;
													urlRecord.baseLocation = libraryLocation;
													try {
														urlRecord.url = new URL("jar:file:" + libraryLocation + "!/" + JarUtilities.JSP11_TAGLIB); //$NON-NLS-1$ //$NON-NLS-2$
														libraryRecord.urlRecords.add(urlRecord);
														fClasspathReferences.put(urlRecord.getURI(), urlRecord);
														if (_debugIndexCreation)
															Logger.log(Logger.INFO, "created record for " + urlRecord.getURI() + "@" + urlRecord.getURL()); //$NON-NLS-1$ //$NON-NLS-2$
													}
													catch (MalformedURLException e) {
														/*
														 * don't record this
														 * URI
														 */
														Logger.logException(e);
													}
												}
												try {
													contents.close();
												}
												catch (IOException e) {
												}
											}
										}

										fClasspathJars.put(libraryLocation, libraryRecord);
									}
									else if ("URL".equalsIgnoreCase(tokenType) && libraryRecord != null) { //$NON-NLS-1$
										// relies on a previously declared JAR
										// record
										boolean exported = Boolean.valueOf(toker.nextToken()).booleanValue();
										// make the rest the URL
										String urlString = toker.nextToken();
										while (toker.hasMoreTokens()) {
											urlString = urlString + "|" + toker.nextToken(); //$NON-NLS-1$ //$NON-NLS-2$
										}
										urlString = urlString.trim();
										// Append a URLrecord
										URLRecord urlRecord = new URLRecord();
										urlRecord.url = new URL(urlString); //$NON-NLS-1$ //$NON-NLS-2$
										urlRecord.isExported = exported;
										urlRecord.baseLocation = libraryRecord.location.toString();
										libraryRecord.urlRecords.add(urlRecord);

										ByteArrayInputStream cachedContents = null;
										InputStream tldStream = null;
										try {
											URLConnection connection = urlRecord.url.openConnection();
											connection.setDefaultUseCaches(false);
											tldStream = connection.getInputStream();
										}
										catch (IOException e1) {
											Logger.logException(e1);
										}

										int c;
										ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
										// array dim restriction?
										byte bytes[] = new byte[2048];
										try {
											while ((c = tldStream.read(bytes)) >= 0) {
												byteArrayOutput.write(bytes, 0, c);
											}
											cachedContents = new ByteArrayInputStream(byteArrayOutput.toByteArray());
										}
										catch (IOException ioe) {
											// no cleanup can be done
										}
										finally {
											try {
												tldStream.close();
											}
											catch (IOException e) {
											}
										}

										TaglibInfo info = extractInfo(urlRecord.url.toString(), cachedContents);
										if (info != null) {
											urlRecord.info = info;
										}
										try {
											cachedContents.close();
										}
										catch (IOException e) {
										}
										fClasspathReferences.put(urlRecord.getURI(), urlRecord);
									}
									else if (BUILDPATH_PROJECT.equalsIgnoreCase(tokenType)) {
										String projectName = toker.nextToken();
										if (Path.ROOT.isValidSegment(projectName)) {
											IProject project = workspaceRoot.getProject(projectName);
											/* do not check if "open" here */
											if (project != null) {
												fClasspathProjects.add(project);
											}
										}
									}
									// last since they occur once
									else if (BUILDPATH_DIRTY.equalsIgnoreCase(tokenType)) {
										fBuildPathIsDirty = Boolean.valueOf(toker.nextToken()).booleanValue();
									}
									else if (BUILDPATH_ENTRIES.equalsIgnoreCase(tokenType)) {
										fBuildPathEntryCount = Integer.valueOf(toker.nextToken()).intValue();
									}
								}
								if (libraryRecord != null && notifyOnRestoration) {
									TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, libraryRecord, ITaglibIndexDelta.ADDED));
								}
							}
							restored = true;
						}
						else {
							Logger.log(Logger.INFO, "Tag Library Index: different cache format found, was \"" + lineText + "\", supports \"" + SAVE_FORMAT_VERSION + "\", reindexing build path"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						}
					}
					if (_debugIndexTime)
						Logger.log(Logger.INFO, "time spent reloading " + fProject.getName() + " build path: " + (System.currentTimeMillis() - time0)); //$NON-NLS-1$ //$NON-NLS-2$
				}
				catch (Exception e) {
					restored = false;
					if (_debugIndexTime)
						Logger.log(Logger.INFO, "failure reloading " + fProject.getName() + " build path index", e); //$NON-NLS-1$ //$NON-NLS-2$
				}
				finally {
					if (reader != null) {
						try {
							reader.close();
						}
						catch (IOException e) {
						}
					}
				}
			}

			// ================ test reload time (end) ==================


			if (!restored) {
				setBuildPathIsDirty();
			}
		}
	}

	/**
	 * Saves any storable references to disk. This is only called when the
	 * description is being cleared and not after every update.
	 */
	void saveReferences() {
		// the build path information is out of date, remember that
		time0 = System.currentTimeMillis();
		Writer writer = null;

		/**
		 * <pre>
		 *                     		 1.0.1
		 *                     		 Save classpath information (| is field delimiter)
		 *                     		 Jars are saved as &quot;JAR:&quot;+ has11TLD + jar path 
		 *                     		 URLRecords as &quot;URL:&quot;+URL
		 * </pre>
		 */
		try {
			writer = new OutputStreamWriter(new FileOutputStream(fSaveStateFilename), "UTF-16"); //$NON-NLS-1$
			writer.write(SAVE_FORMAT_VERSION);
			writer.write('\n'); //$NON-NLS-1$
			writer.write(BUILDPATH_DIRTY + "|" + fBuildPathIsDirty); //$NON-NLS-1$
			writer.write('\n'); //$NON-NLS-1$
			writer.write(BUILDPATH_ENTRIES + "|" + fBuildPathEntryCount); //$NON-NLS-1$
			writer.write('\n'); //$NON-NLS-1$

			IProject[] projects = (IProject[]) fClasspathProjects.toArray(new IProject[0]);
			for (int i = 0; i < projects.length; i++) {
				writer.write(BUILDPATH_PROJECT);
				writer.write("|"); //$NON-NLS-1$
				writer.write(projects[i].getName());
				writer.write('\n'); //$NON-NLS-1$
			}

			Enumeration jars = fClasspathJars.keys();
			while (jars.hasMoreElements()) {
				String jarPath = jars.nextElement().toString();
				JarRecord jarRecord = (JarRecord) fClasspathJars.get(jarPath);
				writer.write("JAR|"); //$NON-NLS-1$
				writer.write(Boolean.toString(jarRecord.has11TLD));
				writer.write('|'); //$NON-NLS-1$
				writer.write(Boolean.toString(jarRecord.isExported));
				writer.write('|'); //$NON-NLS-1$
				writer.write(jarPath);
				writer.write('\n'); //$NON-NLS-1$
				Iterator i = jarRecord.urlRecords.iterator();
				while (i.hasNext()) {
					URLRecord urlRecord = (URLRecord) i.next();
					writer.write("URL|"); //$NON-NLS-1$
					writer.write(String.valueOf(urlRecord.isExported));
					writer.write("|"); //$NON-NLS-1$
					writer.write(urlRecord.getURL().toExternalForm());
					writer.write('\n'); //$NON-NLS-1$
				}
			}
		}
		catch (IOException e) {
		}
		finally {
			try {
				if (writer != null) {
					writer.close();
				}
			}
			catch (Exception e) {
			}
		}

		if (_debugIndexTime)
			Logger.log(Logger.INFO, "time spent saving index for " + fProject.getName() + ": " + (System.currentTimeMillis() - time0)); //$NON-NLS-1$
	}

	void setBuildPathIsDirty() {
		fBuildPathIsDirty = true;
		if (_debugIndexTime)
			Logger.log(Logger.INFO, "marking build path information for " + fProject.getName() + " as dirty"); //$NON-NLS-1$
	}

	void updateClasspathLibrary(String libraryLocation, int deltaKind, boolean isExported) {
		JarRecord libraryRecord = null;
		if (deltaKind == ITaglibIndexDelta.REMOVED || deltaKind == ITaglibIndexDelta.CHANGED) {
			libraryRecord = (JarRecord) fClasspathJars.remove(libraryLocation);
			if (libraryRecord != null) {
				IURLRecord[] urlRecords = (IURLRecord[]) libraryRecord.urlRecords.toArray(new IURLRecord[0]);
				for (int i = 0; i < urlRecords.length; i++) {
					ITaglibRecord record = (ITaglibRecord) fClasspathReferences.remove(urlRecords[i].getURI());
					if (record != null) {
						TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.REMOVED));
					}
				}
			}
		}
		if (deltaKind == ITaglibIndexDelta.ADDED || deltaKind == ITaglibIndexDelta.CHANGED) {
			libraryRecord = createJARRecord(libraryLocation);
			libraryRecord.isExported = isExported;
			fClasspathJars.put(libraryLocation, libraryRecord);

			ZipFile jarfile = null;
			try {
				jarfile = new ZipFile(libraryLocation);
				Enumeration entries = jarfile.entries();
				while (entries.hasMoreElements()) {
					ZipEntry z = (ZipEntry) entries.nextElement();
					if (!z.isDirectory()) {
						if (z.getName().toLowerCase(Locale.US).endsWith(".tld")) { //$NON-NLS-1$
							if (z.getName().equals(JarUtilities.JSP11_TAGLIB)) {
								libraryRecord.has11TLD = true;
							}
							InputStream contents = getCachedInputStream(jarfile, z);
							if (contents != null) {
								TaglibInfo info = extractInfo(libraryLocation, contents);

								if (info != null && info.uri != null && info.uri.length() > 0) {
									URLRecord urlRecord = new URLRecord();
									urlRecord.info = info;
									urlRecord.baseLocation = libraryLocation;
									try {
										urlRecord.isExported = isExported;
										urlRecord.url = new URL("jar:file:" + libraryLocation + "!/" + z.getName()); //$NON-NLS-1$ //$NON-NLS-2$
										libraryRecord.urlRecords.add(urlRecord);
										TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, urlRecord, deltaKind));
										fClasspathReferences.put(urlRecord.getURI(), urlRecord);
										if (_debugIndexCreation)
											Logger.log(Logger.INFO, "created record for " + urlRecord.getURI() + "@" + urlRecord.getURL()); //$NON-NLS-1$ //$NON-NLS-2$
									}
									catch (MalformedURLException e) {
										// don't record this URI
										Logger.logException(e);
									}
								}
								try {
									contents.close();
								}
								catch (IOException e) {
								}
							}
						}
					}
				}
			}
			catch (ZipException zExc) {
				Logger.log(Logger.WARNING, "Taglib Index ZipException: " + libraryLocation + " " + zExc.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
			}
			catch (IOException ioExc) {
				Logger.log(Logger.WARNING, "Taglib Index IOException: " + libraryLocation + " " + ioExc.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
			}
			finally {
				closeJarFile(jarfile);
			}
		}
		if (libraryRecord != null) {
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, libraryRecord, deltaKind));
		}
	}

	void updateJAR(IResource jar, int deltaKind) {
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "creating records for JAR " + jar.getFullPath()); //$NON-NLS-1$

		String jarLocationString = null;
		if (jar.getLocation() != null)
			jarLocationString = jar.getLocation().toString();
		else
			jarLocationString = jar.getLocationURI().toString();
		String[] entries = JarUtilities.getEntryNames(jar);
		JarRecord jarRecord = createJARRecord(jar);
		fJARReferences.put(jar.getFullPath().toString(), jarRecord);
		for (int i = 0; i < entries.length; i++) {
			if (entries[i].endsWith(".tld")) { //$NON-NLS-1$
				if (entries[i].equals(JarUtilities.JSP11_TAGLIB)) {
					jarRecord.has11TLD = true;
				}
				InputStream contents = JarUtilities.getInputStream(jar, entries[i]);
				if (contents != null) {
					TaglibInfo info = extractInfo(jarLocationString, contents);

					if (info != null && info.uri != null && info.uri.length() > 0) {
						URLRecord record = new URLRecord();
						record.info = info;
						record.baseLocation = jarLocationString;
						try {
							record.url = new URL("jar:file:" + jarLocationString + "!/" + entries[i]); //$NON-NLS-1$ //$NON-NLS-2$
							jarRecord.urlRecords.add(record);

							int taglibDeltaKind = ITaglibIndexDelta.ADDED;
							Hashtable table = getImplicitReferences(jar.getFullPath().toString());
							if (table != null && table.get(record.getURI()) != null) {
								taglibDeltaKind = ITaglibIndexDelta.CHANGED;
							}

							getImplicitReferences(jar.getFullPath().toString()).put(record.getURI(), record);
							TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, taglibDeltaKind));
							if (_debugIndexCreation)
								Logger.log(Logger.INFO, "created record for " + record.getURI() + "@" + record.getURL()); //$NON-NLS-1$ //$NON-NLS-2$
						}
						catch (MalformedURLException e) {
							// don't record this URI
							Logger.logException(e);
						}
					}
					try {
						contents.close();
					}
					catch (IOException e) {
					}
				}
				else {
					Logger.log(Logger.ERROR_DEBUG, getClass().getName() + "could not read resource " + jar.getFullPath()); //$NON-NLS-1$
				}
			}
		}
		if (jarRecord.has11TLD) {
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, jarRecord, deltaKind));
		}
	}


	void updateTag(IResource resource, int kind) {
		TagDirRecord record = (TagDirRecord) fTagDirReferences.get(resource.getParent().getFullPath().toString());
		if (record == null) {
			record = createTagdirRecord((IFolder) resource.getParent());
			fTagDirReferences.put(resource.getParent().getFullPath().toString(), record);
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.ADDED));
		}
		else {
			if (!record.tags.contains(resource.getName())) {
				record.tags.add(resource.getName());
			}
			TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, ITaglibIndexDelta.CHANGED));
		}
	}

	void updateTagDir(IResource tagdirResource, int deltaKind) {
		/**
		 * 8.4.1: tag files are loose files under /WEB-INF/tags
		 */
		if ((tagdirResource.getType() & IResource.FOLDER) != 0) {
			if (_debugIndexCreation)
				Logger.log(Logger.INFO, "creating record for directory " + tagdirResource.getFullPath()); //$NON-NLS-1$
			TagDirRecord record = (TagDirRecord) fTagDirReferences.get(tagdirResource.getFullPath().toString());
			if (record == null) {
				record = createTagdirRecord((IFolder) tagdirResource);
				fTagDirReferences.put(tagdirResource.getFullPath().toString(), record);
				TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, deltaKind));
			}
			else {

			}
		}
		/**
		 * 8.4.1: tag files can also be packaged in the /META-INF/tags folder
		 * of a jar in /WEB-INF/lib/ (8.4.2: but must be mentioned in a .tld)
		 */
		else {
			// these tags are merely surfaced when the TLD is modelled
		}
	}

	void updateTLD(IResource tld, int deltaKind) {
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "creating record for " + tld.getFullPath()); //$NON-NLS-1$
		TLDRecord record = createTLDRecord(tld);
		fTLDReferences.put(tld.getFullPath().toString(), record);
		if (record.getURI() != null) {
			getImplicitReferences(tld.getFullPath().toString()).put(record.getURI(), record);
		}
		TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, deltaKind));
	}

	void updateWebXML(IResource webxml, int deltaKind) {
		if (webxml.getType() != IResource.FILE)
			return;
		InputStream webxmlContents = null;
		Document document = null;
		try {
			webxmlContents = ((IFile) webxml).getContents(true);
			DocumentProvider provider = new DocumentProvider();
			provider.setInputStream(webxmlContents);
			provider.setValidating(false);
			provider.setRootElementName("web-app"); //$NON-NLS-1$
			provider.setBaseReference(webxml.getParent().getFullPath().toString());
			document = provider.getDocument(false);
		}
		catch (CoreException e) {
			Logger.log(Logger.ERROR_DEBUG, "", e); //$NON-NLS-1$
		}
		finally {
			if (webxmlContents != null)
				try {
					webxmlContents.close();
				}
				catch (IOException e1) {
					// ignore
				}
		}
		if (document == null)
			return;
		if (_debugIndexCreation)
			Logger.log(Logger.INFO, "creating records for " + webxml.getFullPath()); //$NON-NLS-1$

		WebXMLRecord webxmlRecord = new WebXMLRecord();
		webxmlRecord.path = webxml.getFullPath();
		fWebXMLReferences.put(webxmlRecord.getWebXML().toString(), webxmlRecord);
		NodeList taglibs = document.getElementsByTagName(JSP12TLDNames.TAGLIB);
		for (int iTaglib = 0; iTaglib < taglibs.getLength(); iTaglib++) {
			String taglibUri = readTextofChild(taglibs.item(iTaglib), "taglib-uri").trim(); //$NON-NLS-1$
			// specified location is relative to root of the webapp
			String taglibLocation = readTextofChild(taglibs.item(iTaglib), "taglib-location").trim(); //$NON-NLS-1$
			IPath path = null;
			if (taglibLocation.startsWith("/")) { //$NON-NLS-1$
				path = new Path(getLocalRoot(webxml.getFullPath().toString()) + taglibLocation);
			}
			else {
				path = new Path(URIHelper.normalize(taglibLocation, webxml.getFullPath().toString(), getLocalRoot(webxml.getFullPath().toString())));
			}
			if (path.segmentCount() > 1) {
				IFile resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				if (resource.isAccessible()) {
					ITaglibRecord record = null;
					/*
					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=125960
					 * 
					 * Also support mappings to .jar files
					 */
					if ("jar".equalsIgnoreCase(resource.getFileExtension())) { //$NON-NLS-1$
						JarRecord jarRecord = createJARRecord(resource);
						String[] entries = JarUtilities.getEntryNames(resource);
						for (int jEntry = 0; jEntry < entries.length; jEntry++) {
							if (entries[jEntry].endsWith(".tld")) { //$NON-NLS-1$
								if (entries[jEntry].equals(JarUtilities.JSP11_TAGLIB)) {
									jarRecord.has11TLD = true;
									InputStream contents = JarUtilities.getInputStream(resource, entries[jEntry]);
									if (contents != null) {
										TaglibInfo info = extractInfo(resource.getFullPath().toString(), contents);
										jarRecord.info = info;
										try {
											contents.close();
										}
										catch (IOException e) {
										}
									}
								}
							}
						}
						record = jarRecord;
						// the stored URI should reflect the web.xml's value
						if (jarRecord.info == null) {
							jarRecord.info = new TaglibInfo();
						}
						jarRecord.info.uri = taglibUri;
						jarRecord.isMappedInWebXML = true;
						if (_debugIndexCreation)
							Logger.log(Logger.INFO, "created web.xml record for " + taglibUri + "@" + jarRecord.getLocation()); //$NON-NLS-1$ //$NON-NLS-2$
					}
					else {
						TLDRecord tldRecord = createTLDRecord(resource);
						record = tldRecord;
						// the stored URI should reflect the web.xml's value
						tldRecord.info.uri = taglibUri;
						if (_debugIndexCreation)
							Logger.log(Logger.INFO, "created web.xml record for " + taglibUri + "@" + tldRecord.getPath()); //$NON-NLS-1$ //$NON-NLS-2$
					}
					if (record != null) {
						webxmlRecord.tldRecords.add(record);
						getImplicitReferences(webxml.getFullPath().toString()).put(taglibUri, record);
						TaglibIndex.getInstance().addDelta(new TaglibIndexDelta(fProject, record, deltaKind));
					}
				}
			}
		}
	}
}
