public DocumentUndoManager (DocumentBuffer buffer)
	{
		frozen_cnt = 0;
		try_merge = false;
		undo_stack = new Stack ();
		redo_stack = new Stack ();
		
		this.buffer  = buffer;
		chop_buffer = new ChopBuffer (buffer.TagTable);
		
		buffer.InsertText += OnInsertText;
		buffer.DeleteRange += OnDeleteRange;
	}
        public DocumentUndoManager(DocumentBuffer buffer)
        {
            frozen_cnt = 0;
            try_merge  = false;
            undo_stack = new Stack();
            redo_stack = new Stack();

            this.buffer = buffer;
            chop_buffer = new ChopBuffer(buffer.TagTable);

            buffer.InsertText  += OnInsertText;
            buffer.DeleteRange += OnDeleteRange;
        }
	public InsertAction (TextIter start, string text, int length, ChopBuffer chop_buf)
	{
		#if DEBUG
		Console.WriteLine ("DEBUG: InsertAction: {0}", text);
		Console.WriteLine ("DEBUG: Insert Offset: {0} Char {1}", start.Offset, start.Char);
		#endif
		
		this.index = start.Offset - length;
		this.is_paste = length > 1;
		
		TextIter indexIter = start.Buffer.GetIterAtOffset (index);
		#if DEBUG
		Console.WriteLine ("DEBUG: Start Offset: {0} Char: {1}", indexIter.Offset, indexIter.Char);
		#endif
		this.chop = chop_buf.AddChop (indexIter, start);
		#if DEBUG
		Console.WriteLine ("DEBUG: Chop Text: {0}", chop.Text);
		#endif
	}
        public InsertAction(TextIter start, string text, int length, ChopBuffer chop_buf)
        {
                #if DEBUG
            Console.WriteLine("DEBUG: InsertAction: {0}", text);
            Console.WriteLine("DEBUG: Insert Offset: {0} Char {1}", start.Offset, start.Char);
                #endif

            this.index    = start.Offset - length;
            this.is_paste = length > 1;

            TextIter indexIter = start.Buffer.GetIterAtOffset(index);
                #if DEBUG
            Console.WriteLine("DEBUG: Start Offset: {0} Char: {1}", indexIter.Offset, indexIter.Char);
                #endif
            this.chop = chop_buf.AddChop(indexIter, start);
                #if DEBUG
            Console.WriteLine("DEBUG: Chop Text: {0}", chop.Text);
                #endif
        }
        public EraseAction(TextIter startIter, TextIter endIter, ChopBuffer chop_buf)
        {
                #if DEBUG
            Console.WriteLine("DEBUG: EraseAction: {0}", startIter.GetText(endIter));
            Console.WriteLine("DEBUG: Start Offset: {0} Char: {1}", startIter.Offset, startIter.Char);
            Console.WriteLine("DEBUG: End Offset: {0} Char: {1}", endIter.Offset, endIter.Char);
                #endif

            this.start  = startIter.Offset;
            this.end    = endIter.Offset;
            this.is_cut = end - start > 1;

            TextIter previousIter = startIter.Buffer.GetIterAtOffset(start - 1);
            bool     startsRegion = previousIter.Char.Equals("[");
            bool     endsRegion   = endIter.Char.Equals("]");
            this.whole_region = startsRegion && endsRegion;

            TextIter insert = startIter.Buffer.GetIterAtMark(startIter.Buffer.InsertMark);
            this.is_forward = insert.Offset <= start;

            this.chop = chop_buf.AddChop(startIter, endIter);
        }
	public EraseAction (TextIter startIter, TextIter endIter, ChopBuffer chop_buf)
	{
		#if DEBUG
		Console.WriteLine ("DEBUG: EraseAction: {0}", startIter.GetText (endIter));
		Console.WriteLine ("DEBUG: Start Offset: {0} Char: {1}", startIter.Offset, startIter.Char);
		Console.WriteLine ("DEBUG: End Offset: {0} Char: {1}", endIter.Offset, endIter.Char);
		#endif
		
		this.start = startIter.Offset;
		this.end = endIter.Offset;
		this.is_cut = end - start > 1;
		
		TextIter previousIter = startIter.Buffer.GetIterAtOffset (start - 1);
		bool startsRegion = previousIter.Char.Equals ("[");
		bool endsRegion = endIter.Char.Equals ("]");
		this.whole_region = startsRegion && endsRegion;
		
		TextIter insert = startIter.Buffer.GetIterAtMark (startIter.Buffer.InsertMark);
		this.is_forward = insert.Offset <= start;
		
		this.chop = chop_buf.AddChop (startIter, endIter);
	}