/*******************************************************************************
 * Copyright (c) 2019 Paul Pazderski and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Paul Pazderski - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.tests.console;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.tests.AbstractDebugTest;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentAdapter;
import org.eclipse.swt.custom.TextChangeListener;
import org.eclipse.swt.custom.TextChangedEvent;
import org.eclipse.swt.custom.TextChangingEvent;
import org.eclipse.ui.internal.console.ConsoleDocumentAdapter;

/**
 * Tests {@link ConsoleDocumentAdapter}.
 * <p>
 * Primary tests fixed width mode and calculation of {@link TextChangingEvent}s.
 * </p>
 */
@SuppressWarnings("restriction")
public class ConsoleDocumentAdapterTests extends AbstractDebugTest {

	public ConsoleDocumentAdapterTests() {
		super(ConsoleDocumentAdapterTests.class.getSimpleName());
	}

	public ConsoleDocumentAdapterTests(String name) {
		super(name);
	}

	/**
	 * Test {@link ConsoleDocumentAdapter#setText(String)}.
	 */
	public void testSetText() {
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(true, null);
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1);
		docAdapter.setDocument(new Document());
		docAdapter.addTextChangeListener(eventListener);

		final String text = "123456";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.SET));
		docAdapter.setText(text);
		assertContent(docAdapter, text);
		assertNumberOfLines(docAdapter, 1);
		checkLineMapping(docAdapter, null);

		for (String s : new String[] { "", null }) {
			docAdapter.setText(s);
			assertContent(docAdapter, "");
			assertNumberOfLines(docAdapter, 1);
			checkLineMapping(docAdapter, null);
		}
	}

	/**
	 * Test fixed width line wrap. (mostly with changes affecting a single line)
	 */
	public void testLineWrap() {
		final Random rand = new Random(4);
		final int wrapWidth = 10;
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth);
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter);
		assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth());
		docAdapter.setDocument(new Document());
		docAdapter.addTextChangeListener(eventListener);
		// repeated add should not result in repeated events
		docAdapter.addTextChangeListener(eventListener);

		// initialize document
		final String initText = "012345";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.SET));
		docAdapter.setText(initText);
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, initText);
		checkLineMapping(docAdapter, rand);

		// add text without new line wrap
		String addText = "67";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, "01234567");
		checkLineMapping(docAdapter, rand);

		// add text with one new line wrap
		addText = "89AB";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "AB");
		checkLineMapping(docAdapter, rand);

		// insert text in wrapped line without new line wrap
		int offset = 6;
		addText = "---";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "012345---6");
		assertLine(docAdapter, 1, "789AB");
		checkLineMapping(docAdapter, rand);

		// remove last insert
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 3, 0, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 3, "");
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "AB");
		checkLineMapping(docAdapter, rand);

		// add text with two new line wrap
		addText = "CDEFGHIJabcdefghijKL";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KL");
		checkLineMapping(docAdapter, rand);

		// replace text without new line wrap
		String replaceText = "~~~";
		offset = 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, replaceText.length(), replaceText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "012~~~6789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KL");
		checkLineMapping(docAdapter, rand);

		// remove text with one removed line wrap
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 3, 0, 3, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 3, "");
		assertNumberOfLines(docAdapter, 3);
		assertLine(docAdapter, 0, "012" + "6789ABC");
		assertLine(docAdapter, 1, "DEFGHIJabc");
		assertLine(docAdapter, 2, "defghijKL");
		checkLineMapping(docAdapter, rand);

		// insert text with one new line wrap
		addText = "345";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 2, 3));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KL");
		checkLineMapping(docAdapter, rand);

		// add text ending at fixed width border
		addText = "MNOPQRST";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertEquals("Got wrong line index.", 3, docAdapter.getLineAtOffset(40));
		checkLineMapping(docAdapter, rand);

		// add text starting at fixed width border
		addText = "kl";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 5);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		checkLineMapping(docAdapter, rand);

		// insert text starting at fixed width border
		addText = ">";
		offset = docAdapter.getCharCount() - 2;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 5);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, ">kl");
		checkLineMapping(docAdapter, rand);

		// delete character at fixed width border
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 1, "");
		assertNumberOfLines(docAdapter, 5);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		checkLineMapping(docAdapter, rand);

		// add newline to start... new line
		addText = "\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "");
		assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(docAdapter.getCharCount() - 2));
		assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(docAdapter.getCharCount() - 1));
		assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount()));
		assertEquals("Get wrong content.", "\n", docAdapter.getTextRange(42, 1));
		checkLineMapping(docAdapter, rand);

		// add text ending at fixed width border
		addText = "UVWXYZ.,:;";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "UVWXYZ.,:;");
		assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount()));
		assertEquals("Get wrong content.", "l\nU", docAdapter.getTextRange(41, 3));
		checkLineMapping(docAdapter, rand);

		// remove text without line wrap change
		offset = docAdapter.getOffsetAtLine(docAdapter.getLineCount() - 1) + 2;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 4, 0, 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 4, "");
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "UV" + ".,:;");
		checkLineMapping(docAdapter, rand);

		// replace and insert text and end at fixed width border
		replaceText = "WXYZ.,:;";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, 4, replaceText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 4, replaceText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "UVWXYZ.,:;");
		assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount()));
		checkLineMapping(docAdapter, rand);

		// replace text without length change
		offset = docAdapter.getCharCount() - 3;
		replaceText = "~~~";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, replaceText.length(), replaceText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "UVWXYZ.~~~");
		assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount()));
		checkLineMapping(docAdapter, rand);

		// insert text with one new line wrap
		addText = ",:;";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 7);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "kl");
		assertLine(docAdapter, 5, "UVWXYZ.,:;");
		assertLine(docAdapter, 6, "~~~");
		checkLineMapping(docAdapter, rand);

		// manipulate text so both document lines end at wrap border
		addText = "mnopqrst";
		offset = 42;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		replaceText = "uvwxyz_-=|";
		offset = docAdapter.getCharCount() - 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 3, replaceText);
		assertNumberOfLines(docAdapter, 7);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abcdefghij");
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "klmnopqrst"); // <-- real line delimiter here
		assertLine(docAdapter, 5, "UVWXYZ.,:;");
		assertLine(docAdapter, 6, "uvwxyz_-=|");
		assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(49));
		assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(50));
		assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(51));
		assertEquals("Got wrong line.", 6, docAdapter.getLineAtOffset(docAdapter.getCharCount()));
		checkLineMapping(docAdapter, rand);

		// remove last wrapped line
		offset = docAdapter.getOffsetAtLine(docAdapter.getLineCount() - 1);
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 10, "");
		assertNumberOfLines(docAdapter, 6);
		checkLineMapping(docAdapter, rand);

		// replace text ending at wrap border without new line wrap
		replaceText = "~~~";
		offset = 7;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, replaceText.length(), replaceText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "0123456~~~");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		checkLineMapping(docAdapter, rand);

		// remove 5th line including it's real line delimiter
		offset = docAdapter.getOffsetAtLine(5 - 1);
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, null, null));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 11, "");
		assertNumberOfLines(docAdapter, 5);
		assertLine(docAdapter, 3, "KLMNOPQRST");
		assertLine(docAdapter, 4, "UVWXYZ.,:;");
		checkLineMapping(docAdapter, rand);

		// remove text ending at wrap border
		int remove = 3;
		offset = 7;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 4, 4));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 5);
		assertLine(docAdapter, 0, "0123456ABC");
		assertLine(docAdapter, 1, "DEFGHIJabc");
		assertLine(docAdapter, 2, "defghijKLM");
		assertLine(docAdapter, 3, "NOPQRSTUVW");
		assertLine(docAdapter, 4, "XYZ.,:;");
		checkLineMapping(docAdapter, rand);

		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
		docAdapter.removeTextChangeListener(eventListener);
		clearDocument(docAdapter);
	}

	/**
	 * Test inserting text containing line delimiters.
	 */
	public void testMultilineInserts() {
		final Random rand = new Random(4);
		final int wrapWidth = 10;
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth);
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter);
		assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth());
		docAdapter.setDocument(new Document());
		docAdapter.addTextChangeListener(eventListener);

		// add 4 new document lines with 1 line wrapped
		String addText = "012345\nABCDEFGHIJa\r\n\nklmnopqrst\r\nuv";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 5));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, addText);
		assertNumberOfLines(docAdapter, 6);
		assertLine(docAdapter, 0, "012345");
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "a");
		assertLine(docAdapter, 3, "");
		assertLine(docAdapter, 4, "klmnopqrst");
		assertLine(docAdapter, 5, "uv");
		checkLineMapping(docAdapter, rand);

		// insert newline at begin of line
		addText = "\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, addText);
		assertNumberOfLines(docAdapter, 7);
		assertLine(docAdapter, 0, "");
		assertLine(docAdapter, 1, "012345");
		checkLineMapping(docAdapter, rand);

		// insert text + newline at begin of line
		addText = "9876543210?\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, addText);
		assertNumberOfLines(docAdapter, 9);
		assertLine(docAdapter, 0, "9876543210");
		assertLine(docAdapter, 1, "?");
		assertLine(docAdapter, 2, "");
		checkLineMapping(docAdapter, rand);

		// insert newline + text at begin of line
		addText = "\r\nfoo";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 1, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, addText);
		assertNumberOfLines(docAdapter, 10);
		assertLine(docAdapter, 0, "");
		assertLine(docAdapter, 1, "foo9876543");
		assertLine(docAdapter, 2, "210?");
		assertLine(docAdapter, 3, "");
		checkLineMapping(docAdapter, rand);

		// insert text + newline + text at begin of line
		addText = ".,:;\r\nbar";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, addText);
		assertNumberOfLines(docAdapter, 11);
		assertLine(docAdapter, 0, ".,:;");
		assertLine(docAdapter, 1, "bar");
		assertLine(docAdapter, 2, "foo9876543");
		checkLineMapping(docAdapter, rand);

		// insert 2 newline at end of line
		addText = "\r\n\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 13);
		assertLine(docAdapter, 10, "uv");
		assertLine(docAdapter, 11, "");
		assertLine(docAdapter, 12, "");
		checkLineMapping(docAdapter, rand);

		// insert text + 2 newline at end of line (one line wrapping)
		addText = "BCDEFGHIJKbc\n\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 3));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 16);
		assertLine(docAdapter, 12, "BCDEFGHIJK");
		assertLine(docAdapter, 13, "bc");
		assertLine(docAdapter, 14, "");
		assertLine(docAdapter, 15, "");
		checkLineMapping(docAdapter, rand);

		// insert 2 newline + text at end of line
		addText = "\r\nLMNOPQR\nlmnopqrst";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 18);
		assertLine(docAdapter, 15, "");
		assertLine(docAdapter, 16, "LMNOPQR");
		assertLine(docAdapter, 17, "lmnopqrst");
		checkLineMapping(docAdapter, rand);

		// insert text + 2 newline + text at end of line (+one line wrapping)
		addText = "uVW\nvwxy\r\n1357902468";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 3));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText);
		assertNumberOfLines(docAdapter, 21);
		assertLine(docAdapter, 17, "lmnopqrstu");
		assertLine(docAdapter, 18, "VW");
		assertLine(docAdapter, 19, "vwxy");
		assertLine(docAdapter, 20, "1357902468");
		checkLineMapping(docAdapter, rand);

		// insert newline inside (wrapped) line
		int offset = docAdapter.getOffsetAtLine(17) + 8;
		addText = "\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 21);
		assertLine(docAdapter, 17, "lmnopqrs");
		assertLine(docAdapter, 18, "tuVW");
		assertLine(docAdapter, 19, "vwxy");
		checkLineMapping(docAdapter, rand);

		// insert newline + text + newline in existing line
		offset = docAdapter.getOffsetAtLine(19) + 2;
		addText = "\n[()]\r\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 23);
		assertLine(docAdapter, 19, "vw");
		assertLine(docAdapter, 20, "[()]");
		assertLine(docAdapter, 21, "xy");
		checkLineMapping(docAdapter, rand);

		// insert newline + long text + newline in existing line
		offset = docAdapter.getOffsetAtLine(20);
		addText = "\r\nCDEFGHIJKLcdefghijklMNOPQR\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 4));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 27);
		assertLine(docAdapter, 20, "");
		assertLine(docAdapter, 21, "CDEFGHIJKL");
		assertLine(docAdapter, 22, "cdefghijkl");
		assertLine(docAdapter, 23, "MNOPQR");
		assertLine(docAdapter, 24, "[()]");
		checkLineMapping(docAdapter, rand);

		// insert newline inside (wrapped) line
		offset = docAdapter.getOffsetAtLine(21) + 9;
		addText = "\n";
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 2, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, 0, addText);
		assertNumberOfLines(docAdapter, 27);
		assertLine(docAdapter, 21, "CDEFGHIJK");
		assertLine(docAdapter, 22, "Lcdefghijk");
		assertLine(docAdapter, 23, "lMNOPQR");
		checkLineMapping(docAdapter, rand);

		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
		docAdapter.removeTextChangeListener(eventListener);
		clearDocument(docAdapter);
	}

	/**
	 * Test text remove affecting than one line.
	 */
	public void testMultilineRemove() {
		final Random rand = new Random(4);
		final int wrapWidth = 10;
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(true, null);
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth);
		assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth());
		docAdapter.setDocument(new Document());
		docAdapter.addTextChangeListener(eventListener);

		// prepare one wrapped line
		clearDocument(docAdapter);
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDE");
		// remove over wrap border but wrap remains
		int offset = 8;
		int remove = 4;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "01234567CD");
		assertLine(docAdapter, 1, "E");
		checkLineMapping(docAdapter, rand);

		// perform empty change event
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, "", 0, 0, 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(0, 0, "");
		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
		checkLineMapping(docAdapter, rand);

		// remove over wrap border (removes wrap)
		offset = 8;
		remove = 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, "01234567");
		checkLineMapping(docAdapter, rand);

		// prepare one double wrapped line
		clearDocument(docAdapter);
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "abcde");
		// remove over two wrap border
		offset = 8;
		remove = 14;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 2, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "01234567cd");
		assertLine(docAdapter, 1, "e");
		checkLineMapping(docAdapter, rand);

		// remove at fixed width border
		offset = 10;
		remove = 1;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, "01234567cd");
		checkLineMapping(docAdapter, rand);

		// prepare two unwrapped lines
		clearDocument(docAdapter);
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEF");
		// remove line delimiter (produces wrapped line)
		offset = 8;
		remove = 1;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "01234567AB");
		assertLine(docAdapter, 1, "CDEF");
		checkLineMapping(docAdapter, rand);

		// prepare some more lines
		clearDocument(docAdapter);
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "abcdefghij");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "KLMN\r\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "klmno\n");
		assertLine(docAdapter, 5, "");
		// remove multiple lines
		offset = 5;
		remove = 36;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 5, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, "01234");
		checkLineMapping(docAdapter, rand);

		// prepare more lines
		clearDocument(docAdapter);
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\r\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\n");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, docAdapter.getLineDelimiter());
		assertNumberOfLines(docAdapter, 6);
		// remove empty lines
		// (and do not start in first line like most tests before)
		offset = 10;
		remove = 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 2, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, remove, "");
		assertNumberOfLines(docAdapter, 4);
		checkLineMapping(docAdapter, rand);

		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
	}

	/**
	 * Test text change affecting and inserting more than one line.
	 */
	public void testMultilineReplace() {
		final Random rand = new Random(4);
		final int wrapWidth = 10;
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(true, null);
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth);
		assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth());
		docAdapter.setDocument(new Document());
		docAdapter.addTextChangeListener(eventListener);

		docAdapter.setText("0123~~~AB");

		// remove in single line and insert newline
		String addText = "\n";
		int offset = 4;
		int length = 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 0, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 2);
		assertLine(docAdapter, 0, "0123"); // \n
		assertLine(docAdapter, 1, "AB");
		checkLineMapping(docAdapter, rand);

		// replace newline with more text and a new newline
		addText = "456789abc\r\n+";
		length = 2;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 1, 2));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 3);
		assertLine(docAdapter, 0, "0123456789");
		assertLine(docAdapter, 1, "abc"); // \r\n
		assertLine(docAdapter, 2, "+B");
		checkLineMapping(docAdapter, rand);

		// remove and insert newline
		addText = "<->\nABCDEFGHIJabc\n#";
		length = 12;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 2, 3));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "0123<->"); // \n
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "abc"); // \n
		assertLine(docAdapter, 3, "#B");
		checkLineMapping(docAdapter, rand);

		// insert newline and replace wrap
		addText = "\n>=<";
		offset = 18;
		length = 3;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 0, "0123<->"); // \n
		assertLine(docAdapter, 1, "ABCDEFGHIJ"); // \n
		assertLine(docAdapter, 2, ">=<"); // \n
		assertLine(docAdapter, 3, "#B");
		checkLineMapping(docAdapter, rand);

		addText = "*+";
		offset = docAdapter.getCharCount() - 2;
		length = 1;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 0, 0));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 4);
		assertLine(docAdapter, 2, ">=<"); // \n
		assertLine(docAdapter, 3, "*+B");
		checkLineMapping(docAdapter, rand);

		docAdapter.setText("");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ");
		docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "a");
		addText = "$b";
		offset = docAdapter.getCharCount() - 1;
		length = 1;
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1));
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED));
		docAdapter.replaceTextRange(offset, length, addText);
		assertNumberOfLines(docAdapter, 3);
		assertLine(docAdapter, 1, "ABCDEFGHIJ");
		assertLine(docAdapter, 2, "$b");
		checkLineMapping(docAdapter, rand);

		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
	}

	/**
	 * Test line wrapping is correctly updated if fixed width changed.
	 */
	public void testSetWidth() {
		final Random rand = new Random(7);
		final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1);
		docAdapter.setDocument(new Document());

		final String line0_0 = "#123456789";
		final String line0_1 = "ABCDEF";
		final String line0 = line0_0 + line0_1;
		final String line1 = "";
		final String line2 = "abcd";
		final String text = line0 + "\n" + line1 + "\r\n" + line2;
		docAdapter.setText(text);
		assertEquals("Get text range failed.", "#", docAdapter.getTextRange(0, 1));

		// check with initial disabled fixed width mode
		assertLine(docAdapter, 0, line0);
		assertLine(docAdapter, 1, line1);
		assertLine(docAdapter, 2, line2);
		assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount());
		checkLineMapping(docAdapter, rand);

		// test with enabled fixed width mode
		docAdapter.setWidth(10);
		docAdapter.setWidth(10); // intentional double set
		assertLine(docAdapter, 0, line0_0);
		assertLine(docAdapter, 1, line0_1);
		assertLine(docAdapter, 2, line1);
		assertLine(docAdapter, 3, line2);
		assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount());
		checkLineMapping(docAdapter, rand);

		// test with disabled fixed width mode after it was enabled
		docAdapter.setWidth(-1);
		assertLine(docAdapter, 0, line0);
		assertLine(docAdapter, 1, line1);
		assertLine(docAdapter, 2, line2);
		assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount());
		checkLineMapping(docAdapter, rand);

		// test with fixed width mode but no virtual wrappings
		docAdapter.setWidth(80);
		assertLine(docAdapter, 0, line0);
		assertLine(docAdapter, 1, line1);
		assertLine(docAdapter, 2, line2);
		assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount());
		checkLineMapping(docAdapter, rand);

		// add a listener for the next width change
		final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter);
		docAdapter.addTextChangeListener(eventListener);
		eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.SET));

		// test extreme small console
		docAdapter.setWidth(1);
		int expectedLines = Math.max(line0.length(), 1);
		expectedLines += Math.max(line1.length(), 1);
		expectedLines += Math.max(line2.length(), 1);
		assertNumberOfLines(docAdapter, expectedLines);
		checkLineMapping(docAdapter, rand);
		assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections());
	}

	/**
	 * Some test cases derived from JavaDoc examples of {@link IDocumentAdapter}
	 * (and its super interfaces).
	 */
	public void testInterfaceContract() {
		final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1);
		docAdapter.setDocument(new Document());
		assertNotNull("Adapter has no legal line delimiter.", docAdapter.getLineDelimiter());

		for (int width : new int[] { -1, 80 }) {
			docAdapter.setWidth(width);

			// test against documentation of
			// IDocumentAdapter#getLineAtOffset(int)
			docAdapter.setText("\r\n\r\n");
			checkLineMapping(docAdapter, null);
			assertEquals("Wrong line for offset.", 0, docAdapter.getLineAtOffset(0));
			assertEquals("Wrong line for offset.", 0, docAdapter.getLineAtOffset(1));
			assertEquals("Wrong line for offset.", 1, docAdapter.getLineAtOffset(2));
			assertEquals("Wrong line for offset.", 1, docAdapter.getLineAtOffset(3));
			assertEquals("Wrong line for offset.", 2, docAdapter.getLineAtOffset(4));
			assertEquals("Wrong line for offset.", docAdapter.getLineCount() - 1, docAdapter.getLineAtOffset(docAdapter.getCharCount()));

			// test against documentation of IDocumentAdapter#getLineCount()
			docAdapter.setText(null);
			assertNumberOfLines(docAdapter, 1);
			docAdapter.setText("");
			assertNumberOfLines(docAdapter, 1);
			docAdapter.setText("a\n");
			assertNumberOfLines(docAdapter, 2);
			docAdapter.setText("\n\n");
			assertNumberOfLines(docAdapter, 3);

			// test against documentation of
			// IDocumentAdapter#getOffsetAtLine(int)
			docAdapter.setText("\r\ntest\r\n");
			checkLineMapping(docAdapter, null);
			assertEquals("Wrong offset for line.", 0, docAdapter.getOffsetAtLine(0));
			assertEquals("Wrong offset for line.", 2, docAdapter.getOffsetAtLine(1));
			assertEquals("Wrong offset for line.", 8, docAdapter.getOffsetAtLine(2));
			docAdapter.setText("");
			assertEquals("Wrong offset for line.", 0, docAdapter.getOffsetAtLine(0));
		}
	}

	/**
	 * Test
	 * {@link IDocumentAdapter#setDocument(org.eclipse.jface.text.IDocument)}
	 * and ensure old document is indeed disconnected and not notified anymore.
	 */
	public void testChangeDocument() {
		final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1);
		final IDocument doc1 = new Document();
		final IDocument doc2 = new Document();
		final String text1 = "foo";
		final String text2 = "bar";

		docAdapter.setDocument(doc1);
		docAdapter.setText(text1);
		assertContent(docAdapter, text1);

		final String doc1Text = doc1.get();
		docAdapter.setDocument(doc2);
		docAdapter.setText(text2);
		assertContent(docAdapter, text2);
		assertEquals("Document was changed after disconnect.", doc1Text, doc1.get());

		docAdapter.setDocument(null);
	}

	/**
	 * Test if invalid arguments produces error log messages.
	 */
	public void _testInvalidInvocations() {
		final AtomicInteger expectedErrors = new AtomicInteger(0);
		final ILogListener logListener = new ILogListener() {
			@Override
			public void logging(IStatus status, String plugin) {
				if (status.matches(IStatus.ERROR)) {
					expectedErrors.decrementAndGet();
				}
			}
		};
		try {
			Platform.addLogListener(logListener);

			final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1);
			docAdapter.setDocument(null);
			docAdapter.setDocument(new Document());
			try {
				docAdapter.addTextChangeListener(null);
				fail("Exception not thrown.");
			} catch (IllegalArgumentException ex) {
				// expected behavior
			}
			try {
				docAdapter.removeTextChangeListener(null);
				fail("Exception not thrown.");
			} catch (IllegalArgumentException ex) {
				// expected behavior
			}

			for (int width : new int[] { -1, -2, 80 }) {
				docAdapter.setWidth(width);
				if (width != -2) {
					docAdapter.setText("?");
				} else {
					// In non fixed mode the documents line tracker is used for
					// most queries. Document may use different trackers if test
					// is set or replaced.
					docAdapter.replaceTextRange(0, docAdapter.getCharCount(), "?");
				}

				expectedErrors.set(3);
				docAdapter.getLine(Integer.MIN_VALUE);
				docAdapter.getLine(-1);
				// getLine(1) should be invalid as well but the current
				// implementation uses getLineInformation and ListLineTracker
				// returns information for this non existing line and
				// TreeLineTracke does so for compatibility reasons
				docAdapter.getLine(Integer.MAX_VALUE);
				assertEquals("Too much success with width: " + width, 0, expectedErrors.get());

				expectedErrors.set(4);
				docAdapter.getLineAtOffset(Integer.MIN_VALUE);
				docAdapter.getLineAtOffset(-1);
				docAdapter.getLineAtOffset(1);
				docAdapter.getLineAtOffset(2);
				docAdapter.getLineAtOffset(Integer.MAX_VALUE);
				assertEquals("Too much success with width: " + width, 0, expectedErrors.get());

				expectedErrors.set(4);
				docAdapter.getOffsetAtLine(Integer.MIN_VALUE);
				docAdapter.getOffsetAtLine(-1);
				docAdapter.getOffsetAtLine(1);
				docAdapter.getOffsetAtLine(Integer.MAX_VALUE);
				assertEquals("Too much success with width: " + width, 0, expectedErrors.get());

				expectedErrors.set(6);
				docAdapter.getTextRange(-1, 1);
				docAdapter.getTextRange(0, -1);
				docAdapter.getTextRange(1, -1);
				docAdapter.getTextRange(-1, 2);
				docAdapter.getTextRange(0, 2);
				docAdapter.getTextRange(0, 3);
				assertEquals("Too much success with width: " + width, 0, expectedErrors.get());

				expectedErrors.set(10);
				docAdapter.replaceTextRange(2, 0, "");
				docAdapter.replaceTextRange(-1, 0, "");
				docAdapter.replaceTextRange(0, 2, "");
				docAdapter.replaceTextRange(0, -1, "");
				docAdapter.replaceTextRange(1, 1, "");
				docAdapter.replaceTextRange(0, 2, "foo");
				docAdapter.replaceTextRange(0, -1, "foo");
				docAdapter.replaceTextRange(1, 1, "foo");
				docAdapter.replaceTextRange(1, -1, "foo");
				docAdapter.replaceTextRange(2, 0, "foo");
				assertEquals("Too much success with width: " + width, 0, expectedErrors.get());
			}
		} finally {
			Platform.removeLogListener(logListener);
		}
	}

	/**
	 * Test adapter with a larger number of lines. (especially tests array grow)
	 */
	public void testManyLines() {
		final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(80);
		docAdapter.setDocument(new Document());
		final String lineDelimiter = docAdapter.getLineDelimiter();
		final int n = 6000;
		for (int i = 0; i < n; i++) {
			docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, lineDelimiter);
		}
		assertNumberOfLines(docAdapter, n + 1);
		docAdapter.setWidth(-1);
		assertNumberOfLines(docAdapter, n + 1);
		clearDocument(docAdapter);
	}

	private static void assertContent(IDocumentAdapter docAdapter, String content) {
		assertEquals("Adapter returned wrong content.", content, docAdapter.getTextRange(0, docAdapter.getCharCount()));
	}

	private static void assertNumberOfLines(IDocumentAdapter docAdapter, int expectedLines) {
		assertEquals("Adapter has wrong line count.", expectedLines, docAdapter.getLineCount());
	}

	private static void assertLine(IDocumentAdapter docAdapter, int lineIndex, String expectedContent) {
		assertEquals("Adapter returned wrong content for line " + lineIndex + ".", expectedContent, docAdapter.getLine(lineIndex));
	}

	/**
	 * Goes through every line in adapted document and checks if value of
	 * {@link IDocumentAdapter#getOffsetAtLine(int)} for a line returns the same
	 * line again if put into {@link IDocumentAdapter#getLineAtOffset(int)}.
	 * <p>
	 * If random source is provided test is more intensive and to some extend
	 * tests {@link IDocumentAdapter#getLine(int)}.
	 * </p>
	 *
	 * @param docAdapter document adapter to test
	 * @param rand Optional. If provided will request line from random offset of
	 *            this line instead of first and check lines in random order.
	 */
	private static void checkLineMapping(IDocumentAdapter docAdapter, Random rand) {
		final int n = docAdapter.getLineCount();
		final List<Integer> lines = new ArrayList<>(n);
		for (int i = 0; i < n; i++) {
			lines.add(i);
		}
		if (rand != null) {
			Collections.shuffle(lines, rand);
		}
		for (int lineIndex : lines) {
			int offset = docAdapter.getOffsetAtLine(lineIndex);
			if (rand != null) {
				int lineLength = docAdapter.getLine(lineIndex).length();
				if (lineLength > 0) {
					offset += rand.nextInt(lineLength);
				}
			}
			final int testLineIndex = docAdapter.getLineAtOffset(offset);
			assertEquals("Got wrong line with offset " + offset + ".", lineIndex, testLineIndex);
		}
	}

	private static void clearDocument(IDocumentAdapter docAdapter) {
		docAdapter.setText("");
		assertEquals("Document not cleared.", 0, docAdapter.getCharCount());
		assertNumberOfLines(docAdapter, 1);
		assertLine(docAdapter, 0, "");
	}

	private static class TextEventExpectation {
		// common attributes
		/** Expected text change event type. */
		public final TextChangeEventType type;

		// text changing only attributes
		/**
		 * Expected value of {@link TextChangingEvent#start} or
		 * <code>null</code> to ignore.
		 */
		public final Integer start;
		/**
		 * Expected value of {@link TextChangingEvent#newText} or
		 * <code>null</code> to ignore.
		 */
		public final String newText;
		/**
		 * Expected value of {@link TextChangingEvent#replaceCharCount} or
		 * <code>null</code> to ignore.
		 */
		public final Integer replaceCharCount;
		/**
		 * Expected value of {@link TextChangingEvent#newCharCount} or
		 * <code>null</code> to ignore.
		 */
		public final Integer newCharCount;
		/**
		 * Expected value of {@link TextChangingEvent#replaceLineCount} or
		 * <code>null</code> to ignore.
		 */
		public final Integer replaceLineCount;
		/**
		 * Expected value of {@link TextChangingEvent#newLineCount} or
		 * <code>null</code> to ignore.
		 */
		public final Integer newLineCount;

		public TextEventExpectation(TextChangeEventType type) {
			this(type, null, null, null, null, null, null);
		}

		public TextEventExpectation(TextChangeEventType type, Integer start, String newText, Integer replaceCharCount, Integer newCharCount, Integer replaceLineCount, Integer newLineCount) {
			super();
			this.type = type;
			this.start = start;
			this.newText = newText;
			this.replaceCharCount = replaceCharCount;
			this.newCharCount = newCharCount;
			this.replaceLineCount = replaceLineCount;
			this.newLineCount = newLineCount;
		}
	}

	/**
	 * A {@link TextChangeListener} which has some expectations about generated
	 * text change events and is not gladly disappointed.
	 */
	private static class ExpectingTextChangeListener implements TextChangeListener {

		final Queue<TextEventExpectation> expectations = new LinkedList<>();
		final boolean allowUnexpectedEvents;
		/**
		 * The {@link IDocumentAdapter} generating the events. If set some
		 * additional checks are performed.
		 */
		final IDocumentAdapter docAdapter;
		/**
		 * If all events are checked ({@link #allowUnexpectedEvents} = false)
		 * and {@link #docAdapter} is set do some additional validations.
		 */
		TextChangingEvent lastEvent;
		int linesBeforeReplace = -1;
		int lengthBeforeReplace = -1;

		public ExpectingTextChangeListener(boolean allowUnexpectedEvents, IDocumentAdapter docAdapter) {
			super();
			this.allowUnexpectedEvents = allowUnexpectedEvents;
			this.docAdapter = docAdapter;
		}

		public void addExpectation(TextEventExpectation expectation) {
			expectations.add(expectation);
		}

		@Override
		public void textChanging(TextChangingEvent event) {
			final TextEventExpectation expectation = checkCommon(TextChangeEventType.CHANGING);
			if (expectation == null) {
				return;
			}

			if (expectation.start != null) {
				assertEquals("event.start", (int) expectation.start, event.start);
			}
			if (expectation.newText != null) {
				assertEquals("event.newText", expectation.newText, event.newText);
			}
			if (expectation.replaceCharCount != null) {
				assertEquals("event.replaceCharCount", (int) expectation.replaceCharCount, event.replaceCharCount);
			}
			if (expectation.newCharCount != null) {
				assertEquals("event.newCharCount", (int) expectation.newCharCount, event.newCharCount);
			}
			if (expectation.replaceLineCount != null) {
				assertEquals("event.replaceLineCount", (int) expectation.replaceLineCount, event.replaceLineCount);
			}
			if (expectation.newLineCount != null) {
				assertEquals("event.newLineCount", (int) expectation.newLineCount, event.newLineCount);
			}

			if (!allowUnexpectedEvents && docAdapter != null) {
				lastEvent = event;
				linesBeforeReplace = docAdapter.getLineCount();
				lengthBeforeReplace = docAdapter.getCharCount();

				final int charactersBehindEventStart = docAdapter.getCharCount() - event.start;
				assertTrue("Tried to remove more characters than available.", event.replaceCharCount <= charactersBehindEventStart);

				final int linesBehindEvent = docAdapter.getLineCount() - docAdapter.getLineAtOffset(event.start);
				assertTrue("Tried to remove more lines than available.", event.replaceLineCount <= linesBehindEvent);
			}
		}

		@Override
		public void textChanged(TextChangedEvent event) {
			checkCommon(TextChangeEventType.CHANGED);

			if (docAdapter != null && lastEvent != null) {
				final int lastEventOffset = lastEvent.start;
				final int lastEventLineIndex = docAdapter.getLineAtOffset(lastEventOffset);
				assertEquals("Line of offset " + lastEventOffset + " has changed after text change.", lastEventLineIndex, docAdapter.getLineAtOffset(lastEventOffset));

				// check if predicted changes are correct
				final int predictedDocLength = lengthBeforeReplace - lastEvent.replaceCharCount + lastEvent.newCharCount;
				assertEquals("New widget length not as announce by changing event.", predictedDocLength, docAdapter.getCharCount());
				final int predictedDocLines = linesBeforeReplace - lastEvent.replaceLineCount + lastEvent.newLineCount;
				assertEquals("New widget line number not as announce by changing event.", predictedDocLines, docAdapter.getLineCount());
				assertEquals("Inserted text not found in document.", lastEvent.newText, docAdapter.getTextRange(lastEvent.start, lastEvent.newText.length()));
			}
		}

		@Override
		public void textSet(TextChangedEvent event) {
			checkCommon(TextChangeEventType.SET);
		}

		public boolean hasPendingExpections() {
			return !expectations.isEmpty();
		}

		private TextEventExpectation checkCommon(TextChangeEventType eventType) {
			final TextEventExpectation expectation = expectations.poll();
			if (expectation == null && allowUnexpectedEvents) {
				return null;
			}
			assertNotNull("Unexpected event.", expectation);
			if (expectation == null) {
				// prevents wrong compiler warning 'expectation may be null'
				return null;
			}
			if (expectation.type != eventType && allowUnexpectedEvents) {
				return null;
			}
			assertEquals("Wrong event type.", expectation.type, eventType);
			return expectation;
		}
	}

	public enum TextChangeEventType {
		CHANGING, CHANGED, SET,
	}
}
