/// <summary>
        /// Apply a Variant to a marker. Variant is a duplication
        /// </summary>
        /// <param name="variant"></param>
        /// <returns></returns>
        protected Interval ApplyDup(Variant variant)
        {
            Interval m = new Interval(this);

            if (variant.OneBasedEnd < m.OneBasedStart)
            {
                // Duplication before marker start? => Adjust both coordinates
                long lenChange = variant.LengthChange();
                m.OneBasedStart += lenChange;
                m.OneBasedEnd   += lenChange;
            }
            else if (variant.Includes(m))
            {
                // Duplication includes whole marker? => Adjust both coordinates
                long lenChange = variant.LengthChange();
                m.OneBasedStart += lenChange;
                m.OneBasedEnd   += lenChange;
            }
            else if (m.Includes(variant))
            {
                // Duplication included in marker? => Adjust end coordinate
                m.OneBasedEnd += variant.LengthChange();
            }
            else if (variant.Intersects(m))
            {
                // Duplication includes part of marker? => Adjust end
                m.OneBasedEnd += variant.IntersectSize(m);
            }
            else
            {
                // Duplication after end, no effect on marker coordinates
            }

            return(m);
        }
        /// <summary>
        /// Apply a Variant to a marker. Variant is a deletion
        /// </summary>
        /// <param name="variant"></param>
        /// <returns></returns>
        protected Interval ApplyDel(Variant variant)
        {
            Interval m = new Interval(this);

            if (variant.OneBasedEnd < m.OneBasedStart)
            {
                // Deletion before start: Adjust coordinates
                long lenChange = variant.LengthChange();
                m.OneBasedStart += lenChange;
                m.OneBasedEnd   += lenChange;
            }
            else if (variant.Includes(m))
            {
                // Deletion completely includes this marker => The whole marker deleted
                return(null);
            }
            else if (m.Includes(variant))
            {
                // This marker completely includes the deletion, but deletion does not include
                // marker. Marker is shortened (i.e. only 'end' coordinate needs to be updated)
                m.OneBasedEnd += variant.LengthChange();
            }
            else
            {
                // Variant is partially included in this marker.
                // This is treated as three different type of deletions:
                //		1- One after the marker
                //		2- One inside the marker
                //		3- One before the marker
                // Note that type 1 and 3 cannot exists at the same time, otherwise the
                // deletion would fully include the marker (previous case)

                // Part 1: Deletion after the marker
                if (m.OneBasedEnd < variant.OneBasedEnd)
                {
                    // Actually this does not affect the coordinates, so we don't care about this part
                }

                // Part 2: Deletion matching the marker (intersection)
                long istart = Math.Max(variant.OneBasedStart, m.OneBasedStart);
                long iend   = Math.Min(variant.OneBasedEnd, m.OneBasedEnd);
                if (iend < istart)
                {
                    throw new ArgumentOutOfRangeException("This should never happen!");
                }                                     // Sanity check
                m.OneBasedEnd -= (iend - istart + 1); // Update end coordinate

                // Part 3: Deletion before the marker
                if (variant.OneBasedStart < m.OneBasedEnd)
                {
                    // Update coordinates shifting the marker to the left
                    long delta = m.OneBasedStart - variant.OneBasedStart;
                    m.OneBasedStart -= delta;
                    m.OneBasedEnd   -= delta;
                }
            }

            return(m);
        }
        /// <summary>
        /// Apply a Variant to a marker. Variant is an insertion
        /// </summary>
        /// <param name="variant"></param>
        /// <returns></returns>
        protected Interval ApplyIns(Variant variant)
        {
            Interval m = new Interval(this);

            if (variant.OneBasedStart < m.OneBasedStart)
            {
                // Insertion point before marker start? => Adjust both coordinates
                long lenChange = variant.LengthChange();
                m.OneBasedStart += lenChange;
                m.OneBasedEnd   += lenChange;
            }
            else if (variant.OneBasedStart <= m.OneBasedEnd)
            {
                // Insertion point after start, but before end? => Adjust end coordinate
                m.OneBasedEnd += variant.LengthChange();
            }
            else
            {
                // Insertion point after end, no effect on marker coordinates
            }

            return(m);
        }