public Node getNextSiblingOfIssuer(Document doc) {
    // Find the sibling of Issuer
    NodeList nl =
        doc.getElementsByTagNameNS(
            JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ISSUER.get());
    if (nl.getLength() > 0) {
      Node issuer = nl.item(0);

      return issuer.getNextSibling();
    }
    return null;
  }
  /**
   * Sets the IDness of the ID attribute. Santuario 1.5.1 does not assumes IDness based on attribute
   * names anymore. This method should be called before signing/validating a saml document.
   *
   * @param document SAML document to have its ID attribute configured.
   */
  private void configureIdAttribute(Document document) {
    // Estabilish the IDness of the ID attribute.
    document.getDocumentElement().setIdAttribute(ID_ATTRIBUTE_NAME, true);

    NodeList nodes =
        document.getElementsByTagNameNS(
            JBossSAMLURIConstants.ASSERTION_NSURI.get(), JBossSAMLConstants.ASSERTION.get());

    for (int i = 0; i < nodes.getLength(); i++) {
      Node n = nodes.item(i);
      if (n instanceof Element) {
        ((Element) n).setIdAttribute(ID_ATTRIBUTE_NAME, true);
      }
    }
  }
  public void writeEntitiesDescriptor(EntitiesDescriptorType entities) throws ProcessingException {
    StaxUtil.writeStartElement(
        writer,
        METADATA_PREFIX,
        JBossSAMLConstants.ENTITIES_DESCRIPTOR.get(),
        METADATA_NSURI.get());

    StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.METADATA_NSURI.get());
    StaxUtil.writeNameSpace(writer, "md", JBossSAMLURIConstants.METADATA_NSURI.get());
    StaxUtil.writeNameSpace(writer, "saml", JBossSAMLURIConstants.ASSERTION_NSURI.get());
    StaxUtil.writeNameSpace(writer, "ds", JBossSAMLURIConstants.XMLDSIG_NSURI.get());

    if (entities.getValidUntil() != null) {
      StaxUtil.writeAttribute(
          writer, JBossSAMLConstants.VALID_UNTIL.get(), entities.getValidUntil().toString());
    }
    if (entities.getID() != null) {
      StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), entities.getID());
    }

    if (entities.getName() != null) {
      StaxUtil.writeAttribute(writer, JBossSAMLConstants.NAME.get(), entities.getName());
    }

    Element signature = entities.getSignature();
    if (signature != null) {
      StaxUtil.writeDOMElement(writer, signature);
    }
    ExtensionsType extensions = entities.getExtensions();
    if (extensions != null) {
      StaxUtil.writeDOMElement(writer, extensions.getElement());
    }

    List<Object> entityDescriptors = entities.getEntityDescriptor();
    for (Object ed : entityDescriptors) {
      if (ed instanceof EntityDescriptorType) {
        writeEntityDescriptor((EntityDescriptorType) ed);
      } else writeEntitiesDescriptor((EntitiesDescriptorType) ed);
    }

    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
  }
  public void writeEntityDescriptor(EntityDescriptorType entityDescriptor)
      throws ProcessingException {
    StaxUtil.writeStartElement(
        writer, METADATA_PREFIX, JBossSAMLConstants.ENTITY_DESCRIPTOR.get(), METADATA_NSURI.get());
    StaxUtil.writeDefaultNameSpace(writer, JBossSAMLURIConstants.METADATA_NSURI.get());
    StaxUtil.writeNameSpace(writer, "md", JBossSAMLURIConstants.METADATA_NSURI.get());
    StaxUtil.writeNameSpace(writer, "saml", JBossSAMLURIConstants.ASSERTION_NSURI.get());
    StaxUtil.writeNameSpace(writer, "ds", JBossSAMLURIConstants.XMLDSIG_NSURI.get());

    StaxUtil.writeAttribute(
        writer, JBossSAMLConstants.ENTITY_ID.get(), entityDescriptor.getEntityID());
    if (entityDescriptor.getValidUntil() != null) {
      StaxUtil.writeAttribute(
          writer,
          JBossSAMLConstants.VALID_UNTIL.get(),
          entityDescriptor.getValidUntil().toString());
    }
    if (entityDescriptor.getID() != null) {
      StaxUtil.writeAttribute(writer, JBossSAMLConstants.ID.get(), entityDescriptor.getID());
    }

    Element signature = entityDescriptor.getSignature();
    if (signature != null) {
      StaxUtil.writeDOMElement(writer, signature);
    }
    ExtensionsType extensions = entityDescriptor.getExtensions();
    if (extensions != null) {
      StaxUtil.writeDOMElement(writer, extensions.getElement());
    }

    List<EDTChoiceType> choiceTypes = entityDescriptor.getChoiceType();
    for (EDTChoiceType edtChoice : choiceTypes) {
      AffiliationDescriptorType affliationDesc = edtChoice.getAffiliationDescriptor();
      if (affliationDesc != null) throw logger.notImplementedYet("affliation"); // TODO: affiliation

      List<EDTDescriptorChoiceType> edtDescChoices = edtChoice.getDescriptors();
      for (EDTDescriptorChoiceType edtDescChoice : edtDescChoices) {
        RoleDescriptorType roleDesc = edtDescChoice.getRoleDescriptor();

        if (roleDesc != null) throw logger.notImplementedYet("Role Descriptor type");

        IDPSSODescriptorType idpSSO = edtDescChoice.getIdpDescriptor();
        if (idpSSO != null) write(idpSSO);

        SPSSODescriptorType spSSO = edtDescChoice.getSpDescriptor();
        if (spSSO != null) write(spSSO);

        AttributeAuthorityDescriptorType attribAuth = edtDescChoice.getAttribDescriptor();
        if (attribAuth != null) writeAttributeAuthorityDescriptor(attribAuth);

        AuthnAuthorityDescriptorType authNDesc = edtDescChoice.getAuthnDescriptor();
        if (authNDesc != null) throw logger.notImplementedYet("AuthnAuthorityDescriptorType");

        PDPDescriptorType pdpDesc = edtDescChoice.getPdpDescriptor();
        if (pdpDesc != null) throw logger.notImplementedYet("PDPDescriptorType");
      }
    }
    OrganizationType organization = entityDescriptor.getOrganization();
    if (organization != null) {
      writeOrganization(organization);
    }

    List<ContactType> contactPersons = entityDescriptor.getContactPerson();
    for (ContactType contact : contactPersons) {
      write(contact);
    }

    List<AdditionalMetadataLocationType> addl = entityDescriptor.getAdditionalMetadataLocation();
    if (addl.size() > 0) throw logger.notImplementedYet("AdditionalMetadataLocationType");

    StaxUtil.writeEndElement(writer);
    StaxUtil.flush(writer);
  }