void RaiseHashed(TorrentCreatorEventArgs e)
 {
     Toolbox.RaiseAsyncEvent <TorrentCreatorEventArgs> (Hashed, this, e);
 }
        byte [] CalcPiecesHash(List <TorrentFile> files, PieceWriter writer)
        {
            byte []     buffer        = null;
            int         bufferRead    = 0;
            long        fileRead      = 0;
            long        overallRead   = 0;
            long        overallTotal  = 0;
            MD5         md5Hasher     = null;
            SHA1        shaHasher     = null;
            List <byte> torrentHashes = null;

#if NETSTANDARD1_5
            shaHasher = SHA1.Create();
#else
            shaHasher = HashAlgoFactory.Create <SHA1> ();
#endif
            torrentHashes = new List <byte> ();
            overallTotal  = Toolbox.Accumulate <TorrentFile> (files, delegate(TorrentFile m) { return(m.Length); });

            long pieceLength = PieceLength;
            buffer = new byte [pieceLength];

            if (StoreMD5)
#if NETSTANDARD1_5
            { md5Hasher = MD5.Create();  //HashAlgoFactory.Create<MD5> ();
            }
#else
            { md5Hasher = HashAlgoFactory.Create <MD5> (); }
#endif

            try
            {
                foreach (TorrentFile file in files)
                {
                    fileRead = 0;
                    if (md5Hasher != null)
                    {
                        md5Hasher.Initialize();
                    }

                    while (fileRead < file.Length)
                    {
                        int toRead = (int)Math.Min(buffer.Length - bufferRead, file.Length - fileRead);
                        int read   = writer.Read(file, fileRead, buffer, bufferRead, toRead);

                        if (md5Hasher != null)
                        {
#if NETSTANDARD1_5
                            var hash = md5Hasher.ComputeHash(buffer, bufferRead, read);
                            hash.CopyTo(buffer, bufferRead);
#else
                            md5Hasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);
#endif
                        }
#if NETSTANDARD1_5
                        var shaHash = shaHasher.ComputeHash(buffer, bufferRead, read);
                        shaHash.CopyTo(buffer, bufferRead);
#else
                        shaHasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);
#endif

                        bufferRead  += read;
                        fileRead    += read;
                        overallRead += read;

                        if (bufferRead == buffer.Length)
                        {
                            bufferRead = 0;
#if NETSTANDARD1_5
                            var hash = shaHasher.ComputeHash(buffer, 0, 0);
                            torrentHashes.AddRange(hash);
#else
                            shaHasher.TransformFinalBlock(buffer, 0, 0);
                            torrentHashes.AddRange(shaHasher.Hash);
#endif
                            shaHasher.Initialize();
                        }
                        RaiseHashed(new TorrentCreatorEventArgs(file.Path, fileRead, file.Length, overallRead, overallTotal));
                    }
                    if (md5Hasher != null)
                    {
#if NETSTANDARD1_5
                        var hash = md5Hasher.ComputeHash(buffer, 0, 0);
                        md5Hasher.Initialize();
                        file.MD5 = hash;
#else
                        md5Hasher.TransformFinalBlock(buffer, 0, 0);
                        md5Hasher.Initialize();
                        file.MD5 = md5Hasher.Hash;
#endif
                    }
                }
                if (bufferRead > 0)
                {
#if NETSTANDARD1_5
                    var hash = shaHasher.ComputeHash(buffer, 0, 0);
                    torrentHashes.AddRange(hash);
#else
                    shaHasher.TransformFinalBlock(buffer, 0, 0);
                    torrentHashes.AddRange(shaHasher.Hash);
#endif
                }
            } finally {
#if NETSTANDARD1_5
                if (shaHasher != null)
                {
                    shaHasher.Dispose();
                }
                if (md5Hasher != null)
                {
                    md5Hasher.Dispose();
                }
#else
                if (shaHasher != null)
                {
                    shaHasher.Clear();
                }
                if (md5Hasher != null)
                {
                    md5Hasher.Clear();
                }
#endif
            }
            return(torrentHashes.ToArray());
        }