/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view.model.jsp.analyzer;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.internal.proxy.core.IBeanProxy;
import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
import org.eclipse.jem.internal.proxy.core.IConfigurationContributor;
import org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory;
import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry;
import org.eclipse.jem.internal.proxy.ide.IDERegistration;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IJSFTagElement;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IHandlerTagElement.TagHandlerType;
import org.eclipse.jst.jsf.common.runtime.internal.view.model.common.IJSFTagElement.TagType;
import org.eclipse.jst.jsf.core.JSFVersion;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.BeanProxyWrapper;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.ProxyException;
import org.eclipse.jst.jsf.designtime.internal.view.DTComponentIntrospector;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDComponentTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDConverterTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDTagHandlerElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.TLDValidatorTagElement;
import org.eclipse.jst.jsf.designtime.internal.view.model.jsp.IAttributeAdvisor.NullAttributeAdvisor;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;

/**
 * Utility class supporting methods to derive information from JSP tag
 * definitions (TLD)
 * 
 * @author cbateman
 * 
 */
public final class TagAnalyzer
{
    private static final String JAVAX_FACES_WEBAPP_CONVERTER_TAG = "javax.faces.webapp.ConverterTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_CONVERTER_ELTAG = "javax.faces.webapp.ConverterELTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_VALIDATOR_TAG = "javax.faces.webapp.ValidatorTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_VALIDATOR_ELTAG = "javax.faces.webapp.ValidatorELTag"; //$NON-NLS-1$
    private static final String JAVAX_FACES_WEBAPP_FACET_TAG = "javax.faces.webapp.FacetTag"; //$NON-NLS-1$

    // private static final String JAVAX_FACES_WEBAPP_ACTIONLISTENER_TAG =
    // "javax.faces.webapp.ActionListenerTag";
    // private static final String JAVAX_FACES_WEBAPP_VALUECHANGELISTENER_TAG =
    // "javax.faces.webapp.ValueChangeListenerTag";
    private static final String JAVAX_FACES_WEBAPP_ATTRIBUTE_TAG = "javax.faces.webapp.AttributeTag"; //$NON-NLS-1$

    private final static Set<String> COMPONENT_TAG_HANDLER_TYPES_JSF11;
    private final static Set<String> COMPONENT_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> CONVERTER_TAG_HANDLER_TYPES_JSF11 = Collections
            .singleton(JAVAX_FACES_WEBAPP_CONVERTER_TAG);
    private final static Set<String> CONVERTER_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> VALIDATOR_TAG_HANDLER_TYPES_JSF11 = Collections
            .singleton(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
    private final static Set<String> VALIDATOR_TAG_HANDLER_TYPES_JSF12;

    private final static Set<String> FACET_TAG_HANDLER = Collections
            .singleton(JAVAX_FACES_WEBAPP_FACET_TAG);
    private final static Set<String> ATTRIBUTE_TAG_HANDLER = Collections
            .singleton(JAVAX_FACES_WEBAPP_ATTRIBUTE_TAG);
    // private final static Set<String> ACTIONLISTENER_TAG_HANDLER = Collections
    // .singleton(JAVAX_FACES_WEBAPP_ACTIONLISTENER_TAG);
    // private final static Set<String> VALUECHANGELISTENER_TAG_HANDLER =
    // Collections
    // .singleton(JAVAX_FACES_WEBAPP_VALUECHANGELISTENER_TAG);

    private final static Set<String> ALL_HANDLER_TAGS;

    static
    {
        // components
        // JSF 1.1
        Set<String> set = new HashSet<String>(8);
        set.add("javax.faces.webapp.UIComponentTag"); //$NON-NLS-1$
        set.add("javax.faces.webapp.UIComponentBodyTag"); //$NON-NLS-1$
        COMPONENT_TAG_HANDLER_TYPES_JSF11 = Collections.unmodifiableSet(set);

        // JSF 1.2+
        set = new HashSet<String>(8);
        set.addAll(COMPONENT_TAG_HANDLER_TYPES_JSF11);
        set.add("javax.faces.webapp.UIComponentELTag"); //$NON-NLS-1$
        COMPONENT_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // converters
        set = new HashSet<String>(8);
        set.add(JAVAX_FACES_WEBAPP_CONVERTER_TAG);
        set.add(JAVAX_FACES_WEBAPP_CONVERTER_ELTAG);
        CONVERTER_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // validators
        set = new HashSet<String>(8);
        set.add(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
        set.add(JAVAX_FACES_WEBAPP_VALIDATOR_ELTAG);
        VALIDATOR_TAG_HANDLER_TYPES_JSF12 = Collections.unmodifiableSet(set);

        // tag handlers
        ALL_HANDLER_TAGS = new HashSet<String>();
        ALL_HANDLER_TAGS.addAll(FACET_TAG_HANDLER);
        ALL_HANDLER_TAGS.addAll(ATTRIBUTE_TAG_HANDLER);
        // ALL_HANDLER_TAGS.addAll(VALUECHANGELISTENER_TAG_HANDLER);
        // ALL_HANDLER_TAGS.addAll(ACTIONLISTENER_TAG_HANDLER);
    }

    /**
     * Tries to determine the component type of the component that corresponds
     * to the JSP tag defined by tldDecl.
     * 
     * @param tldDecl
     * @param project
     * @return get the component type from the tag definition or null if none.
     */
    public static String findComponentType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        final String className = tldDecl.getTagclass();

        final IConfigurationContributor[] contributor = new IConfigurationContributor[]
        { new ServletBeanProxyContributor(project) };

        ProxyFactoryRegistry registry = null;
        try
        {
            registry = getProxyFactoryRegistry(contributor, project);
    
            if (registry != null)
            {

                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
                final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                        classTypeProxy);
    
                try
                {
                    classTypeWrapper.init();
                    return classTypeWrapper.callStringMethod("getComponentType"); //$NON-NLS-1$
                }
                catch (final ProxyException tp)
                {
                    if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                    {
                        JSFCoreTraceOptions.log("TagAnalyzer.findComponentType", tp); //$NON-NLS-1$
                    }
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;
    }

    /**
     * Tries to introspect tldDecl's tag class to determine what the identifier
     * of the underlying Converter that is used to register it in the app config
     * 
     * @param tldDecl
     * @param project
     * @return the converter type identifier for the tldDecl or null if not
     *         found
     */
    public static String findConverterType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        // TODO: allow for pluggable resolver?

        // This one is more hacky and less prone to success than the component
        // type finder because the ConverterTag doesn't initialize its type
        // field on construction. Instead, both MyFaces and RI seem to do it
        // based on the doStartTag method. They also don't provide a standard
        // interface for acquiring the id so instead we make some guess on
        // the internal field name.
        ProxyFactoryRegistry registry = null;
        try
        {
            final String className = tldDecl.getTagclass();
    
            final IConfigurationContributor[] contributor = new IConfigurationContributor[]
            { new ServletBeanProxyContributor(project) };
            registry = getProxyFactoryRegistry(
                    contributor, project);
    
            if (registry != null)
            {
                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
    
                try
                {
                    final IType type = JavaCore.create(project).findType(className);
    
                    if (type != null
                            && DTComponentIntrospector
                                    .isTypeNameInstanceOfClass(
                                            type,
                                            Collections
                                                    .singleton(JAVAX_FACES_WEBAPP_CONVERTER_ELTAG)))
                    {
                        return findConverterType_InELTag(factory, classTypeProxy,project);
                    }
                    // the assumption is that this is a component tag, so we assume
                    // it is one.
                    else if (type != null
                            && DTComponentIntrospector
                                    .isTypeNameInstanceOfClass(
                                            type,
                                            Collections
                                                    .singleton(JAVAX_FACES_WEBAPP_CONVERTER_TAG)))
                    {
                        return findConverterType_InTag(factory, classTypeProxy, project);
                    }
                }
                catch (final JavaModelException jme)
                {
                    // suppress for now
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;
    }

    private static String findConverterType_InTag(
            final IStandardBeanTypeProxyFactory factory,
            final IBeanTypeProxy classTypeProxy, final IProject project)
    {
        final IBeanTypeProxy nullPageContextType = factory
                .getBeanTypeProxy("javax.servlet.jsp.PageContext"); //$NON-NLS-1$
        final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                classTypeProxy);

        try
        {
            classTypeWrapper.init();

            callSuppressExceptions(classTypeWrapper, "setPageContext", //$NON-NLS-1$
                    new IBeanProxy[]
                    { null }, new IBeanTypeProxy[]
                    { nullPageContextType });
            callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$

            final IBeanTypeProxy converterProxy = factory
                    .getBeanTypeProxy(JAVAX_FACES_WEBAPP_CONVERTER_TAG);

            // hopefully doStartTag set the converter field before it
            // failed.
            // now try to guess what it's called
            String converterId = getStringField(classTypeWrapper,
                    converterProxy, "converterId"); //$NON-NLS-1$

            if (converterId != null)
            {
                return converterId;
            }

            converterId = getStringField(classTypeWrapper, converterProxy,
                    "_converterId"); //$NON-NLS-1$

            if (converterId != null)
            {
                return converterId;
            }

            // no? look for a CONVERTER_ID
            converterId = getStringField(classTypeWrapper, classTypeProxy,
                    "CONVERTER_ID"); //$NON-NLS-1$
        }
        catch (final ProxyException tp)
        {
            // fall through
        }
        return null;
    }

    private static String findConverterType_InELTag(
            final IStandardBeanTypeProxyFactory factory,
            final IBeanTypeProxy classTypeProxy, final IProject project)
    {
        final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                classTypeProxy);
        final IBeanTypeProxy elExpressionType = factory
                .getBeanTypeProxy("javax.el.ValueExpression"); //$NON-NLS-1$

        if (elExpressionType == null)
        {
            return null;
        }

        try
        {
            classTypeWrapper.init();

            callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$

            // no? look for a CONVERTER_ID
            final IBeanProxy converterId = getFieldInParents(classTypeWrapper,
                    classTypeProxy, "CONVERTER_ID_EXPR"); //$NON-NLS-1$

            if (converterId != null)
            {
                converterId.getTypeProxy().isKindOf(elExpressionType);
                final BeanProxyWrapper elExprValue = new BeanProxyWrapper(project,
                        converterId.getTypeProxy());
                final String value = elExprValue
                        .callStringMethod("getExpressionString"); //$NON-NLS-1$
                System.out.println("Expression string:" + value); //$NON-NLS-1$
            }

            //            
            //
            // final IBeanTypeProxy converterProxy = factory
            // .getBeanTypeProxy(JAVAX_FACES_WEBAPP_CONVERTER_TAG);

        }
        catch (final ProxyException tp)
        {
            // fall through
        }
        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return the validator type identifier for the tldDecl or null if not
     *         found
     */
    public static String findValidatorType(final TLDElementDeclaration tldDecl,
            final IProject project)
    {
        // TODO: allow for pluggable resolver?

        // This one is more hacky and less prone to success than the component
        // type finder because the Validator doesn't initialize its type
        // field on construction. Instead, both MyFaces and RI seem to do it
        // based on the doStartTag method. They also don't provide a standard
        // interface for acquiring the id so instead we make some guess on
        // the internal field name.
        final String className = tldDecl.getTagclass();

        final IConfigurationContributor[] contributor = new IConfigurationContributor[]
        { new ServletBeanProxyContributor(project) };

        ProxyFactoryRegistry registry = null;

        try
        {
            registry = getProxyFactoryRegistry(contributor, project);
    
            if (registry != null)
            {
                final IStandardBeanTypeProxyFactory factory = registry
                        .getBeanTypeProxyFactory();
                final IBeanTypeProxy classTypeProxy = factory
                        .getBeanTypeProxy(className);
                final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
                        classTypeProxy);
                final IBeanTypeProxy converterProxy = factory
                        .getBeanTypeProxy(JAVAX_FACES_WEBAPP_VALIDATOR_TAG);
                try
                {
                    classTypeWrapper.init();
    
                    callSuppressExceptions(classTypeWrapper, "doStartTag"); //$NON-NLS-1$
                    callSuppressExceptions(classTypeWrapper, "createValidator"); //$NON-NLS-1$
    
                    // hopefully doStartTag set the converter field before it
                    // failed.
                    // now try to guess what it's called
                    String validatorId = getStringField(classTypeWrapper,
                            converterProxy, "validatorId"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
    
                    validatorId = getStringField(classTypeWrapper, converterProxy,
                            "_validatorId"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
    
                    // no? then see if there's a VALIDATOR_ID field *on the tag*
                    validatorId = getStringField(classTypeWrapper, classTypeProxy,
                            "VALIDATOR_ID"); //$NON-NLS-1$
    
                    if (validatorId != null)
                    {
                        return validatorId;
                    }
                }
                catch (final ProxyException tp)
                {
                    // fall through
                }
            }
        }
        finally
        {
            if (registry != null)
            {
                registry.terminateRegistry(true);
            }
        }
        return null;

    }

    private static IBeanProxy getFieldInParents(
            final BeanProxyWrapper classTypeWrapper,
            final IBeanTypeProxy typeProxy, final String fieldName)
    {
        try
        {
            return classTypeWrapper.getFieldValueIncludeParents(fieldName,
                    typeProxy);
        }
        catch (final ProxyException e)
        {
            // suppress
        }

        return null;
    }

    private static String getStringField(
            final BeanProxyWrapper classTypeWrapper,
            final IBeanTypeProxy typeProxy, final String fieldName)
    {
        try
        {
            return classTypeWrapper.getStringFieldValue(fieldName, typeProxy);
        }
        catch (final ProxyException e)
        {
            // suppress
        }

        return null;
    }

    private static void callSuppressExceptions(
            final BeanProxyWrapper classTypeWrapper, final String methodName)
    {
        try
        {
            classTypeWrapper.call(methodName);
        }
        catch (final ProxyException tp)
        {
            // suppress this since it may well throw an exception
            // depending on what assumptions the tag class is making
            // that won't be true because we're not in a servlet
        }
    }

    private static void callSuppressExceptions(
            final BeanProxyWrapper classTypeWrapper, final String methodName,
            final IBeanProxy[] args, final IBeanTypeProxy[] argTypes)
    {
        try
        {
            classTypeWrapper.call(methodName, args, argTypes);
        }
        catch (final ProxyException tp)
        {
            // suppress this since it may well throw an exception
            // depending on what assumptions the tag class is making
            // that won't be true because we're not in a servlet
        }

    }

    /**
     * @param project
     * @return a new proxy factory registry or null;
     * 
     * TODO: caching?
     */
    private static ProxyFactoryRegistry getProxyFactoryRegistry(
            final IConfigurationContributor[] configuration,
            final IProject project)
    {
        try
        {
            return IDERegistration.startAnImplementation(configuration, false,
                    project, project.getName(), JSFCorePlugin.PLUGIN_ID,
                    new NullProgressMonitor());
        }
        catch (final CoreException e)
        {
            JSFCorePlugin.log("Error starting vm for project: " //$NON-NLS-1$
                    + project.getName(), e);
        }

        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return the tag element for the tldDecl
     */
    public static TLDTagElement createTLDTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions
                    .log(String
                            .format(
                                    "TagAnalyzer.createTLDTagElement: Start tld=%s, project=%s", //$NON-NLS-1$
                                    tldDecl.getNodeName(), project.getName()));
        }
        long startTime = 0;
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
        {
            startTime = System.nanoTime();
        }

        try
        {
            final IJavaProject javaProject = JavaCore.create(project);
            final String typeName = tldDecl.getTagclass();

            if (typeName == null
                    || JavaConventions.validateJavaTypeName(typeName,
                            JavaCore.VERSION_1_3,
                            JavaCore.VERSION_1_3).getSeverity() == IStatus.ERROR)
            {
            	if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                {
                    JSFCoreTraceOptions.log(
                        "Bad tag class name in " + tldDecl.toString()); //$NON-NLS-1$
                }
                return null;
            }

            final IType type = javaProject.findType(typeName);
            
            if (type == null)
            {
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
                {
                    JSFCoreTraceOptions.log("Type not found for: "+typeName); //$NON-NLS-1$
                }
                return null;
            }
            final TagType tagType = getJSFComponentTagType(type, project);

            if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
            {
                JSFCoreTraceOptions.log(String.format(
                        "Tag class type=%s\nTag type=%s", type, tagType)); //$NON-NLS-1$
            }

            if (tagType == TagType.COMPONENT)
            {
                final TLDTagElement element = createComponentTagElement(tldDecl, project);
                
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create component tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.CONVERTER)
            {
                final TLDTagElement element =  createConverterTagElement(tldDecl, project);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create converter tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.VALIDATOR)
            {
                final TLDTagElement element =  createValidatorTagElement(tldDecl, project);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create validator tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
            else if (tagType == TagType.HANDLER)
            {
                final TLDTagElement element =  createHandlerTagElement(tldDecl, type);
                if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR_PERF)
                {
                    String name = element != null ? element.toString()
                            : "<none>"; //$NON-NLS-1$
                    System.out.printf(
                            "Time to create handler tag element %s was %d\n", //$NON-NLS-1$
                            name, Long.valueOf(System.nanoTime() - startTime));
                }
                return element;
            }
        }
        catch (final JavaModelException jme)
        {
            JSFCorePlugin.log(jme, "Trying to get type for TLD"); //$NON-NLS-1$
        }

        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return a component tag element for tldDecl
     */
    public static TLDTagElement createComponentTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String componentType = findComponentType(tldDecl, project);

        if (componentType != null)
        {
            final String componentClass = DTComponentIntrospector
                    .findComponentClass(componentType, project);

            if (componentClass != null && !"".equals(componentClass.trim())) //$NON-NLS-1$
            {
                final ComponentTypeInfo typeInfo = DTComponentIntrospector
                        .getComponent(componentType, componentClass, project,
                                new IConfigurationContributor[]
                                {new ServletBeanProxyContributor(project)});

                if (typeInfo != null)
                {
                    final TLDComponentTagElement tagElement = new TLDComponentTagElement(
                            tldDecl, typeInfo, new NullAttributeAdvisor());
                    return tagElement;
                }
            }
        }

        // TODO: really return null?
        return null;
    }

    /**
     * @param tldDecl
     * @param project
     * @return a converter tag element for tldDecl
     */
    public static TLDTagElement createConverterTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String converterId = findConverterType(tldDecl, project);

        if (converterId != null)
        {
            final String converterClass = DTComponentIntrospector
                    .findConverterClass(converterId, project);

            if (converterClass != null && !"".equals(converterClass.trim())) //$NON-NLS-1$
            {
                final ConverterTypeInfo typeInfo = DTComponentIntrospector
                        .getConverter(converterId, converterClass);
                final TLDConverterTagElement tagElement = new TLDConverterTagElement(
                        tldDecl, typeInfo, new NullAttributeAdvisor());
                return tagElement;
            }
        }

        // we know (actually we assume by contract) that this a converter
        // so create an unknown converter tag for it
        return new TLDConverterTagElement(tldDecl, ConverterTypeInfo.UNKNOWN, new NullAttributeAdvisor());
    }

    /**
     * @param tldDecl
     * @param project
     * @return a validator tag element for the tldDec
     */
    public static TLDTagElement createValidatorTagElement(
            final TLDElementDeclaration tldDecl, final IProject project)
    {
        final String validatorId = findValidatorType(tldDecl, project);

        if (validatorId != null)
        {
            final String validatorClass = DTComponentIntrospector
                    .findValidatorClass(validatorId, project);

            if (validatorClass != null && !"".equals(validatorClass.trim())) //$NON-NLS-1$
            {
                final ValidatorTypeInfo typeInfo = DTComponentIntrospector
                        .getValidator(validatorId, validatorClass);
                final TLDValidatorTagElement tagElement = new TLDValidatorTagElement(
                        tldDecl, typeInfo, new NullAttributeAdvisor());
                return tagElement;
            }
        }
        // we know (actually we assume by contract) that this a validator
        // so create an unknown converter tag for it
        return new TLDValidatorTagElement(tldDecl, ValidatorTypeInfo.UNKNOWN, new NullAttributeAdvisor());
    }

    /**
     * @param tldDecl
     * @param type
     * @return the tag element for a JSF handler
     */
    public static TLDTagElement createHandlerTagElement(
            final TLDElementDeclaration tldDecl, final IType type)
    {
        if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                FACET_TAG_HANDLER))
        {
            return new TLDTagHandlerElement(tldDecl, TagHandlerType.FACET, new NullAttributeAdvisor());
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                ATTRIBUTE_TAG_HANDLER))
        {
            return new TLDTagHandlerElement(tldDecl, TagHandlerType.ATTRIBUTE, new NullAttributeAdvisor());
        }
        // else if (isTypeNameInstanceOfClass(type, ACTIONLISTENER_TAG_HANDLER))
        // {
        // return new TLDTagHandlerElement(tldDecl,
        // TagHandlerType.ACTIONLISTENER);
        // }
        // else if (isTypeNameInstanceOfClass(type,
        // VALUECHANGELISTENER_TAG_HANDLER))
        // {
        // return new TLDTagHandlerElement(tldDecl,
        // TagHandlerType.VALUECHANGELISTENER);
        // }
        return null;
    }

    /**
     * @param type
     * @param project
     * @return true if type represents a JSF component action class (spec 9.2.2)
     */
    public static IJSFTagElement.TagType getJSFComponentTagType(
            final IType type, final IProject project)
    {
        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions
                    .log(String
                            .format(
                                    "TagAnalyzer.getJSFComponentTagType: Determining Tag Type for type %s on project %s", //$NON-NLS-1$
                                    type.getFullyQualifiedName(), project
                                            .toString()));
        }

        Set<String> componentTags = null;
        Set<String> converterTags = null;
        Set<String> validatorTags = null;

        final JSFVersion jsfVersion = ServletBeanProxyContributor.getProjectVersion(project);

        if (jsfVersion == null){
        	return null;
        }
        // v1.1(9.2.2): JSF component tags must sub-class one of these
        else if (jsfVersion == JSFVersion.V1_0 || jsfVersion == JSFVersion.V1_1)
        {
            componentTags = COMPONENT_TAG_HANDLER_TYPES_JSF11;
            converterTags = CONVERTER_TAG_HANDLER_TYPES_JSF11;
            validatorTags = VALIDATOR_TAG_HANDLER_TYPES_JSF11;
        }
        // v1.2(9.2.2): JSF component tags must sub-class UIComponentELTag
        // the original two are included because we must be backward
        // compatible
        else if (jsfVersion == JSFVersion.V1_2 || jsfVersion == JSFVersion.V2_0)
        {
            componentTags = COMPONENT_TAG_HANDLER_TYPES_JSF12;
            converterTags = CONVERTER_TAG_HANDLER_TYPES_JSF12;
            validatorTags = VALIDATOR_TAG_HANDLER_TYPES_JSF12;
        }
        else 
        {
            throw new IllegalArgumentException();
        }

        TagType tagType = null;

        if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                componentTags))
        {
            tagType = TagType.COMPONENT;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                converterTags))
        {
            tagType = TagType.CONVERTER;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                validatorTags))
        {
            tagType = TagType.VALIDATOR;
        }
        else if (DTComponentIntrospector.isTypeNameInstanceOfClass(type,
                ALL_HANDLER_TAGS))
        {
            tagType = TagType.HANDLER;
        }

        if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
        {
            JSFCoreTraceOptions.log(String.format(
                    "TagAnalyzer.getJSFComponentTagType: tag type is %s", //$NON-NLS-1$
                    tagType != null ? tagType.toString() : "null")); //$NON-NLS-1$
        }
        return tagType;
    }


}
