/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.myfaces.buildtools.maven2.plugin.tagdoc;

//import org.apache.maven.doxia.sink.Sink;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.digester.AbstractObjectCreationFactory;
import org.apache.commons.digester.Digester;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenMultiPageReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.reporting.sink.SinkFactory;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.ComponentBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.ConverterBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.EventBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.EventRefBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.FacesConfigBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.FacesConfigParser;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.FacetBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.ValidatorBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ComponentFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ConverterFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.PropertyFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ValidatorFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.XIncludeFilter;
import org.codehaus.doxia.sink.Sink;
import org.codehaus.doxia.site.renderer.SiteRenderer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * Report for generating JSF tagdoc based on faces-config.xml parsing.
 * Note that this is not really an AbstractMavenMultiPageReport - the
 * secondary pages are manually generated XDoc.  I tried using the true
 * multipage report approach, and ran into Maven bugs (as of Maven 2.0.2,
 * site 2.0b4).
 *
 * @goal tagdoc
 */
public class TagdocReport extends AbstractMavenMultiPageReport
{
  protected void executeReport( Locale locale )
      throws MavenReportException
  {
    // Why the heck doesn't Maven do this for me?
    SinkFactory factory = new SinkFactory();
    factory.setSiteRenderer(getSiteRenderer());
    factory.setSiteDirectory(getOutputDirectory());
    setSinkFactory(factory);
    
    processIndex(project, resourcePath);
    try
    {
      _generateTagDocs();
    }
    catch (Exception e)
    {
      throw new MavenReportException("Couldn't generate tagdoc", e);
    }
  }

  private void _generateTagDocs() throws Exception
  {
    FacesConfigBean facesConfig = getFacesConfig();
    if (!facesConfig.hasComponents())
    {
      getLog().info("Nothing to generate - no components found");
      return;
    }


    Iterator components = facesConfig.components();
    components = new FilteredIterator(components, new SkipFilter());
    components = new FilteredIterator(components, new ComponentTagFilter());
    components = new FilteredIterator(components, new ComponentNamespaceFilter());
    
    Iterator validators = facesConfig.validators();
    validators = new FilteredIterator(validators, new ValidatorTagFilter());
    validators = new FilteredIterator(validators, new ValidatorNamespaceFilter());
    
    Iterator converters = facesConfig.converters();
    converters = new FilteredIterator(converters, new ConverterTagFilter());
    converters = new FilteredIterator(converters, new ConverterNamespaceFilter());
    
    // =-=AEW Note that only updating out-of-date components, etc. is
    // permanently tricky, even if we had proper detection in place,
    // because the index always has to have all docs
    /*
    if (!components.hasNext() && !converters.hasNext() && !validators.hasNext())
    {
      getLog().info("Nothing to generate - all docs are up to date");
      return;
    }
    */

    Set componentPages = new TreeSet();
    Set converterPages = new TreeSet();
    Set validatorPages = new TreeSet();
    
    int count = 0;
    while (components.hasNext())
    {
      String pageName = _generateComponentDoc((ComponentBean)components.next());
      if (pageName != null)
      {
        componentPages.add(pageName);
        count++;
      }
    }
    while (converters.hasNext())
    {
      String pageName = _generateConverterDoc((ConverterBean)converters.next());
      if (pageName != null)
      {
        converterPages.add(pageName);
        count++;
      }
    }
    while (validators.hasNext())
    {
      String pageName = _generateValidatorDoc((ValidatorBean)validators.next());
      if (pageName != null)
      {
        validatorPages.add(pageName);
        count++;
      }
    }


    Set otherPages = _gatherOtherTags();

    getLog().info("Generated " + count + " page(s)");

    Sink sink = getSink();
    sink.head();
    sink.title();
    sink.text("Tag library documentation");
    sink.title_();    
    sink.head_();
    sink.body();

    sink.sectionTitle1();
    sink.text("Tag library information");
    sink.sectionTitle1_();
    sink.section1();

    for (Iterator i = taglibs.entrySet().iterator(); i.hasNext(); )
    {
      Map.Entry entry = (Map.Entry)i.next();
      sink.paragraph();

      sink.bold();
      sink.text("Short name:");
      sink.bold_();
      sink.nonBreakingSpace();
      sink.text(entry.getKey().toString());
      sink.lineBreak();

      sink.bold();
      sink.text("Namespace:");
      sink.bold_();
      sink.nonBreakingSpace();
      sink.text(entry.getValue().toString());
      sink.lineBreak();

      sink.paragraph_();
    }

    sink.section1_();

    _writeIndexSection(sink, componentPages, "Components");
    _writeIndexSection(sink, converterPages, "Converters");
    _writeIndexSection(sink, validatorPages, "Validators");
    _writeIndexSection(sink, otherPages, "Miscellaneous");

    sink.body_();
  }

  private Set _gatherOtherTags()
  {
    TreeSet set = new TreeSet();
    String subDir = 
      _platformAgnosticPath(_platformAgnosticPath("xdoc/" + 
                                                  _DOC_SUBDIRECTORY));
    File siteSubDir = new File(siteDirectory, subDir);
    if (siteSubDir.exists())
    {
      String[] files = siteSubDir.list();
      for (int i = 0; i < files.length; i++)
      {
        String file = files[i];
        if (file.endsWith(".xml"))
        {
          set.add(file.substring(0, file.length() - 4));
        }
      }
    }

    return set;
  }

  private String _formatPropList(
    String[] pList, 
    String   header)
  {
    String[] nullList = {};
    return _formatPropList(pList, header, nullList);
  }

  private String _formatPropList(
    String[] pList, 
    String   header,
    String[] ignores)
  {
    String formatted = null;
    if ((pList != null) && (pList.length > 0))
    {
      // Don't know how long this will be, but 100 should be plenty.
      StringBuffer sb = new StringBuffer(100);
      sb.append("\n");
      sb.append("<b>");
      sb.append(header);
      sb.append(":</b> ");

      boolean gotOne = false;

      for (int arrInd = 0; arrInd < pList.length; arrInd++)
      {
        String curStr = pList[arrInd];
        outer:
        if (curStr != null)
        {
          for (int i = 0; i < ignores.length; i++)
          {
            String s = ignores[i];
            if ((s != null) && (s.equalsIgnoreCase(curStr)))
            {
              break outer;
            }
          }

          if (gotOne)
          {
            sb.append(", ");
          }
          gotOne = true;
          sb.append(curStr);
        }
      }
      if (gotOne)
      {
        sb.append("<br/>\n");
        formatted = sb.toString();
      }
    }
    return formatted;
  }

  private void _writeIndexSection(Sink sink, Set pages, String title)
  {
    if (pages.isEmpty())
    {
      return;
    }

    sink.sectionTitle1();
    sink.text(title);
    sink.sectionTitle1_();
    sink.section1();
    sink.table();
    sink.tableRow();
    sink.tableHeaderCell();
    sink.text("Tag Name");
    sink.tableHeaderCell_();
    sink.tableRow_();
    
    Iterator iter = pages.iterator();
    while (iter.hasNext())
    {
      sink.tableRow();
      sink.tableCell();
      
      String name = (String) iter.next();
      String tagName = "<" + name.replace('_', ':') + ">";
      
      sink.link(_DOC_SUBDIRECTORY + "/" + name + ".html");
      sink.text(tagName);
      sink.link_();
      
      sink.tableCell_();
      sink.tableRow_();
    }
    
    sink.table_();
    sink.section1_();
  }

  public boolean usePageLinkBar()
  {
    return false;
  }

  private String _toPageName(QName qName)
  {
    return _getPrefix(qName) + "_" + qName.getLocalPart();
  }
  
  private String _getQualifiedName(QName qName)
  {
    return _getPrefix(qName) + ":" + qName.getLocalPart();
  }

  private String _getPrefix(QName qName)
  {
    if ((qName.getPrefix() != null) && !"".equals(qName.getPrefix()))
    {
      return qName.getPrefix();
    }
    
    String namespace = qName.getNamespaceURI();
    if (namespace == null)
    {
      return null;
    }

    for (Iterator i = taglibs.entrySet().iterator(); i.hasNext(); )
    {
      Map.Entry entry = (Map.Entry)i.next();
      if (namespace.equals(entry.getValue()))
      {
        return (String) entry.getKey();
      }
    }

    return "unknown";
  }

  private String _generateComponentDoc(ComponentBean component)
    throws Exception
  {
    if (component.getTagName() == null)
    {
      return null;
    }
    String pageName = _toPageName(component.getTagName());

    File targetDir = new File(outputDirectory.getParentFile(), 
                              _platformAgnosticPath("generated-site/xdoc/" + 
                                                      _DOC_SUBDIRECTORY));
    targetDir.mkdirs();
    File targetFile = new File(targetDir, pageName + ".xml");

    Writer out = new OutputStreamWriter(new FileOutputStream(targetFile),
                                        "UTF-8");
    try
    {
      out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
      out.write("<document>\n");
      out.write(" <properties>\n");
      out.write("  <title>&lt;" + _getQualifiedName(component.getTagName()) + "&gt;</title>\n");
      out.write(" </properties>\n");
      out.write(" <body>\n");

      out.write(" <section name=\"Summary\">\n");
      out.write(" <p>\n");
      _writeComponentSummary(out, component);
      out.write(" </p>\n");
      out.write(" </section>\n");
      
      if (component.hasEvents(true))
      {
        out.write(" <section name=\"Events\">\n");
        out.write(" <p>\n");
        _writeComponentEvents(out, component);
        out.write(" </p>\n");
        out.write(" </section>\n");
      }
      
      if (component.hasFacets(true))
      {
        out.write(" <section name=\"Supported Facets\">\n");
        out.write(" <p>\n");
        _writeComponentFacets(out, component);
        out.write(" </p>\n");
        out.write(" </section>\n");
      }
      
      out.write(" <section name=\"Attributes\">\n");
      _writeComponentAttributes(out, component);
      out.write(" </section>\n");

      out.write(" </body>\n");
      out.write("</document>\n");
    }
    finally
    {
      out.close();
    }

    return pageName;
  }
  
  private String _generateConverterDoc(ConverterBean converter) throws IOException
  {
    if (converter.getTagName() == null)
    {
      return null;
    }

    String pageName = _toPageName(converter.getTagName());

    File targetDir = new File(outputDirectory.getParentFile(), 
                              _platformAgnosticPath("generated-site/xdoc/" + 
                                                     _DOC_SUBDIRECTORY));
    targetDir.mkdirs();
    File targetFile = new File(targetDir, pageName + ".xml");

    Writer out = new OutputStreamWriter(new FileOutputStream(targetFile),
                                        "UTF-8");
    try
    {
      out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
      out.write("<document>\n");
      out.write(" <properties>\n");
      out.write("  <title>&lt;" + _getQualifiedName(converter.getTagName()) + "&gt;</title>\n");
      out.write(" </properties>\n");
      out.write(" <body>\n");

      out.write(" <section name=\"Summary\">\n");
      out.write(" <p>\n");
      _writeConverterSummary(out, converter);
      out.write(" </p>\n");
      out.write(" </section>\n");
            
      out.write(" <section name=\"Attributes\">\n");
      _writeConverterAttributes(out, converter);
      out.write(" </section>\n");

      out.write(" </body>\n");
      out.write("</document>\n");
    }
    finally
    {
      out.close();
    }

    return pageName;
  }

  private String _generateValidatorDoc(ValidatorBean validator) throws IOException
  {
    if (validator.getTagName() == null)
    {
      return null;
    }

    String pageName = _toPageName(validator.getTagName());

    File targetDir = new File(outputDirectory.getParentFile(), 
                              _platformAgnosticPath("generated-site/xdoc/" + 
                                                      _DOC_SUBDIRECTORY));
    targetDir.mkdirs();
    File targetFile = new File(targetDir, pageName + ".xml");

    Writer out = new OutputStreamWriter(new FileOutputStream(targetFile),
                                        "UTF-8");
    try
    {
      out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
      out.write("<document>\n");
      out.write(" <properties>\n");
      out.write("  <title>&lt;" + _getQualifiedName(validator.getTagName()) + "&gt;</title>\n");
      out.write(" </properties>\n");
      out.write(" <body>\n");

      out.write(" <section name=\"Summary\">\n");
      out.write(" <p>\n");
      _writeValidatorSummary(out, validator);
      out.write(" </p>\n");
      out.write(" </section>\n");
            
      out.write(" <section name=\"Attributes\">\n");
      _writeValidatorAttributes(out, validator);
      out.write(" </section>\n");

      out.write(" </body>\n");
      out.write("</document>\n");
    }
    finally
    {
      out.close();
    }

    return pageName;
  }


  private void _writeComponentSummary(Writer out, ComponentBean bean) throws IOException
  {
    out.write("   <b>Tag name:</b> &lt;" +
              _getQualifiedName(bean.getTagName()) + "&gt;\n");
    out.write("   <br/>\n");
    

    out.write("   <b>UIComponent class:</b> ");
    String javadocURL = _platformAgnosticPath("../apidocs/" +
      bean.getComponentClass().replace('.', '/') + ".html");
    out.write("<a href=\"" + javadocURL + "\">");

    out.write(bean.getComponentClass());
    out.write("</a>");
    out.write("\n");
    out.write("   <br/>\n");
    out.write("   <b>Component type:</b> " + bean.getComponentType() +  "\n");
    out.write("   <br/>\n");

    if (_isNamingContainer(bean))
    {
      out.write("   <p><b>Naming container:</b>  Yes.  When referring to children of this " +
                "component (\"partialTriggers\", <code>findComponent()</code>, etc.), " +
                "you must prefix the child's ID with this component's ID and a colon (':').</p>");
    }
      
    String fmtd = _formatPropList(bean.getUnsupportedAgents(),
                                  "Unsupported agents",
                                  _NON_DOCUMENTED_AGENTS);
    if (fmtd != null)
    {
      out.write("   " + fmtd);
    }

    String doc = bean.getLongDescription();
    if (doc == null)
    {
      doc = bean.getDescription();
    }

    out.write(_preToSource(doc));
    out.write("\n");
  }


  private boolean _isNamingContainer(ComponentBean bean)
  {
    if (bean.isNamingContainer())
    {
      return true;
    }

    ComponentBean parent = bean.resolveSupertype();
    if (parent == null)
    {
      return false;
    }
    return _isNamingContainer(parent);
  }

  private void _writeValidatorSummary(Writer out, ValidatorBean bean) throws IOException
  {
    out.write("   <b>Tag name:</b> &lt;" +
              _getQualifiedName(bean.getTagName()) + "&gt;\n");
    out.write("   <br/>\n");
    
    out.write("   <br/>\n");
    out.write("   <b> type:</b> " + bean.getValidatorId() +  "\n");
    out.write("   <br/>\n");

    String doc = bean.getLongDescription();
    if (doc == null)
    {
      doc = bean.getDescription();
    }

    out.write(_preToSource(doc));
    out.write("\n");
  }


  private void _writeConverterSummary(Writer out, ConverterBean bean) throws IOException
  {
    out.write("   <b>Tag name:</b> &lt;" +
              _getQualifiedName(bean.getTagName()) + "&gt;\n");
    out.write("   <br/>\n");
    
    out.write("   <br/>\n");
    out.write("   <b> type:</b> " + bean.getConverterId() +  "\n");
    out.write("   <br/>\n");

    String doc = bean.getLongDescription();
    if (doc == null)
    {
      doc = bean.getDescription();
    }

    out.write(_preToSource(doc));
    out.write("\n");
  }

  static private final String _preToSource(String in)
  {
    in = in.replaceAll("<pre>", "<source><![CDATA[");
    in = in.replaceAll("</pre>", "]]></source>");
    in = in.replaceAll("<html:", "<");
    in = in.replaceAll("</html:", "</");

    return in;
  }
  
  static private final String _platformAgnosticPath(String path)
  {
      return path.replace('/', File.separatorChar);
  }


  private class GroupComparator implements Comparator
  {
    public int compare(Object o1, Object o2)
    {
      return _getGroupIndex(o1) - _getGroupIndex(o2);
    }

    public boolean equals(Object o)
    {
      return (o instanceof GroupComparator);
    }

    public int hashCode()
    {
      // Yes, this is a very strange hashCode implementation. But the
      // equals method is also very strange; any two GroupComparator
      // objects are always equal. Therefore by the java rules, any
      // two GroupComparator objects must always have the same hashCode.
      return 17;  // an arbitrary constant.
    }

    private int _getGroupIndex(Object o)
    {
      String s = (o == null) ? null : o.toString();




      if ("message".equalsIgnoreCase(s))
      {
        return 0;
      }

      if ("core".equalsIgnoreCase(s))
      {
        return 1;
      }
      if ("events".equalsIgnoreCase(s))
      {
        return 2;
      }

      if (s != null)
      {
        getLog().warn("UNKNOWN ATTRIBUTE GROUP: " + s);
      }

      return 3;
    }
  }


  private void _writeComponentAttributes(Writer out, ComponentBean bean) throws IOException
  {
    // Sort the names
    TreeSet attributes = new TreeSet();
    Iterator attrs = bean.properties(true);
    while (attrs.hasNext())
    {
      PropertyBean property = (PropertyBean) attrs.next();
      if (!property.isTagAttributeExcluded())
      {
        attributes.add(property.getPropertyName());
      }
    }

    // Now get a list of PropertyBeans
    List list = new ArrayList();
    Iterator iter = attributes.iterator();
    while (iter.hasNext())
    {
      String attrName = (String) iter.next();
      list.add(bean.findProperty(attrName, true));
    }
    

    TreeSet groups = new TreeSet(new GroupComparator());
    /* No current support for grouping
    // Make sure "null" is the representative for unknown groups
    Iterator iter = attributes.iterator();
    while (iter.hasNext())
    {
      String group = ((AttributeDoc) iter.next()).group;
      if (group != null)
      {
        groups.add(group);
      }
    }
    */

    _writeComponentAttributes(out,
                              list.iterator(),
                              bean.getComponentClass(),
                              groups.isEmpty() ? null : "Ungrouped");

    Iterator groupIter = groups.iterator();
    while (groupIter.hasNext())
    {
      _writeComponentAttributes(out,
                                list.iterator(),
                                bean.getComponentClass(),
                                (String) groupIter.next());
    }

  }


  private void _writeConverterAttributes(Writer out, ConverterBean bean) throws IOException
  {
    // Sort the names
    TreeSet attributes = new TreeSet();
    Iterator attrs = bean.properties();
    while (attrs.hasNext())
    {
      PropertyBean property = (PropertyBean) attrs.next();
      if (!property.isTagAttributeExcluded())
      {
        attributes.add(property.getPropertyName());
      }
    }

    // Now get a list of PropertyBeans
    List list = new ArrayList();
    Iterator iter = attributes.iterator();
    while (iter.hasNext())
    {
      String attrName = (String) iter.next();
      list.add(bean.findProperty(attrName));
    }
    
    _writeComponentAttributes(out,
                              list.iterator(),
                              bean.getConverterClass(),
                              null);
  }



  private void _writeValidatorAttributes(Writer out, ValidatorBean bean) throws IOException
  {
    // Sort the names
    TreeSet attributes = new TreeSet();
    Iterator attrs = bean.properties();
    while (attrs.hasNext())
    {
      PropertyBean property = (PropertyBean) attrs.next();
      if (!property.isTagAttributeExcluded())
      {
        attributes.add(property.getPropertyName());
      }
    }

    // Now get a list of PropertyBeans
    List list = new ArrayList();
    Iterator iter = attributes.iterator();
    while (iter.hasNext())
    {
      String attrName = (String) iter.next();
      list.add(bean.findProperty(attrName));
    }
    
    _writeComponentAttributes(out,
                              list.iterator(),
                              bean.getValidatorClass(),
                              null);
  }



  private void _writeComponentAttributes(Writer out,
                                         Iterator attributes,
                                         String className,
                                         String group) throws IOException
  {
    boolean writtenAnyAttributes = false;

    while (attributes.hasNext())
    {
      PropertyBean attr = (PropertyBean) attributes.next();

      /*
      if ((group == null) || "Ungrouped".equals(group))
      {
        if (doc.group != null)
          continue;
      }
      else
      {
        if (!group.equalsIgnoreCase(doc.group))
          continue;
      }
      */

      if (!writtenAnyAttributes)
      {
        writtenAnyAttributes = true;
        if (group != null)
        {
          String sectionName;
          if ("events".equalsIgnoreCase(group))
          {
            sectionName = "Javascript attributes";
          }
          else
          {
            sectionName = group + " attributes";
          }

          out.write("<subsection name=\"" + sectionName + "\">\n");
        }

        out.write("<table>\n");
        out.write("<tr>\n");
        out.write("<th>Name</th>\n");
        out.write("<th>Type</th>\n");
        out.write("<th>Supports EL?</th>\n");
        if (!_attrDocSpansColumns)
        {
          out.write("<th>Description</th>\n");
        }
        out.write("</tr>\n");
      }

      String propertyName = attr.getPropertyName();
      // Quick fix of problems with actionExpression vs. action
      // actionExpression is the MethodExpression on the component,
      // but on the tag it's 'action'
      if ("actionExpression".equals(propertyName))
      {
        propertyName = "action";
      }

      out.write("<tr>\n");
      out.write("<td>" + propertyName + "</td>");
      String type = _getDisplayType(className,
                                    propertyName,
                                    attr.getPropertyClass());

      out.write("<td>" + type + "</td>");

      String elSupported;
      // MethodBindings, "binding", and some other attributes
      // require EL support
      if (attr.isMethodBinding() || 
          attr.isMethodExpression() ||
          "binding".equals(propertyName))
      {
        // "action" doesn't require EL; all else do.
        elSupported = "action".equals(propertyName) ? "Yes" : "Only EL";
      }
      else
      {
        elSupported = attr.isLiteralOnly() ? "No" : "Yes";
      }

      out.write("<td>" + elSupported + "</td>");

      if (attr.getDescription()  != null)
      {
        String valStr = _formatPropList(attr.getPropertyValues(),
                                        "Valid Values");
        String unsupAgentsStr =
          _formatPropList(attr.getUnsupportedAgents(),
                          "Not supported on the following agents",
                          _NON_DOCUMENTED_AGENTS);
        String unsupRkStr =
          _formatPropList(attr.getUnsupportedRenderKits(),
                          "Not supported on the following renderkits");

        if (_attrDocSpansColumns)
        {
          out.write("</tr>\n");
          out.write("<tr>\n");
          out.write("<td colspan=\"3\">\n");
        }
        else
        {
          out.write("<td>\n");
        }
        
        //        out.write(EscapeUtils.escapeElementValue(doc.doc));
        if (valStr != null)
        {
          out.write(valStr);
          out.write("<br/>");
        }
        out.write(attr.getDescription());
        if (unsupAgentsStr != null)
        {
          out.write("<br/>");
          out.write(unsupAgentsStr);
        }
        if (unsupRkStr != null)
        {
          out.write("<br/>");
          out.write(unsupRkStr);
        }
        //out.write(EscapeUtils.escapeAmpersands(doc.doc));
        out.write("</td>\n");
      }

      out.write("</tr>\n");
    }

    if (writtenAnyAttributes)
    {
      out.write("</table>\n");
      if (group != null)
      {
        out.write("</subsection>\n");
      }
    }
  }

  static private String _getDisplayType(String className, String name, String type)
  {
    if (type.startsWith("java.lang."))
    {
      return type.substring("java.lang.".length());
    }
    else if ("binding".equals(name))
    {
      StringTokenizer tokens = new StringTokenizer(className, ".", true);
      String out = "";
      while (tokens.hasMoreTokens())
      {
        String token = tokens.nextToken();
        out = out + token;
        // Give ourselves an opportunity for a line break after "component.";
        if (out.endsWith("component."))
        {
          out = out + "<wbr/>";
        }
      }

      return out;
    }

    return type;
  }

  private void _writeComponentEvents(Writer out, ComponentBean bean) throws IOException
  {
    out.write("<table>\n");
    out.write("<tr>\n");
    out.write("<th>Type</th>\n");
    out.write("<th>Phases</th>\n");
    out.write("<th>Description</th>\n");
    out.write("</tr>\n");

    Iterator iter = bean.events(true);
    while (iter.hasNext())
    {
      EventRefBean eventRef = (EventRefBean) iter.next();
      EventBean    event = eventRef.resolveEventType();

      out.write("<tr>\n");
      out.write("<td>" + event.getEventClass() + "</td>");
      out.write("<td nowrap=\"nowrap\">");
      String[] phases = eventRef.getEventDeliveryPhases();
      for (int i = 0; i < phases.length; i++)
      {
        if (i > 0)
        {
          out.write(",<br/>");
        }
        out.write((String) phases[i]);
      }

      out.write("</td>");
      out.write("<td>" + event.getDescription() + "</td>");
      out.write("</tr>\n");
    }

    out.write("</table>\n");
  }





  private void _writeComponentFacets(Writer out, ComponentBean bean) throws IOException
  {
    // Sort the facets
    TreeSet facetNames = new TreeSet();
    Iterator iter = bean.facets(true);
    while (iter.hasNext())
    {
      facetNames.add(((FacetBean) iter.next()).getFacetName());
    }

    out.write("<table>\n");
    out.write("<tr>\n");
    out.write("<th>Name</th>\n");
    out.write("<th>Description</th>\n");
    out.write("</tr>\n");

    Iterator nameIter = facetNames.iterator();
    while (nameIter.hasNext())
    {
      String name = (String) nameIter.next();
      FacetBean facet = bean.findFacet(name, true);
      out.write("<tr>\n");
      out.write("<td>" + facet.getFacetName() + "</td>");
      out.write("<td>");
      out.write(facet.getDescription());
      out.write("</td>\n");
      out.write("</tr>\n");
    }

    out.write("</table>\n");
  }




  protected MavenProject getProject()
  {
    return project;
  }
  
  protected String getOutputDirectory()
  {
    return outputDirectory.getAbsolutePath();
  }

  protected SiteRenderer getSiteRenderer()
  {
    return siteRenderer;
  }

  public String getName( Locale locale )
  {
    return "JSF Tag Documentation";
  }

  public String getDescription( Locale locale )
  {
    return "Documentation for JSF Tags";
  }

  public String getOutputName()
  {
    return "tagdoc";
  }

  protected void processIndex(
    MavenProject project,
    String       resourcePath) throws MavenReportException
  {
    _facesConfig = new FacesConfigBean();

    URL[] index = readIndex(project);
    for (int i=0; i < index.length; i++)
    {
      processIndexEntry(index[i]);
    }
  }

  protected void processIndexEntry(
    URL entry) throws MavenReportException
  {
    try
    {
      new FacesConfigParser().merge(_facesConfig, entry);
    }
    catch (MojoExecutionException e)
    {
      throw new MavenReportException("Couldn't parse faces config",e);
    }
  }

  protected FacesConfigBean getFacesConfig()
  {
    return _facesConfig;
  }


  protected List getMasterConfigs(
    MavenProject project) throws MavenReportException
  {
    String resourcePath = "META-INF/maven-faces-plugin/faces-config.xml";
    return getCompileDependencyResources(project, resourcePath);
  }

  protected List getCompileDependencyResources(
    MavenProject project,
    String       resourcePath) throws MavenReportException
  {
    try
    {
      ClassLoader cl = createCompileClassLoader(project);
      Enumeration e = cl.getResources(resourcePath);
      List urls = new ArrayList();
      while (e.hasMoreElements())
      {
        URL url = (URL)e.nextElement();
        urls.add(url);
      }
      return Collections.unmodifiableList(urls);
    }
    catch (IOException e)
    {
      throw new MavenReportException("Unable to get resources for path " +
                                       "\"" + resourcePath + "\"", e);
    }

  }

  protected URL[] readIndex(
    MavenProject project) throws MavenReportException
  {
    try
    {
      // 1. read master faces-config.xml resources
      List masters = getMasterConfigs(project);
      if (masters.isEmpty())
      {
        getLog().warn("Master faces-config.xml not found");
        return new URL[0];
      }
      else
      {
        List entries = new LinkedList();

        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        // requires JAXP 1.3, in JavaSE 5.0
        // spf.setXIncludeAware(false);

        for (Iterator i=masters.iterator(); i.hasNext();)
        {
          URL url = (URL)i.next();
          Digester digester = new Digester(spf.newSAXParser());
          digester.setNamespaceAware(true);

          // XInclude
          digester.setRuleNamespaceURI(XIncludeFilter.XINCLUDE_NAMESPACE);
          digester.addCallMethod("faces-config/include", "add", 1);
          digester.addFactoryCreate("faces-config/include",
                                    URLCreationFactory.class);
          digester.addCallParam("faces-config/include", 0, 0);

          digester.push(url);
          digester.push(entries);
          digester.parse(url.openStream());
        }

        return (URL[])entries.toArray(new URL[0]);
      }
    }
    catch (ParserConfigurationException e)
    {
      throw new MavenReportException("Failed to parse master config", e);
    }
    catch (SAXException e)
    {
      throw new MavenReportException("Failed to parse master config", e);
    }
    catch (IOException e)
    {
      throw new MavenReportException("Failed to parse master config", e);
    }
  }

  private ClassLoader createCompileClassLoader(
    MavenProject project) throws MavenReportException
  {
    Thread current = Thread.currentThread();
    ClassLoader cl = current.getContextClassLoader();

    try
    {
      List classpathElements = project.getCompileClasspathElements();
      if (!classpathElements.isEmpty())
      {
        String[] entries = (String[])classpathElements.toArray(new String[0]);
        URL[] urls = new URL[entries.length];
        for (int i=0; i < urls.length; i++)
        {
          urls[i] = new File(entries[i]).toURL();
        }
        cl = new URLClassLoader(urls, cl);
      }
    }
    catch (DependencyResolutionRequiredException e)
    {
      throw new MavenReportException("Error calculating scope classpath", e);
    }
    catch (MalformedURLException e)
    {
      throw new MavenReportException("Error calculating scope classpath", e);
    }

    return cl;
  }

  static public class URLCreationFactory extends AbstractObjectCreationFactory
  {
    public Object createObject(
      Attributes attributes) throws MalformedURLException
    {
      String href = attributes.getValue("href");
      if (href == null)
      {
        throw new IllegalStateException("Missing href attribute");
      }

      URL master = (URL)digester.getRoot();
      return new URL(master, href);
    }
  }

  static protected class SkipFilter extends ComponentFilter
  {
    protected boolean accept(
      ComponentBean component)
    {
      String componentType = component.getComponentType();

      // always skip API and base class generation
      return (!componentType.startsWith("javax") &&
              !componentType.endsWith("Base"));
    }
  }



  private class ComponentNamespaceFilter extends ComponentFilter
  {
    public ComponentNamespaceFilter()
    {
    }

    protected boolean accept(
      ComponentBean component)
    {
      if (component.getTagName() == null)
      {
        return false;
      }

      return taglibs.containsValue(component.getTagName().getNamespaceURI());
    }
  }

  private class ValidatorNamespaceFilter extends ValidatorFilter
  {
    public ValidatorNamespaceFilter()
    {
    }

    protected boolean accept(
      ValidatorBean component)
    {
      if (component.getTagName() == null)
      {
        return false;
      }

      return taglibs.containsValue(component.getTagName().getNamespaceURI());
    }
  }

  private class ConverterNamespaceFilter extends ConverterFilter
  {
    public ConverterNamespaceFilter()
    {
    }

    protected boolean accept(
      ConverterBean component)
    {
      if (component.getTagName() == null)
      {
        return false;
      }

      return taglibs.containsValue(component.getTagName().getNamespaceURI());
    }
  }



  static final protected class TagAttributeFilter extends PropertyFilter
  {
    protected boolean accept(
      PropertyBean property)
    {
      return (!property.isTagAttributeExcluded());
    }
  }

  static final protected class ComponentTagFilter extends ComponentFilter
  {
    protected boolean accept(
      ComponentBean component)
    {
      return (component.getTagName() != null);
    }
  }

  static final protected class ConverterTagFilter extends ConverterFilter
  {
    protected boolean accept(
      ConverterBean converter)
    {
      return (converter.getTagClass() != null);
    }
  }

  static final protected class ValidatorTagFilter extends ValidatorFilter
  {
    protected boolean accept(
      ValidatorBean validator)
    {
      return (validator.getTagClass() != null);
    }
  }


  private FacesConfigBean _facesConfig;



  // todo: make this configurable?
  private boolean _attrDocSpansColumns = false;

  /**
   * Specifies the directory where the report will be generated
   *
   * @parameter default-value="${project.reporting.outputDirectory}"
   * @required
   */
  private File outputDirectory;
  

  /**
   * Directory where the original site is present.
   * (TRIED using ${baseDir}/src/site;  that inserted a 'null' into
   * the string for some reason.  TRIED using ${siteDirectory},
   * which was undefined.  TRIED ${project.directory}src/site; which also
   * inserted a null.  ${project.build.directory}/../src/site seems to work,
   * though it assumes that ${project.build.directory} is 
   * ${project.directory}/target.
   * 
   * @parameter default-value="${project.build.directory}/../src/site/"
   * @required
   */
  private File siteDirectory;

  /**
   * @parameter expression="${project}"
   * @required
   * @readonly
   */
  private MavenProject project;

  /**
   * @parameter
   * @required
   */
  private Map taglibs;

  /**
   * @parameter expression="META-INF/maven-faces-plugin/faces-config.xml"
   * @required
   * @readonly
   */
  private String resourcePath;


  /**
   * @component
   * @required
   * @readonly
   */
  private SiteRenderer siteRenderer;

  static private final String _DOC_SUBDIRECTORY = "tagdoc";
  static private final String[] _NON_DOCUMENTED_AGENTS = {"phone", "voice"};

}
