/*
 * Copyright (C) 2010, 2014 Christian Halstrick <christian.halstrick@sap.com>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.revplot;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalkTestCase;
import org.junit.Test;

public class PlotCommitListTest extends RevWalkTestCase {

	static class CommitListAssert {
		private PlotCommitList<PlotLane> pcl;
		private PlotCommit<PlotLane> current;
		private int nextIndex = 0;

		CommitListAssert(PlotCommitList<PlotLane> pcl) {
			this.pcl = pcl;
		}

		public CommitListAssert commit(RevCommit id) {
			assertTrue("Unexpected end of list at pos#"+nextIndex, pcl.size()>nextIndex);
			current = pcl.get(nextIndex++);
			assertEquals("Expected commit not found at pos#" + (nextIndex - 1),
					id.getId(), current.getId());
			return this;
		}

		public CommitListAssert lanePos(int pos) {
			PlotLane lane = current.getLane();
			assertEquals("Position of lane of commit #" + (nextIndex - 1)
					+ " not as expected.", pos, lane.getPosition());
			return this;
		}

		public int getLanePos() {
			return current.getLane().position;
		}

		/**
		 * Checks that the current position is valid and consumes this position.
		 *
		 * @param allowedPositions
		 * @return this
		 */
		public CommitListAssert lanePos(Set<Integer> allowedPositions) {
			PlotLane lane = current.getLane();
			@SuppressWarnings("boxing")
			boolean found = allowedPositions.remove(lane.getPosition());
			assertTrue("Position of lane of commit #" + (nextIndex - 1)
					+ " not as expected. Expecting one of: " + allowedPositions + " Actual: "+ lane.getPosition(), found);
			return this;
		}

		public CommitListAssert nrOfPassingLanes(int lanes) {
			assertEquals("Number of passing lanes of commit #"
					+ (nextIndex - 1)
					+ " not as expected.", lanes, current.passingLanes.length);
			return this;
		}

		public CommitListAssert parents(RevCommit... parents) {
			assertEquals("Number of parents of commit #" + (nextIndex - 1)
					+ " not as expected.", parents.length,
					current.getParentCount());
			for (int i = 0; i < parents.length; i++)
				assertEquals("Unexpected parent of commit #" + (nextIndex - 1),
						parents[i], current.getParent(i));
			return this;
		}

		public CommitListAssert noMoreCommits() {
			assertEquals("Unexpected size of list", nextIndex, pcl.size());
			return this;
		}
	}

	private static Set<Integer> asSet(int... numbers) {
		Set<Integer> result = new HashSet<>();
		for (int n : numbers)
			result.add(Integer.valueOf(n));
		return result;
	}

	@Test
	public void testLinear() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(b);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(c.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(c).lanePos(0).parents(b);
		test.commit(b).lanePos(0).parents(a);
		test.commit(a).lanePos(0).parents();
		test.noMoreCommits();
	}

	@Test
	public void testMerged() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(a);
		final RevCommit d = commit(b, c);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(d.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(d).lanePos(0).parents(b, c);
		test.commit(c).lanePos(1).parents(a);
		test.commit(b).lanePos(0).parents(a);
		test.commit(a).lanePos(0).parents();
		test.noMoreCommits();
	}

	@Test
	public void testSideBranch() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(a);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(b.getId()));
		pw.markStart(pw.lookupCommit(c.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> childPositions = asSet(0, 1);
		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(c).lanePos(childPositions).parents(a);
		test.commit(b).lanePos(childPositions).parents(a);
		test.commit(a).lanePos(0).parents();
		test.noMoreCommits();
	}

	@Test
	public void test2SideBranches() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(a);
		final RevCommit d = commit(a);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(b.getId()));
		pw.markStart(pw.lookupCommit(c.getId()));
		pw.markStart(pw.lookupCommit(d.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> childPositions = asSet(0, 1, 2);
		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(d).lanePos(childPositions).parents(a);
		test.commit(c).lanePos(childPositions).parents(a);
		test.commit(b).lanePos(childPositions).parents(a);
		test.commit(a).lanePos(0).parents();
		test.noMoreCommits();
	}

	@Test
	public void testBug300282_1() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(a);
		final RevCommit d = commit(a);
		final RevCommit e = commit(a);
		final RevCommit f = commit(a);
		final RevCommit g = commit(f);

		PlotWalk pw = new PlotWalk(db);
		// TODO: when we add unnecessary commit's as tips (e.g. a commit which
		// is a parent of another tip) the walk will return those commits twice.
		// Find out why!
		// pw.markStart(pw.lookupCommit(a.getId()));
		pw.markStart(pw.lookupCommit(b.getId()));
		pw.markStart(pw.lookupCommit(c.getId()));
		pw.markStart(pw.lookupCommit(d.getId()));
		pw.markStart(pw.lookupCommit(e.getId()));
		// pw.markStart(pw.lookupCommit(f.getId()));
		pw.markStart(pw.lookupCommit(g.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> childPositions = asSet(0, 1, 2, 3, 4);
		CommitListAssert test = new CommitListAssert(pcl);
		int posG = test.commit(g).lanePos(childPositions).parents(f)
				.getLanePos();
		test.commit(f).lanePos(posG).parents(a);

		test.commit(e).lanePos(childPositions).parents(a);
		test.commit(d).lanePos(childPositions).parents(a);
		test.commit(c).lanePos(childPositions).parents(a);
		test.commit(b).lanePos(childPositions).parents(a);
		test.commit(a).lanePos(0).parents();
		test.noMoreCommits();
	}

	@Test
	public void testBug368927() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit(a);
		final RevCommit c = commit(b);
		final RevCommit d = commit(b);
		final RevCommit e = commit(c);
		final RevCommit f = commit(e, d);
		final RevCommit g = commit(a);
		final RevCommit h = commit(f);
		final RevCommit i = commit(h);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(i.getId()));
		pw.markStart(pw.lookupCommit(g.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);
		Set<Integer> childPositions = asSet(0, 1);
		CommitListAssert test = new CommitListAssert(pcl);
		int posI = test.commit(i).lanePos(childPositions).parents(h)
				.getLanePos();
		test.commit(h).lanePos(posI).parents(f);
		test.commit(g).lanePos(childPositions).parents(a);
		test.commit(f).lanePos(posI).parents(e, d);
		test.commit(e).lanePos(posI).parents(c);
		test.commit(d).lanePos(2).parents(b);
		test.commit(c).lanePos(posI).parents(b);
		test.commit(b).lanePos(posI).parents(a);
		test.commit(a).lanePos(0).parents();
	}

	// test the history of the egit project between 9fdaf3c1 and e76ad9170f
	@Test
	public void testEgitHistory() throws Exception {
		final RevCommit merge_fix = commit();
		final RevCommit add_simple = commit(merge_fix);
		final RevCommit remove_unused = commit(merge_fix);
		final RevCommit merge_remove = commit(add_simple, remove_unused);
		final RevCommit resolve_handler = commit(merge_fix);
		final RevCommit clear_repositorycache = commit(merge_remove);
		final RevCommit add_Maven = commit(clear_repositorycache);
		final RevCommit use_remote = commit(clear_repositorycache);
		final RevCommit findToolBar_layout = commit(clear_repositorycache);
		final RevCommit merge_add_Maven = commit(findToolBar_layout, add_Maven);
		final RevCommit update_eclipse_iplog = commit(merge_add_Maven);
		final RevCommit changeset_implementation = commit(clear_repositorycache);
		final RevCommit merge_use_remote = commit(update_eclipse_iplog,
				use_remote);
		final RevCommit disable_source = commit(merge_use_remote);
		final RevCommit update_eclipse_iplog2 = commit(merge_use_remote);
		final RevCommit merge_disable_source = commit(update_eclipse_iplog2,
				disable_source);
		final RevCommit merge_changeset_implementation = commit(
				merge_disable_source, changeset_implementation);
		final RevCommit clone_operation = commit(merge_changeset_implementation);
		final RevCommit update_eclipse = commit(add_Maven);
		final RevCommit merge_resolve_handler = commit(clone_operation,
				resolve_handler);
		final RevCommit disable_comment = commit(clone_operation);
		final RevCommit merge_disable_comment = commit(merge_resolve_handler,
				disable_comment);
		final RevCommit fix_broken = commit(merge_disable_comment);
		final RevCommit add_a_clear = commit(fix_broken);
		final RevCommit merge_update_eclipse = commit(add_a_clear,
				update_eclipse);
		final RevCommit sort_roots = commit(merge_update_eclipse);
		final RevCommit fix_logged_npe = commit(merge_changeset_implementation);
		final RevCommit merge_fixed_logged_npe = commit(sort_roots,
				fix_logged_npe);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);

		// Note: all positions of side branches are rather arbitrary, but some
		// may not overlap. Testing for the positions yielded by the current
		// implementation, which was manually checked to not overlap.
		final int mainPos = 0;
		test.commit(merge_fixed_logged_npe).parents(sort_roots, fix_logged_npe)
				.lanePos(mainPos);
		test.commit(fix_logged_npe).parents(merge_changeset_implementation)
				.lanePos(1);
		test.commit(sort_roots).parents(merge_update_eclipse).lanePos(mainPos);
		test.commit(merge_update_eclipse).parents(add_a_clear, update_eclipse)
				.lanePos(mainPos);
		test.commit(add_a_clear).parents(fix_broken).lanePos(mainPos);
		test.commit(fix_broken).parents(merge_disable_comment).lanePos(mainPos);
		test.commit(merge_disable_comment)
				.parents(merge_resolve_handler, disable_comment)
				.lanePos(mainPos);
		test.commit(disable_comment).parents(clone_operation).lanePos(2);
		test.commit(merge_resolve_handler)
				.parents(clone_operation, resolve_handler).lanePos(mainPos);
		test.commit(update_eclipse).parents(add_Maven).lanePos(3);
		test.commit(clone_operation).parents(merge_changeset_implementation)
				.lanePos(mainPos);
		test.commit(merge_changeset_implementation)
				.parents(merge_disable_source, changeset_implementation)
				.lanePos(mainPos);
		test.commit(merge_disable_source)
				.parents(update_eclipse_iplog2, disable_source)
				.lanePos(mainPos);
		test.commit(update_eclipse_iplog2).parents(merge_use_remote)
				.lanePos(mainPos);
		test.commit(disable_source).parents(merge_use_remote).lanePos(1);
		test.commit(merge_use_remote).parents(update_eclipse_iplog, use_remote)
				.lanePos(mainPos);
		test.commit(changeset_implementation).parents(clear_repositorycache)
				.lanePos(2);
		test.commit(update_eclipse_iplog).parents(merge_add_Maven)
				.lanePos(mainPos);
		test.commit(merge_add_Maven).parents(findToolBar_layout, add_Maven)
				.lanePos(mainPos);
		test.commit(findToolBar_layout).parents(clear_repositorycache)
				.lanePos(mainPos);
		test.commit(use_remote).parents(clear_repositorycache).lanePos(1);
		test.commit(add_Maven).parents(clear_repositorycache).lanePos(3);
		test.commit(clear_repositorycache).parents(merge_remove)
				.lanePos(mainPos);
		test.commit(resolve_handler).parents(merge_fix).lanePos(4);
		test.commit(merge_remove).parents(add_simple, remove_unused)
				.lanePos(mainPos);
		test.commit(remove_unused).parents(merge_fix).lanePos(1);
		test.commit(add_simple).parents(merge_fix).lanePos(mainPos);
		test.commit(merge_fix).parents().lanePos(mainPos);
		test.noMoreCommits();
	}

	// test a history where a merge commit has two time the same parent
	@Test
	public void testDuplicateParents() throws Exception {
		final RevCommit m1 = commit();
		final RevCommit m2 = commit(m1);
		final RevCommit m3 = commit(m2, m2);

		final RevCommit s1 = commit(m2);
		final RevCommit s2 = commit(s1);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(m3));
		pw.markStart(pw.lookupCommit(s2));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(s2).nrOfPassingLanes(0);
		test.commit(s1).nrOfPassingLanes(0);
		test.commit(m3).nrOfPassingLanes(1);
		test.commit(m2).nrOfPassingLanes(0);
		test.commit(m1).nrOfPassingLanes(0);
		test.noMoreCommits();
	}

	/**
	 * The graph shows the problematic original positioning. Due to this some
	 * lanes are no straight lines here, but they are with the new layout code)
	 *
	 * <pre>
	 * a5
	 * | \
	 * |  a4
	 * | /
	 * a3
	 * |
	 * |  e
	 * |    \
	 * |     |
	 * |  b3 |
	 * |  |  d
	 * |  |/
	 * | /|
	 * |/ |
	 * a2 |
	 * |  b2
	 * |    \
	 * |  c |
	 * | /  /
	 * |/ b1
	 * a1
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testBug419359() throws Exception {
		// this may not be the exact situation of bug 419359 but it shows
		// similar behavior
		final RevCommit a1 = commit();
		final RevCommit b1 = commit();
		final RevCommit c = commit(a1);
		final RevCommit b2 = commit(b1);
		final RevCommit a2 = commit(a1);
		final RevCommit d = commit(a2);
		final RevCommit b3 = commit(b2);
		final RevCommit e = commit(d);
		final RevCommit a3 = commit(a2);
		final RevCommit a4 = commit(a3);
		final RevCommit a5 = commit(a3, a4);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(b3.getId()));
		pw.markStart(pw.lookupCommit(c.getId()));
		pw.markStart(pw.lookupCommit(e.getId()));
		pw.markStart(pw.lookupCommit(a5.getId()));

		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		// test that the commits b1, b2 and b3 are on the same position
		int bPos = pcl.get(9).lane.position; // b1
		assertEquals("b2 is an a different position", bPos,
				pcl.get(7).lane.position);
		assertEquals("b3 is on a different position", bPos,
				pcl.get(4).lane.position);

		// test that nothing blocks the connections between b1, b2 and b3
		assertNotEquals("b lane is blocked by c", bPos,
				pcl.get(8).lane.position);
		assertNotEquals("b lane is blocked by a2", bPos,
				pcl.get(6).lane.position);
		assertNotEquals("b lane is blocked by d", bPos,
				pcl.get(5).lane.position);
	}

	/**
	 * <pre>
	 *    b3
	 * a4 |
	 * | \|
	 * |  b2
	 * a3 |
	 * | \|
	 * a2 |
	 * |  b1
	 * | /
	 * a1
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testMultipleMerges() throws Exception {
		final RevCommit a1 = commit();
		final RevCommit b1 = commit(a1);
		final RevCommit a2 = commit(a1);
		final RevCommit a3 = commit(a2, b1);
		final RevCommit b2 = commit(b1);
		final RevCommit a4 = commit(a3, b2);
		final RevCommit b3 = commit(b2);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a4));
		pw.markStart(pw.lookupCommit(b3));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> positions = asSet(0, 1);
		CommitListAssert test = new CommitListAssert(pcl);
		int posB = test.commit(b3).lanePos(positions).getLanePos();
		int posA = test.commit(a4).lanePos(positions).getLanePos();
		test.commit(b2).lanePos(posB);
		test.commit(a3).lanePos(posA);
		test.commit(a2).lanePos(posA);
		test.commit(b1).lanePos(posB);
		test.commit(a1).lanePos(posA);
		test.noMoreCommits();
	}

	/**
	 * <pre>
	 * a4
	 * |   b3
	 * a3  |
	 * | \\|
	 * |   |\\
	 * |   b2||
	 * a2  | //
	 * |   b1
	 * | /
	 * a1
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testMergeBlockedBySelf() throws Exception {
		final RevCommit a1 = commit();
		final RevCommit b1 = commit(a1);
		final RevCommit a2 = commit(a1);
		final RevCommit b2 = commit(b1); // blocks merging arc
		final RevCommit a3 = commit(a2, b1);
		final RevCommit b3 = commit(b2);
		final RevCommit a4 = commit(a3);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a4));
		pw.markStart(pw.lookupCommit(b3));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> positions = asSet(0, 1);
		CommitListAssert test = new CommitListAssert(pcl);
		int posA = test.commit(a4).lanePos(positions).getLanePos();
		int posB = test.commit(b3).lanePos(positions).getLanePos();
		test.commit(a3).lanePos(posA);
		test.commit(b2).lanePos(posB);
		test.commit(a2).lanePos(posA);
		// b1 is not repositioned, uses "detour lane"
		// (drawn as a double arc in the ascii graph above)
		test.commit(b1).lanePos(posB);
		test.commit(a1).lanePos(posA);
		test.noMoreCommits();
	}

	/**
	 * <pre>
	 *      b2
	 * a4   |
	 * |  \ |
	 * a3  \|
	 * | \  |
	 * |  c |
	 * | /  |
	 * a2   |
	 * |    b1
	 *     /
	 * |  /
	 * a1
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testMergeBlockedByOther() throws Exception {
		final RevCommit a1 = commit();
		final RevCommit b1 = commit(a1);
		final RevCommit a2 = commit(a1);
		final RevCommit c = commit(a2);// blocks merging arc
		final RevCommit a3 = commit(a2, c);
		final RevCommit a4 = commit(a3, b1);
		final RevCommit b2 = commit(b1);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a4));
		pw.markStart(pw.lookupCommit(b2));
		pw.markStart(pw.lookupCommit(c));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		Set<Integer> positions = asSet(0, 1, 2);
		CommitListAssert test = new CommitListAssert(pcl);
		int posB = test.commit(b2).lanePos(positions).getLanePos();
		int posA = test.commit(a4).lanePos(positions).getLanePos();
		test.commit(a3).lanePos(posA);
		test.commit(c).lanePos(positions);
		test.commit(a2).lanePos(posA);
		test.commit(b1).lanePos(posB); // repositioned to go around c
		test.commit(a1).lanePos(posA);
		test.noMoreCommits();
	}

	/**
	 * <pre>
	 *     b1
	 * a3  |
	 * |   |
	 * a2  |
	 * -- processing stops here --
	 * |  /
	 * a1
	 * </pre>
	 *
	 * @throws Exception
	 */
	@Test
	public void testDanglingCommitShouldContinueLane() throws Exception {
		final RevCommit a1 = commit();
		final RevCommit a2 = commit(a1);
		final RevCommit a3 = commit(a2);
		final RevCommit b1 = commit(a1);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a3));
		pw.markStart(pw.lookupCommit(b1));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(2); // don't process a1

		Set<Integer> positions = asSet(0, 1);
		CommitListAssert test = new CommitListAssert(pcl);
		PlotLane laneB = test.commit(b1).lanePos(positions).current.getLane();
		int posA = test.commit(a3).lanePos(positions).getLanePos();
		test.commit(a2).lanePos(posA);
		assertArrayEquals(
				"Although the parent of b1, a1, is not processed yet, the b lane should still be drawn",
				new PlotLane[] { laneB }, test.current.passingLanes);
		test.noMoreCommits();
	}

	@Test
	public void testTwoRoots1() throws Exception {
		final RevCommit a = commit();
		final RevCommit b = commit();

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a));
		pw.markStart(pw.lookupCommit(b));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(b).lanePos(0);
		test.commit(a).lanePos(0);
		test.noMoreCommits();
	}

	@Test
	public void testTwoRoots2() throws Exception {
		final RevCommit a = commit();
		final RevCommit b1 = commit();
		final RevCommit b2 = commit(b1);

		PlotWalk pw = new PlotWalk(db);
		pw.markStart(pw.lookupCommit(a));
		pw.markStart(pw.lookupCommit(b2));
		PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
		pcl.source(pw);
		pcl.fillTo(Integer.MAX_VALUE);

		CommitListAssert test = new CommitListAssert(pcl);
		test.commit(b2).lanePos(0);
		test.commit(b1).lanePos(0);
		test.commit(a).lanePos(0);
		test.noMoreCommits();
	}
}
