private void MergeTextChangeRight(TextChange oldChange, TextChange newChange, int offset, int length)
        {
            // If the old change is an addition, find the length of the overlap
            // and adjust the addition and new deletion counts accordingly
            int addedLengthOverlap = oldChange.AddedLength > 0 ? offset + length - oldChange.Offset : 0;

#if PROPERTY_CHANGES
            // Check for a property change in the new change that overlaps the old change
            int propertyOverlap = newChange.Offset + newChange.PropertyCount - oldChange.Offset;
            if (propertyOverlap > 0)
            {
                int delta = Math.Min(propertyOverlap, addedLengthOverlap);
                newChange.SetPropertyCount(newChange.PropertyCount - delta);
                // Don't need to adjust oldChange.PropertyCount, since oldChange is about to be removed
            }
#endif

            // adjust removed count
            if (addedLengthOverlap >= oldChange.AddedLength)
            {
                // old change is entirely within new one
                newChange.RemovedLength += (oldChange.RemovedLength - oldChange.AddedLength);
                Changes.Remove(oldChange.Offset);
            }
            else
            {
                newChange.RemovedLength += (oldChange.RemovedLength - addedLengthOverlap);
                newChange.AddedLength   += (oldChange.AddedLength - addedLengthOverlap);
                Changes.Remove(oldChange.Offset);
            }
        }
 private bool MergePropertyChange(TextChange leftChange, TextChange rightChange)
 {
     if (leftChange.Offset + leftChange.PropertyCount >= rightChange.Offset)
     {
         if (leftChange.Offset + leftChange.PropertyCount < rightChange.Offset + rightChange.PropertyCount)
         {
             // right change is partially inside left, but not completely.
             int overlap = leftChange.Offset + leftChange.PropertyCount - rightChange.Offset;
             int delta   = rightChange.PropertyCount - overlap;
             leftChange.SetPropertyCount(leftChange.PropertyCount + delta);
         }
         rightChange.SetPropertyCount(0);
         return(true);
     }
     return(false);
 }
        // returns true if the change merged into an earlier insertion
        private bool MergeTextChangeLeft(TextChange oldChange, TextChange newChange, bool isDeletion, int length)
        {
            // newChange is inserting or deleting text inside oldChange.
            int overlap;

#if PROPERTY_CHANGES
            // Check for a property change in the old change that overlaps the new change
            if (oldChange.Offset + oldChange.PropertyCount >= newChange.Offset)
            {
                if (isDeletion)
                {
                    overlap = oldChange.PropertyCount - (newChange.Offset - oldChange.Offset);
                    oldChange.SetPropertyCount(oldChange.PropertyCount - Math.Min(overlap, length));
                    DeleteChangeIfEmpty(oldChange);
                }
                else
                {
                    oldChange.SetPropertyCount(oldChange.PropertyCount + length);
                }
            }
#endif

            if (oldChange.Offset + oldChange.AddedLength >= newChange.Offset)
            {
                // If any text was deleted in the new change, adjust the added count of the
                // previous change accordingly.  The removed count of the new change must be
                // adjusted by the same amount.
                if (isDeletion)
                {
                    overlap = oldChange.AddedLength - (newChange.Offset - oldChange.Offset);
                    int cancelledCount = Math.Min(overlap, newChange.RemovedLength);
                    oldChange.AddedLength   -= cancelledCount;
                    oldChange.RemovedLength += (length - cancelledCount);
                }
                else
                {
                    oldChange.AddedLength += length;
                }
#if PROPERTY_CHANGES
                if (newChange.PropertyCount == 0)
                {
                    // We've merged the data from the new change into an older one, so we can
                    // delete the change from the list.
                    Changes.Remove(newChange.Offset);
                }
                else
                {
                    // Can't delete the change, since there's pre-existing property change data, so
                    // just clear the data instead.
                    newChange.AddedLength   = 0;
                    newChange.RemovedLength = 0;
                }
#else
                // We've merged the data from the new change into an older one, so we can
                // delete the change from the list.
                Changes.Remove(newChange.Offset);
#endif
                return(true);
            }
            return(false);
        }