/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.processor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.xml.transform.TransformerException;

import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.templates.AVT;
import org.apache.xalan.templates.Constants;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.StringToIntTable;
import org.apache.xml.utils.StringVector;
import org.apache.xml.utils.XMLChar;
import org.apache.xpath.XPath;

 
/**
 * This class defines an attribute for an element in a XSLT stylesheet,
 * is meant to reflect the structure defined in http://www.w3.org/TR/xslt#dtd, and the
 * mapping between Xalan classes and the markup attributes in the element.
 */
public class XSLTAttributeDef
{
   // How to handle invalid values for this attribute 
   static final int FATAL = 0;
   static final int ERROR = 1;
   static final int WARNING = 2;
   
   
  /**
   * Construct an instance of XSLTAttributeDef.
   *
   * @param namespace The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
   * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
   * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME, T_NCNAME.
   * @param required true if this is attribute is required by the XSLT specification.
   * @param supportsAVT true if this attribute supports AVT's.
   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
   */
  XSLTAttributeDef(String namespace, String name, int type, boolean required, boolean supportsAVT, int errorType)
  {
    this.m_namespace = namespace;
    this.m_name = name;
    this.m_type = type;
    this.m_required = required;
    this.m_supportsAVT = supportsAVT;
    this.m_errorType = errorType;
  }

  /**
   * Construct an instance of XSLTAttributeDef.
   *
   * @param namespace The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param type One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR,
   * T_CHAR, T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM,
   * T_SIMPLEPATTERNLIST, T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, 
   * T_ENUM_OR_PQNAME, T_NCNAME.
   * @param supportsAVT true if this attribute supports AVT's. 
   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
   * @param defaultVal The default value for this attribute.
   */
  XSLTAttributeDef(String namespace, String name, int type, boolean supportsAVT, int errorType, String defaultVal)
  {

    this.m_namespace = namespace;
    this.m_name = name;
    this.m_type = type;
    this.m_required = false;
    this.m_supportsAVT = supportsAVT;  
    this.m_errorType = errorType;      
    this.m_default = defaultVal;
   }

  /**
   * Construct an instance of XSLTAttributeDef that uses two
   * enumerated values.
   *
   * @param namespace The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param required true if this attribute is required by the XSLT specification.
   * @param supportsAVT true if this attribute supports AVT's.  
   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME       
   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING. 
   * @param k1 The XSLT name of the enumerated value.
   * @param v1 An integer representation of k1.
   * @param k2 The XSLT name of the enumerated value.
   * @param v2 An integer representation of k2.
    */
  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT, 
                    boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2)
  {

    this.m_namespace = namespace;
    this.m_name = name;
	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
    this.m_required = required;
    this.m_supportsAVT = supportsAVT;    
    this.m_errorType = errorType;    
    m_enums = new StringToIntTable(2);

    m_enums.put(k1, v1);
    m_enums.put(k2, v2);
  }

  /**
   * Construct an instance of XSLTAttributeDef that uses three
   * enumerated values.
   *
   * @param namespace The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param required true if this attribute is required by the XSLT specification.
   * @param supportsAVT true if this attribute supports AVT's.
   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING.    * 
   * @param k1 The XSLT name of the enumerated value.
   * @param v1 An integer representation of k1.
   * @param k2 The XSLT name of the enumerated value.
   * @param v2 An integer representation of k2.
   * @param k3 The XSLT name of the enumerated value.
   * @param v3 An integer representation of k3.
   */
  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
                    boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2, String k3, int v3)
  {

    this.m_namespace = namespace;
    this.m_name = name;
	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
    this.m_required = required;
    this.m_supportsAVT = supportsAVT; 
    this.m_errorType = errorType;      
    m_enums = new StringToIntTable(3);

    m_enums.put(k1, v1);
    m_enums.put(k2, v2);
    m_enums.put(k3, v3);
  }

  /**
   * Construct an instance of XSLTAttributeDef that uses three
   * enumerated values.
   *
   * @param namespace The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param required true if this attribute is required by the XSLT specification.
   * @param supportsAVT true if this attribute supports AVT's.
   * @param prefixedQNameValAllowed If true, the type is T_ENUM_OR_PQNAME
   * @param errorType the type of error to issue if validation fails.  One of FATAL, ERROR, WARNING.    * @param k1 The XSLT name of the enumerated value.
   * @param v1 An integer representation of k1.
   * @param k2 The XSLT name of the enumerated value.
   * @param v2 An integer representation of k2.
   * @param k3 The XSLT name of the enumerated value.
   * @param v3 An integer representation of k3.
   * @param k4 The XSLT name of the enumerated value.
   * @param v4 An integer representation of k4.
   */
  XSLTAttributeDef(String namespace, String name, boolean required, boolean supportsAVT,
                   boolean prefixedQNameValAllowed, int errorType, String k1, int v1, String k2, int v2, 
                   String k3, int v3, String k4, int v4)
  {

    this.m_namespace = namespace;
    this.m_name = name;
	this.m_type = prefixedQNameValAllowed ? this.T_ENUM_OR_PQNAME : this.T_ENUM;    
    this.m_required = required;
    this.m_supportsAVT = supportsAVT;      
    this.m_errorType = errorType; 
    m_enums = new StringToIntTable(4);

    m_enums.put(k1, v1);
    m_enums.put(k2, v2);
    m_enums.put(k3, v3);
    m_enums.put(k4, v4);
  }

  /** Type values that represent XSLT attribute types. */
  static final int T_CDATA = 1,

  // <!-- Used for the type of an attribute value that is a URI reference.-->
  T_URL = 2,

  // <!-- Used for the type of an attribute value that is an
  // attribute value template.-->
  T_AVT = 3,  // Attribute Value Template

  // <!-- Used for the type of an attribute value that is a pattern.-->
  T_PATTERN = 4,

  // <!-- Used for the type of an attribute value that is an expression.-->
  T_EXPR = 5,

  // <!-- Used for the type of an attribute value that consists
  // of a single character.-->
  T_CHAR = 6,

  // <!-- Used for the type of an attribute value that is a number. -->
  T_NUMBER = 7,

  // Used for boolean values
  T_YESNO = 8,

  // <!-- Used for the type of an attribute value that is a QName; the prefix
  // gets expanded by the XSLT processor. -->
  T_QNAME = 9,

  // <!--Used for a whitespace-separated list of QNames where the non-prefixed
  // entries are not to be placed in the default namespace. -->
  T_QNAMES = 10,

  // <!-- Used for enumerated values -->
  T_ENUM = 11,

  // Used for simple match patterns, i.e. xsl:strip-space spec.
  T_SIMPLEPATTERNLIST = 12,

  // Used for a known token.
  T_NMTOKEN = 13,

  // Used for a list of white-space delimited strings.
  T_STRINGLIST = 14,

  // Used for a list of white-space delimited strings.
  // Prefixes are checked to make sure they refer to 
  // valid namespaces, and are resolved when processed
  T_PREFIX_URLLIST = 15,
  
  // Used for enumerated values, one of which could be a qname-but-not-ncname
  T_ENUM_OR_PQNAME = 16,

  // Used for the type of an attribute value that is a NCName
  T_NCNAME = 17,
  
  // Used for QName attributes that are always AVT.  Prefix isn't resolved.
  T_AVT_QNAME = 18,
  
  // Used for a list of QNames where non-prefixed items are to be resolved
  // using the default namespace (This is only true for cdata-section-elements)
  T_QNAMES_RESOLVE_NULL = 19,
  
  // Used for a list of white-space delimited strings.
  // strings are checked to make sure they are valid 
  // prefixes, and are not expanded when processed. 
  T_PREFIXLIST = 20;

  /** Representation for an attribute in a foreign namespace. */
  static XSLTAttributeDef m_foreignAttr = new XSLTAttributeDef("*", "*",
                                            XSLTAttributeDef.T_CDATA,false, false, WARNING);

  /** Method name that objects may implement if they wish to have forein attributes set. */
  static String S_FOREIGNATTR_SETTER = "setForeignAttr";

  /**
   * The allowed namespace for this element.
   */
  private String m_namespace;

  /**
   * Get the allowed namespace for this attribute.
   *
   * @return The allowed namespace for this attribute, which may be null, or may be "*".
   */
  String getNamespace()
  {
    return m_namespace;
  }

  /**
   * The name of this element.
   */
  private String m_name;

  /**
   * Get the name of this attribute.
   *
   * @return non-null reference to the name of this attribute, which may be "*".
   */
  String getName()
  {
    return m_name;
  }

  /**
   * The type of this attribute value.
   */
  private int m_type;

  /**
   * Get the type of this attribute value.
   *
   * @return One of T_CDATA, T_URL, T_AVT, T_PATTERN, T_EXPR, T_CHAR,
   * T_NUMBER, T_YESNO, T_QNAME, T_QNAMES, T_ENUM, T_SIMPLEPATTERNLIST,
   * T_NMTOKEN, T_STRINGLIST, T_PREFIX_URLLIST, T_ENUM_OR_PQNAME.
   */
  int getType()
  {
    return m_type;
  }

  /**
   * If this element is of type T_ENUM, this will contain
   * a map from the attribute string to the Xalan integer
   * value.
   */
  private StringToIntTable m_enums;

  /**
   * If this element is of type T_ENUM, this will return
   * a map from the attribute string to the Xalan integer
   * value.
   * @param key The XSLT attribute value.
   *
   * @return The integer representation of the enumerated value for this attribute.
   * @throws Throws NullPointerException if m_enums is null.
   */
  private int getEnum(String key)
  {
    return m_enums.get(key);
  }

 /**
   * If this element is of type T_ENUM, this will return
   * an array of strings - the values in the enumeration
   *
   * @return An array of the enumerated values permitted for this attribute.
   *
   * @throws Throws NullPointerException if m_enums is null.
   */
  private String[] getEnumNames()
  {
    return m_enums.keys();
  }

  /**
   * The default value for this attribute.
   */
  private String m_default;

  /**
   * Get the default value for this attribute.
   *
   * @return The default value for this attribute, or null.
   */
  String getDefault()
  {
    return m_default;
  }

  /**
   * Set the default value for this attribute.
   *
   * @param def String representation of the default value for this attribute.
   */
  void setDefault(String def)
  {
    m_default = def;
  }

  /**
   * If true, this is a required attribute.
   */
  private boolean m_required;

  /**
   * Get whether or not this is a required attribute.
   *
   * @return true if this is a required attribute.
   */
  boolean getRequired()
  {
    return m_required;
  }

  /**
   * If true, this is attribute supports AVT's.
   */
  private boolean m_supportsAVT;

  /**
   * Get whether or not this attribute supports AVT's.
   *
   * @return true if this attribute supports AVT's.
   */
  boolean getSupportsAVT()
  {
    return m_supportsAVT;
  }
  
  int m_errorType = this.WARNING;
  
  /**
   * Get the type of error message to use if the attribute value is invalid.
   *
   * @return one of XSLAttributeDef.FATAL, XSLAttributeDef.ERROR, XSLAttributeDef.WARNING
   */
  int getErrorType()
  {
    return m_errorType;
  }
  /**
   * String that should represent the setter method which which
   * may be used on objects to set a value that represents this attribute  
   */
  String m_setterString = null;

  /**
   * Return a string that should represent the setter method.
   * The setter method name will be created algorithmically the
   * first time this method is accessed, and then cached for return
   * by subsequent invocations of this method.
   *
   * @return String that should represent the setter method which which
   * may be used on objects to set a value that represents this attribute,
   * of null if no setter method should be called.
   */
  public String getSetterMethodName()
  {

    if (null == m_setterString)
    {
      if (m_foreignAttr == this)
      {
        return S_FOREIGNATTR_SETTER;
      }
      else if (m_name.equals("*"))
      {
        m_setterString = "addLiteralResultAttribute";

        return m_setterString;
      }

      StringBuffer outBuf = new StringBuffer();

      outBuf.append("set");

      if ((m_namespace != null)
              && m_namespace.equals(Constants.S_XMLNAMESPACEURI))
      {
        outBuf.append("Xml");
      }

      int n = m_name.length();

      for (int i = 0; i < n; i++)
      {
        char c = m_name.charAt(i);

        if ('-' == c)
        {
          i++;

          c = m_name.charAt(i);
          c = Character.toUpperCase(c);
        }
        else if (0 == i)
        {
          c = Character.toUpperCase(c);
        }

        outBuf.append(c);
      }

      m_setterString = outBuf.toString();
    }

    return m_setterString;
  }

  /**
   * Process an attribute string of type T_AVT into
   * a AVT value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value Should be an Attribute Value Template string.
   *
   * @return An AVT object that may be used to evaluate the Attribute Value Template.
   *
   * @throws org.xml.sax.SAXException which will wrap a
   * {@link javax.xml.transform.TransformerException}, if there is a syntax error
   * in the attribute value template string.
   */
  AVT processAVT(
          StylesheetHandler handler, String uri, String name, String rawName, String value,
          ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    try
    {
      AVT avt = new AVT(handler, uri, name, rawName, value, owner);

      return avt;
    }
    catch (TransformerException te)
    {
      throw new org.xml.sax.SAXException(te);
    }
  }

  /**
   * Process an attribute string of type T_CDATA into
   * a String value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value non-null string reference.
   *
   * @return The value argument.
   * 
   * @throws org.xml.sax.SAXException.
   */
  Object processCDATA(StylesheetHandler handler, String uri, String name,
                      String rawName, String value, ElemTemplateElement owner)
                      throws org.xml.sax.SAXException
  {
  	if (getSupportsAVT()) {
	    try
	    {
	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
	      return avt;
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }  		
  	} else {  	  	
	    return value;
  	}
  }

  /**
   * Process an attribute string of type T_CHAR into
   * a Character value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value Should be a string with a length of 1.
   *
   * @return Character object.
   *
   * @throws org.xml.sax.SAXException if the string is not a length of 1.
   */
  Object processCHAR(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {
	if (getSupportsAVT()) {
	    try
	    {
	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
	
		  // If an AVT wasn't used, validate the value
		  if ((avt.isSimple()) && (value.length() != 1)) {
		  	handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
            return null;
		  }	
	      return avt;
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }
	} else {    
	    if (value.length() != 1)
	    {
            handleError(handler, XSLTErrorResources.INVALID_TCHAR, new Object[] {name, value},null);
            return null;
	    }

	    return new Character(value.charAt(0));
	}
  }

  /**
   * Process an attribute string of type T_ENUM into a int value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value non-null string that represents an enumerated value that is
   * valid for this element.
   * @param owner
   *
   * @return An Integer representation of the enumerated value if this attribute does not support
   *         AVT.  Otherwise, and AVT is returned.
   */
  Object processENUM(StylesheetHandler handler, String uri, String name,
                     String rawName, String value, ElemTemplateElement owner)
                     throws org.xml.sax.SAXException
  {

	AVT avt = null;
	if (getSupportsAVT()) {
	    try
	    {
	      avt = new AVT(handler, uri, name, rawName, value, owner);
	      
	      // If this attribute used an avt, then we can't validate at this time.
	      if (!avt.isSimple()) return avt;
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }
	}    
	
    int retVal = this.getEnum(value);
    
	if (retVal == StringToIntTable.INVALID_KEY) 
    {
       StringBuffer enumNamesList = getListOfEnums();
       handleError(handler, XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null);
       return null;
    }

	if (getSupportsAVT()) return avt;
	else return new Integer(retVal);	

  }

  /**
   * Process an attribute string of that is either an enumerated value or a qname-but-not-ncname.
   * Returns an AVT, if this attribute support AVT; otherwise returns int or qname.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value non-null string that represents an enumerated value that is
   * valid for this element.
   * @param owner
   *
   * @return AVT if attribute supports AVT. An Integer representation of the enumerated value if
   *         attribute does not support AVT and an enumerated value was used.  Otherwise a qname
   *         is returned.
   */
  Object processENUM_OR_PQNAME(StylesheetHandler handler, String uri, String name,
                     String rawName, String value, ElemTemplateElement owner)
                     throws org.xml.sax.SAXException
  {

	Object objToReturn = null;
	
	if (getSupportsAVT()) {
	    try
	    {
	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
	      if (!avt.isSimple()) return avt;
	      else objToReturn = avt;
	    }  
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }
	}    
	
    // An avt wasn't used.
  	int key = this.getEnum(value);
    
    if (key != StringToIntTable.INVALID_KEY) 
    {
        if (objToReturn == null) objToReturn = new Integer(key);
    }

    // enum not used.  Validate qname-but-not-ncname.
    else
    {
        try 
        {
			QName qname = new QName(value, handler, true);
            if (objToReturn == null) objToReturn = qname;	
	        
			if (qname.getPrefix() == null) {
	           StringBuffer enumNamesList = getListOfEnums();

 	           enumNamesList.append(" <qname-but-not-ncname>");
               handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },null); 
               return null;
        
	        }            
        }
        catch (IllegalArgumentException ie) 
        {
           StringBuffer enumNamesList = getListOfEnums();
           enumNamesList.append(" <qname-but-not-ncname>");
           
           handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },ie); 
           return null;

        }
        catch (RuntimeException re)
        {
           StringBuffer enumNamesList = getListOfEnums();
           enumNamesList.append(" <qname-but-not-ncname>");

           handleError(handler,XSLTErrorResources.INVALID_ENUM,new Object[]{name, value, enumNamesList.toString() },re); 
           return null;
        }    
  	}
  	
  	return objToReturn;
  }

  /**
   * Process an attribute string of type T_EXPR into
   * an XPath value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value An XSLT expression string.
   *
   * @return an XPath object that may be used for evaluation.
   *
   * @throws org.xml.sax.SAXException that wraps a
   * {@link javax.xml.transform.TransformerException} if the expression
   * string contains a syntax error.
   */
  Object processEXPR(
          StylesheetHandler handler, String uri, String name, String rawName, String value,
          ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    try
    {
      XPath expr = handler.createXPath(value, owner);

      return expr;
    }
    catch (TransformerException te)
    {
      org.xml.sax.SAXException se = new org.xml.sax.SAXException(te);
      throw new org.xml.sax.SAXException(te);
    }
  }

  /**
   * Process an attribute string of type T_NMTOKEN into
   * a String value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A NMTOKEN string.
   *
   * @return the value argument or an AVT if this attribute supports AVTs.
   * 
   * @throws org.xml.sax.SAXException if the value is not a valid nmtoken
   */
  Object processNMTOKEN(StylesheetHandler handler, String uri, String name,
                        String rawName, String value, ElemTemplateElement owner)
             throws org.xml.sax.SAXException
  {
  	
  	if (getSupportsAVT()) {
	    try
	    {
	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
	
		  // If an AVT wasn't used, validate the value
		  if ((avt.isSimple()) && (!XMLChar.isValidNmtoken(value))) {
            handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
            return null;
		  }	
	      return avt;
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }  		
  	} else {
  		if (!XMLChar.isValidNmtoken(value)) {
            handleError(handler,XSLTErrorResources.INVALID_NMTOKEN, new Object[] {name,value},null);
            return null;
  		}
  	}	  			
    return value;
  }

  /**
   * Process an attribute string of type T_PATTERN into
   * an XPath match pattern value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A match pattern string.
   *
   * @return An XPath pattern that may be used to evaluate the XPath.
   *
   * @throws org.xml.sax.SAXException that wraps a
   * {@link javax.xml.transform.TransformerException} if the match pattern
   * string contains a syntax error.
   */
  Object processPATTERN(
          StylesheetHandler handler, String uri, String name, String rawName, String value,
          ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    try
    {
      XPath pattern = handler.createMatchPatternXPath(value, owner);

      return pattern;
    }
    catch (TransformerException te)
    {
      throw new org.xml.sax.SAXException(te);
    }
  }

  /**
   * Process an attribute string of type T_NUMBER into
   * a double value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A string that can be parsed into a double value.
   * @param number
   *
   * @return A Double object.
   *
   * @throws org.xml.sax.SAXException that wraps a
   * {@link javax.xml.transform.TransformerException}
   * if the string does not contain a parsable number.
   */
  Object processNUMBER(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {


	if (getSupportsAVT()) 
	{
		Double val;
		AVT avt = null;
	    try
	    {
	      avt = new AVT(handler, uri, name, rawName, value, owner);
	      
	      // If this attribute used an avt, then we can't validate at this time.
	      if (avt.isSimple()) 
	      {
	      	val = Double.valueOf(value);
	      }
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    } 
	    catch (NumberFormatException nfe)
	    {
	     	handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
            return null;
	    }
	    return avt;
	
	} 
	else
    {
	    try
	    {
	      return Double.valueOf(value);
	    }
	    catch (NumberFormatException nfe)
	    {
            handleError(handler,XSLTErrorResources.INVALID_NUMBER, new Object[] {name, value}, nfe);
            return null;
	    }
    }    
  }

  /**
   * Process an attribute string of type T_QNAME into a QName value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A string that represents a potentially prefix qualified name.
   * @param owner
   *
   * @return A QName object if this attribute does not support AVT's.  Otherwise, an AVT
   *         is returned.
   *
   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
   * resolved, or the string contains syntax that is invalid for a qualified name.
   */
  Object processQNAME(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

     try 
        {	
   	      QName qname = new QName(value, handler, true);
          return qname;
        }
        catch (IllegalArgumentException ie)
        {
            // thrown by QName constructor
            handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},ie);
            return null;
        }
        catch (RuntimeException re) {
            // thrown by QName constructor
            handleError(handler,XSLTErrorResources.INVALID_QNAME, new Object[] {name, value},re);
            return null;
        }
  	}
 

  /**
   * Process an attribute string of type T_QNAME into a QName value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A string that represents a potentially prefix qualified name.
   * @param owner
   *
   * @return An AVT is returned.
   *
   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
   * resolved, or the string contains syntax that is invalid for a qualified name.
   */
  Object processAVT_QNAME(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

       AVT avt = null;
       try
       {
          avt = new AVT(handler, uri, name, rawName, value, owner);
    
          // If an AVT wasn't used, validate the value
          if (avt.isSimple())
          {
             int indexOfNSSep = value.indexOf(':');

             if (indexOfNSSep >= 0) 
             {   
                  String prefix = value.substring(0, indexOfNSSep);
                  if (!XMLChar.isValidNCName(prefix))
                  {
                     handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null);
                     return null;
                  }
             }
                 
             String localName =  (indexOfNSSep < 0)
                 ? value : value.substring(indexOfNSSep + 1); 
             
             if ((localName == null) || (localName.length() == 0) ||
                 (!XMLChar.isValidNCName(localName)))
             {    
                     handleError(handler,XSLTErrorResources.INVALID_QNAME,new Object[]{name,value },null );
                     return null;
             }
          }  
        }
        catch (TransformerException te)
        {
           // thrown by AVT constructor
          throw new org.xml.sax.SAXException(te);
        } 
    
    return avt;
 }

  /**
   * Process an attribute string of type NCName into a String
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A string that represents a potentially prefix qualified name.
   * @param owner
   *
   * @return A String object if this attribute does not support AVT's.  Otherwise, an AVT
   *         is returned.
   *
   * @throws org.xml.sax.SAXException if the string contains a prefix that can not be
   * resolved, or the string contains syntax that is invalid for a NCName.
   */
  Object processNCNAME(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {
    
    if (getSupportsAVT()) 
    {
        AVT avt = null;
        try
        {
          avt = new AVT(handler, uri, name, rawName, value, owner);
    
          // If an AVT wasn't used, validate the value
          if ((avt.isSimple()) &&  (!XMLChar.isValidNCName(value))) 
          {
             handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
             return null;
          }      
          return avt;
        }
        catch (TransformerException te)
        {
           // thrown by AVT constructor
          throw new org.xml.sax.SAXException(te);
        } 
        
    } else {
        if (!XMLChar.isValidNCName(value)) 
        {
            handleError(handler,XSLTErrorResources.INVALID_NCNAME,new Object[] {name,value},null);
            return null;
        }
        return value;
    }
 }

  /**
   * Process an attribute string of type T_QNAMES into a vector of QNames where
   * the specification requires that non-prefixed elements not be placed in a
   * namespace.  (See section 2.4 of XSLT 1.0.)
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A whitespace delimited list of qualified names.
   *
   * @return a Vector of QName objects.
   *
   * @throws org.xml.sax.SAXException if the one of the qualified name strings
   * contains a prefix that can not be
   * resolved, or a qualified name contains syntax that is invalid for a qualified name.
   */
  Vector processQNAMES(
          StylesheetHandler handler, String uri, String name, String rawName, String value)
            throws org.xml.sax.SAXException
  {

    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
    int nQNames = tokenizer.countTokens();
    Vector qnames = new Vector(nQNames);

    for (int i = 0; i < nQNames; i++)
    {
      // Fix from Alexander Rudnev
      qnames.addElement(new QName(tokenizer.nextToken(), handler));
    }

    return qnames;
  }

 /**
   * Process an attribute string of type T_QNAMES_RESOLVE_NULL into a vector
   * of QNames where the specification requires non-prefixed elements to be
   * placed in the default namespace.  (See section 16 of XSLT 1.0; the
   * <em>only</em> time that this will get called is for the
   * <code>cdata-section-elements</code> attribute on <code>xsl:output</code>.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A whitespace delimited list of qualified names.
   *
   * @return a Vector of QName objects.
   *
   * @throws org.xml.sax.SAXException if the one of the qualified name strings
   * contains a prefix that can not be resolved, or a qualified name contains
   * syntax that is invalid for a qualified name.
   */
  final Vector processQNAMESRNU(StylesheetHandler handler, String uri,
    String name, String rawName, String value)
    throws org.xml.sax.SAXException
  {

    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
    int nQNames = tokenizer.countTokens();
    Vector qnames = new Vector(nQNames);

    String defaultURI = handler.getNamespaceForPrefix("");
    for (int i = 0; i < nQNames; i++)
    {
      String tok = tokenizer.nextToken();
      if (tok.indexOf(':') == -1) {
        qnames.addElement(new QName(defaultURI,tok));
      } else {
        qnames.addElement(new QName(tok, handler));
      }
    }
    return qnames;
  }

  /**
   * Process an attribute string of type T_SIMPLEPATTERNLIST into
   * a vector of XPath match patterns.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A whitespace delimited list of simple match patterns.
   *
   * @return A Vector of XPath objects.
   *
   * @throws org.xml.sax.SAXException that wraps a
   * {@link javax.xml.transform.TransformerException} if one of the match pattern
   * strings contains a syntax error.
   */
  Vector processSIMPLEPATTERNLIST(
          StylesheetHandler handler, String uri, String name, String rawName, String value,
          ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    try
    {
      StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
      int nPatterns = tokenizer.countTokens();
      Vector patterns = new Vector(nPatterns);

      for (int i = 0; i < nPatterns; i++)
      {
        XPath pattern =
          handler.createMatchPatternXPath(tokenizer.nextToken(), owner);

        patterns.addElement(pattern);
      }

      return patterns;
    }
    catch (TransformerException te)
    {
      throw new org.xml.sax.SAXException(te);
    }
  }

  /**
   * Process an attribute string of type T_STRINGLIST into
   * a vector of XPath match patterns.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value a whitespace delimited list of string values.
   *
   * @return A StringVector of the tokenized strings.
   */
  StringVector processSTRINGLIST(StylesheetHandler handler, String uri,
                                 String name, String rawName, String value)
  {

    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
    int nStrings = tokenizer.countTokens();
    StringVector strings = new StringVector(nStrings);

    for (int i = 0; i < nStrings; i++)
    {
      strings.addElement(tokenizer.nextToken());
    }

    return strings;
  }

  /**
   * Process an attribute string of type T_URLLIST into
   * a vector of prefixes that may be resolved to URLs.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A list of whitespace delimited prefixes.
   *
   * @return A vector of strings that may be resolved to URLs.
   *
   * @throws org.xml.sax.SAXException if one of the prefixes can not be resolved.
   */
  StringVector processPREFIX_URLLIST(
          StylesheetHandler handler, String uri, String name, String rawName, String value)
            throws org.xml.sax.SAXException
  {

    StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
    int nStrings = tokenizer.countTokens();
    StringVector strings = new StringVector(nStrings);

    for (int i = 0; i < nStrings; i++)
    {
      String prefix = tokenizer.nextToken();
      String url = handler.getNamespaceForPrefix(prefix);

      if (url != null)
        strings.addElement(url);
      else
        throw new org.xml.sax.SAXException(XSLMessages.createMessage(XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, new Object[] {prefix}));
    
    }

    return strings;
  }

  /**
    * Process an attribute string of type T_PREFIXLIST into
    * a vector of prefixes that may be resolved to URLs.
    *
    * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
    * @param uri The Namespace URI, or an empty string.
    * @param name The local name (without prefix), or empty string if not namespace processing.
    * @param rawName The qualified name (with prefix).
    * @param value A list of whitespace delimited prefixes.
    *
    * @return A vector of strings that may be resolved to URLs.
    *
    * @throws org.xml.sax.SAXException if one of the prefixes can not be resolved.
    */
   StringVector processPREFIX_LIST(
           StylesheetHandler handler, String uri, String name, 
           String rawName, String value) throws org.xml.sax.SAXException
   {
    
     StringTokenizer tokenizer = new StringTokenizer(value, " \t\n\r\f");
     int nStrings = tokenizer.countTokens();
     StringVector strings = new StringVector(nStrings);

     for (int i = 0; i < nStrings; i++)
     {
       String prefix = tokenizer.nextToken();
       String url = handler.getNamespaceForPrefix(prefix);
       if (prefix.equals(Constants.ATTRVAL_DEFAULT_PREFIX) || url != null)
         strings.addElement(prefix);
       else
         throw new org.xml.sax.SAXException(
              XSLMessages.createMessage(
                   XSLTErrorResources.ER_CANT_RESOLVE_NSPREFIX, 
                   new Object[] {prefix}));
    
     }

     return strings;
   }


  /**
   * Process an attribute string of type T_URL into
   * a URL value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value non-null string that conforms to the URL syntax.
   *
   * @return The non-absolutized URL argument, in other words, the value argument.  If this 
   *         attribute supports AVT, an AVT is returned.
   *
   * @throws org.xml.sax.SAXException if the URL does not conform to the URL syntax.
   */
  Object processURL(
          StylesheetHandler handler, String uri, String name, String rawName, String value, ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    if (getSupportsAVT()) {
	    try
	    {
	      AVT avt = new AVT(handler, uri, name, rawName, value, owner);
	
		  // If an AVT wasn't used, validate the value
		 // if (avt.getSimpleString() != null) {
			   // TODO: syntax check URL value.
			    // return SystemIDResolver.getAbsoluteURI(value, 
			    //                                         handler.getBaseIdentifier());
		  //}	
	      return avt;
	    }
	    catch (TransformerException te)
	    {
	      throw new org.xml.sax.SAXException(te);
	    }  		
     } else {
    // TODO: syntax check URL value.
    // return SystemIDResolver.getAbsoluteURI(value, 
    //                                         handler.getBaseIdentifier());
     	
	    return value;
    }
  }

  /**
   * Process an attribute string of type T_YESNO into
   * a Boolean value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value A string that should be "yes" or "no".
   *
   * @return Boolean object representation of the value.
   *
   * @throws org.xml.sax.SAXException
   */
  private Boolean processYESNO(
          StylesheetHandler handler, String uri, String name, String rawName, String value)
            throws org.xml.sax.SAXException
  {

    // Is this already checked somewhere else?  -sb
    if (!(value.equals("yes") || value.equals("no")))
    {
      handleError(handler, XSLTErrorResources.INVALID_BOOLEAN, new Object[] {name,value}, null);
      return null;
   }
 
     return new Boolean(value.equals("yes") ? true : false);
  }

  /**
   * Process an attribute value.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param uri The Namespace URI, or an empty string.
   * @param name The local name (without prefix), or empty string if not namespace processing.
   * @param rawName The qualified name (with prefix).
   * @param value The unprocessed string value of the attribute.
   *
   * @return The processed Object representation of the attribute.
   *
   * @throws org.xml.sax.SAXException if the attribute value can not be processed.
   */
  Object processValue(
          StylesheetHandler handler, String uri, String name, String rawName, String value,
          ElemTemplateElement owner)
            throws org.xml.sax.SAXException
  {

    int type = getType();
    Object processedValue = null;

    switch (type)
    {
    case T_AVT :
      processedValue = processAVT(handler, uri, name, rawName, value, owner);
      break;
    case T_CDATA :
      processedValue = processCDATA(handler, uri, name, rawName, value, owner);
      break;
    case T_CHAR :
      processedValue = processCHAR(handler, uri, name, rawName, value, owner);
      break;
    case T_ENUM :
      processedValue = processENUM(handler, uri, name, rawName, value, owner);
      break;
    case T_EXPR :
      processedValue = processEXPR(handler, uri, name, rawName, value, owner);
      break;
    case T_NMTOKEN :
      processedValue = processNMTOKEN(handler, uri, name, rawName, value, owner);
      break;
    case T_PATTERN :
      processedValue = processPATTERN(handler, uri, name, rawName, value, owner);
      break;
    case T_NUMBER :
      processedValue = processNUMBER(handler, uri, name, rawName, value, owner);
      break;
    case T_QNAME :
      processedValue = processQNAME(handler, uri, name, rawName, value, owner);
      break;
    case T_QNAMES :
      processedValue = processQNAMES(handler, uri, name, rawName, value);
      break;
	case T_QNAMES_RESOLVE_NULL:
      processedValue = processQNAMESRNU(handler, uri, name, rawName, value);
      break;
    case T_SIMPLEPATTERNLIST :
      processedValue = processSIMPLEPATTERNLIST(handler, uri, name, rawName,
                                                value, owner);
      break;
    case T_URL :
      processedValue = processURL(handler, uri, name, rawName, value, owner);
      break;
    case T_YESNO :
      processedValue = processYESNO(handler, uri, name, rawName, value);
      break;
    case T_STRINGLIST :
      processedValue = processSTRINGLIST(handler, uri, name, rawName, value);
      break;
    case T_PREFIX_URLLIST :
      processedValue = processPREFIX_URLLIST(handler, uri, name, rawName,
                                             value);
      break;
    case T_ENUM_OR_PQNAME :
    	processedValue = processENUM_OR_PQNAME(handler, uri, name, rawName, value, owner);
    	break;
    case T_NCNAME :
        processedValue = processNCNAME(handler, uri, name, rawName, value, owner);
        break;
    case T_AVT_QNAME :
        processedValue = processAVT_QNAME(handler, uri, name, rawName, value, owner);
        break;
    case T_PREFIXLIST :
      processedValue = processPREFIX_LIST(handler, uri, name, rawName,
                                             value);
      break;

    default :
    }

    return processedValue;
  }

  /**
   * Set the default value of an attribute.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param elem The object on which the property will be set.
   *
   * @throws org.xml.sax.SAXException wraps an invocation exception if the
   * setter method can not be invoked on the object.
   */
  void setDefAttrValue(StylesheetHandler handler, ElemTemplateElement elem)
          throws org.xml.sax.SAXException
  {
    setAttrValue(handler, this.getNamespace(), this.getName(),
                 this.getName(), this.getDefault(), elem);
  }

  /**
   * Get the primative type for the class, if there
   * is one.  If the class is a Double, for instance,
   * this will return double.class.  If the class is not one
   * of the 9 primative types, it will return the same
   * class that was passed in.
   *
   * @param obj The object which will be resolved to a primative class object if possible.
   *
   * @return The most primative class representation possible for the object, never null.
   */
  private Class getPrimativeClass(Object obj)
  {

    if (obj instanceof XPath)
      return XPath.class;

    Class cl = obj.getClass();

    if (cl == Double.class)
    {
      cl = double.class;
    }

    if (cl == Float.class)
    {
      cl = float.class;
    }
    else if (cl == Boolean.class)
    {
      cl = boolean.class;
    }
    else if (cl == Byte.class)
    {
      cl = byte.class;
    }
    else if (cl == Character.class)
    {
      cl = char.class;
    }
    else if (cl == Short.class)
    {
      cl = short.class;
    }
    else if (cl == Integer.class)
    {
      cl = int.class;
    }
    else if (cl == Long.class)
    {
      cl = long.class;
    }

    return cl;
  }
  
  /**
   * StringBuffer containing comma delimited list of valid values for ENUM type.
   * Used to build error message.
   */
  private StringBuffer getListOfEnums() 
  {
     StringBuffer enumNamesList = new StringBuffer();            
     String [] enumValues = this.getEnumNames();

     for (int i = 0; i < enumValues.length; i++)
     {
        if (i > 0)
        {
           enumNamesList.append(' ');
        }
        enumNamesList.append(enumValues[i]);
    }        
    return enumNamesList;
  }

  /**
   * Set a value on an attribute.
   *
   * @param handler non-null reference to current StylesheetHandler that is constructing the Templates.
   * @param attrUri The Namespace URI of the attribute, or an empty string.
   * @param attrLocalName The local name (without prefix), or empty string if not namespace processing.
   * @param attrRawName The raw name of the attribute, including possible prefix.
   * @param attrValue The attribute's value.
   * @param elem The object that should contain a property that represents the attribute.
   *
   * @throws org.xml.sax.SAXException
   */
  boolean setAttrValue(
          StylesheetHandler handler, String attrUri, String attrLocalName, 
          String attrRawName, String attrValue, ElemTemplateElement elem)
            throws org.xml.sax.SAXException
  {
    if(attrRawName.equals("xmlns") || attrRawName.startsWith("xmlns:"))
      return true;
      
    String setterString = getSetterMethodName();

    // If this is null, then it is a foreign namespace and we 
    // do not process it.
    if (null != setterString)
    {
      try
      {
        Method meth;
        Object[] args;

        if(setterString.equals(S_FOREIGNATTR_SETTER))
        {
          // workaround for possible crimson bug
          if( attrUri==null) attrUri="";
          // First try to match with the primative value.
          Class sclass = attrUri.getClass();
          Class[] argTypes = new Class[]{ sclass, sclass,
                                      sclass, sclass };
  
          meth = elem.getClass().getMethod(setterString, argTypes);
  
          args = new Object[]{ attrUri, attrLocalName,
                                      attrRawName, attrValue };
        }
        else
        {
          Object value = processValue(handler, attrUri, attrLocalName,
                                      attrRawName, attrValue, elem);
          // If a warning was issued because the value for this attribute was
          // invalid, then the value will be null.  Just return
          if (null == value) return false;
                                      
          // First try to match with the primative value.
          Class[] argTypes = new Class[]{ getPrimativeClass(value) };
  
          try
          {
            meth = elem.getClass().getMethod(setterString, argTypes);
          }
          catch (NoSuchMethodException nsme)
          {
            Class cl = ((Object) value).getClass();
  
            // If this doesn't work, try it with the non-primative value;
            argTypes[0] = cl;
            meth = elem.getClass().getMethod(setterString, argTypes);
          }
  
          args = new Object[]{ value };
        }

        meth.invoke(elem, args);
      }
      catch (NoSuchMethodException nsme)
      {
        if (!setterString.equals(S_FOREIGNATTR_SETTER)) 
        {
          handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, nsme);//"Failed calling " + setterString + " method!", nsme);
          return false;
        }
      }
      catch (IllegalAccessException iae)
      {
        handler.error(XSLTErrorResources.ER_FAILED_CALLING_METHOD, new Object[]{setterString}, iae);//"Failed calling " + setterString + " method!", iae);
        return false;
      }
      catch (InvocationTargetException nsme)
      {
        handleError(handler, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
            new Object[]{ Constants.ATTRNAME_NAME, getName()}, nsme);
        return false;
      }
    }
    
    return true;
  }
  
  private void handleError(StylesheetHandler handler, String msg, Object [] args, Exception exc) throws org.xml.sax.SAXException
  {
    switch (getErrorType()) 
    {
        case (FATAL):
        case (ERROR):
                handler.error(msg, args, exc);          
                break;
        case (WARNING):
                handler.warn(msg, args);       
        default: break;
    }
  }
}
