/** {@inheritDoc} */
  protected void doEncode(MessageContext messageContext) throws MessageEncodingException {
    if (!(messageContext instanceof SAMLMessageContext)) {
      log.error("Invalid message context type, this encoder only support SAMLMessageContext");
      throw new MessageEncodingException(
          "Invalid message context type, this encoder only support SAMLMessageContext");
    }

    if (!(messageContext.getOutboundMessageTransport() instanceof HTTPOutTransport)) {
      log.error(
          "Invalid outbound message transport type, this encoder only support HTTPOutTransport");
      throw new MessageEncodingException(
          "Invalid outbound message transport type, this encoder only support HTTPOutTransport");
    }

    SAMLMessageContext samlMsgCtx = (SAMLMessageContext) messageContext;

    String endpointURL = getEndpointURL(samlMsgCtx);

    setResponseDestination(samlMsgCtx.getOutboundSAMLMessage(), endpointURL);

    removeSignature(samlMsgCtx);

    String encodedMessage = deflateAndBase64Encode(samlMsgCtx.getOutboundSAMLMessage());

    String redirectURL = buildRedirectURL(samlMsgCtx, endpointURL, encodedMessage);

    HTTPOutTransport out = (HTTPOutTransport) messageContext.getOutboundMessageTransport();
    HTTPTransportUtils.addNoCacheHeaders(out);
    HTTPTransportUtils.setUTF8Encoding(out);

    out.sendRedirect(redirectURL);
  }
  /**
   * Adds an IdP session cookie to the outbound response.
   *
   * @param httpRequest current request
   * @param httpResponse current response
   * @param userSession user's session
   */
  protected void addSessionCookie(
      HttpServletRequest httpRequest, HttpServletResponse httpResponse, Session userSession) {
    httpRequest.setAttribute(Session.HTTP_SESSION_BINDING_ATTRIBUTE, userSession);

    byte[] remoteAddress = httpRequest.getRemoteAddr().getBytes();
    byte[] sessionId = userSession.getSessionID().getBytes();

    String signature = null;
    try {
      MessageDigest digester = MessageDigest.getInstance("SHA");
      digester.update(userSession.getSessionSecret());
      digester.update(remoteAddress);
      digester.update(sessionId);
      signature = Base64.encodeBytes(digester.digest());
    } catch (GeneralSecurityException e) {
      LOG.error("Unable to compute signature over session cookie material", e);
    }

    LOG.debug("Adding IdP session cookie to HTTP response");
    StringBuilder cookieValue = new StringBuilder();
    cookieValue.append(Base64.encodeBytes(remoteAddress, Base64.DONT_BREAK_LINES)).append("|");
    cookieValue.append(Base64.encodeBytes(sessionId, Base64.DONT_BREAK_LINES)).append("|");
    cookieValue.append(signature);

    String cookieDomain = HttpServletHelper.getCookieDomain(context);

    Cookie sessionCookie =
        new Cookie(IDP_SESSION_COOKIE_NAME, HTTPTransportUtils.urlEncode(cookieValue.toString()));
    sessionCookie.setVersion(1);
    if (cookieDomain != null) {
      sessionCookie.setDomain(cookieDomain);
    }
    sessionCookie.setPath(
        "".equals(httpRequest.getContextPath()) ? "/" : httpRequest.getContextPath());
    sessionCookie.setSecure(httpRequest.isSecure());
    httpResponse.addCookie(sessionCookie);
  }