/// <summary>Compute the name of an object, without inserting it.</summary>
        /// <remarks>Compute the name of an object, without inserting it.</remarks>
        /// <param name="type">type code of the object to store.</param>
        /// <param name="data">complete content of the object.</param>
        /// <param name="off">
        /// first position within
        /// <code>data</code>
        /// .
        /// </param>
        /// <param name="len">
        /// number of bytes to copy from
        /// <code>data</code>
        /// .
        /// </param>
        /// <returns>the name of the object.</returns>
        public virtual ObjectId IdFor(int type, byte[] data, int off, int len)
        {
            MessageDigest md = Digest();

            md.Update(Constants.EncodedTypeString(type));
            md.Update(unchecked ((byte)' '));
            md.Update(Constants.EncodeASCII(len));
            md.Update(unchecked ((byte)0));
            md.Update(data, off, len);
            return(ObjectId.FromRaw(md.Digest()));
        }
        /// <summary>Compute the name of an object, without inserting it.</summary>
        /// <remarks>Compute the name of an object, without inserting it.</remarks>
        /// <param name="objectType">type code of the object to store.</param>
        /// <param name="length">
        /// number of bytes to scan from
        /// <code>in</code>
        /// .
        /// </param>
        /// <param name="in">
        /// stream providing the object content. The caller is responsible
        /// for closing the stream.
        /// </param>
        /// <returns>the name of the object.</returns>
        /// <exception cref="System.IO.IOException">the source stream could not be read.</exception>
        public virtual ObjectId IdFor(int objectType, long length, InputStream @in)
        {
            MessageDigest md = Digest();

            md.Update(Constants.EncodedTypeString(objectType));
            md.Update(unchecked ((byte)' '));
            md.Update(Constants.EncodeASCII(length));
            md.Update(unchecked ((byte)0));
            byte[] buf = Buffer();
            while (length > 0)
            {
                int n = @in.Read(buf, 0, (int)Math.Min(length, buf.Length));
                if (n < 0)
                {
                    throw new EOFException("Unexpected end of input");
                }
                md.Update(buf, 0, n);
                length -= n;
            }
            return(ObjectId.FromRaw(md.Digest()));
        }