public async Task <HttpGetIksSuccessResult> ExecuteAsync(DateTime date, string batchTag)
        {
            _logger.WriteRequestingData(date, batchTag);

            var uri = new Uri($"{_efgsConfig.BaseUrl}/diagnosiskeys/download/{date:yyyy-MM-dd}");

            try
            {
                // Configure authentication certificate
                using var clientCert    = _certificateProvider.GetCertificate();
                using var clientHandler = new HttpClientHandler
                      {
                          ClientCertificateOptions = ClientCertificateOption.Manual
                      };

                // Provide the authentication certificate manually
                clientHandler.ClientCertificates.Clear();
                clientHandler.ClientCertificates.Add(clientCert);

                // Build the request
                var request = new HttpRequestMessage {
                    RequestUri = uri
                };
                request.Headers.Add("Accept", ApplicationProtobuf);

                if (!string.IsNullOrWhiteSpace(batchTag))
                {
                    request.Headers.Add("batchTag", batchTag);
                }

                if (_efgsConfig.SendClientAuthenticationHeaders)
                {
                    request.Headers.Add("X-SSL-Client-SHA256", clientCert.ComputeSha256Hash());
                    request.Headers.Add("X-SSL-Client-DN", clientCert.Subject.Replace(" ", string.Empty));
                }

                using var client = new HttpClient(clientHandler);

                _logger.WriteRequest(request);

                var response = await client.SendAsync(request);

                _logger.WriteResponse(response.StatusCode);
                _logger.WriteResponseHeaders(response.Headers);

                // Handle response
                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                    // EFGS returns the string 'null' if there is no batch tag. We will represent this with an actual null.
                    var nextBatchTag = response.Headers.SafeGetValue("nextBatchTag");
                    nextBatchTag = nextBatchTag == "null" ? null : nextBatchTag;
                    return(new HttpGetIksSuccessResult
                    {
                        //TODO errors if info not present
                        BatchTag = response.Headers.SafeGetValue("batchTag"),
                        NextBatchTag = nextBatchTag,
                        Content = await response.Content.ReadAsByteArrayAsync()
                    });

                case HttpStatusCode.NotFound:
                    _logger.WriteResponseNotFound();
                    return(null);

                case HttpStatusCode.Gone:
                    _logger.WriteResponseGone();
                    return(null);

                case HttpStatusCode.BadRequest:
                    _logger.WriteResponseBadRequest();
                    throw new EfgsCommunicationException();

                case HttpStatusCode.Forbidden:
                    _logger.WriteResponseForbidden();
                    throw new EfgsCommunicationException();

                case HttpStatusCode.NotAcceptable:
                    _logger.WriteResponseNotAcceptable();
                    throw new EfgsCommunicationException();

                default:
                    _logger.WriteResponseUndefined(response.StatusCode);
                    throw new EfgsCommunicationException();
                }
            }
            catch (Exception e)
            {
                _logger.WriteEfgsError(e);

                throw;
            }
        }
        public async Task <HttpPostIksResult> ExecuteAsync(IksSendCommandArgs args)
        {
            var uri = new Uri($"{_EfgsConfig.BaseUrl}/diagnosiskeys/upload");

            // Configure authentication certificate
            using var clientCert    = _CertificateProvider.GetCertificate();
            using var clientHandler = new HttpClientHandler
                  {
                      ClientCertificateOptions = ClientCertificateOption.Manual
                  };

            // Provide the authentication certificate manually
            clientHandler.ClientCertificates.Clear();
            clientHandler.ClientCertificates.Add(clientCert);

            // Build request
            var request = new HttpRequestMessage(HttpMethod.Post, uri);

            request.Content = new ByteArrayContent(args.Content);
            request.Content.Headers.Add("Content-Type", "application/protobuf; version=1.0");
            request.Headers.Add("BatchTag", args.BatchTag);
            request.Headers.Add("batchSignature", Convert.ToBase64String(args.Signature));
            request.Headers.Add("Accept", "application/json;version=1.0");

            if (_EfgsConfig.SendClientAuthenticationHeaders)
            {
                request.Headers.Add("X-SSL-Client-SHA256", clientCert.ComputeSha256Hash());
                request.Headers.Add("X-SSL-Client-DN", clientCert.Subject.Replace(" ", string.Empty));
            }

            _Logger.WriteRequest(request);
            _Logger.WriteRequestContent(args.Content);

            using var client = new HttpClient(clientHandler);
            client.Timeout   = TimeSpan.FromSeconds(5); //TODO config

            try
            {
                var response = await client.SendAsync(request);

                return(new HttpPostIksResult
                {
                    HttpResponseCode = response.StatusCode,
                    Content = await response.Content.ReadAsStringAsync()
                              //TODO How is this used?
                              //TODO BatchTag = response.Headers.GetSingleValueOrDefault("batchTag")
                });
            }
            catch (Exception e)
            {
                _Logger.WriteEfgsError(e);

                if (e.InnerException != null)
                {
                    _Logger.WriteEfgsInnerException(e.InnerException);
                }

                return(new HttpPostIksResult
                {
                    Exception = true
                });
            }
        }