/// <summary>
        /// Parse the HTTP payload to WOPI message.
        /// </summary>
        /// <param name="requestHeaders">The HTTP request header.</param>
        /// <param name="responseHeaders">The HTTP response header.</param>
        /// <param name="url">url for a HTTP message.</param>
        /// <param name="bytesFromHTTP">The raw data from HTTP layer.</param>
        /// <param name="direction">The direction of the traffic.</param>
        /// <returns>The object parsed result</returns>
        public object ParseHTTPPayloadForWOPI(HTTPHeaders requestHeaders, HTTPHeaders responseHeaders, string url, byte[] bytesFromHTTP, out string binaryStructureRopName, TrafficDirection direction)
        {
            object objectOut = null;

            binaryStructureRopName = string.Empty;
            try
            {
                if (direction == TrafficDirection.Out && responseHeaders.Exists("Transfer-Encoding") && responseHeaders["Transfer-Encoding"] == "chunked")
                {
                    bytesFromHTTP = Utilities.GetPaylodFromChunkedBody(bytesFromHTTP);
                }

                Stream         stream    = new MemoryStream(bytesFromHTTP);
                StreamReader   reader    = new StreamReader(stream);
                string         text      = reader.ReadToEnd();
                WOPIOperations operation = GetWOPIOperationName(requestHeaders, url);
                if (direction == TrafficDirection.In)
                {
                    switch (operation)
                    {
                    case WOPIOperations.PutRelativeFile:
                        objectOut = bytesFromHTTP;
                        binaryStructureRopName = "PutRelativeFile";
                        break;

                    case WOPIOperations.PutFile:
                        objectOut = bytesFromHTTP;
                        binaryStructureRopName = "PutFile";
                        break;

                    case WOPIOperations.ExecuteCellStorageRelativeRequest:
                    case WOPIOperations.ExecuteCellStorageRequest:
                        byte[]       cellreq = bytesFromHTTP;
                        MemoryStream ms;
                        if (requestHeaders.Exists("Content-Encoding") && requestHeaders["Content-Encoding"] == "gzip")
                        {
                            cellreq = Fiddler.Utilities.GzipExpand(cellreq);
                            ms      = new MemoryStream(cellreq);
                        }
                        else
                        {
                            ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text ?? ""));
                        }
                        XmlSerializer   serializer     = new XmlSerializer(typeof(RequestEnvelope));
                        RequestEnvelope requestEnvelop = (RequestEnvelope)serializer.Deserialize(ms);
                        objectOut = requestEnvelop.Body;

                        if (requestEnvelop.Body.RequestCollection != null)
                        {
                            TryParseFSSHTTPBRequestMessage(requestEnvelop.Body.RequestCollection.Request, bytesFromHTTP);
                        }
                        break;

                    case WOPIOperations.PutUserInfo:
                        objectOut = text;
                        break;

                    case WOPIOperations.Discovery:
                    case WOPIOperations.CheckFileInfo:
                    case WOPIOperations.Lock:
                    case WOPIOperations.RefreshLock:
                    case WOPIOperations.RevokeRestrictedLink:
                    case WOPIOperations.Unlock:
                    case WOPIOperations.UnlockAndRelock:
                    case WOPIOperations.GetLock:
                    case WOPIOperations.DeleteFile:
                    case WOPIOperations.ReadSecureStore:
                    case WOPIOperations.RenameFile:
                    case WOPIOperations.GetRestrictedLink:
                    case WOPIOperations.CheckFolderInfo:
                    case WOPIOperations.GetFile:
                    case WOPIOperations.EnumerateChildren:
                        objectOut = string.Format("{0} operation's request body is null", operation.ToString());
                        break;

                    default:
                        throw new Exception("The WOPI operations type is not right.");
                    }
                }
                else
                {
                    string status = this.session.ResponseHeaders.HTTPResponseStatus.Replace(" " + this.session.ResponseHeaders.StatusDescription, string.Empty);
                    if (Convert.ToUInt32(status) != 200)// the status is not success
                    {
                        return(null);
                    }

                    ResponseBodyBase responseBody = new ResponseBodyBase();
                    switch (operation)
                    {
                    case WOPIOperations.Discovery:
                        MemoryStream  discoveryms         = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text ?? ""));
                        XmlSerializer discoverySerializer = new XmlSerializer(typeof(wopidiscovery));
                        wopidiscovery discoveryres        = (wopidiscovery)discoverySerializer.Deserialize(discoveryms);
                        objectOut = discoveryres;
                        break;

                    case WOPIOperations.CheckFileInfo:
                        objectOut = WOPISerilizer.JsonToObject <CheckFileInfo>(text);
                        break;

                    case WOPIOperations.CheckFolderInfo:
                        objectOut = WOPISerilizer.JsonToObject <CheckFolderInfo>(text);
                        break;

                    case WOPIOperations.PutRelativeFile:
                        objectOut = WOPISerilizer.JsonToObject <PutRelativeFile>(text);
                        break;

                    case WOPIOperations.ReadSecureStore:
                        objectOut = WOPISerilizer.JsonToObject <ReadSecureStore>(text);
                        break;

                    case WOPIOperations.EnumerateChildren:
                        objectOut = WOPISerilizer.JsonToObject <EnumerateChildren>(text);
                        break;

                    case WOPIOperations.RenameFile:
                        objectOut = WOPISerilizer.JsonToObject <RenameFile>(text);
                        break;

                    case WOPIOperations.ExecuteCellStorageRelativeRequest:
                    case WOPIOperations.ExecuteCellStorageRequest:
                    {
                        byte[]       cellres = bytesFromHTTP;
                        MemoryStream ms;
                        string       res;
                        if (responseHeaders.Exists("Content-Encoding") && responseHeaders["Content-Encoding"] == "gzip")
                        {
                            cellres = Fiddler.Utilities.GzipExpand(cellres);
                            string res_sub = System.Text.Encoding.UTF8.GetString(cellres);
                            res = string.Format("{0}{1}{2}", @"<Body>", res_sub, "</Body>");
                        }
                        else
                        {
                            res = string.Format("{0}{1}{2}", @"<Body>", text, "</Body>");
                        }
                        ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(res ?? ""));
                        XmlSerializer        serializer = new XmlSerializer(typeof(ResponseEnvelopeBody));
                        ResponseEnvelopeBody body       = (ResponseEnvelopeBody)serializer.Deserialize(ms);
                        objectOut = body;

                        // if SubResponseData has fsshttpb messages do parser.
                        if (body.ResponseCollection != null)
                        {
                            TryParseFSSHTTPBResponseMessage(body.ResponseCollection.Response, bytesFromHTTP);
                        }
                        break;
                    }

                    case WOPIOperations.GetFile:
                        objectOut = bytesFromHTTP;
                        binaryStructureRopName = "GetFile";
                        break;

                    case WOPIOperations.DeleteFile:
                    case WOPIOperations.Lock:
                    case WOPIOperations.GetRestrictedLink:
                    case WOPIOperations.PutFile:
                    case WOPIOperations.RefreshLock:
                    case WOPIOperations.RevokeRestrictedLink:
                    case WOPIOperations.Unlock:
                    case WOPIOperations.UnlockAndRelock:
                    case WOPIOperations.GetLock:
                    case WOPIOperations.PutUserInfo:
                        objectOut = string.Format("{0} operation's response body is null", operation.ToString());
                        break;

                    default:
                        throw new Exception("The WOPI operations type is not right.");
                    }
                }
                return(objectOut);
            }
            catch (Exception ex)
            {
                objectOut = ex.ToString();
                return(objectOut);
            }
        }
        /// <summary>
        /// Parse the HTTP payload to WOPI message.
        /// </summary>
        /// <param name="requestHeaders">The HTTP request header.</param>
        /// <param name="responseHeaders">The HTTP response header.</param>
        /// <param name="url">url for a HTTP message.</param>
        /// <param name="bytesFromHTTP">The raw data from HTTP layer.</param>
        /// <param name="direction">The direction of the traffic.</param>
        /// <returns>The object parsed result</returns>
        public object ParseHTTPPayloadForWOPI(HTTPHeaders requestHeaders, HTTPHeaders responseHeaders, string url, byte[] bytesFromHTTP, out string binaryStructureRopName, TrafficDirection direction)
        {
            object objectOut = null;
            binaryStructureRopName = string.Empty;
            try
            {
                if (direction == TrafficDirection.Out && responseHeaders.Exists("Transfer-Encoding") && responseHeaders["Transfer-Encoding"] == "chunked")
                {
                    bytesFromHTTP = Utilities.GetPaylodFromChunkedBody(bytesFromHTTP);
                }

                Stream stream = new MemoryStream(bytesFromHTTP);
                StreamReader reader = new StreamReader(stream);
                string text = reader.ReadToEnd();
                WOPIOperations operation = GetWOPIOperationName(requestHeaders, url);
                if (direction == TrafficDirection.In)
                {
                    switch (operation)
                    {
                        case WOPIOperations.PutRelativeFile:
                            objectOut = bytesFromHTTP;
                            binaryStructureRopName = "PutRelativeFile";
                            break;
                        case WOPIOperations.PutFile:
                            objectOut = bytesFromHTTP;
                            binaryStructureRopName = "PutFile";
                            break;
                        case WOPIOperations.ExecuteCellStorageRelativeRequest:
                        case WOPIOperations.ExecuteCellStorageRequest:
                            byte[] cellreq = bytesFromHTTP;
                            MemoryStream ms;
                            if (requestHeaders.Exists("Content-Encoding") && requestHeaders["Content-Encoding"] == "gzip")
                            {
                                cellreq = Fiddler.Utilities.GzipExpand(cellreq);
                                ms = new MemoryStream(cellreq);
                            }
                            else
                            {
                                ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text ?? ""));
                            }
                            XmlSerializer serializer = new XmlSerializer(typeof(RequestEnvelope));
                            RequestEnvelope requestEnvelop = (RequestEnvelope)serializer.Deserialize(ms);
                            objectOut = requestEnvelop.Body;

                            if (requestEnvelop.Body.RequestCollection != null)
                            {
                                TryParseFSSHTTPBRequestMessage(requestEnvelop.Body.RequestCollection.Request, bytesFromHTTP);
                            }
                            break;
                        case WOPIOperations.PutUserInfo:
                            objectOut = text;
                            break;
                        case WOPIOperations.Discovery:
                        case WOPIOperations.CheckFileInfo:
                        case WOPIOperations.Lock:
                        case WOPIOperations.RefreshLock:
                        case WOPIOperations.RevokeRestrictedLink:
                        case WOPIOperations.Unlock:
                        case WOPIOperations.UnlockAndRelock:
                        case WOPIOperations.GetLock:
                        case WOPIOperations.DeleteFile:
                        case WOPIOperations.ReadSecureStore:
                        case WOPIOperations.RenameFile:
                        case WOPIOperations.GetRestrictedLink:
                        case WOPIOperations.CheckFolderInfo:
                        case WOPIOperations.GetFile:
                        case WOPIOperations.EnumerateChildren:
                            objectOut = string.Format("{0} operation's request body is null", operation.ToString());
                            break;
                        default:
                            throw new Exception("The WOPI operations type is not right.");
                    }
                }
                else
                {
                    string status = this.session.ResponseHeaders.HTTPResponseStatus.Replace(" " + this.session.ResponseHeaders.StatusDescription, string.Empty);
                    if (Convert.ToUInt32(status) != 200)// the status is not success
                        return null;

                    ResponseBodyBase responseBody = new ResponseBodyBase();
                    switch (operation)
                    {
                        case WOPIOperations.Discovery:
                            MemoryStream discoveryms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(text ?? ""));
                            XmlSerializer discoverySerializer = new XmlSerializer(typeof(wopidiscovery));
                            wopidiscovery discoveryres = (wopidiscovery)discoverySerializer.Deserialize(discoveryms);
                            objectOut = discoveryres;
                            break;
                        case WOPIOperations.CheckFileInfo:
                            objectOut = WOPISerilizer.JsonToObject<CheckFileInfo>(text);
                            break;
                        case WOPIOperations.CheckFolderInfo:
                            objectOut = WOPISerilizer.JsonToObject<CheckFolderInfo>(text);
                            break;
                        case WOPIOperations.PutRelativeFile:
                            objectOut = WOPISerilizer.JsonToObject<PutRelativeFile>(text);
                            break;
                        case WOPIOperations.ReadSecureStore:
                            objectOut = WOPISerilizer.JsonToObject<ReadSecureStore>(text);
                            break;
                        case WOPIOperations.EnumerateChildren:
                            objectOut = WOPISerilizer.JsonToObject<EnumerateChildren>(text);
                            break;
                        case WOPIOperations.RenameFile:
                            objectOut = WOPISerilizer.JsonToObject<RenameFile>(text);
                            break;
                        case WOPIOperations.ExecuteCellStorageRelativeRequest:
                        case WOPIOperations.ExecuteCellStorageRequest:
                            {
                                byte[] cellres = bytesFromHTTP;
                                MemoryStream ms;
                                string res;
                                if (responseHeaders.Exists("Content-Encoding") && responseHeaders["Content-Encoding"] == "gzip")
                                {
                                    cellres = Fiddler.Utilities.GzipExpand(cellres);
                                    string res_sub = System.Text.Encoding.UTF8.GetString(cellres);
                                    res = string.Format("{0}{1}{2}", @"<Body>", res_sub, "</Body>");
                                }
                                else
                                {
                                    res = string.Format("{0}{1}{2}", @"<Body>", text, "</Body>");
                                }
                                ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(res ?? ""));
                                XmlSerializer serializer = new XmlSerializer(typeof(ResponseEnvelopeBody));
                                ResponseEnvelopeBody body = (ResponseEnvelopeBody)serializer.Deserialize(ms);
                                objectOut = body;

                                // if SubResponseData has fsshttpb messages do parser.
                                if (body.ResponseCollection != null)
                                {
                                    TryParseFSSHTTPBResponseMessage(body.ResponseCollection.Response, bytesFromHTTP);
                                }
                                break;
                            }
                        case WOPIOperations.GetFile:
                            objectOut = bytesFromHTTP;
                            binaryStructureRopName = "GetFile";
                            break;
                        case WOPIOperations.DeleteFile:
                        case WOPIOperations.Lock:
                        case WOPIOperations.GetRestrictedLink:
                        case WOPIOperations.PutFile:
                        case WOPIOperations.RefreshLock:
                        case WOPIOperations.RevokeRestrictedLink:
                        case WOPIOperations.Unlock:
                        case WOPIOperations.UnlockAndRelock:
                        case WOPIOperations.GetLock:
                        case WOPIOperations.PutUserInfo:
                            objectOut = string.Format("{0} operation's response body is null", operation.ToString());
                            break;
                        default:
                            throw new Exception("The WOPI operations type is not right.");
                    }
                }
                return objectOut;
            }
            catch (Exception ex)
            {
                objectOut = ex.ToString();
                return objectOut;
            }
        }