private static TResult Execute <TResult>(Func <WebClient, TResult> execute)
            where TResult : AuthyResult, new()
        {
            var client         = new WebClient();
            var libraryVersion = AuthyHelpers.GetVersion();
            var runtimeVersion = AuthyHelpers.GetSystemInfo();
            var userAgent      = $"AuthyNet/{libraryVersion} ({runtimeVersion})";

            // Set a custom user agent
            client.Headers.Add("user-agent", userAgent);

            try
            {
                return(execute(client));
            }
            catch (WebException webex)
            {
                var response = webex.Response.GetResponseStream();

                string body;
                using (var reader = new StreamReader(response ?? throw new Exception("Error streaming response")))
                {
                    body = reader.ReadToEnd();
                }

                var result = JsonConvert.DeserializeObject <TResult>(body);

                switch (((HttpWebResponse)webex.Response).StatusCode)
                {
                case HttpStatusCode.ServiceUnavailable:
                    result.Status = AuthyStatus.ServiceUnavailable;
                    break;

                case HttpStatusCode.Unauthorized:
                    result.Status = AuthyStatus.Unauthorized;
                    break;

                default:
                case HttpStatusCode.BadRequest:
                    result.Status = AuthyStatus.BadRequest;
                    break;
                }

                return(result);
            }
            finally
            {
                client.Dispose();
            }
        }