/// <summary>
        /// Returns a possibly-empty list of incorrect entries in this <see cref="FileContentTable" />.
        /// </summary>
        /// <remarks>
        /// In the absence of an incorrect file content table implementation, file system bugs, or disk corruption, the list should
        /// be empty.
        /// Hence, this is a diagnostic facility.
        /// </remarks>
        public static List <IncorrectFileContentEntry> FindIncorrectEntries(this FileContentTable fileContentTable, IFileContentTableAccessor accessor)
        {
            Contract.Requires(fileContentTable != null);
            Contract.Requires(accessor != null);
            Contract.Ensures(Contract.Result <List <IncorrectFileContentEntry> >() != null);
            Contract.Ensures(Contract.ForAll(Contract.Result <List <IncorrectFileContentEntry> >(), e => e != null));

            var badEntries = new List <IncorrectFileContentEntry>();

            fileContentTable.VisitKnownFiles(
                accessor,
                FileShare.Read | FileShare.Delete,
                // On accessing the entry of file content table, we do not allow concurrent writes; otherwise the content may change as we're hashing it.
                // To this end, the file needs to be opened with FileShare.Read | FileShare.Delete accesses.
                (fileIdAndVolumeId, handle, path, knownUsn, knownHash) =>
            {
                using (var fs = new FileStream(handle, FileAccess.Read))
                {
                    ContentHash actualHash = ContentHashingUtilities.HashContentStreamAsync(fs).GetAwaiter().GetResult();
                    if (knownHash != actualHash)
                    {
                        badEntries.Add(new IncorrectFileContentEntry(path, fileIdAndVolumeId, knownUsn, knownHash, actualHash));
                    }
                }

                return(true);
            });

            return(badEntries);
        }