public static ResultObject Present(string language, string policy_url, string verify_url, string optional_cookie)
        {
            try
            {

                long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
                var sessionID = "PresentIE" + milliseconds;

                BrowserHelperObject.log("BHO", "Present", "Start : " + language + " " + policy_url + " " + verify_url + " " + optional_cookie);

                // todo : check smartcard
                ResultObject error = CheckSmartCard(sessionID);
                if (error != null) return error;

                //
                var xmlPolicyRequest = (HttpWebRequest)WebRequest.Create(policy_url);
                xmlPolicyRequest.Method = "GET";
                xmlPolicyRequest.Accept = "text/xml,application/xml";
                xmlPolicyRequest.KeepAlive = false;
                xmlPolicyRequest.ContentLength = 0;
                xmlPolicyRequest.ReadWriteTimeout = 5000;
                xmlPolicyRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
                xmlPolicyRequest.ServicePoint.MaxIdleTime = 5000;
                xmlPolicyRequest.ServicePoint.ConnectionLimit = 400;
                BrowserHelperObject.log("BHO", "Present", "- xmlVerifyRequest.ServicePoint : " + xmlPolicyRequest.ServicePoint.ConnectionLeaseTimeout + " : " + xmlPolicyRequest.ServicePoint.ConnectionLimit);

                if (!String.IsNullOrEmpty(optional_cookie))
                {
                    BrowserHelperObject.log("BHO", "Present", "- Set Cookie for Policy : " + optional_cookie);
                    xmlPolicyRequest.Headers.Add("Cookie", optional_cookie);
                }
                else
                {
                    BrowserHelperObject.log("BHO", "Present", "- No Cookie");
                }

                HttpWebResponse xmlPolicyResponse;
                try
                {
                    BrowserHelperObject.log("BHO", "Present", "- Try to get policy.... " + policy_url + " - timeout : " + xmlPolicyRequest.ReadWriteTimeout);
                    xmlPolicyResponse = (HttpWebResponse)xmlPolicyRequest.GetResponse();
                    BrowserHelperObject.log("BHO", "Present", "- Contacted Verifier... " + xmlPolicyResponse.StatusCode + " : " + xmlPolicyResponse.ContentType + " - content length : " + xmlPolicyResponse.ContentLength);
                }
                catch (Exception e)
                {
                    if (e.GetType() == typeof(System.Net.WebException))
                    {
                        System.Net.WebException we = (System.Net.WebException)e;
                        BrowserHelperObject.log("BHO", "Present", "- WebException - on policy : " + e);
                        if (we.Status == WebExceptionStatus.ProtocolError)
                        {
                            BrowserHelperObject.log("BHO", "Present", "- e.Status : " + we.Status + " - e.Response : " + we.Response);
                            var response = we.Response as HttpWebResponse;
                            BrowserHelperObject.log("BHO", "Present", "- got response ? : " + response);
                            if (response != null)
                            {
                                BrowserHelperObject.log("BHO", "Present", "- response : " + response.StatusCode + " : " + response.StatusDescription);
                                return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                            }
                            else
                            {
                                return new ResultObject { status = 500, message = "Unhandled error : " + we.Status };
                            }

                        }
                        else
                        {
                            return new ResultObject { status = 500, message = "Could not contact policyserver." };
                        }
                    }
                    else
                    {
                        BrowserHelperObject.log("BHO", "Present", "- Unknown exception  : " + e);
                        return new ResultObject { status = 500, message = "Unknown error  : " + e.Message };
                    }
                }

                if (xmlPolicyResponse.StatusCode != HttpStatusCode.OK)
                {
                    BrowserHelperObject.log("BHO", "Present", "- No Policy from Server " + xmlPolicyResponse.StatusCode + " " + xmlPolicyResponse);

                    return new ResultObject { status = (int)xmlPolicyResponse.StatusCode, message = "Failed to obtain presentation policy" };
                }
                BrowserHelperObject.log("BHO", "Present", "- OK From Policy from Server " + xmlPolicyResponse.StatusCode + " " + xmlPolicyResponse);
                BrowserHelperObject.log("BHO", "Present", "- Policy Response Headers : " + xmlPolicyResponse.Headers);

                var xmlPolicyStream = xmlPolicyResponse.GetResponseStream();
                BrowserHelperObject.log("BHO", "Present", "- got Response Stream! " + xmlPolicyStream);

                //
                var abcRequest = (HttpWebRequest)WebRequest.Create(USER_ABCE_SERVICE + "/user/createPresentationToken/" + sessionID);
                abcRequest.Method = "POST";
                abcRequest.Accept = "text/xml,application/xml";
                abcRequest.ContentType = "application/xml";
                Stream abcToStream = null; // = abcRequest.GetRequestStream();
                try
                {
                    abcToStream = abcRequest.GetRequestStream();
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        var response = e.Response as HttpWebResponse;
                        if (response != null)
                        {
                            return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                        }
                        else
                        {
                            return new ResultObject { status = 400, message = "Unhandled error : " + e.Status };
                        }
                    }
                    else
                    {
                        return new ResultObject { status = 400, message = "User ABCE Not Running (Verification)" };
                    }
                }

                BrowserHelperObject.log("BHO", "Present", "- got Request Stream! " + abcToStream);
                MemoryStream policyByteStream = new MemoryStream();
                byte[] b = new byte[1];
                using (BinaryWriter writer = new BinaryWriter(policyByteStream))
                {
                    while (xmlPolicyStream.Read(b, 0, 1) != 0)
                    {
                        writer.Write(b);
                    }
                    writer.Close();
                }
                xmlPolicyStream.Close();
                BrowserHelperObject.log("BHO", "Present", "- dispose xmlPolicyStream...");
                xmlPolicyStream.Dispose();
                BrowserHelperObject.log("BHO", "Present", "- close xmlPolicyResponse...");
                xmlPolicyResponse.Close();

                policyByteStream.Close();
                byte[] policyBytes = policyByteStream.ToArray();
                //                var xmlPolicyString = new System.Text.UTF8Encoding().GetString(policyBytes);
                //                BrowserHelperObject.log("BHO", "Present", "- xml from Verifier - length : " + policyBytes.Length + " : " + xmlPolicyString);
                BrowserHelperObject.log("BHO", "Present", "- xml from Verifier - length : " + policyBytes.Length + " - abc stream : " + abcToStream);

                abcToStream.Write(policyBytes, 0, policyBytes.Length);
                abcToStream.Close();
                abcToStream.Dispose();

                HttpWebResponse abcResponse = (HttpWebResponse)abcRequest.GetResponse();
                var abcStatus = (int)abcResponse.StatusCode;
                BrowserHelperObject.log("BHO", "Present", "- response from user service : " + abcResponse + " " + abcStatus);

                if (abcStatus == 422)
                {
                    abcResponse.Close();
                    return new ResultObject { status = abcStatus, message = "Can not satisfy policy" };
                }
                if (abcStatus != 200 && abcStatus != 203)
                {
                    abcResponse.Close();
                    return new ResultObject { status = abcStatus, message = "Failed to contact local ABC engine" };
                }
                if (abcStatus == 203)
                {   // 203 - means id selection...

                    abcResponse.Close();
                    var selectionUIURL = USER_UI_SERVICE + "?mode=presentation&demo=false&language=" + language + "&sessionid=" + sessionID;
                    BrowserHelperObject.log("BHO", "Present", "- selectionUIURL : " + selectionUIURL);

                    var form = new WebForm { URL = selectionUIURL };
                    var dialogResponse = form.ShowDialog();
                    // web form is closed
                    BrowserHelperObject.log("BHO", "Present", "- ID Select web form was closed : " + dialogResponse);

                    // get presentation token... maybe...
                    abcRequest = (HttpWebRequest)WebRequest.Create(USER_ABCE_SERVICE + "/user/createPresentationTokenIdentitySelection/" + sessionID);
                    abcRequest.Method = "POST";
                    abcRequest.Accept = "text/xml,application/xml";
                    abcRequest.ContentType = "text/plain";

                    try
                    {
                        abcResponse = (HttpWebResponse)abcRequest.GetResponse();
                        abcStatus = (int)abcResponse.StatusCode;
                    }
                    catch (WebException e)
                    {
                        BrowserHelperObject.log("BHO", "Present", "- abc service error obtaining token : " + e);
                        if (e.Status == WebExceptionStatus.ProtocolError)
                        {
                            BrowserHelperObject.log("BHO", "Present", "- abc service error obtaining token - status : " + e.Status + " : " + e.Response);
                            var response = e.Response as HttpWebResponse;
                            if (response != null)
                            {
                                return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                            }
                            else
                            {
                                return new ResultObject { status = 400, message = "Unhandled error : " + e.Status };
                            }
                        }
                        else
                        {
                            return new ResultObject { status = 400, message = "User ABCE Not Running (Verification)" };
                        }
                    }

                    BrowserHelperObject.log("BHO", "Present", "- abc service response : " + abcStatus);

                    if (abcStatus != 200)
                    {
                        return new ResultObject { status = abcStatus, message = "Failed to contact local ABC engine" };
                    }
                }
                // abcResponse should now have ABCE PresentationToken..
                BrowserHelperObject.log("BHO", "Present", "- setup verify post");
                var xmlVerifyRequest = (HttpWebRequest)WebRequest.Create(verify_url);
                xmlVerifyRequest.Method = "POST";
                xmlVerifyRequest.Accept = "text/xml,application/xml";
                xmlVerifyRequest.ContentType = "application/xml; charset=utf-8"; // charset=utf-8
                xmlVerifyRequest.KeepAlive = false;
                xmlVerifyRequest.ReadWriteTimeout = 5000;
                xmlVerifyRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
                xmlVerifyRequest.ServicePoint.MaxIdleTime = 5000;
                xmlVerifyRequest.ServicePoint.ConnectionLimit = 400;
                BrowserHelperObject.log("BHO", "Present", "- xmlVerifyRequest.ServicePoint - keepalive false : " + xmlVerifyRequest.ServicePoint.ConnectionLeaseTimeout + " : " + xmlVerifyRequest.ServicePoint.ConnectionLimit);

                // just hand over cookie
                if (!String.IsNullOrEmpty(optional_cookie))
                {
                    BrowserHelperObject.log("BHO", "Present", "- Set Cookie for Verify : " + optional_cookie);
                    xmlVerifyRequest.Headers.Add("Cookie", optional_cookie);
                }

                BrowserHelperObject.log("BHO", "Present", "- get response stream from ABC...");
                var abcFromStream = abcResponse.GetResponseStream();

                BrowserHelperObject.log("BHO", "Present", "- get request stream to verifier...");
                var xmlToStream = xmlVerifyRequest.GetRequestStream();
                BrowserHelperObject.log("BHO", "Present", "- send xml to verifier...");

                MemoryStream tokenByteStream = new MemoryStream();
                using (BinaryWriter writer = new BinaryWriter(tokenByteStream))
                {
                    while (abcFromStream.Read(b, 0, 1) != 0)
                    {
                        writer.Write(b);
                    }
                    writer.Close();
                }
                abcFromStream.Close();
                abcFromStream.Dispose();
                abcResponse.Close();

                tokenByteStream.Close();
                byte[] tokenBytes = tokenByteStream.ToArray();
                //                var xmlTokenString = new System.Text.UTF8Encoding().GetString(tokenBytes);
                //                BrowserHelperObject.log("BHO", "Present", "- xml to Verifier - length : " + tokenBytes.Length + " : " + xmlTokenString);
                BrowserHelperObject.log("BHO", "Present", "- xml to Verifier - length : " + tokenBytes.Length);

                xmlToStream.Write(tokenBytes, 0, tokenBytes.Length);
                xmlToStream.Close();
                xmlToStream.Dispose();

                HttpWebResponse xmlVerifyResponse;
                try
                {
                    BrowserHelperObject.log("BHO", "Present", "- check response...");
                    xmlVerifyResponse = (HttpWebResponse)xmlVerifyRequest.GetResponse();
                    xmlVerifyResponse.Close();
                    BrowserHelperObject.log("BHO", "Present", "- check response - not exception... - response closed");
                }
                catch (Exception e)
                {
                    if (e.GetType() == typeof(System.Net.WebException))
                    {
                        System.Net.WebException we = (System.Net.WebException)e;
                        BrowserHelperObject.log("BHO", "Present", "- WebException - on verify : " + e);
                        if (we.Status == WebExceptionStatus.ProtocolError)
                        {
                            BrowserHelperObject.log("BHO", "Present", "- e.Status : " + we.Status + " - e.Response : " + we.Response);
                            var response = we.Response as HttpWebResponse;
                            BrowserHelperObject.log("BHO", "Present", "- got response ? : " + response);
                            if (response != null)
                            {
                                BrowserHelperObject.log("BHO", "Present", "- response : " + response.StatusCode + " : " + response.StatusDescription);
                                return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                            }
                            else
                            {
                                return new ResultObject { status = 500, message = "Unhandled error : " + we.Status };
                            }
                        }
                        else
                        {
                            return new ResultObject { status = 500, message = "Could not contact policyserver." };
                        }
                    }
                    else
                    {
                        BrowserHelperObject.log("BHO", "Present", "- Unknown exception - on verify : " + e);
                        return new ResultObject { status = 500, message = "Unknown error  : " + e.Message };
                    }
                }

                BrowserHelperObject.log("BHO", "Present", "- Token Response Headers : " + xmlVerifyResponse.Headers);

                int xmlVerifyStatus = (int)xmlVerifyResponse.StatusCode;

                BrowserHelperObject.log("BHO", "Present", "- status from verify request : " + xmlVerifyStatus + " " + xmlVerifyResponse.StatusDescription);

                if (xmlVerifyStatus != 200 && xmlVerifyStatus != 202 && xmlVerifyStatus != 204)
                {
                    return new ResultObject { status = xmlVerifyStatus, message = "Failed to contact verifier" };
                }
                return new ResultObject { status = xmlVerifyStatus, message = "Verfication was succesful" };
            }
            catch (Exception e)
            {
                BrowserHelperObject.log("BHO", "Present", "- Present Exception : " + e);
                MessageBox.Show("BHO-Present ", "Exception ! " + e);

            }

            return new ResultObject { status = 504, message = "Bail out after exception." };
        }
        public static ResultObject Issue(string language, string start_url, string step_url, string status_url, string optional_cookie)
        {
            long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            var sessionID = "IssuanceIE" + milliseconds;

            BrowserHelperObject.log("BHO", "Issue", "Start : " + language + " " + start_url + " " + step_url + " " + status_url);

            // todo : check smartcard
            ResultObject error = CheckSmartCard(sessionID);
            if (error != null) return error;

            // These URLs are for re-isuance. Encode/Escape them before handing over to ABCE service.
            var start_request_mod = Uri.EscapeUriString(start_url);
            var step_request_mod = Uri.EscapeUriString(step_url);

            //
            //
            var xmlPolicyRequest = (HttpWebRequest)WebRequest.Create(start_url);
            xmlPolicyRequest.Method = "POST";
            xmlPolicyRequest.Accept = "text/xml,application/xml";
            xmlPolicyRequest.KeepAlive = false;
            xmlPolicyRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
            xmlPolicyRequest.ServicePoint.MaxIdleTime = 5000;
            xmlPolicyRequest.ServicePoint.ConnectionLimit = 400;
            BrowserHelperObject.log("BHO", "Issue", "- xmlPolicyRequest.ServicePoint : " + xmlPolicyRequest.ServicePoint.ConnectionLeaseTimeout + " : " + xmlPolicyRequest.ServicePoint.ConnectionLimit);

            // set cookie
            if (!String.IsNullOrEmpty(optional_cookie))
            {
                xmlPolicyRequest.Headers.Add("Cookie", optional_cookie);
                BrowserHelperObject.log("BHO", "Issue", "- Set Cookie : " + optional_cookie);
            }
            else
            {
                BrowserHelperObject.log("BHO", "Issue", "- No Cookie");
            }

            HttpWebResponse xmlResponse;
            try
            {
                BrowserHelperObject.log("BHO", "Issue", "- Try to get initial issuance message - Timeout : " + xmlPolicyRequest.ReadWriteTimeout);
                xmlResponse = (HttpWebResponse)xmlPolicyRequest.GetResponse();
                BrowserHelperObject.log("BHO", "Issue", "- Contacted Issuer...");
            }
            catch (WebException e)
            {
                BrowserHelperObject.log("BHO", "Issuer", "- WebException - getting Issuance Policy : " + e);
                if (e.Status == WebExceptionStatus.ProtocolError)
                {
                    var response = e.Response as HttpWebResponse;
                    if (response != null)
                    {
                        return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                    }
                    else
                    {
                        return new ResultObject { status = 500, message = "Unhandled error : " + e.Status };
                    }

                }
                else
                {
                    return new ResultObject { status = 500, message = "Could not contact issuanceserver." };
                }
            }
            if (xmlResponse.StatusCode != HttpStatusCode.OK)
            {
                BrowserHelperObject.log("BHO", "Issuer", "- Failed to obtain issuance policy from issuance server " + xmlResponse.StatusCode + " " + xmlResponse);

                return new ResultObject { status = (int)xmlResponse.StatusCode, message = "Failed to obtain issuance policy from issuance server" };
            }
            BrowserHelperObject.log("BHO", "Issuer", "- OK From Issuance Policy from Server " + xmlResponse.StatusCode + " " + xmlResponse);

            var xmlFromStream = xmlResponse.GetResponseStream();
            BrowserHelperObject.log("BHO", "Issuer", "- got Response Stream! " + xmlFromStream);

            while (true)
            {
                // read from issuer - write to local abc
                var abcRequest = (HttpWebRequest)WebRequest.Create(USER_ABCE_SERVICE + "/user/issuanceProtocolStep/" + sessionID +
                   "?startRequest=" + start_request_mod +
                    "&stepRequest=" + step_request_mod);
                abcRequest.Method = "POST";
                abcRequest.Accept = "text/xml,application/xml";
                abcRequest.ContentType = "application/xml";
                Stream abcToStream; // = abcRequest.GetRequestStream();
                try
                {
                    abcToStream = abcRequest.GetRequestStream();
                }
                catch (WebException e)
                {
                    BrowserHelperObject.log("BHO", "Issuer", "- WebException - on step - contacting ABCE : " + e);
                    reportIssuanceStatus(status_url, false, optional_cookie);
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        var response = e.Response as HttpWebResponse;
                        if (response != null)
                        {
                            int statusCode = (int)response.StatusCode;
                            if (statusCode == 501)
                            {
                                // specific check for insufficient storage.
                                MessageBox.Show("Insufficient storage on card. Please try to use check revocation status from the ABC4Trust menu.",
                                    "Smart Card Error!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation,
                                    MessageBoxDefaultButton.Button1);

                                return new ResultObject { status = 501, message = "Insufficient storage on card." };
                            }
                            else
                            {
                                return new ResultObject { status = statusCode, message = response.StatusDescription };
                            }
                        }
                        else
                        {
                            return new ResultObject { status = 400, message = "Unhandled error : " + e.Status };
                        }
                    }
                    else
                    {
                        return new ResultObject { status = 400, message = "User ABCE Not Running (Issuance)" };
                    }
                }

                BrowserHelperObject.log("BHO", "Issuer", "- got Request Stream! " + abcToStream);
                MemoryStream issuer2ABCEStream = new MemoryStream();
                byte[] b = new byte[1];
                using (BinaryWriter writer = new BinaryWriter(issuer2ABCEStream))
                {
                    while (xmlFromStream.Read(b, 0, 1) != 0)
                    {
                        writer.Write(b);
                    }
                    writer.Close();
                }
                xmlFromStream.Close();
                xmlFromStream.Dispose();

                issuer2ABCEStream.Close();
                byte[] issuer2ABCEBytes = issuer2ABCEStream.ToArray();
                //                var issuer2ABCEString = new System.Text.UTF8Encoding().GetString(issuer2ABCEBytes);
                //                BrowserHelperObject.log("BHO", "Issuer", "- xml from Issuer - length : " + issuer2ABCEBytes.Length + " : " + issuer2ABCEString);
                BrowserHelperObject.log("BHO", "Issuer", "- xml from Issuer - length : " + issuer2ABCEBytes.Length);

                abcToStream.Write(issuer2ABCEBytes, 0, issuer2ABCEBytes.Length);
                abcToStream.Close();

                BrowserHelperObject.log("BHO", "Issuer", "- get status from ABCE UserService...");
                HttpWebResponse abcResponse;
                try
                {
                    abcResponse = (HttpWebResponse)abcRequest.GetResponse();
                }
                catch (WebException e)
                {
                    BrowserHelperObject.log("BHO", "Issuer", "- WebException - on step - sending to ABCE : " + e);
                    reportIssuanceStatus(status_url, false, optional_cookie);
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        var response = e.Response as HttpWebResponse;
                        if (response != null)
                        {
                            int statusCode = (int)response.StatusCode;
                            if (statusCode == 501)
                            {
                                // specific check for insufficient storage.
                                MessageBox.Show("Insufficient storage on card. Please try to use check revocation status from the ABC4Trust menu.",
                                    "Smart Card Error!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Exclamation,
                                    MessageBoxDefaultButton.Button1);

                                return new ResultObject { status = 501, message = "Insufficient storage on card." };
                            }
                            else
                            {
                                return new ResultObject { status = statusCode, message = response.StatusDescription };
                            }
                        }
                        else
                        {
                            return new ResultObject { status = 400, message = "Unhandled error : " + e.Status };
                        }
                    }
                    else
                    {
                        return new ResultObject { status = 400, message = "User ABCE Not Running (Issuance)" };
                    }
                }

                var abcStatus = (int)abcResponse.StatusCode;
                BrowserHelperObject.log("BHO", "Issue", "- response from user service : " + abcResponse + " " + abcStatus);

                if (abcStatus != 200 && abcStatus != 203 && abcStatus != 204)
                {
                    reportIssuanceStatus(status_url, false, optional_cookie);
                    return new ResultObject { status = abcStatus, message = "Local ABC engine did not return an Issuancemessage." };
                }

                // we now have step response from User ABCE...
                if (abcStatus == 203)
                {
                    // select credentials
                    abcResponse.Close();
                    var selectionUIURL = USER_UI_SERVICE + "?mode=issuance&demo=false&language=" + language + "&sessionid=" + sessionID;
                    BrowserHelperObject.log("BHO", "Issue", "- selectionUIURL : " + selectionUIURL);

                    var form = new WebForm { URL = selectionUIURL };

                    var dialogResponse = form.ShowDialog();
                    BrowserHelperObject.log("BHO", "Issue", "- dialogResponse : " + dialogResponse);

                    // get presentation token... maybe...
                    abcRequest = (HttpWebRequest)WebRequest.Create(USER_ABCE_SERVICE + "/user/issuanceProtocolStepSelect/" + sessionID +
                        "?startRequest=" + start_request_mod +
                        "&stepRequest=" + step_request_mod);
                    abcRequest.Method = "POST";
                    abcRequest.Accept = "text/xml,application/xml";
                    abcRequest.ContentType = "text/plain";

                    abcResponse = (HttpWebResponse)abcRequest.GetResponse();
                    abcStatus = (int)abcResponse.StatusCode;
                    BrowserHelperObject.log("BHO", "Issue", "- abc service response : " + abcStatus);

                    if (abcStatus != 200)
                    {
                        reportIssuanceStatus(status_url, false, optional_cookie);
                        return new ResultObject { status = abcStatus, message = "Failed to contact local ABC engine" };
                    }
                }

                // we now have issuance message ready on abcResponse
                if (abcStatus == 204)
                {
                    reportIssuanceStatus(status_url, true, optional_cookie);
                    return new ResultObject { status = abcStatus, message = "Credential obtained... SUCCESS" };
                }

                // we should continue - read from abc send to xmlstep
                var abcFromStream = abcResponse.GetResponseStream();

                var xmlStepRequest = (HttpWebRequest)WebRequest.Create(step_url);
                xmlStepRequest.Method = "POST";
                xmlStepRequest.ContentType = "application/xml; charset=utf-8";
                xmlStepRequest.Accept = "text/xml,application/xml";
                xmlStepRequest.KeepAlive = false;
                xmlStepRequest.ServicePoint.ConnectionLeaseTimeout = 5000;
                xmlStepRequest.ServicePoint.MaxIdleTime = 5000;
                xmlStepRequest.ServicePoint.ConnectionLimit = 400;
                BrowserHelperObject.log("BHO", "Issue", "- xmlStepRequest.ServicePoint : " + xmlStepRequest.ServicePoint.ConnectionLeaseTimeout + " : " + xmlStepRequest.ServicePoint.ConnectionLimit);

                if (!String.IsNullOrEmpty(optional_cookie))
                {
                    xmlStepRequest.Headers.Add("Cookie", optional_cookie);
                }

                HttpWebResponse xmlStepResponse;
                try
                {
                    BrowserHelperObject.log("BHO", "Issue", "- Send Step IssuanceMessage to Issuer....");
                    MemoryStream abce2IssuerStream = new MemoryStream();
                    using (BinaryWriter writer = new BinaryWriter(abce2IssuerStream))
                    {
                        while (abcFromStream.Read(b, 0, 1) != 0)
                        {
                            writer.Write(b);
                        }
                        writer.Close();
                    }
                    abcFromStream.Close();

                    abce2IssuerStream.Close();
                    byte[] abce2IssuerBytes = abce2IssuerStream.ToArray();
                    //                    var abce2IssuerString = new System.Text.UTF8Encoding().GetString(abce2IssuerBytes);
                    //                    BrowserHelperObject.log("BHO", "Issuer", "- xml from ABCE - length : " + abce2IssuerBytes.Length + " : " + abce2IssuerString);
                    BrowserHelperObject.log("BHO", "Issuer", "- xml from ABCE - length : " + abce2IssuerBytes.Length);

                    var xmlToStream = xmlStepRequest.GetRequestStream();
                    xmlToStream.Write(abce2IssuerBytes, 0, abce2IssuerBytes.Length);
                    xmlToStream.Close();
                    xmlToStream.Dispose();

                    BrowserHelperObject.log("BHO", "Issue", "- get Response from Issuer step...");

                    xmlStepResponse = (HttpWebResponse)xmlStepRequest.GetResponse();
                    BrowserHelperObject.log("BHO", "Issue", "- Contacted Issuer...");
                }
                catch (WebException e)
                {
                    reportIssuanceStatus(status_url, false, optional_cookie);
                    BrowserHelperObject.log("BHO", "Issue", "- WebException : " + e);
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        var response = e.Response as HttpWebResponse;
                        if (response != null)
                        {
                            BrowserHelperObject.log("BHO", "Issue", "- Error : " + (int)response.StatusCode + " : " + response.StatusDescription);
                            return new ResultObject { status = (int)response.StatusCode, message = response.StatusDescription };
                        }
                        else
                        {
                            BrowserHelperObject.log("BHO", "Issue", "- Unhandled error : " + e.Status);
                            return new ResultObject { status = 500, message = "Unhandled error : " + e.Status };
                        }
                    }
                    else
                    {
                        BrowserHelperObject.log("BHO", "Issue", "- Could not contact issuanceserver.");
                        return new ResultObject { status = 500, message = "Could not contact issuanceserver." };
                    }
                }
                catch (Exception e)
                {
                    BrowserHelperObject.log("BHO", "Issue", "- Internal Error ? : " + e);
                    return new ResultObject { status = 500, message = "Internal Error ? : " + e };
                }

                // skip verify response from issuer! - seems we never stop on issuer side...
                int xmlStepStatus = (int)xmlStepResponse.StatusCode;
                BrowserHelperObject.log("BHO", "Issue", "- xmlStepStatus sending Step to Issuer : " + xmlStepStatus + " - type : " + xmlStepRequest.ContentType + " - length : " + xmlStepRequest.ContentLength);

                // we now have IssuanceMessage from Issuer - continuer loop and send to local User ABC
                xmlFromStream = xmlStepResponse.GetResponseStream();
            }
        }
        public static void ManageCredentials()
        {
            BrowserHelperObject.log("BHO", "ManageCredentials", "ManageCredentials - start");

            long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            var sessionID = "ManageCredentialsIE" + milliseconds;
            ResultObject check = CheckSmartCard(sessionID);
            if (check != null)
            {
                MessageBox.Show("Manager credentials - Unlock Failed : " + check.message,
                    "Manager credentials",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1);
                return;
            }
            // var manageCredentialListURL = USER_ABCE_SERVICE + "/user/getUiManageCredentialData/" + sessionID;

            // TODO : Language ??
            var language = "en";
            var manageCredentialListURL = USER_UI_SERVICE + "?mode=management&demo=false&language=" + language + "&sessionid=" + sessionID;

            var form = new WebForm { URL = manageCredentialListURL };
            var dialogResponse = form.ShowDialog();
            BrowserHelperObject.log("BHO", "ManageCredentials", "- dialogResponse : " + dialogResponse);
        }
        public static void ShowDebugInfo()
        {
            BrowserHelperObject.log("BHO", "showDebugInfo", "Get Debug Info from UserABCE startup");

            long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            var sessionID = "DebugInfoIE" + milliseconds;

            var debugInfoURL = USER_ABCE_SERVICE + "/user/getDebugInfo/" + sessionID;

            var form = new WebForm { URL = debugInfoURL };
            var dialogResponse = form.ShowDialog();
            BrowserHelperObject.log("BHO", "showDebugInfo", "- dialogResponse : " + dialogResponse);
        }