diff --git a/docs/reference/lasso/lasso-sections.txt b/docs/reference/lasso/lasso-sections.txt
index 67753ac4..67d9e013 100644
--- a/docs/reference/lasso/lasso-sections.txt
+++ b/docs/reference/lasso/lasso-sections.txt
@@ -895,8 +895,8 @@ LASSO_IDWSF2_SB2_HREF
LASSO_IDWSF2_SB2_PREFIX
LASSO_IDWSF2_SBF_HREF
LASSO_IDWSF2_SBF_PREFIX
-LASSO_IDWSF2_DISCO_HREF
-LASSO_IDWSF2_DISCO_PREFIX
+LASSO_IDWSF2_DISCOVERY_HREF
+LASSO_IDWSF2_DISCOVERY_PREFIX
LASSO_IDWSF2_DST_HREF
LASSO_IDWSF2_DST_PREFIX
LASSO_IDWSF2_DSTREF_HREF
diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c
index 7fa12dda..77ef6944 100644
--- a/lasso/id-ff/logout.c
+++ b/lasso/id-ff/logout.c
@@ -27,8 +27,164 @@
* This profile Send logout notifications between providers. Any receiving provider must retransmit
* the notification to any other providers with which it shares the current identity by any means
* supported by the two, that is any provider federated with the current provider. There can be
- * partial failures if no binding can be found to notify a federating partner.
+ * partial failures if no binding can be found to notify a federating partner or if a partner fails
+ * to respond.
*
+ * It is generally advised to apply the local logout transaction before sending a logout request to
+ * a partner. In short:
+ *
+ * an identity provider receiving a logout request should kill the local
+ * session before sending logout request to other service provider and proxyied identity
+ * providers.
+ * a service provider intitiating a logout request must first kill its local session,
+ * then proceeds with the logout exchange with its identity provider
+ *
+ *
+ *
+ * Service Provider Initiated Logout
+ *
+ * LassoLogout *logout;
+ * char *session_dump; // must contain the session dump
+ * // for the current user
+ * int rc; // hold return codes
+ * char *soap_response;
+ *
+ * LassoHttpMethod method; // method to use, LASSO_HTTP_METHOD_REDIRECT,
+ * // LASSO_HTTP_METHOD_POST or LASSO_HTTP_METHOD_SOAP,
+ * // other methods are rarely supported
+ *
+ * logout = lasso_logout_new(server);
+ * lasso_profile_set_session_from_dump(&logout->parent, session_dump);
+ * // the second argument can be NULL, lasso_logout_init_request() will automatically choose the
+ * // identity provider from the first assertion int the session
+ * rc = lasso_logout_init_request(login, "http://identity-provider-id/",
+ * method);
+ * if (rc != 0) {
+ * ... // handle errors, most of them are related to bad initialization
+ * // or unsupported binding
+ * }
+ * rc = lasso_logout_build_request_msg(logout);
+ * if (rc != 0) {
+ * ... // handle errors, most of them are related to bad initialization
+ * // or impossibility to build the query string (missing private keys for signing)
+ * }
+ *
+ * // now send the request
+ * switch (method) {
+ * case LASSO_HTTP_METHOD_REDIRECT:
+ * // LASSO_PROFILE(logout)->msg_url contains the URL where the
+ * // User Agent must be redirected
+ * ...
+ * break;
+ * case LASSO_HTTP_METHOD_POST:
+ * // you must build a form with a field name SAMLRequest (SAML 2.0) or LAREQ (ID-FF 1.2)
+ * // with the content of LASSO_PROFILE(logout)->msg_body
+ * // posting to the address LASSO_PROFILE(logout)->msg_url
+ * ...
+ * break;
+ * case LASSO_HTTP_SOAP:
+ * // makes a SOAP call, soap_call is NOT a Lasso function
+ * soap_response = soap_call(login->parent.msg_url, login->parent.msg_body);
+ * rc = lasso_logout_process_response_msg(logout, soap_response);
+ * if (rc != 0) {
+ * // handle errors, important ones are LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE meaning
+ * // that one other service provider of the current session cannot be contacted by the
+ * // identity provider with the current binding, for example it only accept REDIRECT
+ * (asynchronous-binding) or
+ * // POST an we are using SOAP (synchronous-binding).
+ * ...
+ * }
+ * default:
+ * // other binding neither are frequent or largely supported
+ * // so report an error
+ * break;
+ * }
+ *
+ *
+ *
+ * The next snippet show how to implement a logout endpoint, to receive a logout request and
+ * respond.
+ *
+ *
+ * Service Provider Logout Request Endpoint
+ *
+ * LassoLogout *logout;
+ * char *session_dump;
+ * char *request_method = getenv("REQUEST_METHOD");
+ * int rc;
+ * int method;
+ *
+ * logout = lasso_logout_new(server);
+ * // server must be previously initialized, it can be kept around
+ * // and used for many transaction, it is never modified by any profile
+ * if (strcmp(request_method. "GET") == 0) {
+ * method = LASSO_HTTP_METHOD_REDIRECT;
+ * char query_string = getenv("QUERY_STRING");
+ * rc = lasso_logout_process_request_msg(logout, query_string);
+ * if (rc != 0) {
+ * // handle errors
+ * ...
+ * }
+ * } else if (strcmp(request_method, "POST") == 0) {
+ * char *message;
+ * // read submitted content if this is a form, put LAREQ or SAMLRequest field into message and
+ * set method to LASSO_HTTP_METHOD_POST
+ * // if content type is application/xml then put the full body of the POST inside message and
+ * // set method to LASSO_HTTP_METHOD_SOAP
+ * rc = lasso_logout_process_request_msg(logout, message);
+ * if (rc != 0) {
+ * // handle errors
+ * ...
+ * }
+ * }
+ * protocolProfile = lasso_provider_get_protocol_conformance(LASSO_PROVIDER(server));
+ * if (protocolProfile == LASSO_LIBERTY_1_2) {
+ * char *session_index;
+ * LassoSamlNameIdentifier *name_id;
+ * LibLogoutRequest *logout_request;
+ *
+ * logout_request = LIB_LOGOUT_REQUEST(LASSO_PROFILE(logout)->request);
+ * session_index = logout_request->SessionIndex;
+ * name_id = logout_request->NameIdentifier;
+ * // lookup the session dump using session_index and name_id
+ * } else if (protocolProfile == LASSO_SAML_2_0) {
+ * char *session_index;
+ * LassoSaml2NameID *name_id;
+ * LassoSamlp2LogoutRequest *logout_request;
+ *
+ * logout_request = LASSO_SAMLP2_LOGOUT_REQUEST(LASSO_PROFILE(logout)->request);
+ * session_index = logout_request->SessionIndex;
+ * name_id = logout_request->NameID;
+ * // lookup the session dump using session_index and name_id
+ * }
+ * lasso_profile_set_session_from_dump(LASSO_PROFILE(logout), session_dump);
+ * // you can check other property of the request here if you want
+ * //
+ * if (request is accepted) {
+ * rc = lasso_logout_validate_request(logout);
+ * if (rc != 0) {
+ * // handle errors..
+ * ...
+ * } else {
+ * .... // kill the local session
+ * // if local server is an identity provider, then traverse the session using
+ * // lasso_logout_get_next_providerID() and send logout request to all logged
+ * // service providers.
+ * }
+ * }
+ * // if lasso_logout_validate_request() was not called this will automatically create a Failure
+ * // response.
+ * rc = lasso_logout_build_response_msg(logout);
+ * if (rc != 0) {
+ * // handle errors..
+ * ...
+ * }
+ * // the response is produced with the same binding as the request
+ * // see the previous request example for how to send the response
+ * // the only change is for SOAP, you just need to print the msg_body as page content with a
+ * // Content-type of application/xml.
+ *
+ *
*/
#include "../xml/private.h"
diff --git a/lasso/id-wsf-2.0/profile.c b/lasso/id-wsf-2.0/profile.c
index 9642bfaa..51d8251b 100644
--- a/lasso/id-wsf-2.0/profile.c
+++ b/lasso/id-wsf-2.0/profile.c
@@ -327,7 +327,7 @@ cleanup:
* LASSO_PROFILE_ERROR_INVALID_MSG if we cannot parse the message,
* LASSO_SOAP_ERROR_MISSING_BODY if the message has no body
* content.
- *
+ *
*/
gint
lasso_idwsf2_profile_process_request_msg(LassoIdWsf2Profile *wsf2_profile, const gchar *message)
@@ -603,6 +603,7 @@ lasso_idwsf2_profile_build_response_msg(LassoIdWsf2Profile *idwsf2_profile)
* LASSO_SOAP_ERROR_MISSING_BODY if no body element is found,
* LASSO_PROFILE_ERROR_MISSING_RESPONSE if the body element is
* empty.
+ *
*/
gint
lasso_idwsf2_profile_process_response_msg(LassoIdWsf2Profile *profile, const gchar *message)