/// <summary>
        /// Sends a SOAP AttributeQueryRequest to the specified IDP.
        /// </summary>
        /// <param name="attrQueryRequest">
        /// AttributeQueryRequest object.
        /// </param>
        /// <param name="idpEntityId">Entity ID of the IDP.</param>
        public AttributeQueryResponse SendSoapAttributeQueryRequest(AttributeQueryRequest attrQueryRequest, string idpEntityId)
        {
            XmlNodeList soapFault = null;
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            AttributeQueryResponse attributeQueryResponse = null;
            IdentityProvider idp = (IdentityProvider)this.IdentityProviders[idpEntityId];

            if (attrQueryRequest == null)
            {
                throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilityAttributeQueryRequestIsNull);
            }
            else if (idp == null)
            {
                throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilityIdentityProviderNotFound);
            }
            else if (idp.GetSingleAttributeServiceLocation(Saml2Constants.HttpSoapProtocolBinding, attrQueryRequest.X509SubjectName) == null)
            {
                throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilityIdpSingleAttributeQuerySvcLocNotDefined);
            }

            try
            {

                Uri soapAttributeQuerySvcUri = new Uri(idp.GetSingleAttributeServiceLocation(Saml2Constants.HttpSoapProtocolBinding, attrQueryRequest.X509SubjectName));
                if (soapAttributeQuerySvcUri.Scheme == "https")
                {
                    System.Net.ServicePointManager.ServerCertificateValidationCallback +=
                    delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
                    {
                        if (ServiceProvider.TrustAllCerts
                            || sslPolicyErrors.HasFlag(System.Net.Security.SslPolicyErrors.None))
                            {
                                return true;
                            }

                        StringBuilder logErrorMessage = new StringBuilder();
                        logErrorMessage.Append("SSLPolicyError: ").Append(sslPolicyErrors);
                        FedletLogger.Error(logErrorMessage.ToString());
                        return false;
                    };
                }

                request = (HttpWebRequest)WebRequest.Create(soapAttributeQuerySvcUri);

                string authCertAlias = ConfigurationManager.AppSettings[Saml2Constants.MutualAuthCertAlias];
                if (soapAttributeQuerySvcUri.Scheme == "https" && !string.IsNullOrWhiteSpace(authCertAlias))
                {
                    X509Certificate2 cert = FedletCertificateFactory.GetCertificateByFriendlyName(authCertAlias);
                    if (cert != null)
                    {
                        request.ClientCertificates.Add(cert);
                    }
                }

                XmlDocument attrQueryRequestXml = (XmlDocument)attrQueryRequest.XmlDom;

                if (this.ServiceProvider.WantNameIDEncryptedAttributeQuery)
                {
                    if (string.IsNullOrWhiteSpace(idp.EncodedEncryptionCertificate))
                    {
                        throw new ServiceProviderUtilityException(Resources.EncryptedXmlCertNotFound);
                    }

                    if (string.IsNullOrWhiteSpace(idp.EncryptionMethodAlgorithm))
                    {
                        throw new ServiceProviderUtilityException(Resources.EncryptedXmlInvalidEncrAlgorithm);
                    }

                    Saml2Utils.EncryptAttributeQueryNameID(
                        idp.EncodedEncryptionCertificate,
                        idp.EncryptionMethodAlgorithm,
                        attrQueryRequestXml);
                }

                if (string.IsNullOrWhiteSpace(this.ServiceProvider.AttributeQuerySigningCertificateAlias))
                {
                    throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilitySignFailedNoCertAlias);
                }
                else
                {
                    Saml2Utils.SignXml(
                         this.ServiceProvider.AttributeQuerySigningCertificateAlias,
                         attrQueryRequestXml,
                         attrQueryRequest.Id,
                         true,
                         this.ServiceProvider);
                }

                string soapMessage = Saml2Utils.CreateSoapMessage(attrQueryRequestXml.InnerXml);
                StringBuilder logMessageSoap = new StringBuilder();
                logMessageSoap.Append("AttributeQuerySOAPRequest:\r\n").Append(soapMessage);
                FedletLogger.Info(logMessageSoap.ToString());

                byte[] byteArray = Encoding.UTF8.GetBytes(soapMessage);
                request.ContentType = "text/xml";
                request.ContentLength = byteArray.Length;
                request.AllowAutoRedirect = false;
                request.Method = "POST";

                Stream requestStream = request.GetRequestStream();
                requestStream.Write(byteArray, 0, byteArray.Length);
                requestStream.Close();

                response = (HttpWebResponse)request.GetResponse();
                StreamReader streamReader = new StreamReader(response.GetResponseStream());
                string responseContent = streamReader.ReadToEnd();
                streamReader.Close();

                XmlDocument soapResponse = new XmlDocument();
                soapResponse.PreserveWhitespace = true;
                soapResponse.LoadXml(responseContent);

                XmlNamespaceManager soapNsMgr = new XmlNamespaceManager(soapResponse.NameTable);
                soapNsMgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
                soapNsMgr.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
                soapNsMgr.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
                soapNsMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");

                XmlElement root = soapResponse.DocumentElement;

                if ((soapFault = root.GetElementsByTagName("Fault", "http://schemas.xmlsoap.org/soap/envelope/")).Count > 0)
                {
                    StringBuilder faultMessage = new StringBuilder();
                    faultMessage.Append("AttributeQueryResponse Error:\r\n");
                    faultMessage.Append(soapFault[0].InnerText);
                    FedletLogger.Info(faultMessage.ToString());
                    throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilitySoapFault, new SoapException(soapFault[0].InnerText));
                }

                XmlNode responseXml = root.SelectSingleNode("/soap:Envelope/soap:Body/samlp:Response", soapNsMgr);
                string attrQueryResponseXml = responseXml.OuterXml;

                attributeQueryResponse = new AttributeQueryResponse(attrQueryResponseXml);
                StringBuilder logMessage = new StringBuilder();
                logMessage.Append("AttributeQueryResponse:\r\n").Append(attrQueryResponseXml);
                FedletLogger.Info(logMessage.ToString());

                if (attributeQueryResponse != null && !string.IsNullOrWhiteSpace(attributeQueryResponse.StatusCode)
                    && !attributeQueryResponse.StatusCode.Equals(Saml2Constants.Success))
                {
                    throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilityErrorSamlResponseReceived,
                        new Saml2Exception(attributeQueryResponse.StatusMessage));
                }

                ArrayList attributeQueryRequests = new ArrayList();
                attributeQueryRequests.Add(attrQueryRequest);
                this.Validate(attributeQueryResponse, attributeQueryRequests);

            }
            catch (WebException we)
            {
                throw new ServiceProviderUtilityException(Resources.AttributeQueryRequestWebException, we);
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
            return attributeQueryResponse;
        }
        /// <summary>
        /// Sends an AttributeQueryRequest to the specified IDP with the given 
        /// parameters.
        /// </summary>
        /// <param name="context">
        /// HttpContext containing session, request, and response objects.
        /// </param>
        /// <param name="idpEntityId">Entity ID of the IDP.</param>
        /// <param name="parameters">
        /// NameValueCollection of varying parameters for use in the 
        /// construction of the AttributeQueryRequest.
        /// </param>
        /// <param name="attributes">
        /// A list of SamlAttributes for use in the 
        /// construction of the AttributeQueryRequest.
        /// </param>
        public AttributeQueryResponse SendAttributeQueryRequest(HttpContext context, string idpEntityId, NameValueCollection parameters,
             List<SamlAttribute> attributes)
        {
            IdentityProvider idp = (IdentityProvider)this.IdentityProviders[idpEntityId];
            if (idp == null)
            {
                throw new ServiceProviderUtilityException(Resources.ServiceProviderUtilityIdentityProviderNotFound);
            }

            if (parameters == null)
            {
                parameters = new NameValueCollection();
            }

            AttributeQueryRequest aqRequest = new AttributeQueryRequest(idp, this.ServiceProvider, parameters, attributes);
            XmlDocument xmlDoc = (XmlDocument)aqRequest.XmlDom;
            StringBuilder logMessage = new StringBuilder();
            logMessage.Append("AttributeQueryRequest:\r\n").Append(xmlDoc.OuterXml);
            FedletLogger.Info(logMessage.ToString());
            return this.SendSoapAttributeQueryRequest(aqRequest, idpEntityId);
        }