+ private MInterval delete_node_forward ()
+ {
+ if (Parent != null)
+ {
+ int len = Length - RightLength;
+
+ for (MInterval i = Parent; i != null; i = i.Parent)
+ i.Length -= len;
+ if (Parent.Left == this)
+ Parent.Left = Right;
+ else
+ Parent.Right = Right;
+ }
+
+ if (Right != null)
+ {
+ Right.Parent = Parent;
+ return Right.LeftMost;
+ }
+ return Parent;
+ }
+
+ private MInterval delete_node_backward ()
+ {
+ if (Parent != null)
+ {
+ int len = Length - RightLength;
+
+ for (MInterval i = Parent; i != null; i = i.Parent)
+ i.Length -= len;
+ if (Parent.Left == this)
+ Parent.Left = Left;
+ else
+ Parent.Right = Left;
+ }
+
+ if (Left != null)
+ {
+ Left.Parent = Parent;
+ return Left.RightMost;
+ }
+ return Parent;
+ }
+
+ private void set_mtext (MText mt)
+ {
+ mtext = mt;
+ if (Left != null)
+ Left.set_mtext (mt);
+ if (Right != null)
+ Right.set_mtext (mt);
+ }
+
+ private MInterval graft (MInterval interval, bool forward, out int len)
+ {
+ MInterval i;
+
+ len = 0;
+ if (forward)
+ {
+ i = interval.LeftMost;
+ while (i != null)
+ {
+ if (! mergeable (i))
+ break;
+ len += i.Length - i.RightLength;
+ i = i.delete_node_forward ();
+ }
+ }
+ else
+ {
+ i = interval.RightMost;
+ while (i != null)
+ {
+ if (! mergeable (i))
+ break;
+ len += i.Length - i.LeftLength;
+ i = i.delete_node_backward ();
+ }
+ }
+
+ Length += len;
+ To += len;
+ for (MInterval prev = this, ii = this.Parent; ii != null;
+ prev = ii, ii = ii.Parent)
+ {
+ ii.Length += len;
+ if (prev == ii.Left)
+ {
+ ii.From += len;
+ ii.To += len;;
+ }
+ }
+ if (i != null)
+ while (i.Parent != null) i = i.Parent;
+ return i;
+ }
+