/**
   * Send a response
   *
   * @param holder
   * @throws GeneralSecurityException
   * @throws IOException
   */
  public void send(WebRequestUtilHolder holder) throws GeneralSecurityException, IOException {
    Document responseDoc = holder.getResponseDoc();

    if (responseDoc == null) throw logger.nullValueError("responseType");

    String destination = holder.getDestination();
    String relayState = holder.getRelayState();
    boolean supportSignature = holder.isSupportSignature();
    boolean sendRequest = holder.isAreWeSendingRequest();
    HttpServletResponse response = holder.getServletResponse();
    boolean isErrorResponse = holder.isErrorResponse();

    if (holder.isPostBindingRequested() == false && !holder.isStrictPostBinding()) {
      String finalDest = null;

      // This is the case with whole queryString including signature already generated by
      // SAML2SignatureGenerationHandler
      if (holder.getDestinationQueryStringWithSignature() != null) {
        finalDest = destination + "?" + holder.getDestinationQueryStringWithSignature();
      }
      // This is the case without signature
      else {
        byte[] responseBytes = DocumentUtil.getDocumentAsString(responseDoc).getBytes("UTF-8");

        String urlEncodedResponse = RedirectBindingUtil.deflateBase64URLEncode(responseBytes);

        if (isNotNull(relayState)) relayState = RedirectBindingUtil.urlEncode(relayState);

        finalDest =
            destination
                + getDestination(
                    urlEncodedResponse, relayState, supportSignature, sendRequest, isErrorResponse);
      }

      logger.trace("Destination = " + finalDest);
      HTTPRedirectUtil.sendRedirectForResponder(finalDest, response);
    } else {
      if (logger.isTraceEnabled()) {
        logger.trace("SAML Response Document: " + DocumentUtil.asString(responseDoc));
      }

      byte[] responseBytes = DocumentUtil.getDocumentAsString(responseDoc).getBytes("UTF-8");

      String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes));

      PostBindingUtil.sendPost(
          new DestinationInfoHolder(destination, samlResponse, relayState), response, sendRequest);
    }
  }