+ MInterval head = find_head (start), i = head;
+ MInterval tail = start < end ? find_tail (end) : head;
+
+ if (tail.To < Length)
+ tail = tail.Next;
+
+ if (start == head.From && start > 0)
+ {
+ MInterval prev = head.Prev;
+ if (head.mergeable (prev))
+ head = prev;
+ }
+ M17n.DebugPrint ("merge between {0} and {1}\n", head, tail);
+ while (i != tail)
+ {
+ MInterval next = i.Next;
+
+ if (! i.mergeable (next))
+ {
+ if (head != i)
+ combine (head, i);
+ head = next;
+ }
+ i = next;
+ }
+ if (head != i)
+ combine (head, i);
+ }
+
+ public void Pop (int start, int end)
+ {
+ update_from_to ();
+ M17n.DebugPrint ("pop({0} {1}) at {2}\n", start, end, this);
+ if (start < From)
+ {
+ if (end <= From)
+ {
+ Left.Pop (start, end);
+ return;
+ }
+ Left.Pop (start, From);
+ start = From;
+ }
+ if (end > To)
+ {
+ if (start >= To)
+ {
+ Right.Pop (start, end);
+ return;
+ }
+ Right.Pop (To, end);
+ end = To;
+ }
+
+ if (! Stack.IsEmpty)
+ {
+ if (isSensitive)
+ Stack.Clear ();
+ else
+ {
+ if (start > From)
+ divide_left (start);
+ if (end < To)
+ divide_right (end);
+ Stack.Pop ();
+ }
+ }
+ }
+
+ public void PopSensitive (int start, int end)
+ {
+ update_from_to ();
+ MInterval head = find_head (start);
+ MInterval tail = find_tail (end);
+ Pop (head.From, tail.To);
+ }
+
+ public void PopAll (int start, int end)
+ {
+ update_from_to ();
+ M17n.DebugPrint ("popall({0} {1}) at {2}\n", start, end, this);
+ if (start < From)
+ {
+ if (end <= From)
+ {
+ Left.PopAll (start, end);
+ return;
+ }
+ Left.PopAll (start, From);
+ start = From;
+ }
+ if (end > To)
+ {
+ if (start >= To)
+ {
+ Right.PopAll (start, end);
+ return;
+ }
+ Right.PopAll (To, end);
+ end = To;
+ }
+
+ if (! Stack.IsEmpty)
+ {
+ if (isSensitive)
+ Stack.Clear ();
+ else
+ {
+ if (start > From)
+ divide_left (start);
+ if (end < To)
+ divide_right (end);
+ Stack.Clear ();
+ }
+ }
+ }
+
+ public override string ToString ()
+ {
+ string str = String.Format ("#{0}({1} {2} {3} [", ID, Length, From, To);
+ bool first = true;
+ foreach (MPlist p in Stack)
+ {
+ if (first)
+ {
+ str += ((MProperty) p.Val).Val;
+ first = false;
+ }
+ else
+ str += " " + ((MProperty) p.Val).Val;
+ }
+ return (str + "])");
+ }
+
+ private void DumpOne (bool with_prop, bool newline, bool force)
+ {
+ if (force || M17n.debug)
+ {
+ Console.Write ("#{0}({1} {2} {3}", ID, Length, From, To);
+ if (with_prop && ! Stack.IsEmpty)
+ {
+ string prepend = " [";
+ foreach (MPlist p in Stack)
+ {
+ Console.Write (prepend + ((MProperty) p.Val).Val);
+ prepend = " ";
+ }
+ Console.Write ("]");
+ }
+ Console.Write (")");
+ if (newline)
+ Console.WriteLine ();
+ if (Length <= 0)
+ throw new Exception ("Invalid interval length");
+ }
+ }
+
+ public void Dump () { Dump (false); }
+
+ public void Dump (bool force)
+ {
+ if (force || M17n.debug)
+ {
+ update_from_to ();
+
+ if (Left != null)
+ Left.Dump (force);
+ if (From > 0)
+ Console.Write (" ");
+ DumpOne (true, false, force);
+ if (Right != null)
+ Right.Dump (force);
+ }
+ }
+
+ private int Depth {
+ get { return (Parent == null ? 0 : Parent.Depth + 1); }
+ }
+
+ public void DumpNested (bool force)
+ {
+ DumpNested (" " + Key.ToString () + ":", force);
+ }
+
+ public void DumpNested (string indent, bool force)
+ {
+ if (force || M17n.debug)
+ {
+ int indent_type = (Parent == null ? 1
+ : Parent.Left == this ? 0 : 2);
+
+ update_from_to ();
+ if (Left != null)
+ {
+ if (indent_type <= 1)
+ Left.DumpNested (indent + " ", force);
+ else
+ Left.DumpNested (indent + "| ", force);
+ }
+ Console.Write (indent);
+ if (indent_type == 0)
+ Console.Write (".-");
+ else if (indent_type == 2)
+ Console.Write ("`-");
+ DumpOne (true, true, true);
+ if (Right != null)
+ {
+ if (indent_type >= 1)
+ Right.DumpNested (indent + " ", force);
+ else
+ Right.DumpNested (indent + "| ", force);
+ }
+ }