/**
   * Obtains attributes first from the repository by calling {@link
   * org.jasig.services.persondir.IPersonAttributeDao#getPerson(String)}.
   *
   * @param id the person id to locate in the attribute repository
   * @return the map of attributes
   */
  private Map<String, List<Object>> retrievePersonAttributesToPrincipalAttributes(final String id) {

    final IPersonAttributes attrs;
    if (this.attributeRepository == null) {
      final ApplicationContext context = ApplicationContextProvider.getApplicationContext();
      final IPersonAttributeDao attributeRepository =
          context.getBean("attributeRepository", IPersonAttributeDao.class);
      attrs = attributeRepository.getPerson(id);
    } else {
      attrs = this.attributeRepository.getPerson(id);
    }

    if (attrs == null) {
      LOGGER.debug(
          "Could not find principal [{}] in the repository so no attributes are returned.", id);
      return Collections.emptyMap();
    }

    final Map<String, List<Object>> attributes = attrs.getAttributes();
    if (attributes == null) {
      LOGGER.debug("Principal [{}] has no attributes and so none are returned.", id);
      return Collections.emptyMap();
    }
    return attributes;
  }
  /**
   * 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;
  }