/**
   * This method returns any facets that should be applied to the <code>TreeNode (comp)</code>.
   * Useful facets for the sun <code>TreeNode</code> component are: "content" and "image".
   *
   * <p>Facets that already exist on <code>comp</code>, or facets that are directly added to <code>
   * comp</code> do not need to be returned from this method.
   *
   * <p>This implementation directly adds a "content" facet and returns <code>null</code> from this
   * method.
   *
   * @param comp The tree node <code>UIComponent</code>.
   * @param nodeObject The (model) object representing the tree node.
   */
  public Map<String, UIComponent> getFacets(UIComponent comp, Object nodeObject) {
    if (nodeObject == null) {
      return null;
    }
    if (nodeObject.toString().equals(_objectName)) {
      return null;
    }
    Properties props = new Properties();
    LayoutComponent desc = this.getLayoutComponent();

    // Check to see if a childActionListener was added
    // NOTE: This is not needed when a "command" event is used.  In the
    //	 case of a CommandEvent an ActionListener will be
    //	 automatically registered by the ComponentFactoryBase class
    //	 during "setOptions()".  Also, setting a childActionListener
    //	 here should not stop "command" handlers from being invoked.
    setProperty(props, "actionListener", desc.getOption("childActionListener"));

    // Also se the target and text...
    setProperty(props, "target", desc.getOption("childTarget"));
    setProperty(props, "text", comp.getAttributes().get("text"));
    // FIXME: Add support for other hyperlink properties??

    // Create Hyperlink
    // NOTE: Last attribute "content" will be the facet named used.
    UIComponent link =
        ComponentUtil.getChild(
            comp,
            "link",
            "com.sun.jsftemplating.component.factory.sun.HyperlinkFactory",
            props,
            "content");

    // Check to see if we have a childURL, evalute it here (after component
    // is created, before rendered) so we can use the link itself to define
    // the URL.  This has proven to be useful...
    Object val = desc.getOption("childURL");
    if (val != null) {
      link.getAttributes()
          .put("url", desc.resolveValue(FacesContext.getCurrentInstance(), link, val));
    }

    // Set href's handlers...
    // We do it this way rather than earlier b/c the factory will not
    // recognize this as a property, it requires it to be defined in the
    // LayoutComponent as a handler.  So we must do this manually like
    // this.
    List handlers = desc.getHandlers("childCommand");
    if (handlers != null) {
      link.getAttributes().put("command", handlers);
      // This adds the required action listener to proces the commands
      // This is needed here b/c the factory has already executed -- the
      // factory is normally the place where this is added (iff there is
      // at least one command handler).
      ((ActionSource) link).addActionListener(CommandActionListener.getInstance());
    }

    // We already added the facet, return null...
    return null;
  }
 @Override
 public void apply(FaceletContext ctx, UIComponent parent)
     throws IOException, FacesException, FaceletException, ELException {
   if (parent instanceof ActionSource) {
     // only process if parent was just created
     if (parent.getParent() == null) {
       ActionSource src = (ActionSource) parent;
       ActionListener listener =
           new MethodExpressionActionListener(
               new MetaMethodExpression(
                   value.getMethodExpression(ctx, null, ACTION_LISTENER_SIG),
                   ctx.getFunctionMapper(),
                   ctx.getVariableMapper()));
       src.addActionListener(listener);
     }
   } else {
     throw new TagException(tag, "Parent is not of type ActionSource, type is: " + parent);
   }
 }
  @Override
  public int doStartTag() throws JspException {
    UIComponentTag tag = UIComponentTag.getParentUIComponentTag(pageContext);
    if (tag == null) {
      throw new JspException(
          _LOG.getMessage("FILEDOWNLOADACTIONLISTENER_MUST_INSIDE_UICOMPONENT_TAG"));
    }

    // Only run on the first time the tag executes
    if (!tag.getCreated()) return SKIP_BODY;

    UIComponent component = tag.getComponentInstance();
    if (!(component instanceof ActionSource)) {
      throw new JspException(
          _LOG.getMessage("FILEDOWNLOADACTIONLISTENER_MUST_INSIDE_UICOMPONENT_TAG"));
    }

    ELContextTag parentELContext = (ELContextTag) findAncestorWithClass(this, ELContextTag.class);

    Application application = FacesContext.getCurrentInstance().getApplication();

    FileDownloadActionListener listener = new FileDownloadActionListener();

    if (_filename != null) {
      listener.setValueExpression(FileDownloadActionListener.FILENAME_KEY, _filename);
    }

    if (_contentType != null) {
      listener.setValueExpression(FileDownloadActionListener.CONTENT_TYPE_KEY, _contentType);
    }

    listener.setMethod(_method);

    ((ActionSource) component).addActionListener(listener);

    return super.doStartTag();
  }