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_);
        }
      }
    }
  }
  /**
   * @see {@link ExternalContext#addResponseHeader(String, String)}
   * @since JSF 2.0
   */
  @Override
  public void addResponseHeader(String name, String value) {

    if (portletResponse instanceof ResourceResponse) {
      ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
      resourceResponse.addProperty(name, value);
    } else {
      logger.warn(
          "Unable to call {0} for portletResponse=[{1}] because it is not a ResourceResponse.",
          "portletResponse.addProperty(String, String)", portletResponse.getClass().getName());
    }
  }
  /**
   * @see {@link ExternalContext#encodeBookmarkableURL(String, Map)}
   * @since JSF 2.0
   */
  @Override
  public String encodeBookmarkableURL(String baseUrl, Map<String, List<String>> parameters) {

    String renderURL = null;

    if (baseUrl != null) {
      String viewId = baseUrl;

      if (baseUrl.startsWith(requestContextPath)) {
        viewId = baseUrl.substring(requestContextPath.length());
      }

      try {

        if ((portletPhase == Bridge.PortletPhase.RENDER_PHASE)
            || (portletPhase == Bridge.PortletPhase.RESOURCE_PHASE)) {
          PortletURL portletRenderURL =
              bridgeContext.getPortletContainer().createRenderURL(baseUrl);
          portletRenderURL.setParameter(bridgeConfig.getViewIdRenderParameterName(), viewId);

          if (parameters != null) {

            for (Map.Entry<String, List<String>> parameter : parameters.entrySet()) {
              String name = parameter.getKey();

              if (name != null) {
                List<String> values = parameter.getValue();

                if (values != null) {
                  int size = values.size();

                  if (size > 0) {

                    if (size == 1) {
                      String value = values.get(0);

                      if (value != null) {
                        portletRenderURL.setParameter(name, value);
                      }
                    } else {
                      logger.warn("Unable to append multiple values for parameter name=[{0]", name);
                    }
                  }
                }
              }
            }
          }

          renderURL = portletRenderURL.toString();
        } else {
          logger.error(
              "Unable to encode bookmarkable URL during Bridge.PortletPhase.[{0}] -- you should call BridgeUtil.getPortletRequestPhase() and check for Bridge.PortletPhase.RENDER_PHASE or Bridge.PortletPhase.RESOURCE_PHASE before calling ExternalContext.encodeBookmarkableURL(...).",
              portletPhase);
        }
      } catch (Exception e) {
        logger.error(e.getMessage(), e);
      }
    } else {
      logger.warn("Unable to encode RenderURL for url=[null]");
    }

    return renderURL;
  }