Switch from TaglibSupport to more direct TaglibIndex and TaglibController
diff --git a/bundles/org.eclipse.jst.jsp.core/.options b/bundles/org.eclipse.jst.jsp.core/.options
index a427e6b..13f52be 100644
--- a/bundles/org.eclipse.jst.jsp.core/.options
+++ b/bundles/org.eclipse.jst.jsp.core/.options
@@ -11,9 +11,11 @@
 # org.eclipse.jst.jsp.core.contentmodel.tld.CMDocumentFactoryTLD._debug
 org.eclipse.jst.jsp.core/debug/tldcmdocument/factory=false
 
-# BOTH org.eclipse.jst.jsp.core.internal.contentmodel.tld.AbstractTaglibSupport._debug
-# AND org.eclipse.jst.jsp.core.modelquery.ModelQueryAdapterFactoryForJSP._debug
-org.eclipse.jst.jsp.core/debug/taglibsupport=false
+#org.eclipse.jst.jsp.core.internal.contentmodel/index.ProjectDescription._debugIndexCreation
+org.eclipse.jst.jsp.core/taglib/indexcreation=true
+#org.eclipse.jst.jsp.core.internal.contentmodel/index.ProjectDescription._debugIndexTime
+org.eclipse.jst.jsp.core/taglib/indextime=false
 
 #org.eclipse.jst.jsp.core.text.rules.StructuredTextPartitioner.debugPrefixListener
-org.eclipse.jst.jsp.core/partitioner/prefixlistener=false
\ No newline at end of file
+org.eclipse.jst.jsp.core/partitioner/prefixlistener=false
+
diff --git a/bundles/org.eclipse.jst.jsp.core/plugin.xml b/bundles/org.eclipse.jst.jsp.core/plugin.xml
index 8737a0b..a911dda 100644
--- a/bundles/org.eclipse.jst.jsp.core/plugin.xml
+++ b/bundles/org.eclipse.jst.jsp.core/plugin.xml
@@ -60,16 +60,13 @@
             contentTypeId="org.eclipse.jst.jsp.core.jspsource"
             class="org.eclipse.wst.sse.core.filebuffers.BasicStructuredDocumentFactory:org.eclipse.jst.jsp.core.jspsource"/>
    </extension>
-<!--
    <extension point="org.eclipse.core.filebuffers.documentSetup"
          id="org.eclipse.jst.jsp.core.documentsetup"
          name="Structured JSP Document Setup participant">
-      <factory
-      		id="org.eclipse.jst.jsp.core.taglibs"
+      <participant
             contentTypeId="org.eclipse.jst.jsp.core.jspsource"
-            class="org.eclipse.jst.jsp.core.contentmodel.tld.TaglibController"/>
+            class="org.eclipse.jst.jsp.core.contentmodel.TaglibController"/>
    </extension>
--->
    <extension
          point="org.eclipse.team.core.fileTypes">
       <fileTypes
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/JSPCorePlugin.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/JSPCorePlugin.java
index d2a09cb..98c2c99 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/JSPCorePlugin.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/JSPCorePlugin.java
@@ -19,6 +19,7 @@
 import org.eclipse.core.runtime.IPluginDescriptor;
 import org.eclipse.core.runtime.Plugin;
 import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibController;
 import org.eclipse.jst.jsp.core.internal.java.search.JSPIndexManager;
 import org.eclipse.jst.jsp.core.internal.java.search.JSPSearchSupport;
 import org.eclipse.wst.common.encoding.CommonCharsetNames;
@@ -134,12 +135,15 @@
 		// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5091
 		// makes sure IndexManager is aware of our indexes
 		JSPIndexManager.getInstance().saveIndexes();
+		
+		TaglibController.startup();
 	}
 	
 	/* (non-Javadoc)
 	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
 	 */
 	public void stop(BundleContext context) throws Exception {
+		TaglibController.shutdown();
 		// stop any searching/indexing
 		JSPSearchSupport.getInstance().setCanceled(true);
 		// remove JSPIndexManager
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibIndexListener.java
similarity index 60%
copy from bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
copy to bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibIndexListener.java
index 6793869..d70dcca 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibIndexListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2004 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
@@ -7,15 +7,10 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     
  *******************************************************************************/
-package org.eclipse.jst.jsp.core.modelquery;
+package org.eclipse.jst.jsp.core.contentmodel;
 
-
-
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
-
-public interface TaglibModelQuery extends ModelQuery {
-
-	TaglibSupport getTaglibSupport();
-}
\ No newline at end of file
+public interface ITaglibIndexListener {
+	void indexChanged(ITaglibRecordEvent event);
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecord.java
similarity index 60%
copy from bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
copy to bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecord.java
index 6793869..20620ee 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecord.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2004 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
@@ -7,15 +7,16 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     
  *******************************************************************************/
-package org.eclipse.jst.jsp.core.modelquery;
+package org.eclipse.jst.jsp.core.contentmodel;
 
+public interface ITaglibRecord {
+	short JAR = 1 << 2;
+	short TAGDIR = 1 << 4;
+	short TLD = 1 << 1;
+	short URL = 1;
+	short WEB_XML = 1 << 3;
 
-
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
-
-public interface TaglibModelQuery extends ModelQuery {
-
-	TaglibSupport getTaglibSupport();
-}
\ No newline at end of file
+	short getRecordType();
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecordEvent.java
similarity index 60%
rename from bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
rename to bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecordEvent.java
index 6793869..89a7102 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ITaglibRecordEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2004 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
@@ -7,15 +7,16 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     
  *******************************************************************************/
-package org.eclipse.jst.jsp.core.modelquery;
+package org.eclipse.jst.jsp.core.contentmodel;
 
+public interface ITaglibRecordEvent {
+	ITaglibRecord getTaglibRecord();
 
+	short getType();
 
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
-
-public interface TaglibModelQuery extends ModelQuery {
-
-	TaglibSupport getTaglibSupport();
-}
\ No newline at end of file
+	short ADD = 1;
+	short CHANGE = 1 << 1;
+	short REMOVE = 1 << 2;
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/JarRecord.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/JarRecord.java
new file mode 100644
index 0000000..62cfe50
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/JarRecord.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+
+
+public class JarRecord implements ITaglibRecord {
+	IPath location;
+	List urlRecords;
+
+	public short getRecordType() {
+		return ITaglibRecord.JAR;
+	}
+
+	/**
+	 * @return Returns the location.
+	 */
+	public IPath getLocation() {
+		return location;
+	}
+
+	/**
+	 * 
+	 */
+	public List getURLRecords() {
+		return urlRecords;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ProjectDescription.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ProjectDescription.java
new file mode 100644
index 0000000..39f4be5
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ProjectDescription.java
@@ -0,0 +1,442 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+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.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.jsp.core.contentmodel.tld.DocumentProvider;
+import org.eclipse.jst.jsp.core.contentmodel.tld.JSP20TLDNames;
+import org.eclipse.wst.sse.core.util.JarUtilities;
+import org.eclipse.wst.xml.uriresolver.util.URIHelper;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+class ProjectDescription {
+
+	class DeltaVisitor implements IResourceDeltaVisitor {
+		public boolean visit(IResourceDelta delta) throws CoreException {
+			if (delta.getResource().getType() == IResource.FILE) {
+				if (delta.getResource().getName().endsWith(".tld")) {
+					if (delta.getKind() == IResourceDelta.REMOVED) {
+						removeTLD(delta.getResource());
+					}
+					else {
+						addTLD(delta.getResource());
+					}
+				}
+				else if (delta.getResource().getName().endsWith(".jar")) {
+					if (delta.getKind() == IResourceDelta.REMOVED) {
+						removeJAR(delta.getResource());
+					}
+					else {
+						addJAR(delta.getResource());
+					}
+				}
+				else if (delta.getResource().getName().endsWith(".tag") || delta.getResource().getName().endsWith(".tagx")) {
+					if (delta.getKind() == IResourceDelta.REMOVED) {
+						removeTagDir(delta.getResource());
+					}
+					else {
+						addTagDir(delta.getResource());
+					}
+				}
+				else if (delta.getResource().getName().equals(WEB_XML) && delta.getResource().getParent().getName().equals(WEB_INF)) {
+					if (delta.getKind() == IResourceDelta.REMOVED) {
+						removeServlets(delta.getResource());
+					}
+					else {
+						addServlets(delta.getResource());
+					}
+				}
+			}
+			return true;
+		}
+	}
+
+	class Indexer implements IResourceProxyVisitor {
+		public boolean visit(IResourceProxy proxy) throws CoreException {
+			if (proxy.getType() == IResource.FILE) {
+				if (proxy.getName().endsWith(".tld")) {
+					addTLD(proxy.requestResource());
+				}
+				else if (proxy.getName().endsWith(".jar")) {
+					addJAR(proxy.requestResource());
+				}
+				else if (proxy.getName().endsWith(".tag") || proxy.getName().endsWith(".tagx")) {
+					addTagDir(proxy.requestResource());
+				}
+				else if (proxy.getName().equals(WEB_XML) && proxy.requestResource().getParent().getName().equals(WEB_INF)) {
+					addServlets(proxy.requestResource());
+				}
+			}
+			return true;
+		}
+	}
+
+	static boolean _debugIndexCreation = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indexcreation"));
+	static boolean _debugIndexTime = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/taglib/indextime"));
+
+	private static final String WEB_INF = "WEB-INF";
+
+	private static final IPath WEB_INF_PATH = new Path("WEB-INF");
+	private static final String WEB_XML = "web.xml";
+	Hashtable fJARReferences;
+	IProject fProject;
+	Hashtable fServletReferences;
+	Hashtable fTagDirReferences;
+
+	Hashtable fTLDReferences;
+
+	Hashtable fURLReferences;
+
+	IResourceDeltaVisitor fVisitor;
+
+	private long time0;
+
+	ProjectDescription(IProject project) {
+		super();
+		fProject = project;
+		fJARReferences = new Hashtable(0);
+		fTagDirReferences = new Hashtable(0);
+		fTLDReferences = new Hashtable(0);
+		fServletReferences = new Hashtable(0);
+		fURLReferences = new Hashtable(0);
+	}
+
+	void addJAR(IResource jar) {
+		if (_debugIndexCreation)
+			System.out.println("creating records for JAR " + jar.getFullPath());
+		String jarLocationString = jar.getLocation().toString();
+		String[] entries = JarUtilities.getEntryNames(jar);
+		JarRecord jarRecord = (JarRecord) createJARRecord(jar);
+		fTLDReferences.put(jar.getFullPath().toString(), jarRecord);
+		for (int i = 0; i < entries.length; i++) {
+			if (entries[i].endsWith(".tld")) {
+				InputStream contents = JarUtilities.getInputStream(jar, entries[i]);
+				if (contents != null) {
+					String uri = extractURI(jarLocationString, contents);
+					if (uri != null && uri.length() > 0) {
+						URLRecord record = new URLRecord();
+						record.uri = uri;
+						record.baseLocation = jarLocationString;
+						try {
+							record.url = new URL("jar:file:" + jarLocationString + "!/" + entries[i]);
+							jarRecord.urlRecords.add(record);
+							fURLReferences.put(uri, record);
+							if (_debugIndexCreation)
+								System.out.println("created record for " + uri + "@" + record.getURL());
+						}
+						catch (MalformedURLException e) {
+							// don't record this URI
+							e.printStackTrace();
+						}
+					}
+				}
+			}
+		}
+	}
+
+	void addServlets(IResource webxml) {
+		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.setBaseReference(webxml.getParent().getLocation().toString());
+			document = provider.getDocument();
+		}
+		catch (CoreException e) {
+			e.printStackTrace();
+		}
+		finally {
+			if (webxmlContents != null)
+				try {
+					webxmlContents.close();
+				}
+				catch (IOException e1) {
+				}
+		}
+		if (document == null)
+			return;
+		if (_debugIndexCreation)
+			System.out.println("creating records for " + webxml.getFullPath());
+
+		ServletRecord servletRecord = new ServletRecord();
+		servletRecord.location = webxml.getLocation();
+		fServletReferences.put(servletRecord.getWebXML().toString(), servletRecord);
+		NodeList taglibs = document.getElementsByTagName(JSP20TLDNames.TAGLIB);
+		for (int i = 0; i < taglibs.getLength(); i++) {
+			String uri = readTextofChild(taglibs.item(i), "taglib-uri");
+			// specified location is relative to root of the webapp
+			String location = readTextofChild(taglibs.item(i), "taglib-location");
+			TLDRecord record = new TLDRecord();
+			record.uri = uri;
+			// use the local web-app root
+			record.location = new Path(getLocalRoot(webxml.getLocation().toString()) + location);
+			servletRecord.urlRecords.add(record);
+			fURLReferences.put(uri, record);
+			if (_debugIndexCreation)
+				System.out.println("created record for " + uri + "@" + location);
+		}
+	}
+
+	void addTagDir(IResource tagDir) {
+	}
+
+	void addTLD(IResource tld) {
+		if (_debugIndexCreation)
+			System.out.println("creating record for " + tld.getFullPath());
+		fTLDReferences.put(tld.getFullPath().toString(), createTLDRecord(tld));
+	}
+
+	/**
+	 * @param resource
+	 * @return
+	 */
+	private ITaglibRecord createJARRecord(IResource jar) {
+		JarRecord record = new JarRecord();
+		record.location = jar.getLocation();
+		record.urlRecords = new ArrayList(0);
+		return record;
+	}
+
+	/**
+	 * @param resource
+	 * @return
+	 */
+	private ITaglibRecord createTLDRecord(IResource tld) {
+		TLDRecord record = new TLDRecord();
+		record.location = tld.getLocation();
+		InputStream contents = null;
+		try {
+			contents = ((IFile) tld).getContents(true);
+			String baseLocation = null;
+			if (tld.getLocation() != null) {
+				baseLocation = tld.getLocation().toString();
+			}
+			else {
+				baseLocation = getLocalRoot(fProject.getLocation().toString());
+			}
+			String defaultURI = extractURI(baseLocation, contents);
+			if (defaultURI != null && defaultURI.length() > 0) {
+				record.uri = defaultURI;
+			}
+		}
+		catch (CoreException e) {
+		}
+		finally {
+			try {
+				if (contents != null) {
+					contents.close();
+				}
+			}
+			catch (IOException e) {
+			}
+		}
+		return record;
+	}
+
+	/**
+	 * @param tldContents
+	 * @return
+	 */
+	private String extractURI(String baseLocation, InputStream tldContents) {
+		StringBuffer uri = new StringBuffer();
+		Node result = null;
+		DocumentProvider provider = new DocumentProvider();
+		provider.setInputStream(tldContents);
+		provider.setValidating(false);
+		provider.setRootElementName(JSP20TLDNames.TAGLIB);
+		provider.setBaseReference(baseLocation);
+		result = provider.getRootElement();
+		if (result.getNodeType() != Node.ELEMENT_NODE)
+			return null;
+		Element taglibElement = (Element) result;
+		if (taglibElement != null) {
+			Node child = taglibElement.getFirstChild();
+			while (child != null && !(child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals(JSP20TLDNames.URI))) {
+				child = child.getNextSibling();
+			}
+			if (child != null) {
+				Node text = child.getFirstChild();
+				while (text != null) {
+					if (text.getNodeType() == Node.TEXT_NODE || text.getNodeType() == Node.CDATA_SECTION_NODE) {
+						uri.append(text.getNodeValue());
+					}
+					text = text.getNextSibling();
+				}
+			}
+		}
+		return uri.toString();
+	}
+
+	/**
+	 * @param baseLocation
+	 * @return
+	 */
+	private String getLocalRoot(String baseLocation) {
+		IResource file = FileBuffers.getWorkspaceFileAtLocation(new Path(baseLocation));
+		while (file != null && (file.getType() & IResource.ROOT) == 0) {
+			/**
+			 * 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();
+			}
+			IFolder webinf = folder.getFolder(WEB_INF_PATH);
+			if (webinf != null && webinf.exists()) {
+				return file.getLocation().toString();
+			}
+			file = file.getParent();
+		}
+
+		return fProject.getFullPath().toString();
+	}
+
+	/**
+	 * @return Returns the visitor.
+	 */
+	IResourceDeltaVisitor getVisitor() {
+		if (fVisitor == null) {
+			fVisitor = new DeltaVisitor();
+		}
+		return fVisitor;
+	}
+
+	void index() {
+		time0 = System.currentTimeMillis();
+		fTLDReferences.clear();
+		fJARReferences.clear();
+		fTagDirReferences.clear();
+		fServletReferences.clear();
+		try {
+			fProject.accept(new Indexer(), 0);
+		}
+		catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (_debugIndexTime)
+			System.out.println("indexed " + fProject.getName() + " in " + (System.currentTimeMillis() - time0) + "ms");
+	}
+
+	protected String readTextofChild(Node node, String childName) {
+		StringBuffer buffer = new StringBuffer();
+		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)) {
+				Node text = child.getFirstChild();
+				while (text != null) {
+					buffer.append(text.getNodeValue());
+					text = text.getNextSibling();
+				}
+			}
+		}
+		return buffer.toString();
+	}
+
+	void removeJAR(IResource jar) {
+		JarRecord record = (JarRecord) fJARReferences.remove(jar.getFullPath());
+		if (record != null) {
+			URLRecord[] records = (URLRecord[]) record.getURLRecords().toArray(new URLRecord[0]);
+			for (int i = 0; i < records.length; i++) {
+				fURLReferences.remove(records[i].getURI());
+			}
+		}
+	}
+
+	void removeServlets(IResource webxml) {
+		ServletRecord record = (ServletRecord) fServletReferences.remove(webxml.getFullPath());
+		if (record != null) {
+			URLRecord[] records = (URLRecord[]) record.getURLRecords().toArray(new URLRecord[0]);
+			for (int i = 0; i < records.length; i++) {
+				fURLReferences.remove(records[i].getURI());
+			}
+		}
+	}
+
+	void removeTagDir(IResource tagDir) {
+	}
+
+	void removeTLD(IResource tld) {
+		fTLDReferences.remove(tld.getFullPath());
+	}
+
+	/**
+	 * @param baseLocation
+	 * @param reference
+	 * @return
+	 */
+	ITaglibRecord resolve(String baseLocation, String reference) {
+		ITaglibRecord record = null;
+		String location = null;
+
+		/**
+		 * Workaround for problem in URIHelper; uris starting with '/' are
+		 * returned as-is.
+		 */
+		if (reference.startsWith("/")) {
+			location = getLocalRoot(baseLocation) + reference;
+		}
+		else {
+			location = URIHelper.normalize(reference, baseLocation, getLocalRoot(baseLocation));
+		}
+		// order dictated by JSP spec 2.0 section 7.2.3
+		if (record == null) {
+			record = (ITaglibRecord) fServletReferences.get(location);
+		}
+		if (record == null) {
+			record = (ITaglibRecord) fJARReferences.get(location);
+		}
+		if (record == null) {
+			record = (ITaglibRecord) fTLDReferences.get(location);
+		}
+		if (record == null) {
+			record = (ITaglibRecord) fURLReferences.get(reference);
+		}
+		if (record == null) {
+			record = (ITaglibRecord) fTagDirReferences.get(location);
+		}
+		return record;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ServletRecord.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ServletRecord.java
new file mode 100644
index 0000000..3ea9edf
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/ServletRecord.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+
+
+public class ServletRecord implements ITaglibRecord {
+	IPath location;
+	List urlRecords = new ArrayList(0);
+
+	public short getRecordType() {
+		return ITaglibRecord.WEB_XML;
+	}
+
+	/**
+	 * @return Returns the webxml.
+	 */
+	public IPath getWebXML() {
+		return location;
+	}
+
+	/**
+	 * 
+	 */
+	public List getURLRecords() {
+		return urlRecords;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TLDRecord.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TLDRecord.java
new file mode 100644
index 0000000..5f2536e
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TLDRecord.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import org.eclipse.core.runtime.IPath;
+
+
+public class TLDRecord implements ITaglibRecord {
+	IPath location;
+	String uri;
+
+	public short getRecordType() {
+		return ITaglibRecord.TLD;
+	}
+
+	/**
+	 * @return Returns the location.
+	 */
+	public IPath getLocation() {
+		return location;
+	}
+
+	/**
+	 * @return Returns the uri.
+	 */
+	public String getURI() {
+		return uri;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TagDirRecord.java
similarity index 60%
copy from bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
copy to bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TagDirRecord.java
index 6793869..0a44fbd 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/TaglibModelQuery.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TagDirRecord.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
+ * Copyright (c) 2001, 2004 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
@@ -7,15 +7,17 @@
  * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     
  *******************************************************************************/
-package org.eclipse.jst.jsp.core.modelquery;
+package org.eclipse.jst.jsp.core.contentmodel;
+
+import org.eclipse.core.runtime.IPath;
 
 
+public class TagDirRecord implements ITaglibRecord {
+	IPath location;
 
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
-
-public interface TaglibModelQuery extends ModelQuery {
-
-	TaglibSupport getTaglibSupport();
-}
\ No newline at end of file
+	public short getRecordType() {
+		return ITaglibRecord.TAGDIR;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibController.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibController.java
new file mode 100644
index 0000000..2f08f12
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibController.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
+import org.eclipse.core.filebuffers.IFileBuffer;
+import org.eclipse.core.filebuffers.IFileBufferListener;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jst.jsp.core.contentmodel.tld.TLDCMDocumentManager;
+import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser;
+import org.eclipse.wst.sse.core.internal.text.BasicStructuredDocument;
+import org.eclipse.wst.sse.core.text.IStructuredDocument;
+import org.eclipse.wst.sse.core.util.Assert;
+
+/**
+ * Provides a direct mapping from IStructuredDocument to supporting
+ * TLDCMDocumentManager.
+ * 
+ * Listens to the creation of JSP type TextFileBuffers and forces a text-less
+ * reparse after connecting taglib-supporting listeners. Connecting the
+ * listeners before the text is set would be ideal, but there is no way to
+ * look up taglib references since the location is not yet knowable. Since
+ * taglibs can affect the parsing of the document, a reparse is currently
+ * required to react to custom tags with tagdependent content.
+ * 
+ * TODO: Remove the reparse penalty.
+ */
+public class TaglibController implements IDocumentSetupParticipant {
+
+	class DocumentInfo {
+		IStructuredDocument document;
+		ITextFileBuffer textFileBuffer;
+		TLDCMDocumentManager tldDocumentManager;
+	}
+
+	class FileBufferListener implements IFileBufferListener {
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferContentAboutToBeReplaced(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void bufferContentAboutToBeReplaced(IFileBuffer buffer) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferContentReplaced(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void bufferContentReplaced(IFileBuffer buffer) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferCreated(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void bufferCreated(IFileBuffer buffer) {
+			if (buffer instanceof ITextFileBuffer) {
+				IDocument document = ((ITextFileBuffer) buffer).getDocument();
+				// ignore non-JSP documents
+				if (!fJSPdocuments.contains(document))
+					return;
+				Assert.isTrue(document instanceof IStructuredDocument);
+				DocumentInfo info = new DocumentInfo();
+				info.document = (IStructuredDocument) document;
+				info.textFileBuffer = (ITextFileBuffer) buffer;
+				info.tldDocumentManager = new TLDCMDocumentManager();
+				info.tldDocumentManager.setSourceParser((JSPSourceParser) info.document.getParser());
+				fDocumentMap.put(document, info);
+				if (document instanceof BasicStructuredDocument) {
+					((BasicStructuredDocument) document).reparse(this);
+				}
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#bufferDisposed(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void bufferDisposed(IFileBuffer buffer) {
+			if (buffer instanceof ITextFileBuffer) {
+				IDocument document = ((ITextFileBuffer) buffer).getDocument();
+				if (!fJSPdocuments.contains(document))
+					return;
+				fJSPdocuments.remove(document);
+			}
+			Object[] mapEntrys = fDocumentMap.entrySet().toArray();
+			boolean removed = false;
+			for (int i = 0; i < mapEntrys.length && !removed; i++) {
+				DocumentInfo info = (DocumentInfo) ((Map.Entry) mapEntrys[i]).getValue();
+				if (info != null && info.textFileBuffer == buffer) {
+					fDocumentMap.remove(mapEntrys[i]);
+					removed = true;
+				}
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#dirtyStateChanged(org.eclipse.core.filebuffers.IFileBuffer,
+		 *      boolean)
+		 */
+		public void dirtyStateChanged(IFileBuffer buffer, boolean isDirty) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#stateChangeFailed(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void stateChangeFailed(IFileBuffer buffer) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#stateChanging(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void stateChanging(IFileBuffer buffer) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#stateValidationChanged(org.eclipse.core.filebuffers.IFileBuffer,
+		 *      boolean)
+		 */
+		public void stateValidationChanged(IFileBuffer buffer, boolean isStateValidated) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#underlyingFileDeleted(org.eclipse.core.filebuffers.IFileBuffer)
+		 */
+		public void underlyingFileDeleted(IFileBuffer buffer) {
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see org.eclipse.core.filebuffers.IFileBufferListener#underlyingFileMoved(org.eclipse.core.filebuffers.IFileBuffer,
+		 *      org.eclipse.core.runtime.IPath)
+		 */
+		public void underlyingFileMoved(IFileBuffer buffer, IPath path) {
+		}
+
+
+	}
+
+	static TaglibController _instance = null;
+
+	public static ITextFileBuffer getFileBuffer(IDocument document) {
+		DocumentInfo info = (DocumentInfo) _instance.fDocumentMap.get(document);
+		if (info != null)
+			return info.textFileBuffer;
+		return null;
+	}
+
+	/**
+	 * @param manager
+	 * @return
+	 */
+	public static ITextFileBuffer getFileBuffer(TLDCMDocumentManager manager) {
+		Iterator docInfos = _instance.fDocumentMap.values().iterator();
+		while (docInfos.hasNext()) {
+			DocumentInfo info = (DocumentInfo) docInfos.next();
+			if (info.tldDocumentManager == manager)
+				return info.textFileBuffer;
+		}
+		return null;
+	}
+
+	public static TLDCMDocumentManager getTLDCMDocumentManager(IDocument document) {
+		DocumentInfo info = (DocumentInfo) _instance.fDocumentMap.get(document);
+		if (info != null)
+			return info.tldDocumentManager;
+		return null;
+	}
+
+	public static void shutdown() {
+		FileBuffers.getTextFileBufferManager().removeFileBufferListener(_instance.fBufferListener);
+		_instance = null;
+	}
+
+	public static void startup() {
+		_instance = new TaglibController();
+		FileBuffers.getTextFileBufferManager().addFileBufferListener(_instance.fBufferListener);
+	}
+
+	IFileBufferListener fBufferListener;
+	Map fDocumentMap;
+
+	List fJSPdocuments;
+
+	public TaglibController() {
+		super();
+		fBufferListener = new FileBufferListener();
+		fJSPdocuments = new ArrayList(1);
+		fDocumentMap = new HashMap(1);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.filebuffers.IDocumentSetupParticipant#setup(org.eclipse.jface.text.IDocument)
+	 */
+	public void setup(IDocument document) {
+		_instance.fJSPdocuments.add(document);
+	}
+
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibIndex.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibIndex.java
new file mode 100644
index 0000000..8ef1eff
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/TaglibIndex.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * @author nsd
+ * 
+ * A non-extendable index manager for taglibs similar to the J2EE
+ * ITaglibRegistry but lacking any ties to project natures.
+ */
+public class TaglibIndex {
+
+	class ResourceChangeListener implements IResourceChangeListener {
+		public void resourceChanged(IResourceChangeEvent event) {
+			// pair deltas with projects
+			IResourceDelta[] deltas = new IResourceDelta[]{event.getDelta()};
+			IProject[] projects = null;
+
+			if (deltas != null && deltas.length > 0) {
+				IResource resource = deltas[0].getResource();
+
+				if (resource.getType() == IResource.ROOT) {
+					deltas = deltas[0].getAffectedChildren();
+					projects = new IProject[deltas.length];
+					for (int i = 0; i < deltas.length; i++) {
+						if (deltas[i].getResource().getType() == IResource.PROJECT) {
+							projects[i] = (IProject) deltas[i].getResource();
+						}
+					}
+				}
+				else {
+					projects = new IProject[1];
+					if (resource.getType() != IResource.PROJECT) {
+						projects[0] = resource.getProject();
+					}
+					else {
+						projects[0] = (IProject) resource;
+					}
+				}
+				for (int i = 0; i < projects.length; i++) {
+					ProjectDescription description = createDescription(projects[i]);
+					try {
+						deltas[i].accept(description.getVisitor());
+					}
+					catch (CoreException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+
+	}
+
+	static final boolean _debugChangeListener = true;
+
+	static TaglibIndex _instance;
+
+	static {
+		_instance = new TaglibIndex();
+	}
+
+	public static void addTaglibIndexListener(ITaglibIndexListener listener) {
+	}
+
+	public static void removeTaglibIndexListener(ITaglibIndexListener listener) {
+	}
+
+	public static ITaglibRecord resolve(String baseLocation, String reference, boolean crossProjects) {
+		return _instance.internalResolve(baseLocation, reference, crossProjects);
+	}
+
+	Map fProjectDescriptions;
+	private ResourceChangeListener fResourceChangeListener;
+
+	private TaglibIndex() {
+		super();
+		fResourceChangeListener = new ResourceChangeListener();
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(fResourceChangeListener);
+		fProjectDescriptions = new HashMap();
+	}
+
+	/**
+	 * @param project
+	 * @return
+	 */
+	ProjectDescription createDescription(IProject project) {
+		ProjectDescription description = (ProjectDescription) fProjectDescriptions.get(project);
+		if (description == null) {
+			description = new ProjectDescription(project);
+			description.index();
+			fProjectDescriptions.put(project, description);
+		}
+		return description;
+	}
+
+	private ITaglibRecord internalResolve(String baseLocation, String reference, boolean crossProjects) {
+		IProject project = null;
+		ITaglibRecord resolved = null;
+		IFile baseResource = FileBuffers.getWorkspaceFileAtLocation(new Path(baseLocation));
+		if (baseResource != null) {
+			project = baseResource.getProject();
+			ProjectDescription description = createDescription(project);
+			resolved = description.resolve(baseLocation, reference);
+		}
+		else {
+			// TODO: support outside of the workspace?
+			File baseFile = FileBuffers.getSystemFileAtLocation(new Path(baseLocation));
+			if (baseFile != null) {
+			}
+		}
+		return resolved;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/URLRecord.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/URLRecord.java
new file mode 100644
index 0000000..206c51a
--- /dev/null
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/URLRecord.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2004 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.contentmodel;
+
+import java.net.URL;
+
+public class URLRecord implements ITaglibRecord {
+	URL url;
+	String uri;
+	String baseLocation;
+
+	public String getBaseLocation() {
+		return baseLocation;
+	}
+
+	public URLRecord() {
+		super();
+	}
+
+	public short getRecordType() {
+		return ITaglibRecord.URL;
+	}
+
+	/**
+	 * @return Returns the uri.
+	 */
+	public String getURI() {
+		return uri;
+	}
+
+	/**
+	 * @return Returns the URL.
+	 */
+	public URL getURL() {
+		return url;
+	}
+}
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/CMDocumentFactoryTLD.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/CMDocumentFactoryTLD.java
index 7db1f38..7ad6dde 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/CMDocumentFactoryTLD.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/CMDocumentFactoryTLD.java
@@ -17,6 +17,11 @@
 import java.net.URL;
 
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.jst.jsp.core.Logger;
+import org.eclipse.jst.jsp.core.contentmodel.ITaglibRecord;
+import org.eclipse.jst.jsp.core.contentmodel.JarRecord;
+import org.eclipse.jst.jsp.core.contentmodel.TLDRecord;
+import org.eclipse.jst.jsp.core.contentmodel.URLRecord;
 import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMAttributeDeclarationImpl;
 import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentImpl;
 import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMElementDeclarationImpl;
@@ -65,7 +70,7 @@
 		provider.setValidating(false);
 		provider.setRootElementName(JSP11TLDNames.TAGLIB);
 		provider.setInputStream(input);
-		if(baselocation != null)
+		if (baselocation != null)
 			provider.setBaseReference(baselocation);
 		return loadDocument(baselocation, provider.getRootElement());
 	}
@@ -75,15 +80,16 @@
 	 * @return
 	 */
 	private CMDocument buildCMDocumentFromDirectory(File directory) {
-		if(_debug) {
+		if (_debug) {
 			System.out.println("not implemented: tagdir loading for " + directory.getAbsolutePath());
 		}
-//		File[] tagfiles = directory.listFiles();
+		// File[] tagfiles = directory.listFiles();
 		return null;
 	}
 
 	/**
 	 * NOT API
+	 * 
 	 * @param fileName
 	 * @return
 	 */
@@ -94,7 +100,8 @@
 		provider.setBaseReference(fileName);
 		provider.setRootElementName(JSP11TLDNames.TAGLIB);
 		provider.setFileName(fileName);
-		return loadDocument(fileName, provider.getRootElement());
+		Node rootElement = provider.getRootElement();
+		return loadDocument(fileName, rootElement);
 	}
 
 	/**
@@ -184,7 +191,9 @@
 					result = buildCMDocument(url.toExternalForm(), istream);
 				}
 				catch (Exception t) {
-					// Logger.log(Logger.INFO, "Exception creating content model: could not load TLD contents from URI " + uri + " :" + t);
+					// Logger.log(Logger.INFO, "Exception creating content
+					// model: could not load TLD contents from URI " + uri + "
+					// :" + t);
 				}
 			}
 			try {
@@ -300,7 +309,7 @@
 				}
 				// info (1.1 only) or description (1.2 only)
 				else if ((nodeName.equals(JSP11TLDNames.INFO) || nodeName.equals(JSP12TLDNames.DESCRIPTION)) && child.hasChildNodes()) {
-					//					ed.setDescription(getContainedText(child));
+					// ed.setDescription(getContainedText(child));
 					ed.setDescription(getContainedText(child));
 				}
 				// attributes
@@ -481,7 +490,7 @@
 		document.setBaseLocation(baseLocation);
 
 		if (root == null) {
-			if(_debug) {
+			if (_debug) {
 				System.out.println("null \"taglib\" element for TLD " + baseLocation);
 			}
 			return document;
@@ -572,4 +581,56 @@
 		}
 		return document;
 	}
+
+	/**
+	 * @param reference
+	 * @return
+	 */
+	public CMDocument createCMDocument(ITaglibRecord reference) {
+		CMDocument document = null;
+		switch (reference.getRecordType()) {
+			case (ITaglibRecord.TLD) : {
+				TLDRecord record = (TLDRecord) reference;
+				document = buildCMDocumentFromFile(record.getLocation().toString());
+				if (_debug && document != null && document.getElements().getLength() == 0) {
+					System.out.println("failure parsing " + record.getLocation());
+				}
+			}
+				break;
+			case (ITaglibRecord.JAR) : {
+				JarRecord record = (JarRecord) reference;
+				document = buildCMDocumentFromJar(record.getLocation().toString());
+				if (document != null && document.getElements().getLength() == 0) {
+					System.out.println("failure parsing " + record.getLocation());
+				}
+			}
+				break;
+			case (ITaglibRecord.TAGDIR) : {
+				// TODO: implement TAGDIR support
+			}
+				break;
+			case (ITaglibRecord.URL) : {
+				URLRecord record = (URLRecord) reference;
+				InputStream urlContents = null;
+				try {
+					urlContents = record.getURL().openStream();
+					document = buildCMDocument(record.getBaseLocation(), urlContents);
+				}
+				catch (IOException e) {
+					Logger.logException(e);
+				}
+				finally {
+					if (urlContents != null) {
+						try {
+							urlContents.close();
+						}
+						catch (IOException e) {
+						}
+					}
+				}
+			}
+				break;
+		}
+		return document;
+	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TLDCMDocumentManager.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TLDCMDocumentManager.java
index e0e40d8..d298849 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TLDCMDocumentManager.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TLDCMDocumentManager.java
@@ -16,7 +16,6 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -26,6 +25,9 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.jst.jsp.core.JSP12Namespace;
 import org.eclipse.jst.jsp.core.Logger;
+import org.eclipse.jst.jsp.core.contentmodel.ITaglibRecord;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibController;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibIndex;
 import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser;
 import org.eclipse.wst.common.contentmodel.CMDocument;
 import org.eclipse.wst.common.contentmodel.CMNamedNodeMap;
@@ -40,14 +42,10 @@
 import org.eclipse.wst.sse.core.util.Assert;
 import org.eclipse.wst.sse.core.util.Debug;
 import org.eclipse.wst.sse.core.util.StringUtils;
-import org.eclipse.wst.sse.core.util.URIResolver;
 import org.eclipse.wst.xml.core.jsp.model.parser.temp.XMLJSPRegionContexts;
 import org.eclipse.wst.xml.core.parser.XMLRegionContext;
 
 public class TLDCMDocumentManager {
-	static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/tldcmdocument/manager")); //$NON-NLS-1$ //$NON-NLS-2$
-	static final String XMLNS = "xmlns:"; //$NON-NLS-1$ 
-	static final int XMLNS_LENGTH = XMLNS.length();
 
 	protected class DirectiveStructuredDocumentRegionHandler implements StructuredDocumentRegionHandler, StructuredDocumentRegionHandlerExtension {
 
@@ -126,6 +124,63 @@
 			getTaglibTrackers().add(new TaglibTracker(uri, prefix, tld, anchorStructuredDocumentRegion));
 		}
 
+		/**
+		 * Enables a TLD owning the given prefix loaded from the given URI at
+		 * the anchorStructuredDocumentRegion. The list of
+		 * additionalCMDocuments will claim to not know any of its tags at
+		 * positions earlier than that IStructuredDocumentRegion's position.
+		 * 
+		 * For taglib directives, the taglib is the anchor while taglibs
+		 * registered through include directives use the parent document's
+		 * include directive as their anchor.
+		 * 
+		 * @param prefix
+		 * @param uri
+		 * @param taglibStructuredDocumentRegion
+		 */
+		protected void enableTagsInDir(String prefix, String tagdir, IStructuredDocumentRegion taglibStructuredDocumentRegion) {
+			if (prefix == null || tagdir == null || bannedPrefixes.contains(prefix))
+				return;
+			if (_debug) {
+				System.out.println("TLDCMDocumentManager enabling tags from directory" + tagdir + " for prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$
+			}
+			// Try to load the CMDocument for this URI
+			CMDocument tld = getImplicitCMDocument(tagdir);
+			if (tld == null || !(tld instanceof TLDDocument))
+				return;
+			CMNamedNodeMap elements = tld.getElements();
+			// Go through the CMDocument for any tags that must be marked as
+			// block tags
+			// starting at the anchoring IStructuredDocumentRegion. As the
+			// document is edited and the
+			// IStructuredDocumentRegion moved around, the block tag
+			// enablement will automatically follow
+			// it.
+			for (int i = 0; i < elements.getLength(); i++) {
+				TLDElementDeclaration ed = (TLDElementDeclaration) elements.item(i);
+				if (ed.getBodycontent() == JSP12TLDNames.CONTENT_TAGDEPENDENT)
+					addBlockTag(prefix + ":" + ed.getNodeName(), taglibStructuredDocumentRegion); //$NON-NLS-1$
+			}
+			// Since modifications to StructuredDocumentRegions adjacent to a
+			// taglib directive can cause
+			// that IStructuredDocumentRegion to be reported, filter out any
+			// duplicated URIs. When the
+			// taglib is actually modified, a full rebuild will occur and no
+			// duplicates
+			// will/should be found.
+			List trackers = getTaglibTrackers();
+			for (int i = 0; i < trackers.size(); i++) {
+				TaglibTracker tracker = (TaglibTracker) trackers.get(i);
+				if (tracker.getPrefix().equals(prefix) && tracker.getURI().equals(tagdir)) {
+					return;
+				}
+			}
+			if (_debug) {
+				System.out.println("TLDCMDocumentManager registered a tracker for directory" + tagdir + " with prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$
+			}
+			getTaglibTrackers().add(new TaglibTracker(tagdir, prefix, tld, taglibStructuredDocumentRegion));
+		}
+
 		public void nodeParsed(IStructuredDocumentRegion aCoreStructuredDocumentRegion) {
 			// could test > 1, but since we only care if there are 8 (<%@,
 			// taglib, uri, =, where, prefix, =, what) [or 4 for includes]
@@ -166,7 +221,7 @@
 					}
 				}
 				catch (StringIndexOutOfBoundsException sioobExc) {
-					//do nothing
+					// do nothing
 				}
 			}
 			// could test > 1, but since we only care if there are 5 (<,
@@ -216,16 +271,7 @@
 				file = null;
 			}
 			if (file != null) {
-				String fileLocation = null;
-				if (getResolver() != null) {
-					if (getIncludes().empty())
-						fileLocation = getResolver().getLocationByURI(StringUtils.strip(file));
-					else
-						fileLocation = getResolver().getLocationByURI(StringUtils.strip(file), (String) getIncludes().peek());
-				}
-				else {
-					fileLocation = StringUtils.strip(file);
-				}
+				String fileLocation = getBaseLocation();
 				// hopefully, a resolver is present and has returned a
 				// canonical file path
 				if (!getIncludes().contains(fileLocation) && getBaseLocation() != null && !fileLocation.equals(getBaseLocation())) {
@@ -311,7 +357,7 @@
 					int startOffset = taglibStructuredDocumentRegion.getStartOffset(region);
 					int textLength = region.getTextLength();
 					if (region.getType() == XMLRegionContext.XML_TAG_ATTRIBUTE_NAME) {
-						//String name = textSource.getText(startOffset,
+						// String name = textSource.getText(startOffset,
 						// textLength);
 						if (textSource.regionMatches(startOffset, textLength, JSP11TLDNames.PREFIX)) {
 							attrName = JSP11TLDNames.PREFIX;
@@ -356,63 +402,6 @@
 			}
 		}
 
-		/**
-		 * Enables a TLD owning the given prefix loaded from the given URI at
-		 * the anchorStructuredDocumentRegion. The list of
-		 * additionalCMDocuments will claim to not know any of its tags at
-		 * positions earlier than that IStructuredDocumentRegion's position.
-		 * 
-		 * For taglib directives, the taglib is the anchor while taglibs
-		 * registered through include directives use the parent document's
-		 * include directive as their anchor.
-		 * 
-		 * @param prefix
-		 * @param uri
-		 * @param taglibStructuredDocumentRegion
-		 */
-		protected void enableTagsInDir(String prefix, String tagdir, IStructuredDocumentRegion taglibStructuredDocumentRegion) {
-			if (prefix == null || tagdir == null || bannedPrefixes.contains(prefix))
-				return;
-			if (_debug) {
-				System.out.println("TLDCMDocumentManager enabling tags from directory" + tagdir + " for prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$
-			}
-			// Try to load the CMDocument for this URI
-			CMDocument tld = getImplicitCMDocument(tagdir);
-			if (tld == null || !(tld instanceof TLDDocument))
-				return;
-			CMNamedNodeMap elements = tld.getElements();
-			// Go through the CMDocument for any tags that must be marked as
-			// block tags
-			// starting at the anchoring IStructuredDocumentRegion. As the
-			// document is edited and the
-			// IStructuredDocumentRegion moved around, the block tag
-			// enablement will automatically follow
-			// it.
-			for (int i = 0; i < elements.getLength(); i++) {
-				TLDElementDeclaration ed = (TLDElementDeclaration) elements.item(i);
-				if (ed.getBodycontent() == JSP12TLDNames.CONTENT_TAGDEPENDENT)
-					addBlockTag(prefix + ":" + ed.getNodeName(), taglibStructuredDocumentRegion); //$NON-NLS-1$
-			}
-			// Since modifications to StructuredDocumentRegions adjacent to a
-			// taglib directive can cause
-			// that IStructuredDocumentRegion to be reported, filter out any
-			// duplicated URIs. When the
-			// taglib is actually modified, a full rebuild will occur and no
-			// duplicates
-			// will/should be found.
-			List trackers = getTaglibTrackers();
-			for (int i = 0; i < trackers.size(); i++) {
-				TaglibTracker tracker = (TaglibTracker) trackers.get(i);
-				if (tracker.getPrefix().equals(prefix) && tracker.getURI().equals(tagdir)) {
-					return;
-				}
-			}
-			if (_debug) {
-				System.out.println("TLDCMDocumentManager registered a tracker for directory" + tagdir + " with prefix " + prefix); //$NON-NLS-2$//$NON-NLS-1$
-			}
-			getTaglibTrackers().add(new TaglibTracker(tagdir, prefix, tld, taglibStructuredDocumentRegion));
-		}
-
 		private void resetBlockTags() {
 			if (getParser() == null)
 				return;
@@ -435,6 +424,7 @@
 			resetBlockTags();
 			resetTaglibTrackers();
 		}
+
 		public void setStructuredDocument(IStructuredDocument newDocument) {
 			Assert.isTrue(newDocument != null, "null document");
 			Assert.isTrue(newDocument.getParser() != null, "null document parser");
@@ -518,7 +508,7 @@
 					}
 				}
 				catch (StringIndexOutOfBoundsException sioobExc) {
-					//do nothing
+					// do nothing
 				}
 			}
 			// could test > 1, but since we only care if there are 5 (<,
@@ -548,9 +538,13 @@
 		}
 	}
 
+	static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/tldcmdocument/manager")); //$NON-NLS-1$ //$NON-NLS-2$
+
 	// will hold the prefixes banned by the specification; taglibs may not use
 	// them
 	protected static List bannedPrefixes = null;
+	static final String XMLNS = "xmlns:"; //$NON-NLS-1$ 
+	static final int XMLNS_LENGTH = XMLNS.length();
 
 	static {
 		bannedPrefixes = new ArrayList(7);
@@ -590,9 +584,7 @@
 	 * @return java.lang.String
 	 */
 	public String getBaseLocation() {
-		if (getResolver() == null)
-			return null;
-		return getResolver().getFileBaseLocation();
+		return TaglibController.getFileBuffer(this).getLocation().toString();
 	}
 
 	/**
@@ -628,38 +620,6 @@
 	}
 
 	/**
-	 * Return the CMDocument at the tagdir (cached)
-	 */
-	protected CMDocument getImplicitCMDocument(String tagdir) {
-		if (tagdir == null || tagdir.length() == 0)
-			return null;
-		String reference = tagdir;
-		/**
-		 * JSP 1.2 Specification, section 5.2.2 jsp-1_2-fcs-spec.pdf, page 87
-		 */
-		String URNprefix = "urn:jsptld:"; //$NON-NLS-1$
-		if (reference.startsWith(URNprefix)) {
-			/**
-			 * @see section 7.3.2
-			 */
-			if (reference.length() > URNprefix.length())
-				reference = reference.substring(11);
-		}
-		else {
-			/**
-			 * @see section 7.3.6
-			 */
-		}
-		CMDocument doc = (CMDocument) getDocuments().get(reference);
-		if (doc == null) {
-			doc = loadTagDir(reference);
-			if (doc != null)
-				getDocuments().put(reference, doc);
-		}
-		return doc;
-	}
-
-	/**
 	 * Gets the cMDocumentBuilder.
 	 * 
 	 * @return Returns a CMDocumentFactoryTLD, since it has more builder
@@ -712,8 +672,36 @@
 		return fDocuments;
 	}
 
-	public StructuredDocumentRegionHandler getStructuredDocumentRegionHandler() {
-		return getDirectiveStructuredDocumentRegionHandler();
+	/**
+	 * Return the CMDocument at the tagdir (cached)
+	 */
+	protected CMDocument getImplicitCMDocument(String tagdir) {
+		if (tagdir == null || tagdir.length() == 0)
+			return null;
+		String reference = tagdir;
+		/**
+		 * JSP 1.2 Specification, section 5.2.2 jsp-1_2-fcs-spec.pdf, page 87
+		 */
+		String URNprefix = "urn:jsptld:"; //$NON-NLS-1$
+		if (reference.startsWith(URNprefix)) {
+			/**
+			 * @see section 7.3.2
+			 */
+			if (reference.length() > URNprefix.length())
+				reference = reference.substring(11);
+		}
+		else {
+			/**
+			 * @see section 7.3.6
+			 */
+		}
+		CMDocument doc = (CMDocument) getDocuments().get(reference);
+		if (doc == null) {
+			doc = loadTagDir(reference);
+			if (doc != null)
+				getDocuments().put(reference, doc);
+		}
+		return doc;
 	}
 
 	/**
@@ -732,31 +720,20 @@
 	}
 
 	/**
-	 * Gets the resolver
-	 * 
-	 * @return Returns a URIResolver
-	 */
-	protected URIResolver getResolver() {
-		if (getResolverProvider() == null) {
-			Logger.log(Logger.WARNING, "Warning: a URIResolver was requested by " + getClass().getName() + " but none was available; taglib support disabled"); //$NON-NLS-1$ //$NON-NLS-2$
-			return null;
-		}
-		return getResolverProvider().getResolver();
-	}
-
-	/**
-	 * Gets the resolverProvider.
-	 * 
-	 * @return Returns a URIResolverProvider
+	 * @deprecated
 	 */
 	public URIResolverProvider getResolverProvider() {
-		return fResolverProvider;
+		return null;
 	}
 
 	public JSPSourceParser getSourceParser() {
 		return fParser;
 	}
 
+	public StructuredDocumentRegionHandler getStructuredDocumentRegionHandler() {
+		return getDirectiveStructuredDocumentRegionHandler();
+	}
+
 	/**
 	 * 
 	 * @return java.util.List
@@ -768,45 +745,17 @@
 	}
 
 	/**
-	 * Loads the taglib from the specified URI. It must point to a valid
-	 * taglib descriptor or valid JAR file to work.
-	 */
-	protected CMDocument loadTaglib(String uri) {
-		String location = null;
-		InputStream directStream = null;
-		// see if the resolver knows of some special way to get from URI to
-		// InputStream
-		// (automatic discovery of URIs, web.xml mappings, etc.
-		if (getResolver() != null && uri != null)
-			directStream = getResolver().getURIStream(uri);
-		if (directStream != null) {
-			if (_debug) {
-				System.out.println("TLDCMDocumentManager loading taglib " + uri + " directly"); //$NON-NLS-2$//$NON-NLS-1$
-			}
-			return getCMDocumentBuilder().buildCMDocument(uri, directStream);
-		}
-
-		if (getResolver() != null && uri != null)
-			location = getResolver().getLocationByURI(uri);
-
-		//		String location =
-		// URIResolverPlugin.createResolver().resolve(getBaseLocation(), null,
-		// uri);
-
-		// Couldn't be located
-		if (location == null)
-			return null;
-		if (_debug) {
-			System.out.println("TLDCMDocumentManager loading taglib " + uri + " at " + location); //$NON-NLS-2$//$NON-NLS-1$
-		}
-		return getCMDocumentBuilder().createCMDocument(location);
-	}
-
-	/**
 	 * Loads the tags from the specified URI. It must point to a URL of valid
 	 * tag files to work.
 	 */
 	protected CMDocument loadTagDir(String uri) {
+		ITaglibRecord reference = TaglibIndex.resolve(getBaseLocation(), uri, false);
+		if (reference != null) {
+			CMDocument document = getCMDocumentBuilder().createCMDocument(reference);
+			if (document != null) {
+				return document;
+			}
+		}
 		// JSP2_TODO: implement for JSP 2.0
 		String location = URIResolverPlugin.createResolver().resolve(getBaseLocation(), null, uri);
 		if (location == null)
@@ -817,6 +766,19 @@
 		return getCMDocumentBuilder().createCMDocument(location);
 	}
 
+	/**
+	 * Loads the taglib from the specified URI. It must point to a valid
+	 * taglib descriptor or valid JAR file to work.
+	 */
+	protected CMDocument loadTaglib(String uri) {
+		CMDocument document = null;
+		ITaglibRecord reference = TaglibIndex.resolve(getBaseLocation(), uri, false);
+		if (reference != null) {
+			document = getCMDocumentBuilder().createCMDocument(reference);
+		}
+		return document;
+	}
+
 	protected void resetTaglibTrackers() {
 		if (_debug) {
 			System.out.println("TLDCMDocumentManager cleared its taglib trackers\n"); //$NON-NLS-1$
@@ -824,18 +786,11 @@
 		getTaglibTrackers().clear();
 	}
 
-	/**
-	 * Sets the resolverProvider.
-	 * 
-	 * @param resolverProvider
-	 *            The resolverProvider to set
-	 */
-	public void setResolverProvider(URIResolverProvider resolverProvider) {
-		fResolverProvider = resolverProvider;
-	}
-
 	public void setSourceParser(JSPSourceParser parser) {
+		if (fParser != null)
+			fParser.removeStructuredDocumentRegionHandler(getStructuredDocumentRegionHandler());
 		fParser = parser;
+		if (fParser != null)
+			fParser.addStructuredDocumentRegionHandler(getStructuredDocumentRegionHandler());
 	}
-
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TaglibSupport.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TaglibSupport.java
deleted file mode 100644
index b226ac8..0000000
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/contentmodel/tld/TaglibSupport.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 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.contentmodel.tld;
-
-
-
-import java.util.List;
-
-import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
-import org.eclipse.wst.sse.core.text.IStructuredDocument;
-
-public interface TaglibSupport {
-
-	void clearCMDocumentCache();
-
-	/**
-	 * Return the list of CMDocuments active after this offset.
-	 * Elements in the list are only required to implement 
-	 * CMDocument.	 
-	 */
-	List getCMDocuments(int offset);
-
-	/**
-	 * Return the list of CMDocuments active after this offset
-	 * and possessing the given prefix.  Elements in the list
-	 * are only required to implement CMDocument.
-	 */
-	List getCMDocuments(String prefix, int offset);
-
-	/**
-	 * Return the list of CMDocumentTrackers active after this offset.
-	 * Difference from the CMDocument method in that the objects
-	 * are trackers; exists as a formality.
-	 */
-	List getCMDocumentTrackers(int offset);
-
-	/**
-	 * Return the list of CMDocumentsTrackers active after this offset
-	 * and possessing the given prefix.  Different in that the List is
-	 * expected to contain tracker objects; exists as a formality.
-	 */
-	List getCMDocumentTrackers(String prefix, int offset);
-
-	/**
-	 * Return the first declaration found for the qualified tag
-	 * name using CMDocuments enabled for the given offset.
-	 */
-	CMElementDeclaration getDeclaration(String tagName, int offset);
-
-	IStructuredDocument getStructuredDocument();
-
-	void setStructuredDocument(IStructuredDocument model);
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/AbstractTaglibSupport.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/AbstractTaglibSupport.java
deleted file mode 100644
index 8bceac2..0000000
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/AbstractTaglibSupport.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 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.internal.contentmodel.tld;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jst.jsp.core.contentmodel.tld.TLDCMDocumentManager;
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.jst.jsp.core.internal.parser.JSPSourceParser;
-import org.eclipse.wst.common.contentmodel.CMDocument;
-import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
-import org.eclipse.wst.common.contentmodel.CMNamedNodeMap;
-import org.eclipse.wst.common.contentmodel.CMNode;
-import org.eclipse.wst.sse.core.contentmodel.CMDocumentTracker;
-import org.eclipse.wst.sse.core.parser.RegionParser;
-import org.eclipse.wst.sse.core.text.IStructuredDocument;
-import org.eclipse.wst.sse.core.util.Assert;
-
-public abstract class AbstractTaglibSupport implements TaglibSupport {
-	protected IStructuredDocument fm = null;
-	static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/taglibsupport")); //$NON-NLS-1$ //$NON-NLS-2$
-
-
-	protected TLDCMDocumentManager fTaglibMgr = null;
-
-	public AbstractTaglibSupport() {
-		super();
-	}
-
-	public void clearCMDocumentCache() {
-		getTaglibManager().clearCache();
-	}
-
-	public List getCMDocuments(int offset) {
-		return getCMDocumentTrackers(offset);
-	}
-
-	protected List getCMDocuments(List cmDocumentTrackers) {
-		List newList = new ArrayList();
-		if (cmDocumentTrackers != null)
-			for (int i = 0; i < cmDocumentTrackers.size(); i++)
-				newList.add(((CMDocumentTracker) cmDocumentTrackers.get(i)).getDocument());
-		return newList;
-	}
-
-	public List getCMDocuments(String prefix, int offset) {
-		return getCMDocumentTrackers(prefix, offset);
-	}
-
-	public List getCMDocumentTrackers(int offset) {
-		return getTaglibManager().getCMDocumentTrackers(offset);
-	}
-
-	public List getCMDocumentTrackers(String prefix, int offset) {
-		return getTaglibManager().getCMDocumentTrackers(prefix, offset);
-	}
-
-	/**
-	 * Helper method for accessing the content model
-	 */
-	public CMElementDeclaration getDeclaration(String tagName, int offset) {
-		// skip tagnames lacking a or starting with a ':'
-		if (tagName.indexOf(':') <= 0)
-			return null;
-		// determine the prefix
-		String prefix = tagName.substring(0, tagName.indexOf(':'));
-		// find the eligible CMDocuments (when valid, only one exists)
-		List docs = getCMDocuments(prefix, offset);
-		for (int i = 0; i < docs.size(); i++) {
-			CMDocument doc = (CMDocument) docs.get(i);
-			CMNamedNodeMap elementMap = doc.getElements();
-			if (elementMap == null)
-				continue;
-			CMNode decl = elementMap.getNamedItem(tagName);
-			if (decl != null)
-				return (CMElementDeclaration) decl;
-		}
-		return null;
-	}
-
-	public IStructuredDocument getStructuredDocument() {
-		return fm;
-	}
-
-	/**
-	 * Gets the taglibMgr.
-	 * @return Returns a TLDCMDocumentManager
-	 */
-	protected TLDCMDocumentManager getTaglibManager() {
-		if (fTaglibMgr == null)
-			fTaglibMgr = new TLDCMDocumentManager();
-		return fTaglibMgr;
-	}
-
-	protected List getTrackers() {
-		return getTaglibManager().getTaglibTrackers();
-	}
-
-	protected void hookParser() {
-		if (fm == null) {
-			getTaglibManager().setSourceParser(null);
-			return;
-		}
-		RegionParser parser = fm.getParser();
-		// support not possible without this parser; it supports getText() apart from the IStructuredDocument
-		Assert.isTrue(parser instanceof JSPSourceParser, "IStructuredDocument.getParser() must be a JSPSourceParser"); //$NON-NLS-1$
-		JSPSourceParser jspParser = (JSPSourceParser) parser;
-		getTaglibManager().setSourceParser(jspParser);
-		jspParser.addStructuredDocumentRegionHandler(getTaglibManager().getStructuredDocumentRegionHandler());
-	}
-
-	public void setStructuredDocument(IStructuredDocument m) {
-		if (_debug && !(m == null || fm == null)) {
-			System.out.println("AbstractTaglibSupport updated its IStructuredDocument instance");
-		}
-		unhookParser();
-		fm = m;
-		hookParser();
-	}
-
-	protected void unhookParser() {
-		if (fm == null)
-			return;
-		RegionParser parser = fm.getParser();
-		// support not possible without this parser; it supports getText() apart from the IStructuredDocument
-		Assert.isTrue(parser instanceof JSPSourceParser, "IStructuredDocument.getParser() must be a JSPSourceParser"); //$NON-NLS-1$
-		JSPSourceParser jspParser = (JSPSourceParser) parser;
-		getTaglibManager().setSourceParser(null);
-		jspParser.removeStructuredDocumentRegionHandler(getTaglibManager().getStructuredDocumentRegionHandler());
-	}
-
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DefaultTaglibSupport.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DefaultTaglibSupport.java
deleted file mode 100644
index 1b42c83..0000000
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DefaultTaglibSupport.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 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.internal.contentmodel.tld;
-
-
-
-import org.eclipse.jst.jsp.core.contentmodel.tld.URIResolverProvider;
-import org.eclipse.wst.sse.core.util.URIResolver;
-
-public class DefaultTaglibSupport extends AbstractTaglibSupport {
-
-	public DefaultTaglibSupport() {
-		super();
-	}
-
-	public URIResolver getResolver() {
-		if (getTaglibManager().getResolverProvider() == null)
-			return null;
-		return getTaglibManager().getResolverProvider().getResolver();
-	}
-
-	public void setResolver(URIResolver resolver) {
-		final URIResolver tldResolver = resolver;
-		getTaglibManager().setResolverProvider(new URIResolverProvider() {
-			public URIResolver getResolver() {
-				return tldResolver;
-			}
-		});
-	}
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DeferredTaglibSupport.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DeferredTaglibSupport.java
deleted file mode 100644
index ae0d42f..0000000
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/contentmodel/tld/DeferredTaglibSupport.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 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.internal.contentmodel.tld;
-
-import org.eclipse.jst.jsp.core.contentmodel.tld.URIResolverProvider;
-
-
-
-public class DeferredTaglibSupport extends AbstractTaglibSupport {
-
-	public URIResolverProvider getResolverProvider() {
-		return getTaglibManager().getResolverProvider();
-	}
-
-	public void setResolverProvider(URIResolverProvider provider) {
-		getTaglibManager().setResolverProvider(provider);
-	}
-}
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
index 19fe852..26e4b5c 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/JSPTranslator.java
@@ -35,10 +35,10 @@
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.Position;
 import org.eclipse.jst.jsp.core.Logger;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibController;
+import org.eclipse.jst.jsp.core.contentmodel.tld.TLDCMDocumentManager;
 import org.eclipse.jst.jsp.core.contentmodel.tld.TLDElementDeclaration;
 import org.eclipse.jst.jsp.core.contentmodel.tld.TLDVariable;
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
-import org.eclipse.jst.jsp.core.modelquery.TaglibModelQuery;
 import org.eclipse.wst.common.contentmodel.CMDocument;
 import org.eclipse.wst.common.contentmodel.CMNamedNodeMap;
 import org.eclipse.wst.common.contentmodel.CMNode;
@@ -534,9 +534,12 @@
 	 * @param tagToAdd is the name of the tag whose variables we want to add
 	 */
 	protected void addTaglibVariables(String tagToAdd) {
-		if (fModelQuery != null && fModelQuery instanceof TaglibModelQuery) {
+		if (fModelQuery != null) {
 			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=5159
-			Iterator taglibs = ((TaglibModelQuery) fModelQuery).getTaglibSupport().getCMDocuments(fCurrentNode.getStartOffset()).iterator();
+			TLDCMDocumentManager docMgr = TaglibController.getTLDCMDocumentManager(fStructuredDocument);
+			if (docMgr == null)
+				return;
+			Iterator taglibs = docMgr.getCMDocumentTrackers(fCurrentNode.getStartOffset()).iterator();
 			CMDocument doc = null;
 			CMNamedNodeMap elements = null;
 			while (taglibs.hasNext()) {
@@ -1257,9 +1260,9 @@
 	 */
 	protected void handleTaglib() {
 		// get/create TLDCMDocument
-		TaglibSupport tls = getTaglibSupport();
-		if (tls != null) {
-			List trackers = tls.getCMDocumentTrackers(getCurrentNode().getEnd());
+		TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(fStructuredDocument);
+		if (mgr != null) {
+			List trackers = mgr.getCMDocumentTrackers(getCurrentNode().getEnd());
 			Iterator it = trackers.iterator();
 			CMDocumentTracker tracker = null;
 			Iterator taglibRegions = null;
@@ -1889,10 +1892,6 @@
 		}
 	}
 
-	protected TaglibSupport getTaglibSupport() {
-		return (fModelQuery != null && fModelQuery instanceof TaglibModelQuery) ? ((TaglibModelQuery) fModelQuery).getTaglibSupport() : null;
-	}
-
 	final public int getCursorPosition() {
 		return fCursorPosition;
 	}
@@ -1912,6 +1911,10 @@
 	final public int getSourcePosition() {
 		return fSourcePosition;
 	}
+	
+	final public TLDCMDocumentManager getTLDCMDocumentManager() {
+		return TaglibController.getTLDCMDocumentManager(fStructuredDocument);
+	}
 
 	final public void setRelativeOffset(int fRelativeOffset) {
 		this.fRelativeOffset = fRelativeOffset;
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/XMLJSPRegionHelper.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/XMLJSPRegionHelper.java
index bf51392..07b5ca0 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/XMLJSPRegionHelper.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/internal/java/XMLJSPRegionHelper.java
@@ -258,7 +258,7 @@
 		else if (isTaglibDirective(fTagname)) {
 			// also add the ones created here to the parent document
 			String prefix = getAttributeValue("prefix", sdRegion); //$NON-NLS-1$
-			List docs = this.fTranslator.getTaglibSupport().getCMDocuments(prefix, this.fTranslator.getCurrentNode().getEnd());
+			List docs = this.fTranslator.getTLDCMDocumentManager().getCMDocumentTrackers(prefix, this.fTranslator.getCurrentNode().getEnd());
 			Iterator it = docs.iterator();
 			Iterator elements = null;
 			CMNode node = null;
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAdapterImpl.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAdapterImpl.java
index adf551c..d6a669f 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAdapterImpl.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAdapterImpl.java
@@ -12,7 +12,6 @@
 
 
 
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
 import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
 import org.eclipse.wst.common.contentmodel.util.CMDocumentCache;
 import org.eclipse.wst.sse.core.modelquery.ModelQueryAdapterImpl;
@@ -20,27 +19,7 @@
 
 
 public class JSPModelQueryAdapterImpl extends ModelQueryAdapterImpl {
-
-	TaglibSupport support = null;
-
-	public JSPModelQueryAdapterImpl(CMDocumentCache cmDocumentCache, ModelQuery modelQuery, TaglibSupport support, IdResolver idResolver) {
+	public JSPModelQueryAdapterImpl(CMDocumentCache cmDocumentCache, ModelQuery modelQuery, IdResolver idResolver) {
 		super(cmDocumentCache, modelQuery, idResolver);
-		this.support = support;
 	}
-
-	public void release() {
-		super.release();
-		if (support != null)
-			support.setStructuredDocument(null);
-	}
-
-	/**
-	 * @see com.ibm.sse.model.modelquery.ModelQueryAdapter#setIdResolver(IdResolver)
-	 */
-	public void setIdResolver(IdResolver newIdResolver) {
-		super.setIdResolver(newIdResolver);
-		// new location, everything's stale unless the model's been rebuilt
-		support.clearCMDocumentCache();
-	}
-
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAssociationProvider.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAssociationProvider.java
index 2b62aaa..d91bc64 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAssociationProvider.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryAssociationProvider.java
@@ -10,9 +10,6 @@
  *******************************************************************************/
 package org.eclipse.jst.jsp.core.modelquery;
 
-
-
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
 import org.eclipse.wst.common.contentmodel.modelqueryimpl.SimpleAssociationProvider;
 
 /**
@@ -20,9 +17,10 @@
 public class JSPModelQueryAssociationProvider extends SimpleAssociationProvider {
 
 	/**
-	 * @param modelQueryCMProvider org.eclipse.wst.common.contentmodel.modelquery.ModelQueryCMProvider
+	 * @param modelQueryCMProvider
+	 *            org.eclipse.wst.common.contentmodel.modelquery.ModelQueryCMProvider
 	 */
-	public JSPModelQueryAssociationProvider(TaglibSupport support) {
-		super(new JSPModelQueryCMProvider(support));
+	public JSPModelQueryAssociationProvider() {
+		super(new JSPModelQueryCMProvider());
 	}
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryCMProvider.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryCMProvider.java
index a14d84c..01c2612 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryCMProvider.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryCMProvider.java
@@ -15,11 +15,12 @@
 import java.util.List;
 
 import org.eclipse.jst.jsp.core.contentmodel.JSPCMDocumentFactory;
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibController;
+import org.eclipse.jst.jsp.core.contentmodel.tld.TLDCMDocumentManager;
 import org.eclipse.wst.common.contentmodel.CMDocument;
 import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
 import org.eclipse.wst.common.contentmodel.modelquery.ModelQueryCMProvider;
-import org.eclipse.wst.sse.core.IndexedRegion;
+import org.eclipse.wst.xml.core.document.XMLNode;
 import org.w3c.dom.Node;
 
 /**
@@ -27,19 +28,13 @@
  */
 public class JSPModelQueryCMProvider implements ModelQueryCMProvider {
 
-	protected TaglibSupport fTaglibSupport = null;
-
 	protected JSPModelQueryCMProvider() {
 		super();
 	}
 
-	public JSPModelQueryCMProvider(TaglibSupport taglibSupport) {
-		fTaglibSupport = taglibSupport;
-	}
-
 	/**
-	 * Returns the CMDocument that corresponds to the DOM Node.
-	 * or null if no CMDocument is appropriate for the DOM Node.
+	 * Returns the CMDocument that corresponds to the DOM Node. or null if no
+	 * CMDocument is appropriate for the DOM Node.
 	 */
 	public CMDocument getCorrespondingCMDocument(Node node) {
 		CMDocument jcmdoc = JSPCMDocumentFactory.getCMDocument();
@@ -49,19 +44,24 @@
 			if (node.getNodeType() == Node.ELEMENT_NODE) {
 				String elementName = node.getNodeName();
 
-				// test to see if this node belongs to JSP's CMDocument (case sensitive)
+				// test to see if this node belongs to JSP's CMDocument (case
+				// sensitive)
 				CMElementDeclaration dec = (CMElementDeclaration) jcmdoc.getElements().getNamedItem(elementName);
 				if (dec != null) {
 					result = jcmdoc;
 				}
 			}
 
-			if (result == null && fTaglibSupport != null && node instanceof IndexedRegion) {
+			if (result == null && node instanceof XMLNode) {
 				// check position dependent
-				IndexedRegion indexedNode = (IndexedRegion) node;
-				List documents = fTaglibSupport.getCMDocuments(node.getPrefix(), indexedNode.getStartOffset());
-				if (documents != null && documents.size() > 0)
-					result = (CMDocument) documents.get(0);
+				XMLNode xmlNode = (XMLNode) node;
+				TLDCMDocumentManager tldmgr = TaglibController.getTLDCMDocumentManager(xmlNode.getStructuredDocument());
+				if (tldmgr != null) {
+					List documents = tldmgr.getCMDocumentTrackers(node.getPrefix(), xmlNode.getStartOffset());
+					// there shouldn't be more than one cmdocument returned
+					if (documents != null && documents.size() > 0)
+						result = (CMDocument) documents.get(0);
+				}
 			}
 		}
 		catch (Exception e) {
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryImpl.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryImpl.java
index 4cdf4e5..2e92555 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryImpl.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/JSPModelQueryImpl.java
@@ -14,7 +14,6 @@
 import java.util.List;
 
 import org.eclipse.jst.jsp.core.PageDirectiveAdapter;
-import org.eclipse.jst.jsp.core.contentmodel.tld.TaglibSupport;
 import org.eclipse.wst.common.contentmodel.CMAttributeDeclaration;
 import org.eclipse.wst.common.contentmodel.CMDocument;
 import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
@@ -24,21 +23,17 @@
 import org.eclipse.wst.sse.core.INodeNotifier;
 import org.eclipse.wst.sse.core.IStructuredModel;
 import org.eclipse.wst.sse.core.modelquery.ModelQueryAdapter;
-import org.eclipse.wst.sse.core.modelquery.MovableModelQuery;
 import org.eclipse.wst.xml.uriresolver.util.IdResolver;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-public class JSPModelQueryImpl extends ModelQueryImpl implements MovableModelQuery, TaglibModelQuery {
+public class JSPModelQueryImpl extends ModelQueryImpl {
 
 	protected IStructuredModel jspModel = null;
 	protected ModelQuery embeddedModelQuery = null;
-	protected TaglibSupport fTaglibSupport = null;
-
-	public JSPModelQueryImpl(IStructuredModel model, TaglibSupport support, IdResolver resolver) {
-		super(new JSPModelQueryAssociationProvider(support));
-		fTaglibSupport = support;
+	public JSPModelQueryImpl(IStructuredModel model, IdResolver resolver) {
+		super(new JSPModelQueryAssociationProvider());
 		jspModel = model;
 	}
 
@@ -109,17 +104,6 @@
 		return this.embeddedModelQuery;
 	}
 
-	public TaglibSupport getTaglibSupport() {
-		return fTaglibSupport;
-	}
-
-	/**
-	 * @see MovableModelQuery#setIdResolver(IdResolver)
-	 */
-	public void setIdResolver(IdResolver newIdResolver) {
-		getTaglibSupport().clearCMDocumentCache();
-	}
-
 	/* (non-Javadoc)
 	 * @see org.eclipse.wst.common.contentmodel.modelquery.ModelQuery#getCMAttributeDeclaration(org.w3c.dom.Attr)
 	 */
diff --git a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/ModelQueryAdapterFactoryForJSP.java b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/ModelQueryAdapterFactoryForJSP.java
index d381b70..86c9b0d 100644
--- a/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/ModelQueryAdapterFactoryForJSP.java
+++ b/bundles/org.eclipse.jst.jsp.core/src/org/eclipse/jst/jsp/core/modelquery/ModelQueryAdapterFactoryForJSP.java
@@ -10,117 +10,25 @@
  *******************************************************************************/
 package org.eclipse.jst.jsp.core.modelquery;
 
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jst.jsp.core.contentmodel.tld.URIResolverProvider;
-import org.eclipse.jst.jsp.core.internal.contentmodel.tld.DeferredTaglibSupport;
 import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
 import org.eclipse.wst.common.contentmodel.util.CMDocumentCache;
 import org.eclipse.wst.sse.core.AbstractAdapterFactory;
 import org.eclipse.wst.sse.core.AdapterFactory;
-import org.eclipse.wst.sse.core.IModelLifecycleListener;
 import org.eclipse.wst.sse.core.IModelStateListener;
 import org.eclipse.wst.sse.core.INodeAdapter;
 import org.eclipse.wst.sse.core.INodeNotifier;
 import org.eclipse.wst.sse.core.IStructuredModel;
-import org.eclipse.wst.sse.core.ModelLifecycleEvent;
 import org.eclipse.wst.sse.core.modelquery.ModelQueryAdapter;
-import org.eclipse.wst.sse.core.text.IStructuredDocument;
 import org.eclipse.wst.sse.core.util.Debug;
-import org.eclipse.wst.sse.core.util.URIResolver;
 import org.eclipse.wst.xml.core.document.XMLNode;
 import org.eclipse.wst.xml.core.modelquery.XMLCatalogIdResolver;
 import org.eclipse.wst.xml.uriresolver.util.IdResolver;
 
 public class ModelQueryAdapterFactoryForJSP extends AbstractAdapterFactory implements IModelStateListener {
 
-	/**
-	 * This class ensures that the tabligSupport field is always connected to
-	 * the correct IDocument, should the IDocument in the Structured Model
-	 * change.
-	 */
-	protected class TaglibSupportModelLifecycleListener implements IModelLifecycleListener {
-		// had to change to 'false' when implicit job support added. 
-		// somehow, during document.set("") the wrong rule was in effect. 
-		// of course, we shouldn't being doing document set anyway, so
-		// would like to re-consider. (may not need for V6, with other 
-		// workarounds in place?)
-		private static final boolean doForceReloadOnDocumentChange = false;
-
-		public TaglibSupportModelLifecycleListener() {
-			if (stateNotifier != null) {
-				setDocument(stateNotifier.getStructuredDocument());
-			}
-		}
-
-		private void clearDocumentInformation() {
-			if (taglibSupport != null) {
-				taglibSupport.setStructuredDocument(null);
-				taglibSupport.clearCMDocumentCache();
-			}
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see com.ibm.sse.model.IModelLifecycleListener#processPostModelEvent(com.ibm.sse.model.ModelLifecycleEvent)
-		 */
-		public void processPostModelEvent(ModelLifecycleEvent event) {
-			if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {
-//				DocumentChanged documentChangedEvent = (DocumentChanged) event;
-//				IDocument oldDoc = documentChangedEvent.getOldDocument();
-//				IDocument newDoc = documentChangedEvent.getNewDocument();
-//				IDocument debugDoc = event.getModel().getStructuredDocument();
-				setDocument(event.getModel().getStructuredDocument());
-			}
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see com.ibm.sse.model.IModelLifecycleListener#processPreModelEvent(com.ibm.sse.model.ModelLifecycleEvent)
-		 */
-		public void processPreModelEvent(ModelLifecycleEvent event) {
-			if (event.getType() == ModelLifecycleEvent.MODEL_DOCUMENT_CHANGED) {
-				clearDocumentInformation();
-			}
-		}
-
-		/**
-		 * @param event
-		 */
-		private void setDocument(IStructuredDocument document) {
-			if (taglibSupport != null) {
-				taglibSupport.setStructuredDocument(document);
-				// force the reparsing of the IDocument so that taglibs
-				// can be recorded and enabled; while this is expensive,
-				// the lack of control over document and model creation
-				// makes it necessary
-				if (doForceReloadOnDocumentChange && document.getLength() > 0) {
-					String contents = document.get();
-					// don't allow any optimizations to be used
-					document.set(""); //$NON-NLS-1$
-					document.set(contents);
-				}
-			}
-		}
-	}
-
-	protected TaglibSupportModelLifecycleListener fTaglibSupportModelLifecycleListener = null;
-
 	protected JSPModelQueryAdapterImpl modelQueryAdapterImpl;
 
-	// delay providing a URIResolver to the taglib support
-	protected URIResolverProvider resolverProvider = new URIResolverProvider() {
-		public URIResolver getResolver() {
-			if (stateNotifier != null)
-				return stateNotifier.getResolver();
-			return null;
-		}
-	};
 	protected IStructuredModel stateNotifier = null;
-	protected DeferredTaglibSupport taglibSupport = null;
-
-	static final boolean _debug = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/taglibsupport")); //$NON-NLS-1$ //$NON-NLS-2$
 
 	public ModelQueryAdapterFactoryForJSP() {
 		this(ModelQueryAdapter.class, true);
@@ -134,8 +42,8 @@
 	 * @param registerAdapters
 	 *            boolean
 	 */
-	public ModelQueryAdapterFactoryForJSP(Object adapterKey, boolean registerAdapters) {
-		super(adapterKey, registerAdapters);
+	public ModelQueryAdapterFactoryForJSP(Object key, boolean registerAdapters) {
+		super(key, registerAdapters);
 	}
 
 	public AdapterFactory copy() {
@@ -157,20 +65,9 @@
 				CMDocumentCache cmDocumentCache = new CMDocumentCache();
 				IdResolver resolver = new XMLCatalogIdResolver(model.getBaseLocation(), model.getResolver());
 
-				// connect the taglib support package to this model, deferring
-				// the URIResolver requirement
-				taglibSupport = new DeferredTaglibSupport();
-				taglibSupport.setStructuredDocument(model.getStructuredDocument());
-				taglibSupport.setResolverProvider(resolverProvider);
-				fTaglibSupportModelLifecycleListener = new TaglibSupportModelLifecycleListener();
-				model.addModelLifecycleListener(fTaglibSupportModelLifecycleListener);
-
-				ModelQuery modelQuery = new JSPModelQueryImpl(model, taglibSupport, resolver);
+				ModelQuery modelQuery = new JSPModelQueryImpl(model, resolver);
 				modelQuery.setEditMode(ModelQuery.EDIT_MODE_UNCONSTRAINED);
-				modelQueryAdapterImpl = new JSPModelQueryAdapterImpl(cmDocumentCache, modelQuery, taglibSupport, resolver);
-				if(_debug) {
-					System.out.println("ModelQueryAdapterFactoryForJSP.createAdapter registered Taglib Support for model with ID " + model.getId() + " at " + model.getBaseLocation()); //$NON-NLS-2$ //$NON-NLS-1$
-				}
+				modelQueryAdapterImpl = new JSPModelQueryAdapterImpl(cmDocumentCache, modelQuery, resolver);
 			}
 		}
 		return modelQueryAdapterImpl;
@@ -226,12 +123,7 @@
 	}
 
 	protected void updateResolver(IStructuredModel model) {
-		/**
-		 * The taglib support will automatically use the new one, so trigger a
-		 * reparse
-		 */
 		modelQueryAdapterImpl.setIdResolver(new XMLCatalogIdResolver(model.getBaseLocation(), model.getResolver()));
-		fTaglibSupportModelLifecycleListener.setDocument(model.getStructuredDocument());
 	}
 
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
index 0ad57f6..f978986 100644
--- a/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
+++ b/bundles/org.eclipse.jst.jsp.ui/src/org/eclipse/jst/jsp/ui/internal/contentassist/JSPContentAssistProcessor.java
@@ -35,9 +35,10 @@
 import org.eclipse.jst.jsp.core.JSP11Namespace;
 import org.eclipse.jst.jsp.core.JSP12Namespace;
 import org.eclipse.jst.jsp.core.PageDirectiveAdapter;
+import org.eclipse.jst.jsp.core.contentmodel.TaglibController;
+import org.eclipse.jst.jsp.core.contentmodel.tld.TLDCMDocumentManager;
 import org.eclipse.jst.jsp.core.document.PageDirectiveAdapterFactory;
 import org.eclipse.jst.jsp.core.internal.text.rules.StructuredTextPartitionerForJSP;
-import org.eclipse.jst.jsp.core.modelquery.TaglibModelQuery;
 import org.eclipse.jst.jsp.ui.internal.Logger;
 import org.eclipse.wst.common.contentmodel.CMDocument;
 import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
@@ -322,8 +323,9 @@
 						// Be sure that custom tags from taglibs also show up
 						// by
 						// adding taglib declarations to the internal model.
-						if (mq instanceof TaglibModelQuery) {
-							List trackers = ((TaglibModelQuery) mq).getTaglibSupport().getCMDocumentTrackers(contentAssistRequest.getReplacementBeginPosition());
+						TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(xmlOuterModel.getStructuredDocument());
+						if (mgr != null) {
+							List trackers = mgr.getCMDocumentTrackers(contentAssistRequest.getReplacementBeginPosition());
 							if (trackers != null) {
 								for (i = 0; i < trackers.size(); i++) {
 									CMDocumentTracker tracker = (CMDocumentTracker) trackers.get(i);
@@ -467,9 +469,9 @@
 			else
 				mqAdapter = (ModelQueryAdapter) ((XMLNode) node.getOwnerDocument()).getAdapterFor(ModelQueryAdapter.class);
 			if (mqAdapter != null) {
-				ModelQuery query = mqAdapter.getModelQuery();
-				if (query instanceof TaglibModelQuery) {
-					List moreCMDocuments = ((TaglibModelQuery) query).getTaglibSupport().getCMDocuments(textInsertionOffset);
+				TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(((XMLNode) node).getStructuredDocument());
+				if (mgr != null) {
+					List moreCMDocuments = mgr.getCMDocumentTrackers(textInsertionOffset);
 					if (moreCMDocuments != null) {
 						for (int i = 0; i < moreCMDocuments.size(); i++) {
 							CMDocument doc = (CMDocument) moreCMDocuments.get(i);