protected void encodeAlign(ResponseWriter responseWriter, Popover popover, boolean first)
      throws IOException {

    encodeNonEscapedObject(responseWriter, ALIGN, "", first);
    responseWriter.write("{");

    String for_ = popover.getFor();
    encodeClientId(responseWriter, NODE, for_, popover, true);
    responseWriter.write("}");

    UIComponent forComponent = popover.findComponent(for_);

    if (forComponent != null) {

      if (forComponent instanceof Button) {
        Button button = (Button) forComponent;

        if ((button.getOnclick() == null) && (button.getOnmouseover() == null)) {
          logger.warn(
              "Popover [{0}] is *for* button [{1}] but the button does not have an onclick or onmouseover attribute.",
              popover.getClientKey(), for_);
        }
      }
    }
  }
  @Override
  public void encodeJavaScriptCustom(FacesContext facesContext, UIComponent uiComponent)
      throws IOException {

    ResponseWriter responseWriter = facesContext.getResponseWriter();

    Popover popover = (Popover) uiComponent;
    ClientComponent clientComponent = (ClientComponent) uiComponent;
    String clientVarName = getClientVarName(facesContext, clientComponent);
    String clientKey = clientComponent.getClientKey();

    if (clientKey == null) {
      clientKey = clientVarName;
    }

    if (popover.isHideIconRendered()) {

      // Add an "x" toolbar icon so that the popover can be hidden just like alloy:dialog can.
      responseWriter.write(LIFERAY_COMPONENT);
      responseWriter.write("('");
      responseWriter.write(clientKey);
      responseWriter.write(
          "').addToolbar([{cssClass:'close',label:'\u00D7',on:{click:function(event){Liferay.component('");
      responseWriter.write(clientKey);
      responseWriter.write("').hide();}},render:true}],'header');");
    }

    // Move the overlayBody div into the popover-content div.
    String clientId = popover.getClientId(facesContext);
    String overlayBodyClientId = clientId.concat(OVERLAY_BODY_SUFFIX);
    String escapedOverlayBodyClientId = escapeClientId(overlayBodyClientId);

    String contentBoxClientId = clientId.concat(CONTENT_BOX_SUFFIX);
    String escapedContentBoxClientId = escapeClientId(contentBoxClientId);

    responseWriter.write("A.one('#");
    responseWriter.write(escapedOverlayBodyClientId);
    responseWriter.write("').appendTo(A.one('div#");
    responseWriter.write(escapedContentBoxClientId);
    responseWriter.write(">div.popover-content'));");

    if (popover.isDismissible()) {
      encodeOverlayDismissible(responseWriter, popover, clientKey);
    }

    encodeOverlayJavaScriptCustom(responseWriter, facesContext, popover);

    if ((popover.getFor() == null) && facesContext.isProjectStage(ProjectStage.Development)) {
      logger.error("The 'for' attribute is required for alloy:popover");
    }
  }
  @Override
  public void encodeAlloyAttributes(
      FacesContext facesContext, ResponseWriter responseWriter, UIComponent uiComponent)
      throws IOException {

    Popover popover = (Popover) uiComponent;
    boolean first = true;

    String height = popover.getHeight();

    if (height != null) {

      encodeHeight(responseWriter, popover, height, first);
      first = false;
    }

    String position = popover.getPosition();

    if (position != null) {

      encodePosition(responseWriter, popover, position, first);
      first = false;
    }

    String width = popover.getWidth();

    if (width != null) {

      encodeWidth(responseWriter, popover, width, first);
      first = false;
    }

    Integer zIndex = popover.getzIndex();

    if (zIndex != null) {

      encodeZIndex(responseWriter, popover, zIndex, first);
      first = false;
    }

    encodeHiddenAttributes(facesContext, responseWriter, popover, first);
  }