private void LoadFrom(BlameGenerator gen)
        {
            RevCommit   srcCommit    = gen.GetSourceCommit();
            PersonIdent srcAuthor    = gen.GetSourceAuthor();
            PersonIdent srcCommitter = gen.GetSourceCommitter();
            string      srcPath      = gen.GetSourcePath();
            int         srcLine      = gen.GetSourceStart();
            int         resLine      = gen.GetResultStart();
            int         resEnd       = gen.GetResultEnd();

            for (; resLine < resEnd; resLine++)
            {
                // Reverse blame can generate multiple results for the same line.
                // Favor the first one selected, as this is the oldest and most
                // likely to be nearest to the inquiry made by the user.
                if (sourceLines[resLine] != 0)
                {
                    continue;
                }
                sourceCommits[resLine]    = srcCommit;
                sourceAuthors[resLine]    = srcAuthor;
                sourceCommitters[resLine] = srcCommitter;
                sourcePaths[resLine]      = srcPath;
                // Since sourceLines is 1-based to permit hasSourceData to use 0 to
                // mean the line has not been annotated yet, pre-increment instead
                // of the traditional post-increment when making the assignment.
                sourceLines[resLine] = ++srcLine;
            }
        }
        /// <summary>Construct a new BlameResult for a generator.</summary>
        /// <remarks>Construct a new BlameResult for a generator.</remarks>
        /// <param name="gen">the generator the result will consume records from.</param>
        /// <returns>
        /// the new result object. null if the generator cannot find the path
        /// it starts from.
        /// </returns>
        /// <exception cref="System.IO.IOException">the repository cannot be read.</exception>
        public static NGit.Blame.BlameResult Create(BlameGenerator gen)
        {
            string  path     = gen.GetResultPath();
            RawText contents = gen.GetResultContents();

            if (contents == null)
            {
                gen.Release();
                return(null);
            }
            return(new NGit.Blame.BlameResult(gen, path, contents));
        }
        internal BlameResult(BlameGenerator bg, string path, RawText text)
        {
            generator      = bg;
            resultPath     = path;
            resultContents = text;
            int cnt = text.Size();

            sourceCommits    = new RevCommit[cnt];
            sourceAuthors    = new PersonIdent[cnt];
            sourceCommitters = new PersonIdent[cnt];
            sourceLines      = new int[cnt];
            sourcePaths      = new string[cnt];
        }
        /// <summary>Compute the next available segment and return the first index.</summary>
        /// <remarks>
        /// Compute the next available segment and return the first index.
        /// <p>
        /// Computes one segment and returns to the caller the first index that is
        /// available. After return the caller can also inspect
        /// <see cref="LastLength()">LastLength()</see>
        /// to determine how many lines of the result were computed.
        /// </remarks>
        /// <returns>index that is now available. -1 if no more are available.</returns>
        /// <exception cref="System.IO.IOException">the repository cannot be read.</exception>
        public virtual int ComputeNext()
        {
            BlameGenerator gen = generator;

            if (gen == null)
            {
                return(-1);
            }
            if (gen.Next())
            {
                LoadFrom(gen);
                lastLength = gen.GetRegionLength();
                return(gen.GetResultStart());
            }
            else
            {
                gen.Release();
                generator = null;
                return(-1);
            }
        }
        /// <summary>Compute all pending information.</summary>
        /// <remarks>Compute all pending information.</remarks>
        /// <exception cref="System.IO.IOException">the repository cannot be read.</exception>
        public virtual void ComputeAll()
        {
            BlameGenerator gen = generator;

            if (gen == null)
            {
                return;
            }
            try
            {
                while (gen.Next())
                {
                    LoadFrom(gen);
                }
            }
            finally
            {
                gen.Release();
                generator = null;
            }
        }
        /// <summary>Compute until the entire range has been populated.</summary>
        /// <remarks>Compute until the entire range has been populated.</remarks>
        /// <param name="start">first index to examine.</param>
        /// <param name="end">last index to examine.</param>
        /// <exception cref="System.IO.IOException">the repository cannot be read.</exception>
        public virtual void ComputeRange(int start, int end)
        {
            BlameGenerator gen = generator;

            if (gen == null)
            {
                return;
            }
            while (start < end)
            {
                if (HasSourceData(start, end))
                {
                    return;
                }
                if (!gen.Next())
                {
                    gen.Release();
                    generator = null;
                    return;
                }
                LoadFrom(gen);
                // If the result contains either end of our current range bounds,
                // update the bounds to avoid scanning that section during the
                // next loop iteration.
                int resLine = gen.GetResultStart();
                int resEnd  = gen.GetResultEnd();
                if (resLine <= start && start < resEnd)
                {
                    start = resEnd;
                }
                if (resLine <= end && end < resEnd)
                {
                    end = resLine;
                }
            }
        }