async Task <bool> ReadEntry(HttpClient httpClient, Uri url, CDHeader cdh, BinaryReader br, string destinationDirectory)
        {
            Context context            = Context.Instance;
            string  destFilePath       = Path.Combine(destinationDirectory, Path.GetFileName(cdh.FileName));
            string  compressedFilePath = Path.Combine(destinationDirectory, $"{destFilePath}.deflated");

            Log.Status($"  {context.Characters.Bullet} {Path.GetFileName (cdh.FileName)} ");
            Log.Status($"{context.Characters.RightArrow}", ConsoleColor.Cyan);
            Log.StatusLine($" {Utilities.GetRelativePath (BuildPaths.XamarinAndroidSourceRoot, destFilePath)}");
            Log.DebugLine($" {cdh.FileName} (offset: {cdh.RelativeOffsetOfLocalHeader})");

            (bool success, Stream contentStream) = await ReadFileData(httpClient, url, cdh);

            if (!success)
            {
                Log.ErrorLine("Failed to read file data");
                return(false);
            }

            using (var destFile = new BinaryWriter(File.OpenWrite(compressedFilePath))) {
                using (var fbr = new BinaryReader(contentStream)) {
                    if (!await DownloadAndExtract(fbr, contentStream, destFile, compressedFilePath))
                    {
                        return(CleanupAndReturn(false));
                    }
                }
            }

            return(CleanupAndReturn(true));

            bool CleanupAndReturn(bool retval)
            {
                if (File.Exists(compressedFilePath))
                {
                    File.Delete(compressedFilePath);
                }

                return(retval);
            }
        }
        async Task <(bool success, Stream data)> ReadFileData(HttpClient httpClient, Uri url, CDHeader cdh)
        {
            long fileOffset = cdh.RelativeOffsetOfLocalHeader;
            long dataSize   =
                cdh.CompressedSize +
                30 +                   // local file header size, the static portion
                cdh.FileName.Length +  // They're the same in both haders
                cdh.ExtraFieldLength + // This may differ between headers...
                16384;                 // ...so we add some extra padding

            var req = new HttpRequestMessage(HttpMethod.Get, url);

            req.Headers.ConnectionClose = true;
            req.Headers.Range           = new RangeHeaderValue(fileOffset, fileOffset + dataSize);

            HttpResponseMessage resp = await httpClient.SendAsync(req).ConfigureAwait(false);

            if (!resp.IsSuccessStatusCode)
            {
                Log.ErrorLine($"Failed to read file data: HTTP error {resp.StatusCode}");
                return(false, null);
            }

            Stream s = await resp.Content.ReadAsStreamAsync().ConfigureAwait(false);

            if (s.Length < dataSize)
            {
                Log.ErrorLine($"Failed to read file data: invalid data length ({s.Length} < {dataSize})");
                s.Dispose();
                return(false, null);
            }

            return(true, s);
        }