+ len = 0;
+ if (Stack.IsEmpty
+ && (isRearSensitive || (isSensitive && end < i.To)))
+ {
+ M17n.DebugPrint (" backward grafting {0}", i);
+ if (i.From <= start)
+ len = end - start;
+ else
+ len = end - i.From;
+ i = i.Prev;
+ }
+ while (i != null && i.To <= start && mergeable (i))
+ {
+ M17n.DebugPrint (" backward grafting {0}", i);
+ len += i.To - i.From;
+ if (end < i.To)
+ len -= i.To - end;
+ if (i.From <= start)
+ {
+ len -= start - i.From;
+ break;
+ }
+ i = i.Prev;
+ }
+ }
+
+ M17n.DebugPrint (" grafted {0} in {1}\n", len, this);
+ if (len > 0)
+ enlarge (len);
+ return len;
+ }
+
+ public void Insert (int pos, MInterval interval, int start, int end)
+ {
+ update_from_to ();
+
+ M17n.DebugPrint ("insert({0} to {1}) at {2} in {3}",
+ start, end, pos, this);
+
+ if (pos < From)
+ Left.Insert (pos, interval, start, end);
+ else if (pos == From)
+ {
+ MInterval prev = Left != null ? Prev : null;
+
+ if (isFrontSensitive)
+ Stack.Clear ();
+ if (prev != null && isRearSensitive)
+ prev.Stack.Clear ();
+ if (prev != null && isRearSticky && ! prev.Stack.IsEmpty)
+ {
+ prev.enlarge (end - start);
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ if (isFrontSticky && ! Stack.IsEmpty)
+ {
+ enlarge (end - start);
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ bool front_grafted = false, rear_grafted = false;
+ int grafted;
+ if (prev != null
+ && (grafted = prev.graft_forward (interval, start, end)) > 0)
+ {
+ start += grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ front_grafted = true;
+ }
+ if ((grafted = graft_backward (interval, start, end)) > 0)
+ {
+ end -= grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ rear_grafted = true;
+ }
+
+ if (interval != null)
+ interval = interval.Copy (mtext, start, end,
+ (front_grafted
+ || (prev == null && start == 0)),
+ rear_grafted);
+ else
+ interval = new MInterval (Key, mtext, end - start, null);
+
+ MInterval i;
+ if (Left != null)
+ {
+ // .-this-. ==> .-this-.
+ // left-. .-left-.
+ // child child-.
+ // interval
+ i = Left.RightMost;
+ i.Right = interval;
+ }
+ else
+ {
+ Left = interval;
+ i = this;
+ }
+ interval.Parent = i;
+ for (; i != null; i = i.Parent)
+ i.Length += interval.Length;
+ }
+ else if (pos < To)
+ {
+ if (! Stack.IsEmpty)
+ {
+ if (isSensitive)
+ Stack.Clear ();
+ else if (isFrontSticky || isRearSticky)
+ {
+ enlarge (end - start);
+ return;
+ }
+ }
+ bool front_grafted = false, rear_grafted = false;
+ int grafted;
+ if ((grafted = graft_forward (interval, start, end)) > 0)
+ {
+ start += grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ front_grafted = true;
+ pos += grafted;
+ }
+ if ((grafted = graft_backward (interval, start, end)) > 0)
+ {
+ end -= grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ rear_grafted = true;
+ }
+ if (interval != null)
+ interval = interval.Copy (mtext, start, end,
+ front_grafted, rear_grafted);
+ else
+ interval = new MInterval (Key, mtext, end - start, null);
+
+ divide_right (pos);
+ Right.Left = interval;
+ interval.Parent = Right;
+ for (MInterval i = Right; i != null; i = i.Parent)
+ i.Length += interval.Length;
+ }
+ else if (pos == To)
+ {
+ MInterval next = Right != null ? Next : null;
+
+ if (isRearSensitive)
+ Stack.Clear ();
+ if (next != null && isFrontSensitive)
+ next.Stack.Clear ();
+ if (isRearSticky && ! Stack.IsEmpty)
+ {
+ enlarge (end - start);
+ M17n.DebugPrint (" done by enlarging this\n");
+ return;
+ }
+ if (next != null && isFrontSticky && ! next.Stack.IsEmpty)
+ {
+ M17n.DebugPrint (" next is {0}\n", next);
+ next.enlarge (end - start);
+ M17n.DebugPrint (" done by enlarging next\n");
+ return;
+ }
+ bool front_grafted = false, rear_grafted = false;
+ int grafted;
+ if (next != null
+ && (grafted = next.graft_backward (interval, start, end)) > 0)
+ {
+ end -= grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ rear_grafted = true;
+ }
+ if ((grafted = graft_forward (interval, start, end)) > 0)
+ {
+ start += grafted;
+ if (start == end)
+ {
+ M17n.DebugPrint (" done\n");
+ return;
+ }
+ front_grafted = true;
+ }
+ if (interval != null)
+ interval = interval.Copy (mtext, start, end,
+ front_grafted,
+ (rear_grafted
+ || (next == null && end == interval.mtext.Length)));
+ else
+ interval = new MInterval (Key, mtext, end - start, null);
+
+ MInterval i;
+ if (Right != null)
+ {
+ // .-this-. ==> .-this-.
+ // .-right .-right
+ // child .-child
+ // interval
+
+ i = Right.LeftMost;
+ i.Left = interval;
+ }
+ else
+ {
+ Right = interval;
+ i = this;
+ }
+ interval.Parent = i;
+ for (; i != null; i = i.Parent)
+ i.Length += interval.Length;
+ }
+ else // (pos > To)
+ Right.Insert (pos, interval, start, end);
+ M17n.DebugPrint (" done\n");