/*******************************************************************************
 * Copyright (c) 2004, 2010 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.taglib;


import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.jsp.tagext.TagAttributeInfo;
import javax.servlet.jsp.tagext.TagData;
import javax.servlet.jsp.tagext.TagExtraInfo;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import javax.servlet.jsp.tagext.ValidationMessage;
import javax.servlet.jsp.tagext.VariableInfo;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsp.core.internal.JSPCoreMessages;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TLDCMDocumentManager;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TaglibTracker;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDAttributeDeclaration;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDVariable;
import org.eclipse.jst.jsp.core.internal.java.IJSPProblem;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.util.AbstractMemoryListener;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMNodeWrapper;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.osgi.service.event.Event;

import com.ibm.icu.text.MessageFormat;

/**
 * This class helps find TaglibVariables in a JSP file.
 */
public class TaglibHelper {

	private static final String ITERATION_QUALIFIER = "javax.servlet.jsp.tagext"; //$NON-NLS-1$
	private static final String ITERATION_NAME = "IterationTag"; //$NON-NLS-1$
	
	// for debugging
	private static final boolean DEBUG;
	static {
		String value = Platform.getDebugOption("org.eclipse.jst.jsp.core/debug/taglibvars"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}

	private IProject fProject = null;
	private ClassLoader fLoader = null;

	private IJavaProject fJavaProject;
	
	/**
	 * A cache of class names that the class loader could not find.
	 * Because the TaglibHelper is destroyed and recreated whenever
	 * the classpath changes this cache will not become stale
	 */
	private Set fNotFoundClasses = null;

	private Map fClassMap = null;

	/**
	 * Used to keep the {@link #fNotFoundClasses} cache clean when memory is low
	 */
	private MemoryListener fMemoryListener;

	public TaglibHelper(IProject project) {
		super();
		setProject(project);
		fMemoryListener = new MemoryListener();
		fMemoryListener.connect();
		fNotFoundClasses = new HashSet();
		fClassMap = Collections.synchronizedMap(new HashMap());
	}

	/**
	 * Checks that <code>type</code> implements an IterationTag
	 * 
	 * @param type
	 * @return true if <code>type</code> implements IterationTag
	 * @throws JavaModelException
	 * @throws ClassNotFoundException thrown when the <code>type</code> is null
	 */
	private boolean isIterationTag(IType type) throws JavaModelException, ClassNotFoundException {
		if (type == null) {
			throw new ClassNotFoundException();
		}
		synchronized (fClassMap) {
			if (fClassMap.containsKey(type.getFullyQualifiedName()))
				return ((Boolean) fClassMap.get(type.getFullyQualifiedName())).booleanValue();
		}

		String signature;
		String qualifier;
		String name;
		String[] interfaces = type.getSuperInterfaceTypeSignatures();
		boolean isIteration = false;
		// Check any super interfaces for the iteration tag
		for (int i = 0; i < interfaces.length; i++) {
			// For source files, the interface may need to be resolved
			String erasureSig = Signature.getTypeErasure(interfaces[i]);
			qualifier = Signature.getSignatureQualifier(erasureSig);
			name = Signature.getSignatureSimpleName(erasureSig);
			// Interface type is unresolved
			if (erasureSig.charAt(0) == Signature.C_UNRESOLVED) {
				String[][] types = type.resolveType(getQualifiedType(qualifier, name));
				// Type was resolved
				if (types != null && types.length > 0) {
					isIteration = handleInterface(type, types[0][0], types[0][1]);
				}
			}
			else {
				isIteration = handleInterface(type, qualifier, name);
			}
			if (isIteration)
				return true;
		}

		signature = type.getSuperclassTypeSignature();
		if (signature != null) {
			String erasureSig = Signature.getTypeErasure(signature);
			qualifier = Signature.getSignatureQualifier(erasureSig);
			name = Signature.getSignatureSimpleName(erasureSig);
			// superclass was unresolved
			if (erasureSig.charAt(0) == Signature.C_UNRESOLVED) {
				String[][] types = type.resolveType(getQualifiedType(qualifier, name));
				// Type was resolved
				if (types != null && types.length > 0) {
					isIteration = isIterationTag(fJavaProject.findType(types[0][0], types[0][1]));
				}
			}
			else {
				isIteration = isIterationTag(fJavaProject.findType(qualifier, name));
			}
		}
		fClassMap.put(type.getFullyQualifiedName(), Boolean.valueOf(isIteration));
		return isIteration;
	}

	private boolean handleInterface(IType type, String qualifier, String name) throws JavaModelException, ClassNotFoundException {
		boolean isIteration = false;
		// Qualified interface is an iteration tag
		if (ITERATION_QUALIFIER.equals(qualifier) && ITERATION_NAME.equals(name))
			isIteration = true;
		// Check ancestors of this interface
		else
			isIteration = isIterationTag(fJavaProject.findType(qualifier, name));

		fClassMap.put(type.getFullyQualifiedName(), Boolean.valueOf(isIteration));
		return isIteration;
	}

	private String getQualifiedType(String qualifier, String name) {
		StringBuffer qual = new StringBuffer(qualifier);
		if (qual.length() > 0)
			qual.append('.');
		qual.append(name);
		return qual.toString();
	}

	private boolean isIterationTag(TLDElementDeclaration elementDecl, IStructuredDocument document, ITextRegionCollection customTag, List problems) {
		String className = elementDecl.getTagclass();
		if (className == null || className.length() == 0 || fProject == null || fNotFoundClasses.contains(className))
			return false;

		try {
			synchronized (fClassMap) {
				if (fClassMap.containsKey(className))
					return ((Boolean) fClassMap.get(className)).booleanValue();
			}
			return isIterationTag(fJavaProject.findType(className));
		} catch (ClassNotFoundException e) {
			//the class could not be found so add it to the cache
			fNotFoundClasses.add(className);

			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TagClassNotFound, JSPCoreMessages.TaglibHelper_3, className, true);
			if (createdProblem != null)
				problems.add(createdProblem);
			if (DEBUG)
				Logger.logException(className, e);
		} catch (JavaModelException e) {
			if (DEBUG)
				Logger.logException(className, e);
		} catch (Exception e) {
			// this is 3rd party code, need to catch all errors
			if (DEBUG)
				Logger.logException(className, e);
		} catch (Error e) {
			// this is 3rd party code, need to catch all errors
			if (DEBUG)
				Logger.logException(className, e);
		}

		return false;
	}

	public CustomTag getCustomTag(String tagToAdd, IStructuredDocument structuredDoc, ITextRegionCollection customTag, List problems) {
		List results = new ArrayList();
		boolean isIterationTag = false;
		String tagClass = null;
		String teiClass = null;
		if (problems == null)
			problems = new ArrayList();
		ModelQuery mq = getModelQuery(structuredDoc);
		if (mq != null) {
			TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(structuredDoc);

			if (mgr != null) {

				List trackers = mgr.getCMDocumentTrackers(-1);
				Iterator taglibs = trackers.iterator();
	
				CMDocument doc = null;
				CMNamedNodeMap elements = null;
				while (taglibs.hasNext()) {
					doc = (CMDocument) taglibs.next();
					CMNode node = null;
					if ((elements = doc.getElements()) != null && (node = elements.getNamedItem(tagToAdd)) != null && node.getNodeType() == CMNode.ELEMENT_DECLARATION) {
	
						if (node instanceof CMNodeWrapper) {
							node = ((CMNodeWrapper) node).getOriginNode();
						}
						TLDElementDeclaration tldElementDecl = (TLDElementDeclaration) node;

						tagClass = tldElementDecl.getTagclass();
						teiClass = tldElementDecl.getTeiclass();
						isIterationTag = isIterationTag(tldElementDecl, structuredDoc, customTag, problems);
						/*
						 * Although clearly not the right place to add validation
						 * design-wise, this is the first time we have the
						 * necessary information to validate the tag class.
						 */
						validateTagClass(structuredDoc, customTag, tldElementDecl, problems);
	
						// 1.2+ taglib style
						addVariables(results, node, customTag);
	
						// for 1.1 need more info from taglib tracker
						if (doc instanceof TaglibTracker) {
							String uri = ((TaglibTracker) doc).getURI();
							String prefix = ((TaglibTracker) doc).getPrefix();
							// only for 1.1 taglibs
							addTEIVariables(structuredDoc, customTag, results, tldElementDecl, prefix, uri, problems);
						}
						break;
					}
				}
			}
		}

		return new CustomTag(tagToAdd, tagClass, teiClass, (TaglibVariable[]) results.toArray(new TaglibVariable[results.size()]), isIterationTag);
	}
	/**
	 * @param tagToAdd
	 *            is the name of the tag whose variables we want
	 * @param structuredDoc
	 *            is the IStructuredDocument where the tag is found
	 * @param customTag
	 *            is the IStructuredDocumentRegion opening tag for the custom
	 *            tag
	 * @param problems problems that are generated while creating variables are added to this collection
	 */
	public TaglibVariable[] getTaglibVariables(String tagToAdd, IStructuredDocument structuredDoc, ITextRegionCollection customTag, List problems) {

		List results = new ArrayList();
		if (problems == null)
			problems = new ArrayList();
		ModelQuery mq = getModelQuery(structuredDoc);
		if (mq != null) {
			TLDCMDocumentManager mgr = TaglibController.getTLDCMDocumentManager(structuredDoc);

			// TaglibSupport support = ((TaglibModelQuery)
			// mq).getTaglibSupport();
			if (mgr == null)
				return new TaglibVariable[0];

			List trackers = mgr.getCMDocumentTrackers(-1);
			Iterator taglibs = trackers.iterator();

			// TaglibSupport support = ((TaglibModelQuery)
			// mq).getTaglibSupport();
			// if (support == null)
			// return new TaglibVariable[0];
			//
			// Iterator taglibs =
			// support.getCMDocuments(customTag.getStartOffset()).iterator();
			CMDocument doc = null;
			CMNamedNodeMap elements = null;
			while (taglibs.hasNext()) {
				doc = (CMDocument) taglibs.next();
				CMNode node = null;
				if ((elements = doc.getElements()) != null && (node = elements.getNamedItem(tagToAdd)) != null && node.getNodeType() == CMNode.ELEMENT_DECLARATION) {

					if (node instanceof CMNodeWrapper) {
						node = ((CMNodeWrapper) node).getOriginNode();
					}
					TLDElementDeclaration tldElementDecl = (TLDElementDeclaration) node;

					/*
					 * Although clearly not the right place to add validation
					 * design-wise, this is the first time we have the
					 * necessary information to validate the tag class.
					 */
					validateTagClass(structuredDoc, customTag, tldElementDecl, problems);

					// 1.2+ taglib style
					addVariables(results, node, customTag);

					// for 1.1 need more info from taglib tracker
					if (doc instanceof TaglibTracker) {
						String uri = ((TaglibTracker) doc).getURI();
						String prefix = ((TaglibTracker) doc).getPrefix();
						// only for 1.1 taglibs
						addTEIVariables(structuredDoc, customTag, results, tldElementDecl, prefix, uri, problems);
					}
				}
			}
		}

		return (TaglibVariable[]) results.toArray(new TaglibVariable[results.size()]);
	}

	/**
	 * Adds 1.2 style TaglibVariables to the results list.
	 * 
	 * @param results
	 *            list where the <code>TaglibVariable</code> s are added
	 * @param node
	 */
	private void addVariables(List results, CMNode node, ITextRegionCollection customTag) {
		List list = ((TLDElementDeclaration) node).getVariables();
		Iterator it = list.iterator();
		while (it.hasNext()) {
			TLDVariable var = (TLDVariable) it.next();
			if (!var.getDeclare())
				continue;

			String varName = var.getNameGiven();
			if (varName == null) {
				// 2.0
				varName = var.getAlias();
			}
			if (varName == null) {
				String attrName = var.getNameFromAttribute();
				/*
				 * Iterate through the document region to find the
				 * corresponding attribute name, and then use its value
				 */
				ITextRegionList regions = customTag.getRegions();
				boolean attrNameFound = false;
				for (int i = 2; i < regions.size(); i++) {
					ITextRegion region = regions.get(i);
					if (DOMRegionContext.XML_TAG_ATTRIBUTE_NAME.equals(region.getType())) {
						attrNameFound = attrName.equals(customTag.getText(region));
					}
					if (attrNameFound && DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE.equals(region.getType())) {
						varName = StringUtils.strip(customTag.getText(region));
					}
				}
			}
			if (varName != null) {
				String varClass = "java.lang.String"; // the default
				// class...//$NON-NLS-1$
				if (var.getVariableClass() != null) {
					varClass = var.getVariableClass();
				}
				results.add(new TaglibVariable(varClass, varName, var.getScope(), var.getDescription()));
			}
		}
	}

	/**
	 * Adds 1.1 style TaglibVariables (defined in a TagExtraInfo class) to the
	 * results list. Also reports problems with the tag and tei classes in
	 * fTranslatorProblems.
	 * 
	 * @param customTag
	 * @param results
	 *            list where the <code>TaglibVariable</code> s are added
	 * @param decl
	 *            TLDElementDeclaration for the custom tag
	 * @param prefix
	 *            custom tag prefix
	 * @param uri
	 *            URI where the tld can be found
	 */
	private void addTEIVariables(IStructuredDocument document, ITextRegionCollection customTag, List results, TLDElementDeclaration decl, String prefix, String uri, List problems) {
		String teiClassname = decl.getTeiclass();
		if (teiClassname == null || teiClassname.length() == 0 || fJavaProject == null || fNotFoundClasses.contains(teiClassname))
			return;

		ClassLoader loader = getClassloader();

		Class teiClass = null;
		try {
			/*
			 * JDT could tell us about it, but loading and calling it would
			 * still take time
			 */
			teiClass = Class.forName(teiClassname, true, loader);
			if (teiClass != null) {
				Object teiObject = teiClass.newInstance();
				if (TagExtraInfo.class.isInstance(teiObject)) {
					TagExtraInfo tei = (TagExtraInfo) teiObject;
					Hashtable tagDataTable = extractTagData(customTag);
					TagInfo info = getTagInfo(decl, tei, prefix, uri);
					if (info != null) {
						tei.setTagInfo(info);

						// add to results
						TagData td = new TagData(tagDataTable);

						VariableInfo[] vInfos = tei.getVariableInfo(td);
						if (vInfos != null) {
							for (int i = 0; i < vInfos.length; i++) {
								results.add(new TaglibVariable(vInfos[i].getClassName(), vInfos[i].getVarName(), vInfos[i].getScope(), decl.getDescription()));
							}
						}

						ValidationMessage[] messages = tei.validate(td);
						if (messages != null && messages.length > 0) {
							for (int i = 0; i < messages.length; i++) {
								Object createdProblem = createValidationMessageProblem(document, customTag, messages[i].getMessage());
								if (createdProblem != null) {
									problems.add(createdProblem);
								}
							}
						}
					}
				}
				else {
					Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TEIClassMisc, JSPCoreMessages.TaglibHelper_2, teiClassname, true);
					if (createdProblem != null) {
						problems.add(createdProblem);
					}
					// this is 3rd party code, need to catch all exceptions
					if (DEBUG) {
						Logger.log(Logger.WARNING, teiClassname + " is not a subclass of TaxExtraInfo"); //$NON-NLS-1$ 
					}
				}
			}
		}
		catch (ClassNotFoundException e) {
			//the class could not be found so add it to the cache
			fNotFoundClasses.add(teiClassname);

			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TEIClassNotFound, JSPCoreMessages.TaglibHelper_0, teiClassname, true);
			if (createdProblem != null) {
				problems.add(createdProblem);
			}
			// TEI class wasn't on build path
			if (DEBUG)
				logException(teiClassname, e);
		}
		catch (InstantiationException e) {
			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TEIClassNotInstantiated, JSPCoreMessages.TaglibHelper_1, teiClassname, true);
			if (createdProblem != null) {
				problems.add(createdProblem);
			}
			// TEI class couldn't be instantiated
			if (DEBUG)
				logException(teiClassname, e);
		}
		catch (IllegalAccessException e) {
			if (DEBUG)
				logException(teiClassname, e);
		}
		// catch (ClassCastException e) {
		// // TEI class wasn't really a subclass of TagExtraInfo
		// if (DEBUG)
		// logException(teiClassname, e);
		// }
		catch (Exception e) {
			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TEIClassMisc, JSPCoreMessages.TaglibHelper_2, teiClassname, true);
			if (createdProblem != null) {
				problems.add(createdProblem);
			}
			// this is 3rd party code, need to catch all exceptions
			if (DEBUG)
				logException(teiClassname, e);
		}
		catch (Error e) {
			// this is 3rd party code, need to catch all errors
			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TEIClassNotInstantiated, JSPCoreMessages.TaglibHelper_1, teiClassname, true);
			if (createdProblem != null) {
				problems.add(createdProblem);
			}
			if (DEBUG)
				logException(teiClassname, e);
		}
		finally {
			// Thread.currentThread().setContextClassLoader(oldLoader);
		}
	}

	/**
	 * @param customTag
	 * @param teiClass
	 * @return
	 */
	private Object createJSPProblem(final IStructuredDocument document, final ITextRegionCollection customTag, final int problemID, final String messageKey, final String argument, boolean preferVars) {
		final String tagname = customTag.getText(customTag.getRegions().get(1));

		final int start;
		if (customTag.getNumberOfRegions() > 1) {
			start = customTag.getStartOffset(customTag.getRegions().get(1));
		}
		else {
			start = customTag.getStartOffset();
		}

		final int end;
		if (customTag.getNumberOfRegions() > 1) {
			end = customTag.getTextEndOffset(customTag.getRegions().get(1)) - 1;
		}
		else {
			end = customTag.getTextEndOffset() - 1;
		}

		final int line = document.getLineOfOffset(start);

		final char[] name;
		IPath location = TaglibController.getLocation(document);
		if (location == null) {
			name = new char[0];
		}
		else {
			name = location.toString().toCharArray();
		}

		/*
		 * Note: these problems would result in translation errors on the
		 * server, so the severity is not meant to be controllable
		 */
		return new IJSPProblem() {
			public void setSourceStart(int sourceStart) {
			}

			public void setSourceLineNumber(int lineNumber) {
			}

			public void setSourceEnd(int sourceEnd) {
			}

			public boolean isWarning() {
				return false;
			}

			public boolean isError() {
				return true;
			}

			public int getSourceStart() {
				return start;
			}

			public int getSourceLineNumber() {
				return line;
			}

			public int getSourceEnd() {
				return end;
			}

			public char[] getOriginatingFileName() {
				return name;
			}

			public String getMessage() {
				return MessageFormat.format(messageKey, new String[]{tagname, argument});
			}

			public int getID() {
				return problemID;
			}

			public String[] getArguments() {
				return new String[0];
			}

			public int getEID() {
				return problemID;
			}
		};
	}

	/**
	 * @param customTag
	 * @param validationMessage
	 * @return
	 */
	private Object createValidationMessageProblem(final IStructuredDocument document, final ITextRegionCollection customTag, final String validationMessage) {
		final int start;
		if (customTag.getNumberOfRegions() > 3) {
			start = customTag.getStartOffset(customTag.getRegions().get(2));
		}
		else if (customTag.getNumberOfRegions() > 1) {
			start = customTag.getStartOffset(customTag.getRegions().get(1));
		}
		else {
			start = customTag.getStartOffset();
		}

		final int end;
		if (customTag.getNumberOfRegions() > 3) {
			end = customTag.getTextEndOffset(customTag.getRegions().get(customTag.getNumberOfRegions() - 2)) - 1;
		}
		else if (customTag.getNumberOfRegions() > 1) {
			end = customTag.getTextEndOffset(customTag.getRegions().get(1)) - 1;
		}
		else {
			end = customTag.getTextEndOffset();
		}

		final int line = document.getLineOfOffset(start);

		final char[] name;
		IPath location = TaglibController.getLocation(document);
		if (location == null) {
			name = new char[0];
		}
		else {
			name = location.toString().toCharArray();
		}

		return new IJSPProblem() {
			public void setSourceStart(int sourceStart) {
			}

			public void setSourceLineNumber(int lineNumber) {
			}

			public void setSourceEnd(int sourceEnd) {
			}

			public boolean isWarning() {
				return true;
			}

			public boolean isError() {
				return false;
			}

			public int getSourceStart() {
				return start;
			}

			public int getSourceLineNumber() {
				return line;
			}

			public int getSourceEnd() {
				return end;
			}

			public char[] getOriginatingFileName() {
				return name;
			}

			public String getMessage() {
				return validationMessage;
			}

			public int getID() {
				return getEID();
			}

			public String[] getArguments() {
				return new String[0];
			}

			public int getEID() {
				return IJSPProblem.TEIValidationMessage;
			}
		};
	}

	/**
	 * @param decl
	 * @return the TagInfo for the TLDELementDeclaration if the declaration is
	 *         valid, otherwise null
	 */
	private TagInfo getTagInfo(TLDElementDeclaration decl, TagExtraInfo tei, String prefix, String uri) {

		TagLibraryInfo libInfo = new TagLibraryInfo(prefix, uri) { /*
																	 * dummy
																	 * impl
																	 */
		};

		CMNamedNodeMap attrs = decl.getAttributes();
		TagAttributeInfo[] attrInfos = new TagAttributeInfo[attrs.getLength()];
		TLDAttributeDeclaration attr = null;
		String type = ""; //$NON-NLS-1$ 

		// get tag attribute infos
		for (int i = 0; i < attrs.getLength(); i++) {
			attr = (TLDAttributeDeclaration) attrs.item(i);
			type = attr.getType();
			// default value for type is String
			if (attr.getType() == null || attr.getType().equals("")) //$NON-NLS-1$ 
				type = "java.lang.String"; //$NON-NLS-1$ 
			attrInfos[i] = new TagAttributeInfo(attr.getAttrName(), attr.isRequired(), type, false);
		}

		String tagName = decl.getNodeName();
		String tagClass = decl.getTagclass();
		String bodyContent = decl.getBodycontent();
		if (tagName != null && tagClass != null && bodyContent != null)
			return new TagInfo(tagName, tagClass, bodyContent, decl.getInfo(), libInfo, tei, attrInfos);
		return null;

	}

	/**
	 * @param e
	 */
	private void logException(String teiClassname, Throwable e) {

		String message = "teiClassname: ["; //$NON-NLS-1$ 
		if (teiClassname != null)
			message += teiClassname;
		message += "]"; //$NON-NLS-1$
		Logger.logException(message, e);
	}

	/**
	 * Returns all attribute -> value pairs for the tag in a Hashtable.
	 * 
	 * @param customTag
	 * @return
	 */
	private Hashtable extractTagData(ITextRegionCollection customTag) {
		Hashtable tagDataTable = new Hashtable();
		ITextRegionList regions = customTag.getRegions();
		ITextRegion r = null;
		String attrName = ""; //$NON-NLS-1$
		String attrValue = ""; //$NON-NLS-1$
		for (int i = 2; i < regions.size(); i++) {
			r = regions.get(i);
			// check if attr name
			if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_NAME) {
				attrName = customTag.getText(r);
				// check equals is next region
				if (regions.size() > ++i) {
					r = regions.get(i);
					if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_EQUALS && regions.size() > ++i) {
						// get attr value
						r = regions.get(i);
						if (r.getType() == DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE) {
							// attributes in our document have quotes, so we
							// need to strip them
							attrValue = StringUtils.stripQuotes(customTag.getText(r));
							tagDataTable.put(attrName, attrValue);
						}
					}
				}
			}
		}

		tagDataTable.put("jsp:id", customTag.getText(regions.get(1)) + "_" + customTag.getStartOffset()); //$NON-NLS-1$ 

		return tagDataTable;
	}

	private ClassLoader getClassloader() {
		if (fLoader == null) {
			fLoader = new BuildPathClassLoader(this.getClass().getClassLoader(), fJavaProject);
		}
		return fLoader;
	}

	/**
	 * @return Returns the fModelQuery.
	 */
	public ModelQuery getModelQuery(IDocument doc) {
		IStructuredModel model = null;
		ModelQuery mq = null;
		try {
			model = StructuredModelManager.getModelManager().getExistingModelForRead(doc);
			mq = ModelQueryUtil.getModelQuery(model);
		}
		finally {
			if (model != null)
				model.releaseFromRead();
		}
		return mq;
	}


	/**
	 * @return Returns the fFile.
	 */
	public IProject getProject() {

		return fProject;
	}

	/**
	 * @param file
	 *            The fFile to set.
	 */
	public void setProject(IProject p) {
		fProject = p;
		IJavaProject javaProject = JavaCore.create(p);
		if (javaProject.exists()) {
			fJavaProject = javaProject;
		}
	}

	private void validateTagClass(IStructuredDocument document, ITextRegionCollection customTag, TLDElementDeclaration decl, List problems) {
		// skip if from a tag file
		if (TLDElementDeclaration.SOURCE_TAG_FILE.equals(decl.getProperty(TLDElementDeclaration.TAG_SOURCE)) || fJavaProject == null) {
			return;
		}

		String tagClassname = decl.getTagclass();
		Object tagClass = null;
		if (tagClassname != null && tagClassname.length() > 0 && fJavaProject.exists()) {
			try {
				tagClass = fJavaProject.findType(tagClassname);
			}
			catch (JavaModelException e) {
				Logger.logException(e);
			}
		}
		if (tagClass == null) {
			Object createdProblem = createJSPProblem(document, customTag, IJSPProblem.TagClassNotFound, JSPCoreMessages.TaglibHelper_3, tagClassname, false);
			if (createdProblem != null) {
				problems.add(createdProblem);
			}
		}
	}

	/**
	 * 
	 */
	public void dispose() {
		fLoader = null;
		fJavaProject = null;
		fProject = null;
		fNotFoundClasses = null;
		fClassMap = null;
		fMemoryListener.disconnect();
		fMemoryListener = null;
	}

	public void invalidateClass(String className) {
		fClassMap.remove(className);
	}

	/**
	 * <p>A {@link AbstractMemoryListener} that clears the {@link #fNotFoundClasses} cache
	 * whenever specific memory events are received.</p>
	 * 
	 * <p>Events:
	 * <ul>
	 * <li>{@link AbstractMemoryListener#SEV_NORMAL}</li>
	 * <li>{@link AbstractMemoryListener#SEV_SERIOUS}</li>
	 * <li>{@link AbstractMemoryListener#SEV_CRITICAL}</li>
	 * </ul>
	 * </p>
	 */
	private class MemoryListener extends AbstractMemoryListener {
		/**
		 * <p>Constructor causes this listener to listen for specific memory events.</p>
		 * <p>Events:
		 * <ul>
		 * <li>{@link AbstractMemoryListener#SEV_NORMAL}</li>
		 * <li>{@link AbstractMemoryListener#SEV_SERIOUS}</li>
		 * <li>{@link AbstractMemoryListener#SEV_CRITICAL}</li>
		 * </ul>
		 * </p>
		 */
		MemoryListener() {
			super(new String[] { SEV_NORMAL, SEV_SERIOUS, SEV_CRITICAL });
		}

		/**
		 * On any memory event we handle clear out the project descriptions
		 * 
		 * @see org.eclipse.jst.jsp.core.internal.util.AbstractMemoryListener#handleMemoryEvent(org.osgi.service.event.Event)
		 */
		protected void handleMemoryEvent(Event event) {
			/* if running low on memory then this cache can be cleared
			 * and rebuilt at the expense of processing time
			 */
			fNotFoundClasses.clear();
			fClassMap.clear();
		}

	}
}
