/*******************************************************************************
 * 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.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
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.debug.tests.TestUtil;
import org.eclipse.debug.tests.TestsPlugin;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleDocumentPartitioner;
import org.eclipse.ui.console.IConsoleDocumentPartitionerExtension;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleOutputStream;

/**
 * Tests the {@link IOConsole}. Especially the partitioner and viewer parts.
 */
public class IOConsoleTests extends AbstractDebugTest {
	/**
	 * The console view used for the running test. Required to obtain access to
	 * consoles {@link StyledText} widget to simulate user input.
	 */
	@SuppressWarnings("restriction")
	private org.eclipse.ui.internal.console.ConsoleView consoleView;

	/** Track console finished property notification. */
	private final AtomicBoolean consoleFinished = new AtomicBoolean(false);

	/**
	 * Number of received log messages with severity error while running a
	 * single test method.
	 */
	private final AtomicInteger loggedErrors = new AtomicInteger();

	/** Listener to count error messages while testing. */
	private final ILogListener errorLogListener = (IStatus status, String plugin) -> {
		if (status.matches(IStatus.ERROR)) {
			loggedErrors.incrementAndGet();
		}
	};

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

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

	@Override
	protected void setUp() throws Exception {
		super.setUp();

		// create or activate console view
		final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		assertNotNull(window);
		final IWorkbenchPage activePage = window.getActivePage();
		assertNotNull(activePage);
		IViewPart viewPart = activePage.findView(IConsoleConstants.ID_CONSOLE_VIEW);
		if (viewPart == null) {
			viewPart = activePage.showView(IConsoleConstants.ID_CONSOLE_VIEW, null, IWorkbenchPage.VIEW_CREATE);
		}
		@SuppressWarnings("restriction")
		final org.eclipse.ui.internal.console.ConsoleView castConsoleView = (org.eclipse.ui.internal.console.ConsoleView) viewPart;
		consoleView = castConsoleView;
		activePage.activate(consoleView);

		// add error listener
		loggedErrors.set(0);
		Platform.addLogListener(errorLogListener);
	}

	@Override
	protected void tearDown() throws Exception {
		assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
		Platform.removeLogListener(errorLogListener);
		super.tearDown();
	}

	/**
	 * Create test util connected to a new {@link IOConsole}.
	 *
	 * @param title console title
	 * @return util to help testing console functions
	 */
	private IOConsoleTestUtil getTestUtil(String title) {
		final IOConsole console = new IOConsole(title, "", null, StandardCharsets.UTF_8.name(), true);
		consoleFinished.set(false);
		console.addPropertyChangeListener((PropertyChangeEvent event) -> {
			if (event.getSource() == console && IConsoleConstants.P_CONSOLE_OUTPUT_COMPLETE.equals(event.getProperty())) {
				consoleFinished.set(true);
			}
		});
		final IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
		consoleManager.addConsoles(new IConsole[] { console });
		TestUtil.waitForJobs(getName(), 25, 10000);
		consoleManager.showConsoleView(console);
		@SuppressWarnings("restriction")
		final org.eclipse.ui.internal.console.IOConsolePage page = (org.eclipse.ui.internal.console.IOConsolePage) consoleView.getCurrentPage();
		final StyledText textPanel = (StyledText) page.getControl();
		return new IOConsoleTestUtil(console, textPanel, getName());
	}

	/**
	 * Close the console and optionally check content in {@link IOConsole}'s
	 * input stream.
	 * <p>
	 * Note: all output streams explicitly opened with
	 * {@link IOConsole#newOutputStream()} must be closed before.
	 * </p>
	 *
	 * @param c the test util containing the console to close
	 * @param expected content this {@link IOConsole} input stream has received
	 */
	private void closeConsole(IOConsoleTestUtil c, String... expectedInputLines) throws IOException {
		if (consoleFinished.get()) {
			// This should only happen if no output streams where used and the
			// user input stream was explicit closed before
			TestUtil.log(IStatus.WARNING, TestsPlugin.PLUGIN_ID, "Console was finished before streams where explicit closed.");
		}

		c.closeOutputStream();
		if (c.getConsole().getInputStream() != null) {
			c.getConsole().getInputStream().close();
		}

		if (expectedInputLines.length > 0) {
			assertNotNull(c.getConsole().getInputStream());
			assertTrue("InputStream is empty.", c.getConsole().getInputStream().available() > 0);

			final List<String> inputLines = new ArrayList<>();
			try (BufferedReader reader = new BufferedReader(new InputStreamReader(c.getConsole().getInputStream(), c.getConsole().getCharset()))) {
				String line;
				while (reader.ready() && (line = reader.readLine()) != null) {
					inputLines.add(line);
				}
			}
			assertEquals("Input contains to many/few lines.", expectedInputLines.length, inputLines.size());
			for (int i = 0; i < expectedInputLines.length; i++) {
				assertEquals("Content of input line " + i + " not as expected.", expectedInputLines[i], inputLines.get(i));
			}
		}
		c.waitForScheduledJobs();
		assertTrue("Console close was not signaled.", consoleFinished.get());

		final IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
		consoleManager.removeConsoles(new IConsole[] { c.getConsole() });
	}

	/**
	 * Test console clear.
	 */
	public void testConsoleClear() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test clear");

		c.writeAndVerify("Hello World!");
		c.getDocument().replace(0, c.getContentLength(), "");
		c.waitForScheduledJobs();
		c.verifyContent("").verifyPartitions();

		c.writeAndVerify("New console content.");
		c.clear();
		assertEquals("Unexpected partition type.", IOConsoleTestUtil.inputPartitionType(), c.getPartitioner().getContentType(0));

		c.insertAndVerify("wrong").write("out").verifyContent("wrongout").verifyPartitions(2);
		c.clear().insertTypingAndVerify("i").write("ooo").verifyContent("iooo").verifyPartitions();
		c.enter().clear();

		c.insertAndVerify("gnorw").write("tuo").verifyContent("gnorwtuo").verifyPartitions(2);
		c.clear().insertTypingAndVerify("I").write("O").verifyContent("IO").verifyPartitions();
		c.insert("\r\n").clear();

		closeConsole(c, "i", "I");
	}

	/**
	 * Test multiple writes, i.e. {@link IOConsole} receives content from
	 * connected {@link IOConsoleOutputStream}.
	 */
	public void testWrites() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test writes");
		final String[] strings = new String[] {
				"Hello ", "World", "foo-", "bar", "123 456" };
		for (String s : strings) {
			c.writeAndVerify(s);
		}
		c.write("\n");
		final String longString = String.join("", Collections.nCopies(1000, "0123456789"));
		c.writeAndVerify(longString);
		c.verifyContentByOffset(strings[1], strings[0].length());
		c.verifyContentByLine(String.join("", strings), 0);
		c.verifyPartitions();
		closeConsole(c);
	}

	/**
	 * Test {@link IOConsole} input stream, i.e. simulate user typing or pasting
	 * input in console.
	 */
	public void testUserInput() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test input");
		final List<String> expectedInput = new ArrayList<>();

		c.insertAndVerify("RR").backspace(3).verifyContent("").verifyPartitions();
		c.insertAndVerify("remove").select(0, c.getContentLength()).verifyPartitions();
		c.insertTypingAndVerify("abc").insertAndVerify("123").verifyContent("abc123");
		c.moveCaret(-3).insertAndVerify("foo").insertTypingAndVerify("bar").verifyContentByOffset("123", c.getCaretOffset());
		c.moveCaretToLineEnd().backspace(2).verifyContent("abcfoobar1").verifyPartitions();
		c.insert("\r\n").backspace(5);
		expectedInput.add("abcfoobar1");
		int pos = c.getCaretOffset();
		c.insertTypingAndVerify("NewLine").moveCaret(-4).enter();
		expectedInput.add("NewLine");
		assertEquals("Expected newline entered inside line does not break this line.", c.getContentLength(), c.getCaretOffset());
		c.verifyPartitions().verifyContentByOffset("NewLine", pos);
		c.backspace().insertAndVerify("--").select(0, c.getContentLength()).insertTyping("<~>");
		c.verifyContentByLine("<~>", 2).verifyPartitions();
		c.select(-2, 1).insertAndVerify("-=-").verifyContentByLine("<-=->", 2).verifyPartitions();

		// multiline input
		c.clear().insertTyping("=").insert("foo\n><");
		expectedInput.add("=foo");
		c.moveCaretToEnd().moveCaret(-1);
		c.insert("abc\r\n123\n456");
		expectedInput.add(">abc<");
		expectedInput.add("123");
		c.enter().clear();
		expectedInput.add("456");

		closeConsole(c, expectedInput.toArray(new String[0]));
	}

	/**
	 * Test {@link IOConsole} with file as input source.
	 */
	public void testInputFile() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test input file");
		// open default output stream to match usual behavior where two output
		// streams are open and to prevent premature console closing
		c.getDefaultOutputStream();
		try (InputStream in = new ByteArrayInputStream(new byte[0])) {
			c.getConsole().getInputStream().close();
			c.getConsole().setInputStream(in);
		}
		closeConsole(c);
		assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
	}

	/**
	 * Test mixes of outputs and user inputs in various variants.
	 */
	public void testMixedWriteAndInput() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test input output mix");
		final List<String> expectedInput = new ArrayList<>();

		// user input mixed with outputs without caret movement
		c.writeAndVerify("foo");
		c.insertTyping("~~~");
		c.writeAndVerify("bar");
		c.insertTyping("input.");
		c.verifyContent("foo~~~input.bar").verifyPartitions(3);
		c.enter().clear();
		expectedInput.add("~~~input.");

		// type in output or finished input partitions and replace input
		c.insert("fixed\n");
		expectedInput.add("fixed");
		c.setCaretOffset(2);
		c.insertTyping("+");
		c.writeAndVerify("out");
		c.moveCaretToEnd().moveCaret(-1);
		c.insert("more input");
		c.select(0, c.getContentLength()).backspace();
		c.insert("~~p#t").select(c.getContentLength() - 5, 2).insert("in");
		c.select(c.getContentLength() - 2, 1).insertTyping("u");
		c.enter().clear();
		expectedInput.add("input");

		// inserted input is shorter than existing input partition
		c.writeAndVerify("foo");
		c.insertTyping("><--input-partition--").setCaretOffset(4);
		c.writeAndVerify("bar");
		c.insertTypingAndVerify("short");
		c.verifyContent("foo>short<--input-partition--bar").verifyPartitions(3);
		c.enter().clear();
		expectedInput.add(">short<--input-partition--");

		// inserted input is longer than existing input partition
		c.writeAndVerify("Hello");
		c.insertTyping("><").moveCaret(-1);
		c.writeAndVerify("World");
		c.insertTypingAndVerify("user input");
		c.verifyContent("Hello>user input<World").verifyPartitions(3);
		c.enter().clear();
		expectedInput.add(">user input<");

		// replace and remove input
		c.writeAndVerify("oooo");
		c.insertTyping("input");
		c.writeAndVerify("output");
		c.verifyContent("ooooinputoutput").verifyPartitions(3);
		c.select(4, 5).insertAndVerify("iiii");
		c.verifyContent("ooooiiiioutput").verifyPartitions(3);
		c.select(4, 4).backspace();
		c.verifyContent("oooooutput").verifyPartitions(2);
		c.enter().clear();
		expectedInput.add("");

		// insert alternating into distinct input partitions
		c.insertTypingAndVerify("ac").writeAndVerify("ooo");
		c.setCaretOffset(1).insertTypingAndVerify("b");
		c.moveCaretToEnd().insertTypingAndVerify("123");
		c.verifyContent("abcooo123").verifyPartitions(3);
		c.enter().clear();
		expectedInput.add("abc123");

		// insert alternating into distinct input partitions
		c.insertTypingAndVerify("abc").writeAndVerify("ooo");
		c.moveCaretToEnd().insertTypingAndVerify("13").writeAndVerify("OOO");
		c.moveCaret(-1).insertTyping("2");
		c.moveCaretToStart().insertTyping("ABC");
		c.verifyContent("ABCabcooo123OOO").verifyPartitions(4);
		c.enter().clear();
		expectedInput.add("ABCabc123");

		// insert at partition borders
		c.writeAndVerify("###").insertTyping("def").writeAndVerify("###");
		c.setCaretOffset(6).insertAndVerify("ghi");
		c.setCaretOffset(3).insertTypingAndVerify("abc");
		c.moveCaretToLineStart().insertTyping(":");
		c.enter().clear();
		expectedInput.add(":abcdefghi");

		// try to overwrite read-only content
		c.writeAndVerify("o\u00F6O").insertTyping("\u00EFiI").writeAndVerify("\u00D6\u00D8\u00F8");
		// line content: oöOiïIÖØø
		c.verifyContent("o\u00F6O" + "\u00EFiI" + "\u00D6\u00D8\u00F8").verifyPartitions(2);
		c.select(4, 4).backspace();
		c.verifyContent("o\u00F6O" + "\u00EF" + "\u00D6\u00D8\u00F8").verifyPartitions(2);
		c.enter().clear();
		expectedInput.add("\u00EF");

		closeConsole(c, expectedInput.toArray(new String[0]));
	}

	/**
	 * Test larger number of partitions with pseudo random console content.
	 */
	public void testManyPartitions() throws IOException {
		final IOConsoleTestUtil c = getTestUtil("Test many partitions");
		final List<String> expectedInput = new ArrayList<>();
		final StringBuilder input = new StringBuilder();
		try (IOConsoleOutputStream otherOut = c.getConsole().newOutputStream()) {
			final Random rand = new Random(12);
			final StringBuilder sb = new StringBuilder();
			for (int i = 0; i < 20; i++) {
				for (int j = 0; j < 80; j += sb.length()) {
					sb.setLength(0);
					for (int k = rand.nextInt(15) + 1; k > 0; k--) {
						// add printable ASCII character
						sb.append((char) (rand.nextInt(95) + 32));
					}
					switch (rand.nextInt(5)) {
						case 0:
							c.insert(sb.toString());
							input.append(sb);
							break;

						case 1:
						case 2:
							c.writeFast(sb.toString(), otherOut);
							break;

						default:
							c.writeFast(sb.toString());
							break;
					}
				}
				c.enter().verifyPartitions();
				expectedInput.add(input.toString());
				input.setLength(0);
			}
		}
		closeConsole(c, expectedInput.toArray(new String[0]));
	}

	/**
	 * Test console trimming.
	 */
	public void testTrim() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test trim");
		try (IOConsoleOutputStream otherOut = c.getConsole().newOutputStream()) {
			c.writeFast("first\n");
			for (int i = 0; i < 20; i++) {
				c.writeFast("0123456789\n", (i & 1) == 0 ? c.getDefaultOutputStream() : otherOut);
			}
			c.write("last\n");
			c.verifyContentByLine("first", 0).verifyContentByLine("last", -2);
			assertTrue("Document not filled.", c.getDocument().getNumberOfLines() > 15);

			c.getConsole().setWaterMarks(50, 100);
			c.waitForScheduledJobs();
			c.verifyContentByOffset("0123456789", 0);
			assertTrue("Document not trimmed.", c.getDocument().getNumberOfLines() < 15);
		}
		closeConsole(c);
	}

	/**
	 * Some extra tests for IOConsolePartitioner.
	 */
	public void testIOPartitioner() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test partitioner");

		c.writeAndVerify("output");
		c.getDocument().replace(2, 1, ":::");
		c.verifyPartitions();

		c.clear().insertAndVerify("input").enter();
		c.getDocument().replace(3, 0, "()");
		c.verifyInputPartitions(0, c.getContentLength());

		c.clear().writeAndVerify("><");
		c.getDocument().replace(1, 0, "a\nb\r\nc");
		c.verifyContent(">a\nb\r\nc<").verifyPartitions();

		c.clear().writeAndVerify(")");
		c.getDocument().replace(0, 0, "(");
		c.verifyContent("()").verifyPartitions();

		closeConsole(c);
		assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
	}

	/**
	 * Tests for the {@link IConsoleDocumentPartitioner} interface.
	 */
	public void testIConsoleDocumentPartitioner() throws Exception {
		final IOConsoleTestUtil c = getTestUtil("Test IConsoleDocumentPartitioner");
		try (IOConsoleOutputStream otherOut = c.getConsole().newOutputStream()) {
			StyleRange[] styles = c.getPartitioner().getStyleRanges(0, 1);
			assertEquals("Got fake styles.", 0, (styles == null ? 0 : styles.length));

			c.insertAndVerify("#\n");
			c.insertTyping("L");
			c.writeFast("orem ipsum dolor sit amet, consetetur sadipscing elitr,\n");
			c.writeFast("sed diam nonumy eirmod tempor invidunt ut labore et dolore\n", otherOut);
			c.writeFast("magna aliquyam erat, sed diam voluptua. At vero eos et accusam\n");
			c.writeFast("et justo duo dolores et ea rebum. Stet clita kasd gubergren,\n", otherOut);
			c.write("no sea takimata sanctus est Lorem ipsum dolor sit amet.\n");
			final int loremEnd = c.getContentLength();
			c.moveCaretToEnd().insertTypingAndVerify("--").writeAndVerify("ooo");
			c.setCaretLineRelative(1).insertTypingAndVerify("-");
			c.verifyContentByLine("---ooo", -1);


			styles = c.getPartitioner().getStyleRanges(0, c.getContentLength());
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertTrue("Expected more styles.", styles.length >= 3);

			styles = c.getPartitioner().getStyleRanges(5, 20);
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertEquals("Number of styles:", 1, styles.length);

			styles = c.getPartitioner().getStyleRanges(loremEnd + 1, 1);
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertEquals("Number of styles:", 1, styles.length);

			styles = c.getPartitioner().getStyleRanges(loremEnd, c.getContentLength() - loremEnd);
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertEquals("Number of styles:", 2, styles.length);

			styles = c.getPartitioner().getStyleRanges(loremEnd - 3, 5);
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertEquals("Number of styles:", 2, styles.length);

			styles = c.getPartitioner().getStyleRanges(loremEnd - 3, 8);
			checkOverlapping(styles);
			assertNotNull("Partitioner provided no styles.", styles);
			assertEquals("Number of styles:", 3, styles.length);


			assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(0));
			assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(1));
			assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(2));
			for (int i = 3; i < loremEnd; i++) {
				assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(i));
			}
			assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 0));
			assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 1));
			assertFalse("Offset should be writable.", c.getPartitioner().isReadOnly(loremEnd + 2));
			assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 3));
			assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 4));
			assertTrue("Offset should be read-only.", c.getPartitioner().isReadOnly(loremEnd + 5));

			if (c.getPartitioner() instanceof IConsoleDocumentPartitionerExtension) {
				final IConsoleDocumentPartitionerExtension extension = (IConsoleDocumentPartitionerExtension) c.getPartitioner();
				assertFalse("Writable parts not recognized.", extension.isReadOnly(0, c.getContentLength()));
				assertTrue("Read-only parts not recognized.", extension.containsReadOnly(0, c.getContentLength()));
				assertFalse("Writable parts not recognized.", extension.isReadOnly(0, 3));
				assertTrue("Read-only parts not recognized.", extension.containsReadOnly(0, 3));
				assertFalse("Area should be writable.", extension.isReadOnly(loremEnd, 3));
				assertFalse("Area should be writable.", extension.containsReadOnly(loremEnd, 3));
				assertTrue("Area should be read-only.", extension.isReadOnly(6, 105));
				assertTrue("Area should be read-only.", extension.containsReadOnly(8, 111));

				assertTrue("Read-only parts not found.", extension.computeReadOnlyPartitions().length > 0);
				assertTrue("Writable parts not found.", extension.computeWritablePartitions().length > 0);
				assertTrue("Read-only parts not found.", extension.computeReadOnlyPartitions(loremEnd - 5, 7).length > 0);
				assertTrue("Writable parts not found.", extension.computeWritablePartitions(loremEnd - 5, 7).length > 0);
				assertTrue("Area should be read-only.", extension.computeReadOnlyPartitions(5, 100).length > 0);
				assertEquals("Area should be read-only.", 0, extension.computeWritablePartitions(5, 100).length);
				assertEquals("Area should be writable.", 0, extension.computeReadOnlyPartitions(loremEnd, 2).length);
				assertTrue("Area should be writable.", extension.computeWritablePartitions(loremEnd, 2).length > 0);

				assertEquals("Got wrong offset.", 0, extension.getNextOffsetByState(0, false));
				assertEquals("Got wrong offset.", 2, extension.getNextOffsetByState(0, true));
				assertEquals("Got wrong offset.", 0, extension.getPreviousOffsetByState(0, false));
				assertEquals("Got wrong offset.", -1, extension.getPreviousOffsetByState(0, true));
				assertEquals("Got wrong offset.", 1, extension.getNextOffsetByState(1, false));
				assertEquals("Got wrong offset.", 2, extension.getNextOffsetByState(1, true));
				assertEquals("Got wrong offset.", 1, extension.getPreviousOffsetByState(1, false));
				assertEquals("Got wrong offset.", -1, extension.getPreviousOffsetByState(1, true));
				assertEquals("Got wrong offset.", 3, extension.getNextOffsetByState(2, false));
				assertEquals("Got wrong offset.", 2, extension.getNextOffsetByState(2, true));
				assertEquals("Got wrong offset.", 1, extension.getPreviousOffsetByState(2, false));
				assertEquals("Got wrong offset.", 2, extension.getPreviousOffsetByState(2, true));
				for (int i = 3; i < loremEnd; i++) {
					assertEquals("Got wrong offset.", i, extension.getNextOffsetByState(i, false));
					assertEquals("Got wrong offset.", loremEnd, extension.getNextOffsetByState(i, true));
					assertEquals("Got wrong offset.", i, extension.getPreviousOffsetByState(i, false));
					assertEquals("Got wrong offset.", 2, extension.getPreviousOffsetByState(i, true));
				}
				assertEquals("Got wrong offset.", loremEnd + 3, extension.getNextOffsetByState(loremEnd, false));
				assertEquals("Got wrong offset.", loremEnd, extension.getNextOffsetByState(loremEnd, true));
				assertEquals("Got wrong offset.", loremEnd - 1, extension.getPreviousOffsetByState(loremEnd, false));
				assertEquals("Got wrong offset.", loremEnd, extension.getPreviousOffsetByState(loremEnd, true));
				assertEquals("Got wrong offset.", loremEnd + 3, extension.getNextOffsetByState(loremEnd + 2, false));
				assertEquals("Got wrong offset.", loremEnd + 2, extension.getNextOffsetByState(loremEnd + 2, true));
				assertEquals("Got wrong offset.", loremEnd - 1, extension.getPreviousOffsetByState(loremEnd + 2, false));
				assertEquals("Got wrong offset.", loremEnd + 2, extension.getPreviousOffsetByState(loremEnd + 2, true));
			} else {
				TestUtil.log(IStatus.INFO, TestsPlugin.PLUGIN_ID, "IOConsole partitioner does not implement " + IConsoleDocumentPartitionerExtension.class.getName() + ". Skip those tests.");
			}
		}
		c.verifyPartitions();
		closeConsole(c, "#");
		assertEquals("Test triggered errors in IOConsole.", 0, loggedErrors.get());
	}

	/**
	 * Check if there is any offset which received two styles.
	 *
	 * @param styles the styles to check
	 */
	private void checkOverlapping(StyleRange[] styles) {
		if (styles == null || styles.length <= 1) {
			return;
		}
		Arrays.sort(styles, (a, b) -> Integer.compare(a.start, b.start));
		int lastEnd = Integer.MIN_VALUE;
		for (StyleRange s : styles) {
			assertTrue("Styles overlap.", lastEnd <= s.start);
			lastEnd = s.start + s.length;
		}
	}
}
