/**
   * Get an envelope with an assertion from the IdP. If this returns null, something went wrong
   * between the IdP and Client.
   *
   * @param paosClient
   * @param spContent ExchangeContent that contains the e
   * @param idpURL
   * @return
   */
  public ExchangeContent getAssertion(
      PaosClient paosClient, Envelope idpEnvelope, URL idpURL, ClientOptions options) {

    ExchangeContent idpContent = null;

    if (verbose) {
      System.out.println("Forwarding Authnrequest to " + idpURL.toString());
      System.out.println(ParseHelper.anythingToXMLString(idpEnvelope));
    }

    String principal = options.getPrincipal();
    String credentials = options.getCredentials();

    // Set the login credentials at IdP exchangecontent.
    idpContent = new ExchangeContent(idpEnvelope, createRealmResolver(principal, credentials));

    logger.debug("\nWill forward the request to: " + idpURL.toString() + "\n");

    // Send everything to the IdP.
    idpContent = paosClient.send(idpURL, idpContent);

    // If this does not exist, something went wrong @
    // PaosClient.
    return idpContent;
  }
  /**
   * Send a GET request to an SP. Receive an AuthnRequest in the spContent.
   *
   * @param spURL
   * @param paosClient
   * @return
   */
  private ExchangeContent getRequestToSP(URL spURL, PaosClient paosClient) {

    // Create a new, empty SP ExchangeContent.
    ExchangeContent spContent = new ExchangeContent(null, null);

    // Send a PAOS GET request to the given SP endpoint.
    spContent = paosClient.sendHttpGETRequest(spURL, spContent);

    if (verbose) {
      System.out.println(
          "AuthnRequest from SP: \n"
              + new String(
                  ParseHelper.anythingToXMLString(spContent.getResponseParts().getBody())));
    }

    return spContent;
  }
  /**
   * Access some resource at a SP. Returns an ExchangeContent object that contains the response that
   * was sent from the IdP.
   *
   * @param spHost
   * @param spPort
   * @param spUri
   * @throws Exception
   */
  public ExchangeContent accessResource(
      ClientOptions options, IDPEntry idpEntry, HttpClient httpClient) {

    PaosClient paosClient = null;

    ExchangeContent spContent = null;
    URL assertionConsumerEndpoint = null;

    // Set parameters from options in args.
    setParameters(options);

    // Create a Paos HttpClient.
    paosClient = new PaosClient(httpClient);

    // Get the AuthnRequest from the SP
    spContent = getRequestToSP(options.getSpURL(), paosClient);

    if (spContent.getResponseParts() != null) {
      String spAssertionConsumer =
          ExtractField.extractAssertionConsumerURL(spContent.getResponseParts().getHeader());

      // Check if we received an AuthnRequest as a response.
      // validate(spContent.getEnvelope.getbody.getUnknownXMLObjects);

      // Get the SOAP Envelope Body from the IdP that contains the
      // response or a soap fault.
      Body body = getResponseBody(spContent, idpEntry, paosClient, options);

      if (body != null) {
        if (verbose) {
          System.out.println("Received from idp: \n" + ParseHelper.anythingToXMLString(body));
        }

        logger.debug("Received from idp: \n" + ParseHelper.anythingToXMLString(body));
      }

      // Build the envelope you want to send.
      Envelope assertionEnvelope = EnvelopeCreator.createSpResponseEnvelope(body);

      // Build an empty exchangeContent with the envelope
      ExchangeContent assertionContent = new ExchangeContent(assertionEnvelope, null);

      // Turn the assertionConsumer string into an URL
      assertionConsumerEndpoint = getURL(spAssertionConsumer);

      // Add the sp session cookie back
      assertionContent.setCookieField(spContent.getCookieField());

      // Send the exchangeContent.
      assertionContent = paosClient.send(assertionConsumerEndpoint, assertionContent);

      String envelopeString = ParseHelper.anythingToXMLString(assertionEnvelope);

      System.out.println("Sending envelope to SP endpoint: " + options.getSpEndpoint());
      System.out.println(envelopeString);
      logger.info("Sent to SP: \n" + envelopeString);

      if (assertionContent.getOtherResponse() != null) {
        System.out.println("Response received from SP: \n");
        System.out.println(new String(assertionContent.getOtherResponse()));
      }

      // This return is unnecessary in a normal SP exchange.
      return assertionContent;
    }
    logger.debug("The SP did not respond to the GET request.");
    return null; // :(
  }