/*
 *  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.trinidadbuild.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.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
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.trinidadbuild.plugin.faces.parse.AbstractTagBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ComponentBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ConverterBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.EventBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.EventRefBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ExampleBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.FacesConfigBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.FacesConfigParser;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.FacetBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ScreenshotBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ValidatorBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ComponentFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ConverterFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.PropertyFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ValidatorFilter;
import org.apache.myfaces.trinidadbuild.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;
    }

    // Need to cycle through the components two times, hence need two iterators.
    // components Iterator will be used when actually writing out the tag doc
    // compIter Iterator will be used when creating the maps of component relationships
    Iterator<ComponentBean> components = facesConfig.components();
    components = new FilteredIterator(components, new SkipFilter());
    components = new FilteredIterator(components, new ComponentTagFilter());
    components = new FilteredIterator(components, new ComponentNamespaceFilter());

    Iterator<ComponentBean> compIter = facesConfig.components();
    compIter = new FilteredIterator(compIter, new SkipFilter());
    compIter = new FilteredIterator(compIter, new ComponentTagFilter());
    compIter = new FilteredIterator(compIter, new ComponentNamespaceFilter());

    // compTypeMap holds a map of compononent types to tag names that implement that component type
    // The map is built using getComponentType method on the component bean to determine the
    // component type of a given tag name
    Map<String, List<QName>>  compTypeMap = new HashMap<String, List<QName>> ();
    // contractMap holds a map of contract name to tag names that satisify that contract.
    // The map is built using the getSatisfiedContracts method API on the component bean to determine
    // which contracts are satisfied for a given tagname
    Map<String, List<QName>> contractMap = new HashMap<String, List<QName>>();
    while (compIter.hasNext())
    {
      ComponentBean compBean = compIter.next();
      List<QName> tagNames;
      String compType = compBean.getComponentType();
      if (compType != null &&
          compTypeMap.containsKey (compType) &&
          compBean.getTagName() != null)
      {
        // the component type map already contains an entry for this component type
        tagNames = compTypeMap.get(compType);
      }
      else
      {
        // the component type map does not contain an entry for this component type
        // so create a new ArrayList that will be used to store the tag names of
        // component that have this component type
        tagNames = new ArrayList<QName>();
      }
      tagNames.add(compBean.getTagName());
      compTypeMap.put (compType, tagNames);

      if (compBean.hasSatisfiedContracts())
      {
        Iterator<String> satContractsIter = compBean.satisfiedContracts();
        while (satContractsIter.hasNext())
        {
          String satContract = satContractsIter.next();
          if (contractMap.containsKey (satContract))
          {
            // the contract map already contains an entry for this contract
            tagNames = contractMap.get(satContract);
          }
          else
          {
            // the contract map does not contain an entry for this contract, so
            // create a new ArrayList which will be used to store the tag names of
            // components that satisfy this contract
            tagNames = new ArrayList<QName>();
          }
          tagNames.add(compBean.getTagName());
          contractMap.put (satContract, tagNames);
        }
      }
    }

    Iterator<ValidatorBean> validators = facesConfig.validators();
    validators = new FilteredIterator(validators, new ValidatorTagFilter());
    validators = new FilteredIterator(validators, new ValidatorNamespaceFilter());

    Iterator<ConverterBean> 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(components.next(), compTypeMap, contractMap);
      if (pageName != null)
      {
        componentPages.add(pageName);
        count++;
      }
    }
    while (converters.hasNext())
    {
      String pageName = _generateConverterDoc(converters.next());
      if (pageName != null)
      {
        converterPages.add(pageName);
        count++;
      }
    }
    while (validators.hasNext())
    {
      String pageName = _generateValidatorDoc(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<Map.Entry> i = taglibs.entrySet().iterator(); i.hasNext(); )
    {
      Map.Entry 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 _formatTagList(
    Iterator<String> strIter,
    Map <String, List<QName>> pMap,
    String header)
  {
    String formatted = null;

    // Don't know how long this will be, but 300 should be plenty.
    StringBuffer sb = new StringBuffer(300);
    sb.append("\n");

    // In the case of the component summary, the header is written out in a separate table cell, and so no
    // header text is passed into this method
    if (header != null && !header.isEmpty())
    {
      sb.append("<b>");
      sb.append(header);
      sb.append(":</b> ");
    }

    boolean gotOne = false;
    while (strIter.hasNext())
    {
      List<QName> tagNameList = pMap.get(strIter.next());
      if (tagNameList != null && !tagNameList.isEmpty())
      {
        Iterator<QName> tagNameIter  = tagNameList.iterator();

        while (tagNameIter.hasNext())
        {
          QName tagName = tagNameIter.next();

          if (gotOne)
          {
            sb.append(", ");
          }
          String tagdocURL = _platformAgnosticPath("../tagdoc/" +
            _toPageName(tagName) + ".html");
          sb.append("<a href=\"" + tagdocURL + "\">");
          sb.append(_getQualifiedName(tagName));
          sb.append("</a>");
          gotOne = true;
          }
        }
      }
      if (gotOne)
      {
        sb.append("<br/>\n");
        formatted = sb.toString();
      }
    return formatted;
  }

  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");

      // In the case of the component summary section the header text is written out
      // in a separate table cell, so no header text is passed into this method
      if (header != null && !header.isEmpty())
      {
      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<String> iter = pages.iterator();
    while (iter.hasNext())
    {
      sink.tableRow();
      sink.tableCell();

      String name = 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<Map.Entry> i = taglibs.entrySet().iterator(); i.hasNext(); )
    {
      Map.Entry entry = i.next();
      if (namespace.equals(entry.getValue()))
        return (String) entry.getKey();
    }

    return "unknown";
  }

  private String _generateComponentDoc(ComponentBean component, Map<String, List<QName>> compTypeMap, Map <String, List<QName>> contractMap)
    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, contractMap);
      out.write(" </p>\n");
      out.write(" </section>\n");

      _writeScreenshots(out, component);

      _writeExamples(out, component);

      _writeAccessibilityGuidelines(out, component);

      if (component.isClientBehaviorHolder())
      {
        out.write(" <section name=\"Supported Client Events for Client Behaviors\">\n");
        out.write(" <p>\n");
        _writeComponentClientEvents(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, compTypeMap);
        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");

      _writeScreenshots(out, converter);

      _writeExamples(out, converter);

      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");

      _writeScreenshots(out, validator);

      _writeExamples(out, validator);

      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, Map <String, List<QName>> contractMap) throws IOException
  {
    // In order to align all the Summary parts, create an HTML table.  The first column will be in bold, the second column in normal font.
    // The rows of the table are:
    // 1. Tag name
    // 2. Java class
    // 3. JavaScript class (optional)
    // 4. Component type
    // 5. Required ancestors (optional)
    // 6. Naming container (optional)
    // 7. Unsupported agents (optional)

    out.write("<div class=\'summary\'>\n");
    out.write("<table>\n");
    out.write("<tr>\n");
    out.write("<td><b>Tag Name:</b></td>");
    out.write("<td>&lt;" + _getQualifiedName(bean.getTagName()) + "&gt;</td>\n");
    out.write("</tr>\n");

    out.write("<tr>\n");
    out.write("<td><b>Java Class:</b></td>");
    String javadocURL = _platformAgnosticPath("../apidocs/" +
      bean.getComponentClass().replace('.', '/') + ".html");
    out.write("<td><a href=\"" + javadocURL + "\">");
    out.write(bean.getComponentClass());
    out.write("</a></td>\n");
    out.write("</tr>\n");

    // Write out the corresponding Java Script class for this component with a link to its JavaScript doc
    String jsClass = bean.getJsComponentClass();
    if (jsClass != null && !jsClass.isEmpty())
    {
      out.write("<tr>\n");
      out.write("<td><b>JavaScript Class:</b></td>");
      String jsdocURL = _platformAgnosticPath("../js_docs_out/" + jsClass.replace('.', '/') + ".html");
      out.write("<td><a href=\"" + jsdocURL + "\">");
      out.write(jsClass);
      out.write("</a></td>\n");
      out.write("</tr>\n");
    }

    out.write("<tr>\n");
    out.write("<td><b>Component Type:</b></td>");
    out.write("<td>" + bean.getComponentType() +  "</td>\n");
    out.write("</tr>\n");

    if (bean.hasRequiredAncestorContracts())
    {
      String formattedAncestors = _formatTagList ( bean.requiredAncestorContracts(),
                                                   contractMap,
                                                   null);
      out.write("<tr>\n");
      out.write("<td><b>Required Ancestor Tag(s):</b></td>");
      out.write ("<td>" + formattedAncestors + "</td>");
      out.write("</tr>\n");
    }

    if (_isNamingContainer(bean))
    {
      out.write("<tr>\n");
      out.write("<td><b>Naming Container:</b></td>");
      out.write("<td>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 (':').</td>");
      out.write("</tr>\n");
    }

    String fmtd = _formatPropList(bean.getUnsupportedAgents(),
                                  null,
                                  _NON_DOCUMENTED_AGENTS);
    if (fmtd != null)
    {
      out.write("<tr>\n");
      out.write("<td><b>Unsupported Agent(s):</b></td>");
      out.write("<td>" + fmtd + "</td>");
      out.write("</tr>\n");
    }

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

    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("<div class=\'summary\'>\n");
    out.write("<table>\n");

    out.write("<tr>\n");
    out.write("<td><b>Tag Name:</b></td>");
    out.write("<td>" + _getQualifiedName(bean.getTagName()) + "&gt;</td>\n");
    out.write("</tr>\n");

    out.write("<tr>\n");
    out.write("<td><b>Type:</b></td>");
    out.write("<td>" + bean.getValidatorId() +  "</td>\n");
    out.write("</tr>\n");
    out.write("</table>\n");
    out.write("</div>\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("<div class=\'summary\'>\n");
    out.write("<table>\n");

    out.write("<tr>\n");
    out.write("<td><b>Tag Name:</b></td>");
    out.write("<td>" + _getQualifiedName(bean.getTagName()) + "&gt;</td>\n");
    out.write("</tr>\n");

    out.write("<tr>\n");
    out.write("<td><b>Type:</b></td>");
    out.write("<td>" + bean.getConverterId() +  "</td>\n");
    out.write("</tr>\n");
    out.write("</table>\n");
    out.write("</div>\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);
    }

    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<String> attributes = new TreeSet<String>();
    Iterator<PropertyBean> attrs = bean.properties(true);
    attrs = new FilteredIterator(attrs, new NonHiddenFilter());

    while (attrs.hasNext())
    {
      PropertyBean property = attrs.next();
      if (!property.isTagAttributeExcluded())
        attributes.add(property.getPropertyName());
    }

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

    TreeSet<String> groups = new TreeSet<String>(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<String> groupIter = groups.iterator();
    while (groupIter.hasNext())
    {
      _writeComponentAttributes(out,
                                list.iterator(),
                                bean.getComponentClass(),
                                groupIter.next());
    }
  }

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

    // Now get a list of PropertyBeans
    List list = new ArrayList();
    Iterator<String> iter = attributes.iterator();
    while (iter.hasNext())
    {
      String attrName = 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<PropertyBean> attrs = bean.properties();
    while (attrs.hasNext())
    {
      PropertyBean property = attrs.next();
      if (!property.isTagAttributeExcluded())
        attributes.add(property.getPropertyName());
    }

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

    _writeComponentAttributes(out,
                              list.iterator(),
                              bean.getValidatorClass(),
                              null);
  }



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

    while (attributes.hasNext())
    {
      PropertyBean attr = 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");

        // The default value for the attribute. defaultValueStr will be null if no
        // default value is specified via <default-value> in component xml file.
        // Since _formatPropList takes an array as the first input param, covert the default
        // value into a single item array when calling formatPropList
        String defaultValueStr = _formatPropList (new String[] { attr.getDefaultValue() },
                                        "Default Value");

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

        if (defaultValueStr != null)
        {
          out.write(defaultValueStr);
        }

        // if we print out a list of possible values and/or a default value for the attribute,
        // then enter a line break before printing out other information about the attribute.
        if (valStr != null || defaultValueStr != null)
        {
          out.write("<br/>");
        }

        if (attr.getDeprecated() != null)
        {
          out.write("<b>");
          out.write(attr.getDeprecated());
          out.write("</b>");
        }

        if (attr.isNoOp())
        {
          out.write("<b>");
          out.write("This property has a no-op setter for both the client and server components effectively making it a read-only property.");
          out.write("</b>");
        }

        if (attr.isNoOp() || attr.getDeprecated() != null)
        {
          out.write("<br/><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 _writeComponentClientEvents(
    Writer        out,
    ComponentBean bean
    ) throws IOException
  {
    String defaultEvent = bean.getDefaultEventName();

    out.write("<table>\n<tbody>\n<tr>\n<td>\n<ul>\n");

    String[] eventNames = bean.getEventNames();
    int size = eventNames.length;
    String[] dest = new String[size];
    System.arraycopy(eventNames, 0, dest, 0, size);
    Arrays.sort(dest);
    // create 3 columns to better utilize the space on the page
    int numRows = (int)Math.ceil(size / 3d);

    for (int i = 0; i < size; ++i)
    {
      if (i > 0 && (i % numRows) == 0)
      {
        out.write("</ul>\n</td>\n<td>\n<ul>\n");
      }
      String eventName = dest[i];
      out.write("<li>");
      out.write(eventName);
      if (eventName.equals(defaultEvent))
      {
        out.write(" <small>(default)</small>");
      }
      out.write("</li>\n");
    }
    out.write("</ul>\n</td>\n</tr>\n</tbody>\n</table>\n");
  }

  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<EventRefBean> iter = bean.events(true);
    while (iter.hasNext())
    {
      EventRefBean eventRef = 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(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, Map<String, List<QName>> compTypeMap) throws IOException
  {
    // Sort the facets
    TreeSet facetNames = new TreeSet();
    Iterator<FacetBean> iter = bean.facets(true);
    while (iter.hasNext())
    {
      FacetBean facetBean = iter.next();
      if (!facetBean.isHidden())
      {
        facetNames.add(facetBean.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<String> nameIter = facetNames.iterator();
    while (nameIter.hasNext())
    {
      String name = nameIter.next();
      FacetBean facet = bean.findFacet(name, true);
      out.write("<tr>\n");
      out.write("<td>" + facet.getFacetName() + "</td>");
      out.write("<td>");

      if (facet.hasAllowedChildComponents())
      {
        String formattedChildComps = _formatTagList (facet.allowedChildComponents(), compTypeMap, "Allowed Child Components");
        out.write (formattedChildComps);
        out.write("<br/>");
      }

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

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

  private void _writeExamples(Writer out, AbstractTagBean bean) throws IOException
  {
    if (!bean.hasExamples())
      return;

    ExampleBean exBean = null;

    // Write header
    out.write(" <section name=\"Code Example(s)\">\n");
    out.write(" <p>\n");
    out.write("   <html>\n");

    // Go through each example, write its description
    // followed by the example source code.
    Iterator<ExampleBean> iter = bean.examples();
    while (iter.hasNext())
    {
      exBean = iter.next();
      String desc   = exBean.getSourceDescription();
      String source = exBean.getSourceCode();

      if (desc != null)
      {
        desc = desc.replaceAll("<", "&lt;");
        desc = desc.replaceAll(">", "&gt;");

        if (!"".equals(desc))
          out.write("   <p>" + desc + "</p>");
      }

      if (source != null)
      {
        source = source.replaceAll("<", "&lt;");
        source = source.replaceAll(">", "&gt;");
        if (!"".equals(source))
        {
          out.write("    <div class=\'source\'>\n");
          out.write("      <pre>\n" + source + "</pre>\n");
          out.write("    </div>\n");
        }
      }
    }
    out.write("   </html>\n");
    out.write(" </p>\n");
    out.write(" </section>\n");
  }

  private void _writeScreenshots(Writer out, AbstractTagBean bean) throws IOException
  {
    if (!bean.hasScreenshots())
      return;

    ScreenshotBean ssBean = null;

    // Write header
    out.write(" <section name=\"Screenshot(s)\">\n");
    out.write(" <p>\n");
    out.write("   <html>\n");

    // Go through each screenshot, write its image
    // followed by the image's caption.
    Iterator<ScreenshotBean> iter = bean.screenshots();
    while (iter.hasNext())
    {
      ssBean = iter.next();
      String desc   = ssBean.getDescription();
      String img = ssBean.getImage();

      out.write("    <div class=\'screenshot\'>\n");

      if (img != null)
      {
        if (!"".equals(img))
        {
          out.write(img);
        }
      }

      if (desc != null)
      {
        desc = desc.replaceAll("<", "&lt;");
        desc = desc.replaceAll(">", "&gt;");

        if (!"".equals(desc))
        {
          out.write("<br/>");
          out.write(desc + "\n");
        }
      }
      out.write("    </div>\n");

      // create extra space between each screenshot to ensure it is clear which description
      // text belongs to which image
      if (iter.hasNext())
      {
        out.write("<br/>");
      }
    }
    out.write("   </html>\n");
    out.write(" </p>\n");
    out.write(" </section>\n");
  }

  // Write out the accessibility Guidelines for the component.  Accessibility Guidelines
  // help the application developer to create an application that can be used by users that e.g.
  // use a screen reader (e.g JAWS).  Oftentimes, in order to be accessibility compliant (e.g. section 508
  // compliant) an application developer needs to specify metadata for the screenreader application
  // to be able to correctly interpret the application for the blind user.  The accessibility guideline
  // can be associated with the Component itself, with a specific attribute of the component
  // or with a specific facet of the component.  All accessibility guidelines are printed out
  // together in an "Accessibility Guidelines" section, with the component-generic guidelines
  // listed first, followed by the attribute specific guidelines and finally the facet-specific
  // guidelines
  private void _writeAccessibilityGuidelines(Writer out, ComponentBean bean) throws IOException
  {
    // accAttributes and accFacets are sorted lists of attributes and facets, respectively,
    // that have an associated accessibility guideline
    TreeSet<PropertyBean> accAttributes = new TreeSet<PropertyBean>();
    TreeSet<String> accFacets = new TreeSet<String>();

    // see if any of the component's properties has an associated accessibility guideline
    Iterator<PropertyBean> attrs = bean.properties();
    while (attrs.hasNext())
    {
      PropertyBean property = attrs.next();
      if (!property.isTagAttributeExcluded() && property.hasAccessibilityGuidelines())
      {
        accAttributes.add(property);
      }
    }

    // see if any of the component's facets has an associated accessibility guideline
    if (bean.hasFacets())
    {
      Iterator<FacetBean> facets = bean.facets(true);
      while (facets.hasNext())
      {
        FacetBean facetBean = facets.next();
        if (!facetBean.isHidden() && facetBean.hasAccessibilityGuidelines())
        {
          accFacets.add(facetBean.getFacetName());
        }
      }
    }

    // if neither the component nor the component's attributes nor the component's facets
    // has an accessibility guideline, return
    if (!bean.hasAccessibilityGuidelines() && accAttributes.isEmpty() && accFacets.isEmpty())
      return;

    String accGuideline;

    // Write header
    out.write(" <section name=\"Accessibility Guideline(s)\">\n");
    out.write(" <p>\n");
    out.write("   <html>\n");
    out.write("     <ul>");

    // write out component-generic accessibility guidelines, i.e. accessibility
    // guidelines that apply to the component as a whole, not associated with a
    // specific attribute
    if (bean.hasAccessibilityGuidelines())
    {
      Iterator<String> iter = bean.accessibilityGuidelines();
      while (iter.hasNext())
      {
        accGuideline = iter.next();
        _writeAccessibilityGuideline(out, "", accGuideline);
      }
    }

    // Write out attribute-specific accessibility guidelines.  Each attribute can have
    // one or more associated accessibility guidelines.
    if (!accAttributes.isEmpty())
    {
      Iterator<PropertyBean> propIter = accAttributes.iterator();
      while (propIter.hasNext())
      {
        PropertyBean property = propIter.next();
        Iterator<String> propAccIter = property.accessibilityGuidelines();
        while (propAccIter.hasNext())
        {
          accGuideline = propAccIter.next();
          _writeAccessibilityGuideline(out, property.getPropertyName() + " attribute", accGuideline);
        }
      }
    }

    // Write out facet-specific accessibility guidelines. A facet in the accFacets iterator
    // can have one or more associated accessibility guidelines
    if (!accFacets.isEmpty())
    {
      Iterator<String> facetIter = accFacets.iterator();
      while (facetIter.hasNext())
      {
        String facetName = facetIter.next();
        FacetBean facet = bean.findFacet(facetName, true);

        Iterator<String> facetAccIter = facet.accessibilityGuidelines();
        while (facetAccIter.hasNext())
        {
          accGuideline = facetAccIter.next();
          _writeAccessibilityGuideline(out, facetName + " facet", accGuideline);
        }
      }
    }

    out.write("     </ul>");
    out.write("   </html>\n");
    out.write(" </p>\n");
    out.write(" </section>\n");
  }

  // Write out an Accessibility Guideline
  // A bullet in an unordered list, followed by (optionally) the reference name in bold, e.g. the
  // name of the attribute or name of the facet which the guideline applies to, then the text
  // of the accessibility guideline.  For accessibility guidelines on the component, the referenceName
  // attribute is left blank.
  private void _writeAccessibilityGuideline(Writer out, String referenceName, String desc) throws IOException
  {
    out.write("    <div class=\'accGuideline\'>\n");
    out.write("<li>");

    if (!"".equals(referenceName))
    {
      out.write("<b>");
      out.write(referenceName);
      out.write("</b>: ");
    }

    if (desc != null)
    {
      if (!"".equals(desc))
      {
        out.write(desc + "\n");
      }
    }

    out.write("</li>");
    out.write("    </div>\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<URL> i=masters.iterator(); i.hasNext();)
        {
          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);
    }
  }

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

  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"};

}
