/*
 *  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.faces.generator.component;

import org.apache.maven.plugin.logging.Log;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.GeneratorHelper;
import org.apache.myfaces.buildtools.maven2.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.*;
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.SourceTemplate;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.Util;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class AbstractComponentGenerator implements ComponentGenerator
{

  private Log _log;
  boolean _is12;

  public AbstractComponentGenerator(Log log, boolean is12)
  {
    _log = log;
    _is12 = is12;
  }

  protected Log getLog()
  {
    return _log;
  }

  public void writeClassBegin(
      PrettyWriter out,
      String className,
      String superclassName,
      ComponentBean component,
      SourceTemplate template)
  {
    out.println("/**");

    // TODO: restore description (needs escaping?)
//    String description = component.getDescription();
//    if (description != null)
//    {
//      out.println(" *");
//      out.println(" * " + convertMultilineComment(description));
//    }

    String longDescription = component.getLongDescription();
    if (longDescription != null)
    {
      out.println(" *");
      out.println(" * " + convertMultilineComment(longDescription));
    }

    if (component.hasEvents(true))
    {
      // the events javadoc
      out.println(" *");
      out.println(" * <h4>Events:</h4>");
      out.println(" * <table border=\"1\" width=\"100%\" cellpadding=\"3\" summary=\"\">");
      out.println(" * <tr bgcolor=\"#CCCCFF\" class=\"TableHeadingColor\">");
      out.println(" * <th align=\"left\">Type</th>");
      out.println(" * <th align=\"left\">Phases</th>");
      out.println(" * <th align=\"left\">Description</th>");
      out.println(" * </tr>");
      Iterator events = component.events(true);
      while (events.hasNext())
      {
        EventRefBean eventRef = (EventRefBean) events.next();
        EventBean event = eventRef.resolveEventType();
        if (event != null)
        {
          String eventClass = event.getEventClass();
          String[] eventPhases = eventRef.getEventDeliveryPhases();
          String eventDescription = event.getDescription();
          out.println(" * <tr class=\"TableRowColor\">");
          out.println(" * <td valign=\"top\"><code>" + eventClass + "</code></td>");
          out.print(" * <td valign=\"top\" nowrap>");
          if (eventPhases != null)
          {
            for (int i = 0; i < eventPhases.length; i++)
            {
              if (i > 0)
                out.print("<br>");
              out.print(eventPhases[i]);
            }
          }
          out.println("</td>");
          out.println(" * <td valign=\"top\">" + eventDescription + "</td>");
          out.println(" * </tr>");
        }
      }
      out.println(" * </table>");
    }

    if (!component.hasChildren())
    {
      out.println(" * <p>");
      out.println(" * It does not support any children.");
    }

    out.println(" */");

    // TODO: eliminate <mfp:component-class-modifier> metadata
    int modifiers = component.getComponentClassModifiers();
    String classStart = Modifier.toString(modifiers);
    // TODO: use canonical ordering
    classStart = classStart.replaceAll("public abstract", "abstract public");
    out.println(classStart + " class " + className +
        " extends " + superclassName);

    Set interfaces = new HashSet();
    if (template != null)
      interfaces.addAll(template.getImplements());

    if (component.getComponentImplements() != null){
        StringTokenizer st = new StringTokenizer(component.getComponentImplements(),",",false);
        while (st.hasMoreTokens()){
            interfaces.add(st.nextToken());    
        }        
    }
    
    if (component.isNamingContainer())
      interfaces.add("javax.faces.component.NamingContainer");

    Iterator events = component.events();
    while (events.hasNext())
    {
      EventRefBean eventRef = (EventRefBean) events.next();
      EventBean event = eventRef.resolveEventType();
      if (event != null)
      {
        if (!eventRef.isIgnoreSourceInterface())
        {
          String source = event.getEventSourceInterface();
          if (source != null)
            interfaces.add(Util.getClassFromFullClass(source));
        }
      }
    }

    if (!interfaces.isEmpty())
    {
      Set implementsSet = new HashSet();
      for (Iterator iter = interfaces.iterator(); iter.hasNext();)
      {
        String fcqn = (String) iter.next();
        implementsSet.add(Util.getClassFromFullClass(fcqn));
      }

      // implements clause spans multiple lines
      char[] indent = new char[classStart.length() +
          " class ".length() +
          className.length() + 1];
      Arrays.fill(indent, ' ');
      out.print(indent);
      out.print("implements ");
      for (Iterator iter = implementsSet.iterator(); iter.hasNext();)
      {
        out.print((String) iter.next());
        if (iter.hasNext())
        {
          out.println(",");
          out.print(indent);
          out.print("           ");  // same length as "implements "
        }
      }
      out.println();
    }

    out.println("{");
    out.indent();
    
    //Write serialVersionUID
    if (component.getComponentSerialUID() != null &&
            !"".equals(component.getComponentSerialUID())){
        out.println();
        out.println("private static final long serialVersionUID = "+
                component.getComponentSerialUID()+";");
        out.println();
    }
  }

  public void writeClassEnd(
      PrettyWriter out)
  {
    out.unindent();
    out.println("}");
  }


  public void writeImports(PrettyWriter out, SourceTemplate template, String packageName, String fullSuperclassName,
                           String superclassName, Collection components)
  {
    throw new UnsupportedOperationException("not implemented");
  }

  public void writeImports(
      PrettyWriter out,
      SourceTemplate template,
      String packageName,
      String fullSuperclassName,
      String superclassName,
      ComponentBean component)
  {
    Set imports = new TreeSet();

    // Use the template imports
    if (template != null)
      imports.addAll(template.getImports());

    if (component.getComponentImplements() != null){
        StringTokenizer st = new StringTokenizer(component.getComponentImplements(),",",false);
        while (st.hasMoreTokens()){
            imports.add(st.nextToken());    
        }        
    }    
    
    // Detect NamingContainer
    if (component.isNamingContainer())
      imports.add("javax.faces.component.NamingContainer");

    Iterator properties = component.properties();
    properties = new FilteredIterator(properties, new NonVirtualFilter());
    // PropertyKey only needed if there are properties
    if (properties.hasNext())
    {
      while (properties.hasNext())
      {
        PropertyBean property = (PropertyBean) properties.next();
        String propertyClass = property.getPropertyClass();
        if (propertyClass != null)
        {
          imports.add(propertyClass);
          // Check for generics
          String[] types = property.getAttributeClassParameters();
          if (types != null)
          {
            for (int i = types.length - 1; i >= 0; i--)
            {
              addGenericImports(imports, types[i]);
            }
          }
        }
      }
    }

    Iterator facets = component.facets();
    // UIComponent needed if there are facets
    if (facets.hasNext())
      imports.add("javax.faces.component.UIComponent");

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

      if (event == null)
      {
        getLog().warn("Unknown event type \"" + eventRef.getEventType() + "\"" +
            " in component:" + component.getComponentType());
      }
      else
      {
        String listenerClass = event.getEventListenerClass();
        if (listenerClass != null)
          imports.add(listenerClass);

        if (!eventRef.isIgnoreSourceInterface())
        {
          String sourceInterface = event.getEventSourceInterface();
          if (sourceInterface != null)
            imports.add(sourceInterface);
        }
      }
    }

    // Import causes a collision if className and superclassName are equal
    if (!superclassName.equals(fullSuperclassName))
    {
      String superPackageName = Util.getPackageFromFullClass(fullSuperclassName);
      // component superclass only needed if not in
      // same package as component class
      if (superPackageName != packageName)
        imports.add(fullSuperclassName);
    }

    // add other imports (generator specific)
    addSpecificImports(imports, component);

    // do not import implicit types!
    imports.removeAll(Util.PRIMITIVE_TYPES);

    GeneratorHelper.writeImports(out, packageName, imports);
  }

  protected void addSpecificImports(
      Set imports,
      ComponentBean component)
  {
    // nothing by default
  }

  public void addGenericImports(Set imports, String type)
  {
    Matcher matcher = _GENERIC_TYPE.matcher(type);
    if (matcher.matches())
    {
      // Generic type
      imports.add(matcher.group(1));
      String[] types = matcher.group(2).split(",");
      for (int i = types.length - 1; i >= 0; i--)
      {
        addGenericImports(imports, types[i]);
      }
    }
    else
    {
      // Non-generic type
      imports.add(type);
    }
  }

  public void writeGenericConstants(
      PrettyWriter out,
      String componentFamily,
      String componentType) throws IOException
  {
    out.println();
    out.println("static public final String COMPONENT_FAMILY =");
    out.println("  \"" + componentFamily + "\";");
    out.println("static public final String COMPONENT_TYPE =");
    out.println("  \"" + componentType + "\";");
  }

  public void writePropertyConstants(
      PrettyWriter out,
      String superclassName,
      ComponentBean component) throws IOException
  {
    // nothing
  }

  public void writePropertyValueConstants(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    //  component property keys
    Iterator properties = component.properties();
    properties = new FilteredIterator(properties, new NonVirtualFilter());
    while (properties.hasNext())
    {
      PropertyBean property = (PropertyBean) properties.next();
      String[] propertyValues = property.getPropertyValues();

      if (propertyValues != null)
      {
        String propName = property.getPropertyName();

        for (int i = 0; i < propertyValues.length; i++)
        {
          String propValue = propertyValues[i];
          String propValueName = propName +
              Character.toUpperCase(propValue.charAt(0)) +
              propValue.substring(1);
          String propValueKey = Util.getConstantNameFromProperty(propValueName);

          out.println("static public final String " + propValueKey + " = \"" + propValue + "\";");
        }

      }
    }
  }

  public void writeFacetConstants(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    Iterator facets = component.facets();
    while (facets.hasNext())
    {
      FacetBean facet = (FacetBean) facets.next();
      String facetName = facet.getFacetName();
      String facetKey = Util.getConstantNameFromProperty(facetName, "_FACET");
      out.println("static public final " +
          "String " + facetKey + " = \"" + facetName + "\";");
    }
  }

  protected String convertStringToBoxedLiteral(
      String className,
      String value)
  {
    if (value == null)
    {
      return null;
    }
    else if ("String".equals(className))
    {
      return "\"" + value.replaceAll("\'", "\\'") + "\"";
    }
    else if ("boolean".equals(className))
    {
      return ("true".equals(value)) ? "Boolean.TRUE" : "Boolean.FALSE";
    }
    else if ("char".equals(className))
    {
      return "Character.valueOf('" + value.replaceAll("\'", "\\'") + "')";
    }
    else if ("int".equals(className))
    {
      return "Integer.valueOf(" + value + ")";
    }
    else if ("double".equals(className))
    {
      return "Double.valueOf(" + value + ")";
    }
    else if ("float".equals(className))
    {
      return "Float.valueOf(" + value + ")";
    }
    else if ("Number".equals(className))
    {
      if(value.indexOf(".") == -1)
      {
        return "Integer.valueOf(" + value + ")";
      }
      else
      {
        return "Double.valueOf(" + value + ")";
      }
    }
    else
    {
      throw new IllegalStateException("property-class " + className + " not supported for auto-boxing");
    }
  }


  protected String convertVariableToBoxedForm(
    String  className,
    String  varName)
  {
    if ("boolean".equals(className))
    {
      return varName + " ? Boolean.TRUE : Boolean.FALSE";
    }
    else if ("char".equals(className))
    {
      return "Character.valueOf(" + varName + ")";
    }
    else if ("int".equals(className))
    {
      return "Integer.valueOf(" + varName + ")";
    }
    else if ("short".equals(className))
    {
      return "Short.valueOf(" + varName + ")";
    }
    else if ("long".equals(className))
    {
      return "Long.valueOf(" + varName + ")";
    }
    else if ("double".equals(className))
    {
      return "Double.valueOf(" + varName + ")";
    }
    else if ("float".equals(className))
    {
      return "Float.valueOf(" + varName + ")";
    }
    else
    {
      throw new IllegalStateException("property-class " + className + " not supported for auto-boxing");
    }
  }

  public void writeConstructor(
      PrettyWriter out,
      ComponentBean component,
      int modifiers) throws IOException
  {
    String fullClassName = component.getComponentClass();
    String className = Util.getClassFromFullClass(fullClassName);

    if (Modifier.isPublic(modifiers))
    {
      // TODO: eliminate this inconsistency
      if (!Modifier.isAbstract(component.getComponentClassModifiers()))
      {
        String rendererType = component.getRendererType();

        if (rendererType != null)
          rendererType = convertStringToBoxedLiteral("String", rendererType);

        out.println();
        out.println("/**");
        // TODO: restore this correctly phrased comment (tense vs. command)
        //out.println(" * Constructs an instance of " + className + ".");
        out.println(" * Construct an instance of the " + className + ".");
        out.println(" */");
        out.println("public " + className + "()");
        out.println("{");
        out.indent();

        writeConstructorContent(out, component, modifiers, rendererType);

        out.unindent();
        out.println("}");
      }
    }
    else if (Modifier.isProtected(modifiers))
    {
      out.println();
      out.println("/**");
      // TODO: restore this more descriptive comment with param docs
      //out.println(" * Construct an instance of the " + className);
      //out.println(" * with the specified renderer type.");
      //out.println(" * ");
      //out.println(" * @param rendererType  the renderer type");
      out.println(" * Construct an instance of the " + className + ".");
      out.println(" */");
      out.println("protected " + className + "(");
      out.indent();
      out.println("String rendererType");
      out.println(")");
      out.unindent();
      out.println("{");
      out.indent();

      writeConstructorContent(out, component, modifiers, "rendererType");

      out.unindent();
      out.println("}");

      // TODO: eliminate this inconsistency
      if (Modifier.isAbstract(component.getComponentClassModifiers()))
      {
        out.println();
        out.println("/**");
        // TODO: restore this correctly phrased comment (tense vs. command)
        //out.println(" * Constructs an instance of " + className + ".");
        out.println(" * Construct an instance of the " + className + ".");
        out.println(" */");
        out.println("protected " + className + "()");
        out.println("{");
        out.indent();
        out.println("this(null);");
        out.unindent();
        out.println("}");
      }
    }
  }

  protected abstract void writeConstructorContent(
      PrettyWriter out,
      ComponentBean component,
      int modifiers, String rendererType) throws IOException;

  public void writeGetFamily(
      PrettyWriter out) throws IOException
  {
    out.println();
    if (_is12){
        out.println("@Override");
    }
    out.println("public String getFamily()");
    out.println("{");
    out.indent();
    out.println("return COMPONENT_FAMILY;");
    out.unindent();
    out.println("}");
  }

  public void writePropertyMethods(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    writePropertyMethods(out, component, null);
  }


  public void writePropertyMethods(PrettyWriter out, ComponentBean component, Collection ignoreList)
      throws IOException
  {
    Iterator properties = component.properties();
    properties = new FilteredIterator(properties, new NonVirtualFilter());
    while (properties.hasNext())
    {
      PropertyBean property = (PropertyBean) properties.next();
      if (property.isList())
        writePropertyListMethods(out, property, ignoreList);
      else
      {
        writePropertyDeclaration(out, property);
        writePropertyGet(out, property, ignoreList);
        writePropertySet(out, property, ignoreList);
        if (GeneratorHelper.isValidator(property, _is12))
        {
          writePropertyListMethods(out, property, ignoreList);
        }
      }
    }
  }

  abstract protected void writePropertyListMethods(
      PrettyWriter out,
      PropertyBean property,
      Collection inoreList) throws IOException;

  abstract protected void writePropertyListMethods(
      PrettyWriter out,
      PropertyBean property) throws IOException;

  static protected String getSingular(String plural)
  {
    if (plural.endsWith("s"))
      return plural.substring(0, plural.length() - 1);
    return plural;
  }

  protected abstract void writePropertyDeclaration(
      PrettyWriter out,
      PropertyBean property) throws IOException;

  protected void writePropertySet(
      PrettyWriter out,
      PropertyBean property,
      Collection ignoreList) throws IOException
  {
    String propertyClass = Util.getPropertyClass(property);
    writePropertySet(out, property, propertyClass, ignoreList);

    if (property.getAlternateClass() != null)
    {
      String alternateClass = Util.getAlternatePropertyClass(property);
      writePropertySet(out, property, alternateClass, ignoreList);
    }
  }

  protected void writePropertySet(
      PrettyWriter out,
      PropertyBean property,
      String propertyClass,
      Collection ignoreList) throws IOException
  {
    String propName = property.getPropertyName();
    String propVar = Util.getVariableFromName(propName);
    String description = property.getDescription();
    String setMethod = Util.getPrefixedPropertyName("set", propName);
    if (ignoreList != null && ignoreList.contains(setMethod))
    {
      return;
    }
    out.println();
    out.println("/**");
    if (description != null)
    {
      out.println(" * Sets " + convertMultilineComment(description));
    }

    if (property.isRequired())
    {
      out.println(" * <p>");
      out.println(" * This is a required property on the component.");
    }
    out.println(" * ");
    out.println(" * @param " + Util.getVariableFromName(propName) + "  the new " + propName + " value");
    if (property.isMethodBinding() && _is12)
    {
      out.println(" * @deprecated");
    }
    out.println(" */");

    if (isAccessorMethodFinal())
    {
      out.print("final ");
    }

    out.println("public void " + setMethod + "(" + propertyClass + " " + propVar + ")");
    out.println("{");
    out.indent();
    writePropertySetterMethodBody(out, property, propertyClass);
    out.unindent();
    out.println("}");
  }

  protected abstract void writePropertySetterMethodBody(
      PrettyWriter out,
      PropertyBean property,
      String propertyClass) throws IOException;

  protected void writePropertyGet(
      PrettyWriter out,
      PropertyBean property,
      Collection ignoreList) throws IOException
  {
    String propName = property.getPropertyName();
    String propertyFullClass = property.getPropertyClass();
    String propertyClass = Util.getClassFromFullClass(propertyFullClass);
    String description = property.getDescription();
    String getMethod = Util.getMethodReaderFromProperty(propName, propertyClass);
    if (ignoreList != null && ignoreList.contains(getMethod))
    {
      return;
    }
    boolean isUnchecked = false;
    String[] genericTypes = property.getPropertyClassParameters();
    if (genericTypes != null && genericTypes.length > 0)
    {
      isUnchecked = true;
      propertyClass = Util.getPropertyClass(property);
    }

    out.println();
    out.println("/**");
    if (description != null)
    {
      out.println(" * Gets " + convertMultilineComment(description));
    }
    if (property.isRequired())
    {
      out.println(" * <p>");
      out.println(" * This is a required property on the component.");
      out.println(" * </p>");
    }

    out.println(" *");
    out.println(" * @return  the new " + propName + " value");
    if (property.isMethodBinding() && _is12)
    {
      out.println(" * @deprecated");
    }
    out.println(" */");

    if (isUnchecked)
    {
      out.println("@SuppressWarnings(\"unchecked\")");
    }

    if (isAccessorMethodFinal())
    {
      out.print("final ");
    }

    out.println("public " + propertyClass + " " + getMethod + "()");
    out.println("{");
    out.indent();

    writePropertyGetterMethodBody(out, property);

    out.unindent();
    out.println("}");
  }

  /**
   * Whether the getters/setters have the final modifier
   *
   * @return true if the getters/setters are final
   */
  protected boolean isAccessorMethodFinal()
  {
    return false;
  }

  protected abstract void writePropertyGetterMethodBody(
      PrettyWriter out,
      PropertyBean property) throws IOException;

  public void writeFacetMethods(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    Iterator facets = component.facets();
    while (facets.hasNext())
    {
      FacetBean facet = (FacetBean) facets.next();
      writeFacetGet(out, facet);
      writeFacetSet(out, facet);
    }
  }

  public void writeFacetSet(
      PrettyWriter out,
      FacetBean facet) throws IOException
  {
    String facetName = facet.getFacetName();
    // TODO: drop the unnecessary "Facet" suffix
    String facetVar = facetName + "Facet";
    String facetKey = Util.getConstantNameFromProperty(facetName, "_FACET");
    String setMethod = Util.getPrefixedPropertyName("set", facetName);
    String description = facet.getDescription();

    out.println();
    out.println("/**");
    if (description != null)
    {
      out.println(" * " + convertMultilineComment(description));
    }
    if (facet.isRequired())
    {
      out.println(" * <p>");
      out.println(" * This is a required facet on the component.");
    }
    // TODO: put this back in
    //out.println(" * ");
    //out.println(" * @param " + facetVar + "  the new " + facetName + " facet");
    out.println(" */");

    // Remove type safety warning since getFacets is not generics enabled
    // under JSF 1.1 spec
    // TODO: Remove this line when Trinidad switch to JSF 1.2
    out.println("@SuppressWarnings(\"unchecked\")");

    out.println("final public void " + setMethod + "(UIComponent " + facetVar + ")");
    out.println("{");
    out.indent();
    out.println("getFacets().put(" + facetKey + ", " + facetVar + ");");
    out.unindent();
    out.println("}");
  }

  public void writeFacetGet(
      PrettyWriter out,
      FacetBean facet) throws IOException
  {
    String facetName = facet.getFacetName();
    String facetKey = Util.getConstantNameFromProperty(facetName, "_FACET");
    String getMethod = Util.getPrefixedPropertyName("get", facetName);
    String description = facet.getDescription();

    out.println();
    out.println("/**");
    if (description != null)
    {
      out.println(" * " + convertMultilineComment(description));
    }
    if (facet.isRequired())
    {
      out.println(" * <p>");
      out.println(" * This is a required facet on the component.");
    }
    // TODO: put this back in
    //out.println(" * ");
    //out.println(" * @return  the " + facetName + " facet");
    out.println(" */");

    out.println("final public UIComponent " + getMethod + "()");
    out.println("{");
    out.indent();
    out.println("return getFacet(" + facetKey + ");");
    out.unindent();
    out.println("}");
  }

  public void writeListenerMethods(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    Iterator events = component.events();
    while (events.hasNext())
    {
      EventRefBean eventRef = (EventRefBean) events.next();
      EventBean event = eventRef.resolveEventType();
      if (event != null)
      {
        writeListenerAdd(out, event);
        writeListenerRemove(out, event);
        writeListenersGet(out, event);
      }
    }
  }

  public void writeListenerAdd(
      PrettyWriter out,
      EventBean event) throws IOException
  {
    String listenerFullClass = event.getEventListenerClass();
    String listenerClass = Util.getClassFromFullClass(listenerFullClass);

    String eventName = event.getEventName();
    String addMethod = Util.getMethodNameFromEvent("add", eventName, "Listener");

    out.println();
    out.println("/**");
    out.println(" * Adds a " + eventName + " listener.");
    out.println(" *");
    out.println(" * @param listener  the " + eventName + " listener to add");
    out.println(" */");

    if (isAccessorMethodFinal())
    {
      out.print("final ");
    }
    out.println("public void " + addMethod + "(");
    out.indent();
    out.println(listenerClass + " listener)");
    out.unindent();
    out.println("{");
    out.indent();
    out.println("addFacesListener(listener);");
    out.unindent();
    out.println("}");
  }

  public void writeListenerRemove(
      PrettyWriter out,
      EventBean event) throws IOException
  {
    String listenerFullClass = event.getEventListenerClass();
    String listenerClass = Util.getClassFromFullClass(listenerFullClass);

    String eventName = event.getEventName();
    String removeMethod = Util.getMethodNameFromEvent("remove", eventName, "Listener");

    out.println();
    out.println("/**");
    out.println(" * Removes a " + eventName + " listener.");
    out.println(" *");
    out.println(" * @param listener  the " + eventName + " listener to remove");
    out.println(" */");

    if (isAccessorMethodFinal())
    {
      out.print("final ");
    }
    out.println("public void " + removeMethod + "(");
    out.indent();
    out.println(listenerClass + " listener)");
    out.unindent();
    out.println("{");
    out.indent();
    out.println("removeFacesListener(listener);");
    out.unindent();
    out.println("}");
  }

  public void writeListenersGet(
      PrettyWriter out,
      EventBean event) throws IOException
  {
    String listenerFullClass = event.getEventListenerClass();
    String listenerClass = Util.getClassFromFullClass(listenerFullClass);

    String eventName = event.getEventName();
    String getMethod = Util.getMethodNameFromEvent("get", eventName, "Listeners");

    out.println();
    out.println("/**");
    out.println(" * Returns an array of attached " + eventName + " listeners.");
    out.println(" *");
    out.println(" * @return  an array of attached " + eventName + " listeners.");
    out.println(" */");

    if (isAccessorMethodFinal())
    {
      out.print("final ");
    }
    out.println("public " + listenerClass + "[] " + getMethod + "()");
    out.println("{");
    out.indent();
    out.println("return (" + listenerClass + "[])" +
        "getFacesListeners(" + listenerClass + ".class);");
    out.unindent();
    out.println("}");
  }


  public abstract void writeStateManagementMethods(PrettyWriter out,
                                                   ComponentBean component) throws IOException;

  public void writeOther(
      PrettyWriter out, ComponentBean component) throws IOException
  {
    // nothing
  }

  protected String convertMultilineComment(
      String commentBody)
  {
    return commentBody.replaceAll("\n", "\n * ");
  }

  protected class ResolvableTypeFilter extends PropertyFilter
  {
    protected boolean accept(
        PropertyBean property)
    {
      String propertyClass = property.getPropertyClass();
      String resolvableType = resolveType(propertyClass);
      return (resolvableType != null);
    }
  }

  protected class NonVirtualFilter extends PropertyFilter
  {
    protected boolean accept(
        PropertyBean property)
    {
      return (!property.isVirtual());
    }
  }

  static protected String resolveType(
      String className)
  {
    return (String) _RESOLVABLE_TYPES.get(className);
  }


  static private Map _createResolvableTypes()
  {
    Map resolvableTypes = new HashMap();

    resolvableTypes.put("boolean", "Boolean");
    resolvableTypes.put("char", "Character");
    // TODO: put this back in
    //resolvableTypes.put("java.util.Date", "Date");
    resolvableTypes.put("int", "Integer");
    resolvableTypes.put("float", "Float");
    resolvableTypes.put("double", "Double");
    resolvableTypes.put("java.util.Locale", "Locale");
    resolvableTypes.put("long", "Long");
    resolvableTypes.put("java.lang.String", "String");
    resolvableTypes.put("java.lang.Number", "Number");
    // TODO: put this back in
    //resolvableTypes.put("java.lang.String[]", "StringArray");
    resolvableTypes.put("java.util.TimeZone", "TimeZone");

    return Collections.unmodifiableMap(resolvableTypes);
  }

  static private final Pattern _GENERIC_TYPE = Pattern.compile("([^<]+)<(.+)>");
  static final private Map _RESOLVABLE_TYPES = _createResolvableTypes();
}
