/// <summary>
        /// Calculate tab offsets by going up
        /// </summary>
        private void CalculateTabOffsetUp(ITextSnapshotLine curLine, int colNumber, ColumnSizeInfo colTabOffset)
        {
            int curLineNumber = curLine.LineNumber - 1;

            ITextSnapshot textSnapshot = _textView.TextSnapshot;

            ElasticTabstopsLine elasticLine = _elasticTabstopsLinesCache[curLine.LineNumber];
            bool isLastColumnInLine         = elasticLine.IsLastColumnInLine(colNumber);

            while (curLineNumber >= 0)
            {
                ITextSnapshotLine   upLine        = textSnapshot.GetLineFromLineNumber(curLineNumber);
                ElasticTabstopsLine upElasticLine = GetElasticTabstopsLine(upLine);

                if (upElasticLine.IsLastColumnInLine(colNumber) != isLastColumnInLine)
                {
                    break;
                }

                ElasticTabstopsColumn upColumn = upElasticLine.GetColumnOrDefault(colNumber);

                if (upColumn == null)
                {
                    break;
                }

                upColumn.TabOffset = colTabOffset;
                ShrinkTabOffset(upElasticLine, colNumber);
                curLineNumber--;
            }
        }
        /// <summary>
        /// Calculate tab offsets for line in a given direction
        /// </summary>
        private void CalculateTabOffsets(ITextSnapshotLine line, CalculateDirection direction, bool forceInvalidate)
        {
            //Calculates tab offset for a given line for the given direction
            ElasticTabstopsLine elasticLine = GetElasticTabstopsLine(line, forceInvalidate);

            for (int colNumber = 0; colNumber < elasticLine.ElasticColumns.Length; colNumber++)
            {
                ElasticTabstopsColumn column = elasticLine.ElasticColumns[colNumber];

                //Tab offset is allready calculated during other line calculation
                if (!forceInvalidate && column.TabOffset != null)
                {
                    continue;
                }

                //Assign the same ColumnTabOffset to all columns in the same block
                ColumnSizeInfo colTabOffset = new ColumnSizeInfo
                {
                    TabOffset   = CalculateInitialTabOffset(elasticLine, colNumber),
                    ColumnWidth = CalculateInitialWidth(elasticLine, colNumber)
                };

                column.TabOffset = colTabOffset;

                switch (direction)
                {
                case CalculateDirection.Up:
                    CalculateTabOffsetUp(line, colNumber, colTabOffset);
                    break;

                case CalculateDirection.Down:
                    CalculateTabOffsetDown(line, colNumber, colTabOffset);
                    break;

                case CalculateDirection.DownUp:
                    CalculateTabOffsetDown(line, colNumber, colTabOffset);
                    CalculateTabOffsetUp(line, colNumber, colTabOffset);
                    break;

                default:
                    throw new ArgumentException("direction");
                }
            }
        }
        /// <summary>
        /// Calculate tab offsets by going down
        /// </summary>
        private void CalculateTabOffsetDown(ITextSnapshotLine curLine, int colNumber, ColumnSizeInfo colTabOffset)
        {
            int curLineNumber = curLine.LineNumber + 1;

            ITextSnapshot textSnapshot = _textView.TextSnapshot;

            ElasticTabstopsLine elasticLine = _elasticTabstopsLinesCache[curLine.LineNumber];
            bool isLastColumnInLine         = elasticLine.IsLastColumnInLine(colNumber);

            while (curLineNumber < textSnapshot.LineCount)
            {
                ITextSnapshotLine   downLine        = textSnapshot.GetLineFromLineNumber(curLineNumber);
                ElasticTabstopsLine downElasticLine = GetElasticTabstopsLine(downLine);

                if (downElasticLine.IsLastColumnInLine(colNumber) != isLastColumnInLine)
                {
                    break;
                }

                ElasticTabstopsColumn downColumn = downElasticLine.GetColumnOrDefault(colNumber);

                if (downColumn == null)
                {
                    break;
                }

                downColumn.TabOffset = colTabOffset;
                ShrinkTabOffset(downElasticLine, colNumber);
                curLineNumber++;
            }
        }
 /// <summary>
 /// returns true if column size contains change, false otherwise
 /// </summary>
 /// <param name="columnSizeInfo"></param>
 /// <returns></returns>
 internal bool ChangedRegardingTo(ColumnSizeInfo columnSizeInfo)
 {
     return(Math.Abs(TabOffset - columnSizeInfo.TabOffset) > 1.0E-10 || Math.Abs(ColumnWidth - columnSizeInfo.ColumnWidth) > 1.0E-10);
 }