/// <summary>
        /// Completely populate all Region property members. Missing data
        /// is computed based on the values that are already present.
        /// </summary>
        /// <param name="region"></param>
        /// <param name="newLineIndex"></param>
        public static void Populate(this Region region, NewLineIndex newLineIndex)
        {
            if (region == null)
            {
                throw new ArgumentNullException(nameof(region));
            }

            if (newLineIndex == null)
            {
                throw new ArgumentNullException(nameof(newLineIndex));
            }

            // A call to Populate is an implicit indicator that we are working
            // with a text region (otherwise the offset and length would be
            // sufficient data to constitute the region).

            if (region.StartLine == 0)
            {
                OffsetInfo offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.Offset);
                region.StartLine   = offsetInfo.LineNumber;
                region.StartColumn = offsetInfo.ColumnNumber;

                offsetInfo       = newLineIndex.GetOffsetInfoForOffset(region.Offset + region.Length);
                region.EndLine   = offsetInfo.LineNumber;
                region.EndColumn = offsetInfo.ColumnNumber;
            }
            else
            {
                // Make endColumn and endLine explicit, if not expressed
                if (region.EndLine == 0)
                {
                    region.EndLine = region.StartLine;
                }
                if (region.StartColumn == 0)
                {
                    region.StartColumn = 1;
                }
                if (region.EndColumn == 0)
                {
                    region.EndColumn = region.StartColumn;
                }

                LineInfo lineInfo = newLineIndex.GetLineInfoForLine(region.StartLine);
                region.Offset = lineInfo.StartOffset + (region.StartColumn - 1);

                lineInfo      = newLineIndex.GetLineInfoForLine(region.EndLine);
                region.Length = lineInfo.StartOffset + (region.EndColumn - 1) - region.Offset;
            }
        }
        private void PopulatePropertiesFromCharOffsetAndLength(NewLineIndex newLineIndex, Region region)
        {
            Assert(!region.IsBinaryRegion);
            Assert(region.StartLine == 0);
            Assert(region.CharLength >= 0 || region.CharOffset >= 0);

            int startLine, startColumn, endLine, endColumn;

            // Retrieve start and end line and column information from the new line index
            OffsetInfo offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.CharOffset);

            startLine   = offsetInfo.LineNumber;
            startColumn = offsetInfo.ColumnNumber;

            offsetInfo = newLineIndex.GetOffsetInfoForOffset(region.CharOffset + region.CharLength);
            endLine    = offsetInfo.LineNumber;

            // The computation above points one past our actual region, because endColumn
            // is exclusive of the region. This allows for length to easily be computed
            // for single line regions: region.EndColumn - region.StartColumn
            endColumn = offsetInfo.ColumnNumber;

            // Only set values if they aren't already specified
            if (region.StartLine == 0)
            {
                region.StartLine = startLine;
            }
            if (region.StartColumn == 0)
            {
                region.StartColumn = startColumn;
            }
            if (region.EndLine == 0)
            {
                region.EndLine = endLine;
            }
            if (region.EndColumn == 0)
            {
                region.EndColumn = endColumn;
            }

            // Validate cases where new line index disagrees with explicit values
            Assert(region.StartLine == startLine);
            Assert(region.StartColumn == startColumn);
            Assert(region.EndLine == endLine);
            Assert(region.EndColumn == endColumn);
        }