/**
   * Create an Error Response
   *
   * @param responseURL
   * @param status
   * @param identityURL
   * @param supportSignature
   * @return
   * @throws ConfigurationException
   */
  public Document getErrorResponse(
      String responseURL, String status, String identityURL, boolean supportSignature) {
    Document samlResponse = null;
    ResponseType responseType = null;

    SAML2Response saml2Response = new SAML2Response();

    // Create a response type
    String id = IDGenerator.create("ID_");

    IssuerInfoHolder issuerHolder = new IssuerInfoHolder(identityURL);
    issuerHolder.setStatusCode(status);

    IDPInfoHolder idp = new IDPInfoHolder();
    idp.setNameIDFormatValue(null);
    idp.setNameIDFormat(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get());

    SPInfoHolder sp = new SPInfoHolder();
    sp.setResponseDestinationURI(responseURL);

    responseType = saml2Response.createResponseType(id);
    responseType.setStatus(JBossSAMLAuthnResponseFactory.createStatusType(status));

    // Lets see how the response looks like
    if (logger.isTraceEnabled()) {
      StringWriter sw = new StringWriter();
      try {
        saml2Response.marshall(responseType, sw);
      } catch (ProcessingException e) {
        logger.trace(e);
      }
      logger.trace("SAML Response Document: " + sw.toString());
    }

    if (supportSignature) {
      try {
        SAML2Signature ss = new SAML2Signature();
        samlResponse = ss.sign(responseType, keyManager.getSigningKeyPair());
      } catch (Exception e) {
        logger.trace(e);
        throw new RuntimeException(logger.signatureError(e));
      }
    } else
      try {
        samlResponse = saml2Response.convert(responseType);
      } catch (Exception e) {
        logger.trace(e);
      }

    return samlResponse;
  }
  /** @see {@link ParserNamespaceSupport#parse(XMLEventReader)} */
  public Object parse(XMLEventReader xmlEventReader) throws ParsingException {
    // Get the startelement
    StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
    StaxParserUtil.validate(startElement, RESPONSE);

    ResponseType response = (ResponseType) parseBaseAttributes(startElement);

    while (xmlEventReader.hasNext()) {
      // Let us peek at the next start element
      startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
      if (startElement == null) break;
      String elementName = StaxParserUtil.getStartElementName(startElement);

      if (JBossSAMLConstants.ISSUER.get().equals(elementName)) {
        startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
        NameIDType issuer = new NameIDType();
        issuer.setValue(StaxParserUtil.getElementText(xmlEventReader));
        response.setIssuer(issuer);
      } else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName)) {
        Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
        response.setSignature(sig);
      } else if (JBossSAMLConstants.ASSERTION.get().equals(elementName)) {
        SAMLAssertionParser assertionParser = new SAMLAssertionParser();
        response.addAssertion(
            new RTChoiceType((AssertionType) assertionParser.parse(xmlEventReader)));
      } else if (JBossSAMLConstants.STATUS.get().equals(elementName)) {
        response.setStatus(parseStatus(xmlEventReader));
      } else if (JBossSAMLConstants.ENCRYPTED_ASSERTION.get().equals(elementName)) {
        Element encryptedAssertion = StaxParserUtil.getDOMElement(xmlEventReader);
        response.addAssertion(new RTChoiceType(new EncryptedAssertionType(encryptedAssertion)));
      } else throw logger.parserUnknownTag(elementName, startElement.getLocation());
    }

    return response;
  }
  /**
   * Sign an ResponseType at the root
   *
   * @param response
   * @param keypair Key Pair
   * @param digestMethod (Example: DigestMethod.SHA1)
   * @param signatureMethod (Example: SignatureMethod.DSA_SHA1)
   * @return
   * @throws ParserConfigurationException
   * @throws XMLSignatureException
   * @throws MarshalException
   * @throws GeneralSecurityException
   */
  public Document sign(ResponseType response, KeyPair keypair)
      throws ParserConfigurationException, GeneralSecurityException, MarshalException,
          XMLSignatureException {
    SAML2Response saml2Request = new SAML2Response();
    Document doc = saml2Request.convert(response);
    doc.normalize();

    Node theSibling = getNextSiblingOfIssuer(doc);
    if (theSibling != null) {
      this.sibling = theSibling;
    }

    return sign(doc, response.getID(), keypair);
  }