support taglibrecord add/remove events from the index
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
index 7309446..9728d37 100644
--- 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
@@ -107,6 +107,24 @@
 		}
 	}
 
+	class TaglibRecordEvent implements ITaglibRecordEvent {
+		ITaglibRecord fTaglibRecord = null;
+		short fType = -1;
+
+		TaglibRecordEvent(ITaglibRecord record, short type) {
+			fTaglibRecord = record;
+			fType = type;
+		}
+
+		public ITaglibRecord getTaglibRecord() {
+			return fTaglibRecord;
+		}
+
+		public short getType() {
+			return fType;
+		}
+	}
+
 	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"));
 
@@ -175,6 +193,7 @@
 				}
 			}
 		}
+		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(jarRecord, ITaglibRecordEvent.ADD));
 	}
 
 	void addServlets(IResource webxml) {
@@ -228,6 +247,7 @@
 			if (_debugIndexCreation)
 				System.out.println("created record for " + uri + "@" + record.location);
 		}
+		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(servletRecord, ITaglibRecordEvent.ADD));
 	}
 
 	void addTagDir(IResource tagFile) {
@@ -253,6 +273,7 @@
 		if (record.uri != null) {
 			getImplicitReferences(tld.getLocation().toString()).put(record.uri, record);
 		}
+		TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.ADD));
 	}
 
 	void clear() {
@@ -389,14 +410,6 @@
 
 	/**
 	 * @param baseLocation
-	 * @return
-	 */
-	private String getLocalRoot(String baseLocation) {
-		return getLocalRoot(new Path(baseLocation)).toString();
-	}
-
-	/**
-	 * @param baseLocation
 	 * @return the applicable Web context root path, if one exists
 	 */
 	IPath getLocalRoot(IPath baseLocation) {
@@ -427,6 +440,14 @@
 	}
 
 	/**
+	 * @param baseLocation
+	 * @return
+	 */
+	private String getLocalRoot(String baseLocation) {
+		return getLocalRoot(new Path(baseLocation)).toString();
+	}
+
+	/**
 	 * @return Returns the visitor.
 	 */
 	IResourceDeltaVisitor getVisitor() {
@@ -477,6 +498,7 @@
 			for (int i = 0; i < records.length; i++) {
 				getImplicitReferences(jar.getLocation().toString()).remove(records[i].getURI());
 			}
+			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
 		}
 	}
 
@@ -491,6 +513,7 @@
 					System.out.println("removed record for " + records[i].uri + "@" + records[i].location);
 				getImplicitReferences(webxml.getLocation().toString()).remove(records[i].getURI());
 			}
+			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
 		}
 	}
 
@@ -504,8 +527,11 @@
 		if (_debugIndexCreation)
 			System.out.println("removing record for " + tld.getFullPath());
 		TLDRecord record = (TLDRecord) fTLDReferences.remove(tld.getFullPath());
-		if (record != null && record.uri != null) {
-			getImplicitReferences(tld.getLocation().toString()).remove(record.uri);
+		if (record != null) {
+			if (record.uri != null) {
+				getImplicitReferences(tld.getLocation().toString()).remove(record.uri);
+			}
+			TaglibIndex.fireTaglibRecordEvent(new TaglibRecordEvent(record, ITaglibRecordEvent.REMOVE));
 		}
 	}
 
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
index d1b1514..102c83e 100644
--- 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
@@ -12,6 +12,8 @@
 package org.eclipse.jst.jsp.core.contentmodel;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -31,10 +33,16 @@
 import org.eclipse.wst.xml.uriresolver.util.URIHelper;
 
 /**
- * @author nsd
+ * @author nitin
  * 
  * A non-extendable index manager for taglibs similar to the J2EE
  * ITaglibRegistry but lacking any ties to project natures.
+ * 
+ * Indexing is not persisted between sessions, so new ADD events will be sent
+ * to ITaglibIndexListeners during each workbench session. REMOVE events are
+ * not fired on workbench shutdown. Events for TAGDIR, JAR, and WEBXML type
+ * records are only fired for the .jar and web.xml file itself. The record's
+ * contents should be examined for any further information.
  */
 public class TaglibIndex {
 
@@ -109,6 +117,16 @@
 	}
 
 	public static void addTaglibIndexListener(ITaglibIndexListener listener) {
+		_instance.internalAddTaglibIndexListener(listener);
+	}
+
+	static void fireTaglibRecordEvent(ITaglibRecordEvent event) {
+		ITaglibIndexListener[] listeners = _instance.fTaglibIndexListeners;
+		if (listeners != null) {
+			for (int i = 0; i < listeners.length; i++) {
+				listeners[i].indexChanged(event);
+			}
+		}
 	}
 
 	/**
@@ -128,6 +146,7 @@
 	}
 
 	public static void removeTaglibIndexListener(ITaglibIndexListener listener) {
+		_instance.internalRemoveTaglibIndexListener(listener);
 	}
 
 	public static ITaglibRecord resolve(String baseLocation, String reference, boolean crossProjects) {
@@ -137,6 +156,8 @@
 	Map fProjectDescriptions;
 	private ResourceChangeListener fResourceChangeListener;
 
+	private ITaglibIndexListener[] fTaglibIndexListeners = null;
+
 	private TaglibIndex() {
 		super();
 		fResourceChangeListener = new ResourceChangeListener();
@@ -158,6 +179,17 @@
 		return description;
 	}
 
+	private synchronized void internalAddTaglibIndexListener(ITaglibIndexListener listener) {
+		if (fTaglibIndexListeners == null) {
+			fTaglibIndexListeners = new ITaglibIndexListener[]{listener};
+		}
+		else {
+			List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners));
+			listeners.add(listener);
+			fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]);
+		}
+	}
+
 	private ITaglibRecord[] internalGetAvailableTaglibRecords(IPath location) {
 		ITaglibRecord[] records = null;
 		IFile baseResource = ResourcesPlugin.getWorkspace().getRoot().getFile(location);
@@ -190,6 +222,14 @@
 		return root;
 	}
 
+	private synchronized void internalRemoveTaglibIndexListener(ITaglibIndexListener listener) {
+		if (fTaglibIndexListeners != null) {
+			List listeners = new ArrayList(Arrays.asList(fTaglibIndexListeners));
+			listeners.remove(listener);
+			fTaglibIndexListeners = (ITaglibIndexListener[]) listeners.toArray(new ITaglibIndexListener[0]);
+		}
+	}
+
 	private ITaglibRecord internalResolve(String baseLocation, String reference, boolean crossProjects) {
 		IProject project = null;
 		ITaglibRecord resolved = null;