/*******************************************************************************
 * Copyright (c) 2004, 2008 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.io.File;
import java.util.ArrayList;
import java.util.Collection;
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.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
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.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 com.ibm.icu.text.MessageFormat;

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

	// 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 TaglibClassLoader fLoader = null;

	private Set fProjectEntries = null;
	private Map fTranslationProblems = null;
	private Set fContainerEntries = null;
	private IJavaProject fJavaProject;

	public TaglibHelper(IProject project) {
		setProject(project);
		fProjectEntries = new HashSet();
		fContainerEntries = new HashSet();
		fTranslationProblems = new HashMap();
	}

	/**
	 * @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
	 */
	public TaglibVariable[] getTaglibVariables(String tagToAdd, IStructuredDocument structuredDoc, ITextRegionCollection customTag) {

		List results = new ArrayList();
		List 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);
					}
				}
			}
		}

		IPath location = TaglibController.getLocation(structuredDoc);
		if (location != null) {
			fTranslationProblems.put(location, 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)
			return;

		TaglibClassLoader 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) {
			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 TaglibClassLoader getClassloader() {
		if (fLoader == null) {
			fLoader = new TaglibClassLoader(this.getClass().getClassLoader());
			fProjectEntries.clear();
			fContainerEntries.clear();
			addClasspathEntriesForProject(getProject(), fLoader);
		}
		return fLoader;
	}

	/**
	 * @param loader
	 */
	private void addClasspathEntriesForProject(IProject p, TaglibClassLoader loader) {

		// avoid infinite recursion and closed project
		if (!p.isAccessible() || fProjectEntries.contains(p.getFullPath().toString()))
			return;
		fProjectEntries.add(p.getFullPath().toString());

		// add things on classpath that we are interested in
		try {
			if (p.hasNature(JavaCore.NATURE_ID)) {

				IJavaProject project = JavaCore.create(p);

				try {
					IClasspathEntry[] entries = project.getResolvedClasspath(true);
					addDefaultDirEntry(loader, project);
					addClasspathEntries(loader, project, entries);
				}
				catch (JavaModelException e) {
					Logger.logException(e);
				}
			}
		}
		catch (CoreException e) {
			Logger.logException(e);
		}
	}

	private void addClasspathEntries(TaglibClassLoader loader, IJavaProject project, IClasspathEntry[] entries) throws JavaModelException {
		IClasspathEntry entry;
		for (int i = 0; i < entries.length; i++) {

			entry = entries[i];
			if (DEBUG)
				System.out.println("current entry is: " + entry); //$NON-NLS-1$

			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_SOURCE :
					addSourceEntry(loader, entry);
					break;
				case IClasspathEntry.CPE_LIBRARY :
					addLibraryEntry(loader, entry.getPath());
					break;
				case IClasspathEntry.CPE_PROJECT :
					addProjectEntry(loader, entry);
					break;
				case IClasspathEntry.CPE_VARIABLE :
					addVariableEntry(loader, entry);
					break;
				case IClasspathEntry.CPE_CONTAINER :
					addContainerEntry(loader, project, entry);
					break;
			}
		}
	}

	/**
	 * @param loader
	 * @param entry
	 */
	private void addVariableEntry(TaglibClassLoader loader, IClasspathEntry entry) {
		if (DEBUG)
			System.out.println(" -> adding variable entry: [" + entry + "]"); //$NON-NLS-1$ //$NON-NLS-2$

		// variable should either be a project or a library entry

		// BUG 169431
		String variableName = entry.getPath().toString();
		IPath variablePath = JavaCore.getResolvedVariablePath(entry.getPath());
		variablePath = JavaCore.getClasspathVariable(variableName);

		// RATLC01076854
		// variable paths may not exist
		// in that case null will be returned
		if (variablePath != null) {
			if (variablePath.segments().length == 1) {
				IProject varProj = ResourcesPlugin.getWorkspace().getRoot().getProject(variablePath.toString());
				if (varProj != null && varProj.exists()) {
					addClasspathEntriesForProject(varProj, loader);
					return;
				}
			}
			addLibraryEntry(loader, variablePath);
		}
	}

	/**
	 * @param loader
	 * @param project
	 * @param entry
	 * @throws JavaModelException
	 */
	private void addContainerEntry(TaglibClassLoader loader, IJavaProject project, IClasspathEntry entry) throws JavaModelException {

		IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
		if (container != null) {
			String uniqueProjectAndContainerPath = project.getProject().getFullPath().append(container.getPath()).toString();
			/*
			 * Avoid infinite recursion, but track containers for each project
			 * separately as they may return different values. This may mean
			 * indexing JREs multiple times, however.
			 */
			if (!fContainerEntries.contains(uniqueProjectAndContainerPath)) {
				fContainerEntries.add(uniqueProjectAndContainerPath);

				IClasspathEntry[] cpes = container.getClasspathEntries();
				// recursive call here
				addClasspathEntries(loader, project, cpes);
			}
		}
	}

	/**
	 * @param loader
	 * @param entry
	 */
	private void addProjectEntry(TaglibClassLoader loader, IClasspathEntry entry) {
		if (DEBUG)
			System.out.println(" -> project entry: [" + entry + "]"); //$NON-NLS-1$ //$NON-NLS-2$

		IPath path = entry.getPath();
		IProject referenceProject = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
		if (referenceProject != null && referenceProject.isAccessible()) {
			addClasspathEntriesForProject(referenceProject, loader);
		}
	}

	/**
	 * @param loader
	 * @param project
	 * @param projectLocation
	 * @throws JavaModelException
	 */
	private void addDefaultDirEntry(TaglibClassLoader loader, IJavaProject project) throws JavaModelException {
		// add default bin directory for the project
		IPath outputPath = project.getOutputLocation();
		loader.addFolder(outputPath);
	}

	/**
	 * @param loader
	 * @param entry
	 */
	private void addLibraryEntry(TaglibClassLoader loader, IPath libPath) {
		String libPathString = libPath.toString();
		File file = new File(libPathString);

		if (file.exists()) {
			if (file.isDirectory()) {
				loader.addDirectory(libPathString);
			}
			else {
				loader.addJar(libPathString);
			}
		}
		else {
			if (libPath.segmentCount() > 1) {
				IFile ifile = ResourcesPlugin.getWorkspace().getRoot().getFile(libPath);
				if (ifile != null && ifile.isAccessible()) {
					loader.addFile(libPath);
				}
				else {
					IFolder ifolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(libPath);
					if (ifolder != null && ifolder.isAccessible()) {
						loader.addFolder(libPath);
					}
				}
			}
			else {
				loader.addFolder(libPath);
			}
		}
	}

	/**
	 * @param loader
	 * @param entry
	 */
	private void addSourceEntry(TaglibClassLoader loader, IClasspathEntry entry) {
		// add bin directory for specific entry if it has
		// one
		IPath outputLocation = entry.getOutputLocation();
		if (outputLocation != null) {
			loader.addFolder(outputLocation);
		}
	}

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

	/**
	 * @param path
	 * @return
	 */
	public Collection getProblems(IPath path) {
		return (Collection) fTranslationProblems.remove(path);
	}

	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))) {
			return;
		}

		String tagClassname = decl.getTagclass();
		Object tagClass = null;
		if (tagClassname != null && tagClassname.length() > 0 && fJavaProject != null) {
			try {
				tagClass = fJavaProject.findType(tagClassname, new NullProgressMonitor());
			}
			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);
			}
		}
	}
}
