/// <summary>
        /// Checks for unpleasant HTTP status codes as well as other problems with the response.
        /// All errors found here are fatal: they break the chain of async processes.
        /// </summary>
        /// <param name="content">HttpContent for Posting to TNT</param>
        /// <param name="expectXml">Do we expect the response to be XML?</param>
        private async Task <PostResults> PostAsync(HttpContent content, bool expectXml)
        {
            HttpResponseMessage resp = null;

            try
            {
                resp = await client.PostAsync(new Uri(TARGET_URL), content);
            }
            catch (Exception e)
            {
                FirePostError(0, "PostAsync Exception: " + e.Message);
                throw e;  //just to stop the flow
            }
            if (!resp.IsSuccessStatusCode)
            {
                FirePostError(0, "HTTP error status " + resp.StatusCode + ": " + resp.ReasonPhrase);
                throw new InvalidOperationException("HTTP error status " + resp.StatusCode + ": " + resp.ReasonPhrase);
            }
            //xml checks
            if (expectXml)
            {
                MyXMLDocument xdoc = null;
                Stream        st   = await resp.Content.ReadAsStreamAsync();

                try
                {
                    TextReader rd      = new StreamReader(st, new UTF8Encoding(false, true));
                    XmlReader  XReader = XmlReader.Create(rd);
                    xdoc = new MyXMLDocument(XReader, readOnly: true);
                    if (
                        xdoc.NodeExists("/runtime_error") ||
                        xdoc.NodeExists("/parse_error")
                        )
                    {
                        string errormsg = xdoc.GetStringValue("//error_reason/text()");
                        FirePostError(0, "Errormessage sent by TNT: " + errormsg);
                        throw new InvalidOperationException("Errormessage sent by TNT: " + errormsg);
                    }
                }
                catch (Exception e)
                {
                    FirePostError(0, "Problem parsing xml " + e.Message);
                    throw e;
                }
                return(new PostResults(null, xdoc));
            }
            else
            {
                string c = await resp.Content.ReadAsStringAsync();

                return(new PostResults(c, null));
            }
        }
 /// <summary>
 /// Make the Consignments enumerable according to the CREATE section of the doc.
 /// Then index the Consignments for each of the relevant sections.
 /// Assumption: The CREATE section exists, or we have no Consignments.
 /// </summary>
 private bool Initialize(IndexBy indexBy)
 {
     IdPropertyXPath = XPathExpression.Compile("./" + indexBy.ToString() + "/text()");
     //determine available sections
     hasCreate       = doc.NodeExists("/document/CREATE");
     hasBook         = doc.NodeExists("/document/BOOK");
     hasShip         = doc.NodeExists("/document/SHIP");
     hasPrint        = doc.NodeExists("/document/PRINT");
     hasError        = doc.NodeExists("//ERROR");
     hasRuntimeError = doc.NodeExists("/runtime_error");
     //prepare iterator and indexes
     if (doc.NodeExists("/document"))
     {
         if (hasCreate)
         {
             createEnum  = doc.GetChildEnumerable(XPathExpression.Compile("/document"), "CREATE");
             createIndex = doc.GetChildIndex(XPathExpression.Compile("/document"), "CREATE", IdPropertyXPath);
         }
         if (hasBook)
         {
             bookIndex = doc.GetChildIndex(XPathExpression.Compile("/document/BOOK"), "CONSIGNMENT", IdPropertyXPath);
         }
         if (hasShip)
         {
             shipIndex = doc.GetChildIndex(XPathExpression.Compile("/document/SHIP"), "CONSIGNMENT", IdPropertyXPath);
         }
         //...etc
         return(true);
     }
     else
     {
         return(false); //after all, not worthy of further investigation.
     }
 }