public async Task <HealthServiceResponseData> ExecuteAsync(
            HealthVaultMethods method,
            int methodVersion,
            string parameters  = null,
            Guid?recordId      = null,
            Guid?correlationId = null)
        {
            bool isMethodAnonymous = IsMethodAnonymous(method);

            // Make sure that session credential is set for method calls requiring
            // authentication
            if (!isMethodAnonymous && string.IsNullOrEmpty(SessionCredential?.Token))
            {
                await AuthenticateAsync().ConfigureAwait(false);
            }

            // Create the message using a Func in case we need to re-generate it for a retry later
            Func <string> requestXmlCreator = () => _requestMessageCreator.Create(
                method,
                methodVersion,
                isMethodAnonymous,
                parameters,
                recordId,
                isMethodAnonymous && method == HealthVaultMethods.CreateAuthenticatedSessionToken
                   ? ApplicationId
                   : Configuration.MasterApplicationId);

            var requestXml = requestXmlCreator();

            HealthServiceResponseData responseData = null;

            try
            {
                responseData = await SendRequestAsync(requestXml, correlationId).ConfigureAwait(false);
            }
            catch (HealthServiceAuthenticatedSessionTokenExpiredException)
            {
                if (!isMethodAnonymous)
                {
                    await RefreshSessionAsync(CancellationToken.None);

                    // Re-generate the message so it pulls in the new SessionCredential
                    requestXml = requestXmlCreator();
                    return(await SendRequestAsync(requestXml, correlationId).ConfigureAwait(false));
                }
            }

            return(responseData);
        }
        private bool IsMethodAnonymous(HealthVaultMethods method)
        {
            if (_anonymousMethodSet.Contains(method))
            {
                return(true);
            }

            var type   = method.GetType().GetTypeInfo();
            var member = type.GetDeclaredField(method.ToString());

            if (member.GetCustomAttribute <AnonymousMethodAttribute>() != null)
            {
                _anonymousMethodSet.Add(method);
                return(true);
            }

            return(false);
        }
        public void SetRequestHeader(
            HealthVaultMethods method,
            int methodVersion,
            bool isAnonymous,
            Guid?recordId,
            Guid?appId,
            string infoXml,
            Request request)
        {
            request.Header = new RequestHeader
            {
                Method        = method.ToString(),
                MethodVersion = methodVersion
            };

            if (recordId != null)
            {
                request.Header.RecordId = recordId.Value.ToString();
            }

            // in case the method is anonymous - set app id, else set auth session
            if (isAnonymous)
            {
                request.Header.AppId = appId.HasValue
                    ? appId.Value.ToString()
                    : _healthVaultConfiguration.MasterApplicationId.ToString();
            }
            else
            {
                request.Header.AuthSession = _connectionInternal.GetAuthSessionHeader();
            }

            request.Header.MessageTime = SDKHelper.XmlFromNow();
            request.Header.MessageTtl  = (int)_healthVaultConfiguration.RequestTimeToLiveDuration.TotalSeconds;

            request.Header.Version =
                $"{_telemetryInformation.Category}/{_telemetryInformation.FileVersion} {_telemetryInformation.OsInformation}";

            request.Header.InfoHash = new InfoHash
            {
                HashData = _cryptographer.Hash(Encoding.UTF8.GetBytes(infoXml))
            };
        }
        /// <summary>
        /// <see cref="IRequestMessageCreator.Create"/>
        /// </summary>
        public string Create(
            HealthVaultMethods method,
            int methodVersion,
            bool isMethodAnonymous,
            string parameters = null,
            Guid?recordId     = null,
            Guid?appId        = null)
        {
            Request request = new Request {
                Info = new RequestInfo {
                    InfoXml = parameters
                }
            };

            // Serialize info part of the request message
            string infoXml = Serialize(new RequestInfoSerializer(), request.Info.InfoXml);

            SetRequestHeader(
                method,
                methodVersion,
                isMethodAnonymous,
                recordId,
                appId,
                infoXml,
                request);

            //Serialize header part of the request message
            string headerXml = Serialize(new RequestHeaderSerializer(), request.Header);

            string authXml = null;

            // in case the method is anonymous, there is no need to set auth
            if (!isMethodAnonymous)
            {
                SetAuth(headerXml, request);
                authXml = Serialize(new RequestAuthSerializer(), request.Auth);
            }

            string requestXml = SerializeRequest(authXml, headerXml, infoXml);

            return(requestXml);
        }