private static void ComputeAndWriteChecksum(CanvasDocument app, ChecksumMaker checksum, ZipArchive z, ErrorContainer errors, bool isValidation)
        {
            var hash = checksum.GetChecksum();

            if (app._checksum != null && hash.wholeChecksum != app._checksum.ClientStampedChecksum)
            {
                // These warnings are Debug only. Throwing a bunch of warning messages at the customer could lead to them ignoring real errors.
#if DEBUG
                if (app._checksum.ClientPerFileChecksums != null)
                {
                    foreach (var file in app._checksum.ClientPerFileChecksums)
                    {
                        if (!hash.perFileChecksum.TryGetValue(file.Key, out var fileChecksum))
                        {
                            errors.ChecksumMismatch("Missing file " + file.Key);
                        }
                        else if (fileChecksum != file.Value)
                        {
                            errors.ChecksumMismatch($"File {file.Key} checksum does not match on extract");
                        }
                    }
                    foreach (var file in hash.perFileChecksum)
                    {
                        if (!app._checksum.ClientPerFileChecksums.ContainsKey(file.Key))
                        {
                            errors.ChecksumMismatch("Extra file " + file.Key);
                        }
                    }
                }
#endif

#if !DEBUG
                // These are the non-debug warnings, if it's unpack this was a serious error, on -pack it's most likely not
                if (isValidation)
                {
                    errors.PostUnpackValidationFailed();
                    throw new DocumentException();
                }
#endif
                errors.ChecksumMismatch("Checksum indicates that sources have been edited since they were unpacked. If this was intentional, ignore this warning.");
            }

            var checksumJson = new ChecksumJson
            {
                ClientStampedChecksum  = hash.wholeChecksum,
                ClientPerFileChecksums = hash.perFileChecksum,
                ServerStampedChecksum  = app._checksum?.ServerStampedChecksum,
                ServerPerFileChecksums = app._checksum?.ServerPerFileChecksums,
            };

            var entry = ToFile(FileKind.Checksum, checksumJson);
            var e     = z.CreateEntry(entry.Name.ToMsAppPath());
            using (var dest = e.Open())
            {
                dest.Write(entry.RawBytes, 0, entry.RawBytes.Length);
            }
        }