/**
   * Construct SAML response. <a href="http://bit.ly/1uI8Ggu">See this reference for more info.</a>
   *
   * @param service the service
   * @return the SAML response
   */
  protected String constructSamlResponse(final GoogleAccountsService service) {
    final DateTime currentDateTime =
        DateTime.parse(new ISOStandardDateFormat().getCurrentDateAndTime());
    final DateTime notBeforeIssueInstant = DateTime.parse("2003-04-17T00:46:02Z");

    /*
     * Must be looked up directly from the context
     * because the services manager is not serializable
     * and cannot be class field.
     */
    final ApplicationContext context = ApplicationContextProvider.getApplicationContext();
    final ServicesManager servicesManager =
        context.getBean("servicesManager", ServicesManager.class);
    final RegisteredService registeredService = servicesManager.findServiceBy(service);
    final String userId =
        registeredService
            .getUsernameAttributeProvider()
            .resolveUsername(service.getPrincipal(), service);

    final org.opensaml.saml.saml2.core.Response response =
        samlObjectBuilder.newResponse(
            samlObjectBuilder.generateSecureRandomId(), currentDateTime, service.getId(), service);
    response.setStatus(samlObjectBuilder.newStatus(StatusCode.SUCCESS, null));

    final AuthnStatement authnStatement =
        samlObjectBuilder.newAuthnStatement(AuthnContext.PASSWORD_AUTHN_CTX, currentDateTime);
    final Assertion assertion =
        samlObjectBuilder.newAssertion(
            authnStatement,
            "https://www.opensaml.org/IDP",
            notBeforeIssueInstant,
            samlObjectBuilder.generateSecureRandomId());

    final Conditions conditions =
        samlObjectBuilder.newConditions(notBeforeIssueInstant, currentDateTime, service.getId());
    assertion.setConditions(conditions);

    final Subject subject =
        samlObjectBuilder.newSubject(
            NameID.EMAIL, userId, service.getId(), currentDateTime, service.getRequestId());
    assertion.setSubject(subject);

    response.getAssertions().add(assertion);

    final StringWriter writer = new StringWriter();
    samlObjectBuilder.marshalSamlXmlObject(response, writer);

    final String result = writer.toString();
    logger.debug("Generated Google SAML response: {}", result);
    return result;
  }
  @Override
  public Response build(final WebApplicationService webApplicationService, final String ticketId) {
    final GoogleAccountsService service = (GoogleAccountsService) webApplicationService;

    final Map<String, String> parameters = new HashMap<>();
    final String samlResponse = constructSamlResponse(service);
    final String signedResponse =
        samlObjectBuilder.signSamlResponse(samlResponse, this.privateKey, this.publicKey);
    parameters.put(SamlProtocolConstants.PARAMETER_SAML_RESPONSE, signedResponse);
    parameters.put(SamlProtocolConstants.PARAMETER_SAML_RELAY_STATE, service.getRelayState());

    return buildPost(service, parameters);
  }