/*******************************************************************************
 * Copyright (c) 2003, 2018 IBM Corporation 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:
 *     IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.core.tests.runtime.jobs;

import java.util.*;
import java.util.concurrent.Semaphore;
import junit.framework.AssertionFailedError;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.core.tests.harness.*;

/**
 * Tests the API of the class IJobManager
 */
public class IJobManagerTest extends AbstractJobManagerTest {
	class TestJobListener extends JobChangeAdapter {
		private Set<Job> scheduled = Collections.synchronizedSet(new HashSet<Job>());

		public void cancelAllJobs() {
			Job[] jobs = scheduled.toArray(new Job[0]);
			for (Job job : jobs) {
				job.cancel();
			}
		}

		@Override
		public void done(IJobChangeEvent event) {
			synchronized (IJobManagerTest.this) {
				if (scheduled.remove(event.getJob())) {
					//wake up the waitForCompletion method
					completedJobs++;
					IJobManagerTest.this.notify();
				}
			}
		}

		@Override
		public void scheduled(IJobChangeEvent event) {
			Job job = event.getJob();
			synchronized (IJobManagerTest.this) {
				if (job instanceof TestJob) {
					scheduledJobs++;
					scheduled.add(job);
				}
			}
		}
	}

	/**
	 * Tests that are timing sensitive cannot be released in automated tests.
	 * Set this flag to true to do manual timing sanity tests
	 */
	private static final boolean PEDANTIC = false;

	protected int completedJobs;
	private IJobChangeListener[] jobListeners;

	protected int scheduledJobs;

	public IJobManagerTest() {
		super("");
	}

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

	/**
	 * Asserts the current job state
	 */
	public void assertState(String msg, Job job, int expectedState) {
		int actualState = job.getState();
		if (actualState != expectedState) {
			assertTrue(msg + ": expected state: " + printState(expectedState) + " actual state: " + printState(actualState), false);
		}
	}

	/**
	 * Cancels a list of jobs
	 */
	protected void cancel(ArrayList<Job> jobs) {
		for (Job job : jobs) {
			job.cancel();
		}
	}

	private String printState(int state) {
		switch (state) {
			case Job.NONE :
				return "NONE";
			case Job.WAITING :
				return "WAITING";
			case Job.SLEEPING :
				return "SLEEPING";
			case Job.RUNNING :
				return "RUNNING";
		}
		return "UNKNOWN";
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();
		completedJobs = 0;
		scheduledJobs = 0;
		jobListeners = new IJobChangeListener[] {/* new VerboseJobListener(),*/
		new TestJobListener()};
		for (IJobChangeListener jobListener : jobListeners) {
			manager.addJobChangeListener(jobListener);
		}
	}

	@Override
	protected void tearDown() throws Exception {
		for (IJobChangeListener jobListener : jobListeners) {
			if (jobListener instanceof TestJobListener) {
				((TestJobListener) jobListener).cancelAllJobs();
			}
		}
		waitForCompletion();
		for (IJobChangeListener jobListener : jobListeners) {
			manager.removeJobChangeListener(jobListener);
		}
		super.tearDown();
		//		manager.startup();
	}

	public void testBadGlobalListener() {
		final int[] status = new int[] {-1};
		Job job = new Job("testBadGlobalListener") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				status[0] = TestBarrier.STATUS_RUNNING;
				return Status.OK_STATUS;
			}
		};
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void running(IJobChangeEvent event) {
				throw new Error("Thrown from bad global listener");
			}
		};
		try {
			Job.getJobManager().addJobChangeListener(listener);
			job.schedule();
			TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
		} finally {
			Job.getJobManager().removeJobChangeListener(listener);
		}
	}

	public void testBadLocalListener() {
		final int[] status = new int[] {-1};
		Job job = new Job("testBadLocalListener") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				status[0] = TestBarrier.STATUS_RUNNING;
				return Status.OK_STATUS;
			}
		};
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void running(IJobChangeEvent event) {
				throw new Error("Thrown from bad local listener");
			}
		};
		try {
			job.addJobChangeListener(listener);
			job.schedule();
			TestBarrier.waitForStatus(status, TestBarrier.STATUS_RUNNING);
		} finally {
			job.removeJobChangeListener(listener);
		}
	}

	public void testBeginInvalidNestedRules() {
		final ISchedulingRule root = new PathRule("/");
		final ISchedulingRule invalid = new ISchedulingRule() {
			@Override
			public boolean isConflicting(ISchedulingRule rule) {
				return this == rule;
			}

			@Override
			public boolean contains(ISchedulingRule rule) {
				return this == rule || root.contains(rule);
			}
		};
		try {
			Job.getJobManager().beginRule(invalid, null);
			try {
				Job.getJobManager().beginRule(root, null);
				fail("1.0");
			} catch (IllegalArgumentException e) {
				// expected
			} finally {
				Job.getJobManager().endRule(root);
			}
		} finally {
			Job.getJobManager().endRule(invalid);
		}
	}

	/**
	 * Tests that if we call beginRule with a monitor that has already been
	 * cancelled, it won't try to obtain the rule.
	 */
	public void testCancellationPriorToBeginRuleWontHoldRule() throws Exception {
		final Semaphore mainThreadSemaphore = new Semaphore(0);
		final Semaphore lockSemaphore = new Semaphore(0);
		final PathRule rule = new PathRule("testBeginRuleNoEnd");
		IProgressMonitor cancelledMonitor = SubMonitor.convert(null);
		cancelledMonitor.setCanceled(true);

		// Create a job that will hold the lock until the semaphore is signaled
		Job job = Job.create("", monitor -> {
			mainThreadSemaphore.release();
			try {
				lockSemaphore.acquire();
			} catch (InterruptedException e) {
			}
		});
		job.setRule(rule);
		job.schedule();

		// Block until the job acquires the lock
		mainThreadSemaphore.acquire();
		boolean canceledExceptionThrown = false;
		try {
			// This will deadlock if it attempts to acquire the rule, and will
			// throw an OCE without doing anything if it is working correctly.
			manager.beginRule(rule, cancelledMonitor);
		} catch (OperationCanceledException e) {
			canceledExceptionThrown = true;
		} finally {
			// Code which follows the recommended pattern documented in
			// beginRule will call endRule even if beginRule threw an OCE.
			// Verify that calling endRule in this situation won't throw any
			// exceptions.
			manager.endRule(rule);
		}
		lockSemaphore.release();
		boolean interrupted = Thread.interrupted();
		assertTrue("An OperationCancelledException should have been thrown", canceledExceptionThrown);
		assertFalse("The Thread.interrupted() state leaked", interrupted);
	}

	/**
	 * Tests that if our monitor is cancelled while we're waiting on beginRule,
	 * it will stop waiting, will throw an {@link OperationCanceledException},
	 * and will clear the Thread.interrupted() flag.
	 */
	public void testCancellationWhileWaitingOnRule() throws Exception {
		final Semaphore mainThreadSemaphore = new Semaphore(0);
		final Semaphore lockSemaphore = new Semaphore(0);
		final PathRule rule = new PathRule("testBeginRuleNoEnd");
		final NullProgressMonitor rootMonitor = new NullProgressMonitor();
		// We use a SubMonitor here to work around a special case in the
		// JobManager code that ignores NullProgressMonitor.
		IProgressMonitor nestedMonitor = SubMonitor.convert(rootMonitor);
		nestedMonitor.setCanceled(false);

		// Create a job that will hold the lock until the semaphore is signalled
		Job job = Job.create("", monitor -> {
			mainThreadSemaphore.release();
			try {
				lockSemaphore.acquire();
			} catch (InterruptedException e) {
			}
		});
		job.setRule(rule);
		job.schedule();

		// Block until the job acquires the lock
		mainThreadSemaphore.acquire();

		// Create a job that will cancel our monitor in 100ms
		Job cancellationJob = Job.create("", monitor -> {
			rootMonitor.setCanceled(true);
		});
		cancellationJob.schedule(100);

		boolean canceledExceptionThrown = false;
		// Now try to obtain the rule that is currently held by "job".
		try {
			manager.beginRule(rule, nestedMonitor);
		} catch (OperationCanceledException e) {
			canceledExceptionThrown = true;
		} finally {
			// Code which follows the recommended pattern documented in
			// beginRule will call endRule even if beginRule threw an OCE.
			// Verify that calling endRule in this situation won't throw any
			// exceptions.
			manager.endRule(rule);
		}
		lockSemaphore.release();
		boolean interrupted = Thread.interrupted();
		assertTrue("An OperationCancelledException should have been thrown", canceledExceptionThrown);
		assertFalse("The THread.interrupted() state leaked", interrupted);
	}

	/**
	 * Tests running a job that begins a rule but never ends it
	 */
	public void testBeginRuleNoEnd() {
		final PathRule rule = new PathRule("testBeginRuleNoEnd");
		Job job = new Job("testBeginRuleNoEnd") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				monitor.beginTask(getName(), 1);
				try {
					Job.getJobManager().beginRule(rule, null);
					monitor.worked(1);
				} finally {
					monitor.done();
				}
				return Status.OK_STATUS;
			}
		};
		job.schedule();
		try {
			job.join();
		} catch (InterruptedException e) {
			fail("4.99", e);
		}
		//another thread should be able to access the rule now
		try {
			manager.beginRule(rule, null);
		} finally {
			manager.endRule(rule);
		}
	}

	public void testBug48073() {
		ISchedulingRule ruleA = new PathRule("/testBug48073");
		ISchedulingRule ruleB = new PathRule("/testBug48073/B");
		ISchedulingRule ruleC = new PathRule("/testBug48073/C");
		TestJob jobA = new TestJob("Job1", 1000, 100);
		TestJob jobB = new TestJob("Job2", 1000, 100);
		TestJob jobC = new TestJob("Job3", 1000, 100);
		jobA.setRule(ruleA);
		jobB.setRule(ruleB);
		jobC.setRule(ruleC);

		//B should be running, A blocked by B and C blocked by A
		jobB.schedule();
		sleep(100);
		jobA.schedule();
		sleep(100);
		jobC.schedule();

		//cancel and restart A
		jobA.cancel();
		jobA.schedule();

		//cancel all jobs
		jobA.cancel();
		jobC.cancel();
		jobB.cancel();
	}

	/**
	 * Regression test for bug 57656
	 */
	public void testBug57656() {
		TestJob jobA = new TestJob("Job1");
		TestJob jobB = new TestJob("Job2");
		//schedule jobA
		jobA.schedule(5000);
		//schedule jobB so it gets behind jobA in the queue
		jobB.schedule(10000);
		//now put jobA to sleep indefinitely
		jobA.sleep();
		//jobB should still run within ten seconds
		waitForCompletion(jobB, 30000);
	}

	/**
	 * This is a regression test for bug 71448. IJobManager.currentJob was not
	 * returning the correct value when executed in a thread that is performing
	 * asynchronous completion of a job (i.e., a UI Job)
	 */
	public void testCurrentJob() {
		final Thread[] thread = new Thread[1];
		final boolean[] done = new boolean[] {false};
		final boolean[] success = new boolean[] {false};
		//create a job that will complete asynchronously
		final Job job = new Job("Test Job") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				setThread(thread[0]);
				done[0] = true;
				return ASYNC_FINISH;
			}
		};
		//create and run a thread that will run and finish the asynchronous job
		Runnable r = () -> {
			job.schedule();
			// wait for job to start running
			while (!done[0]) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// ignore
				}
			}
			// job should now be finishing asynchronously in this thread
			success[0] = job == Job.getJobManager().currentJob();
			job.done(Status.OK_STATUS);
		};
		thread[0] = new Thread(r);
		thread[0].start();
		try {
			thread[0].join();
		} catch (InterruptedException e) {
			//ignore
		}
		//assert that currentJob returned the correct value
		assertTrue("1.0", success[0]);
	}

	/**
	 * Tests for {@link IJobManager#currentRule()}.
	 */
	public void testCurrentRule() {
		//first test when not running in a job
		runRuleSequence();

		//next test in a job with no rule of its own
		final List<AssertionFailedError> errors = new ArrayList<>();
		Job sequenceJob = new Job("testCurrentRule") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					runRuleSequence();
				} catch (AssertionFailedError e) {
					errors.add(e);
				}
				return Status.OK_STATUS;
			}
		};
		sequenceJob.schedule();
		waitForCompletion(sequenceJob);
		if (!errors.isEmpty()) {
			throw errors.iterator().next();
		}

		//now test in a job that has a scheduling rule
		ISchedulingRule jobRule = new PathRule("/testCurrentRule");
		sequenceJob.setRule(jobRule);
		sequenceJob.schedule();
		waitForCompletion(sequenceJob);
		if (!errors.isEmpty()) {
			throw errors.iterator().next();
		}

	}

	/**
	 * Helper method for testing {@link IJobManager#currentRule()}.
	 */
	protected void runRuleSequence() {
		if (runRuleSequenceInJobWithRule()) {
			return;
		}
		ISchedulingRule parent = new PathRule("/testCurrentRule/parent");
		ISchedulingRule child = new PathRule("/testCurrentRule/parent/child");
		assertNull(manager.currentRule());
		manager.beginRule(null, null);
		assertNull(manager.currentRule());
		manager.endRule(null);
		assertNull(manager.currentRule());
		manager.beginRule(parent, null);
		assertEquals(parent, manager.currentRule());
		//nested null rule
		manager.beginRule(null, null);
		assertEquals(parent, manager.currentRule());
		//nested non-null rule
		manager.beginRule(child, null);
		assertEquals(parent, manager.currentRule());
		manager.endRule(child);
		assertEquals(parent, manager.currentRule());
		manager.endRule(null);
		assertEquals(parent, manager.currentRule());
		manager.endRule(parent);
		assertNull(manager.currentRule());
	}

	/**
	 * Runs a sequence of begin/end rules and asserts that the
	 * job rule is always returned by {@link IJobManager#currentRule()}.
	 * Returns <code>false</code> if not invoked from within a job with
	 * a scheduling rule.
	 */
	private boolean runRuleSequenceInJobWithRule() {
		Job currentJob = manager.currentJob();
		if (currentJob == null) {
			return false;
		}
		ISchedulingRule jobRule = currentJob.getRule();
		if (jobRule == null) {
			return false;
		}
		//we are in a job with a rule, so now run our rule sequence
		ISchedulingRule parent = new PathRule("/testCurrentRule/parent");
		ISchedulingRule child = new PathRule("/testCurrentRule/parent/child");
		assertEquals(jobRule, manager.currentRule());
		manager.beginRule(null, null);
		assertEquals(jobRule, manager.currentRule());
		manager.endRule(null);
		assertEquals(jobRule, manager.currentRule());
		manager.beginRule(parent, null);
		assertEquals(jobRule, manager.currentRule());
		//nested null rule
		manager.beginRule(null, null);
		assertEquals(jobRule, manager.currentRule());
		//nested non-null rule
		manager.beginRule(child, null);
		assertEquals(jobRule, manager.currentRule());
		manager.endRule(child);
		assertEquals(jobRule, manager.currentRule());
		manager.endRule(null);
		assertEquals(jobRule, manager.currentRule());
		manager.endRule(parent);
		assertEquals(jobRule, manager.currentRule());
		return true;
	}

	public void testDelayedJob() {
		//schedule a delayed job and ensure it doesn't start until instructed
		int[] sleepTimes = new int[] {0, 10, 50, 100, 500, 1000, 2000, 2500};
		for (int i = 0; i < sleepTimes.length; i++) {
			long start = now();
			TestJob job = new TestJob("Noop", 0, 0);
			assertEquals("1.0", 0, job.getRunCount());
			job.schedule(sleepTimes[i]);
			waitForCompletion();
			assertEquals("1.1." + i, 1, job.getRunCount());
			long duration = now() - start;
			assertTrue("1.2: duration: " + duration + " sleep: " + sleepTimes[i], duration >= sleepTimes[i]);
			//a no-op job shouldn't take any real time
			if (PEDANTIC) {
				assertTrue("1.3: duration: " + duration + " sleep: " + sleepTimes[i], duration < sleepTimes[i] + 1000);
			}
		}
	}

	public void testJobFamilyCancel() {
		//test the cancellation of a family of jobs
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create two different families of jobs
		TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need a scheduling rule so that the jobs would be executed one by one
		ISchedulingRule rule = new IdentityRule();

		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
			} else {
				/*if(i%2 == 1)*/
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
			}
			jobs[i].setRule(rule);
			jobs[i].schedule();
		}

		waitForStart(jobs[0]);

		assertState("1.0", jobs[0], Job.RUNNING);

		//first job is running, the rest are waiting
		for (int i = 1; i < NUM_JOBS; i++) {
			assertState("1." + i, jobs[i], Job.WAITING);
		}

		//cancel the first family of jobs
		manager.cancel(first);
		waitForFamilyCancel(jobs, first);

		//the previously running job should have no state
		assertState("2.0", jobs[0], Job.NONE);
		//the first job from the second family should now be running
		waitForStart(jobs[1]);

		for (int i = 2; i < NUM_JOBS; i++) {
			//all other jobs in the first family should be removed from the waiting queue
			//no operations can be performed on these jobs until they are scheduled with the manager again
			if (jobs[i].belongsTo(first)) {
				assertState("2." + i, jobs[i], Job.NONE);
				jobs[i].wakeUp();
				assertState("2." + i, jobs[i], Job.NONE);
				jobs[i].sleep();
				assertState("2." + i, jobs[i], Job.NONE);
			}
			//all other jobs in the second family should still be in the waiting queue
			else {
				assertState("3." + i, jobs[i], Job.WAITING);
			}
		}

		for (int i = 2; i < NUM_JOBS; i++) {
			//all the jobs in the second family that are waiting to start can now be set to sleep
			if (jobs[i].belongsTo(second)) {
				assertState("4." + i, jobs[i], Job.WAITING);
				assertTrue("5." + i, jobs[i].sleep());
				assertState("6." + i, jobs[i], Job.SLEEPING);
			}
		}
		//cancel the second family of jobs
		manager.cancel(second);
		waitForFamilyCancel(jobs, second);

		//the second job should now have no state
		assertState("7.0", jobs[1], Job.NONE);

		for (int i = 0; i < NUM_JOBS; i++) {
			//all jobs should now be in the NONE state
			assertState("8." + i, jobs[i], Job.NONE);
		}
	}

	public void testJobFamilyFind() {
		//test of finding jobs based on the job family they belong to
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create five different families of jobs
		TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		TestJobFamily third = new TestJobFamily(TestJobFamily.TYPE_THREE);
		TestJobFamily fourth = new TestJobFamily(TestJobFamily.TYPE_FOUR);
		TestJobFamily fifth = new TestJobFamily(TestJobFamily.TYPE_FIVE);

		//need a scheduling rule so that the jobs would be executed one by one
		ISchedulingRule rule = new IdentityRule();

		for (int i = 0; i < NUM_JOBS; i++) {
			//assign four jobs to each family
			switch (i % 5) {
			case 0:
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
				break;
			case 1:
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
				break;
			case 2:
				jobs[i] = new FamilyTestJob("TestThirdFamily", 1000000, 10, TestJobFamily.TYPE_THREE);
				break;
			case 3:
				jobs[i] = new FamilyTestJob("TestFourthFamily", 1000000, 10, TestJobFamily.TYPE_FOUR);
				break;
			default:
				/*if(i%5 == 4)*/
				jobs[i] = new FamilyTestJob("TestFifthFamily", 1000000, 10, TestJobFamily.TYPE_FIVE);
				break;
			}

			jobs[i].setRule(rule);
			jobs[i].schedule();
		}

		waitForStart(jobs[0]);

		//try finding all jobs by supplying the NULL parameter
		//note that this might find other jobs that are running as a side-effect of the test
		//suites running, such as snapshot
		HashSet<Job> allJobs = new HashSet<>();
		allJobs.addAll(Arrays.asList(jobs));
		Job[] result = manager.find(null);
		assertTrue("1.0", result.length >= NUM_JOBS);
		for (int i = 0; i < result.length; i++) {
			//only test jobs that we know about
			if (allJobs.remove(result[i])) {
				assertTrue("1." + i, (result[i].belongsTo(first) || result[i].belongsTo(second) || result[i].belongsTo(third) || result[i].belongsTo(fourth) || result[i].belongsTo(fifth)));
			}
		}
		assertEquals("1.2", 0, allJobs.size());

		//try finding all jobs from the first family
		result = manager.find(first);
		assertTrue("2.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("2." + (i + 1), result[i].belongsTo(first));
		}

		//try finding all jobs from the second family
		result = manager.find(second);
		assertTrue("3.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("3." + (i + 1), result[i].belongsTo(second));
		}

		//try finding all jobs from the third family
		result = manager.find(third);
		assertTrue("4.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("4." + (i + 1), result[i].belongsTo(third));
		}

		//try finding all jobs from the fourth family
		result = manager.find(fourth);
		assertTrue("5.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("5." + (i + 1), result[i].belongsTo(fourth));
		}

		//try finding all jobs from the fifth family
		result = manager.find(fifth);
		assertTrue("6.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("6." + (i + 1), result[i].belongsTo(fifth));
		}

		//the first job should still be running
		assertState("7.0", jobs[0], Job.RUNNING);

		//put the second family of jobs to sleep
		manager.sleep(second);

		//cancel the first family of jobs
		manager.cancel(first);

		//the third job should start running
		waitForStart(jobs[2]);
		assertState("7.1", jobs[2], Job.RUNNING);

		//finding all jobs from the first family should return an empty array
		result = manager.find(first);
		assertEquals("7.2", 0, result.length);

		//finding all jobs from the second family should return all the jobs (they are just sleeping)
		result = manager.find(second);
		assertTrue("8.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("8." + (i + 1), result[i].belongsTo(second));
		}

		//cancel the second family of jobs
		manager.cancel(second);
		//finding all jobs from the second family should now return an empty array
		result = manager.find(second);
		assertEquals("9.0", 0, result.length);

		//cancel the fourth family of jobs
		manager.cancel(fourth);
		//finding all jobs from the fourth family should now return an empty array
		result = manager.find(fourth);
		assertEquals("9.1", 0, result.length);

		//put the third family of jobs to sleep
		manager.sleep(third);
		//the first job from the third family should still be running
		assertState("9.2", jobs[2], Job.RUNNING);
		//wake up the last job from the third family
		jobs[NUM_JOBS - 3].wakeUp();
		//it should now be in the WAITING state
		assertState("9.3", jobs[NUM_JOBS - 3], Job.WAITING);

		//finding all jobs from the third family should return all 4 jobs (1 is running, 1 is waiting, 2 are sleeping)
		result = manager.find(third);
		assertTrue("10.0", result.length == 4);
		for (int i = 0; i < result.length; i++) {
			assertTrue("10." + (i + 1), result[i].belongsTo(third));
		}

		//finding all jobs by supplying the NULL parameter should return 8 jobs (4 from the 3rd family, and 4 from the 5th family)
		//note that this might find other jobs that are running as a side-effect of the test
		//suites running, such as snapshot
		allJobs.addAll(Arrays.asList(jobs));
		result = manager.find(null);
		assertTrue("11.0", result.length >= 8);
		for (int i = 0; i < result.length; i++) {
			//only test jobs that we know about
			if (allJobs.remove(result[i])) {
				assertTrue("11." + (i + 1), (result[i].belongsTo(third) || result[i].belongsTo(fifth)));
			}
		}

		assertEquals("11.2", 12, allJobs.size());
		allJobs.clear();

		//cancel the fifth family of jobs
		manager.cancel(fifth);
		//cancel the third family of jobs
		manager.cancel(third);
		waitForFamilyCancel(jobs, third);

		//all jobs should now be in the NONE state
		for (int i = 0; i < NUM_JOBS; i++) {
			assertState("12." + i, jobs[i], Job.NONE);
		}

		//finding all jobs should return an empty array
		//note that this might find other jobs that are running as a side-effect of the test
		//suites running, such as snapshot
		allJobs.addAll(Arrays.asList(jobs));
		result = manager.find(null);
		assertTrue("13.0", result.length >= 0);

		for (int i = 0; i < result.length; i++) {
			//test jobs that we know about should not be found (they should have all been removed)
			if (allJobs.remove(result[i])) {
				assertTrue("14." + i, false);
			}
		}
		assertEquals("15.0", NUM_JOBS, allJobs.size());
		allJobs.clear();
	}

	public void testJobFamilyJoin() {
		//test the join method on a family of jobs
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		final int NUM_JOBS = 20;
		Job[] jobs = new Job[NUM_JOBS];
		//create two different families of jobs
		final TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need two scheduling rule so that jobs in each family would be executing one by one
		ISchedulingRule rule1 = new IdentityRule();
		ISchedulingRule rule2 = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 10, 10, TestJobFamily.TYPE_ONE);
				jobs[i].setRule(rule1);
				jobs[i].schedule(1000000);
			} else /*if(i%2 == 1)*/{
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
				jobs[i].setRule(rule2);
				jobs[i].schedule();
			}

		}

		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_RUN);
				status[0] = TestBarrier.STATUS_RUNNING;
				manager.join(first, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		//start the thread that will join the first family of jobs and be blocked until they finish execution
		t.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
		//wake up the first family of jobs
		manager.wakeUp(first);

		int i = 0;
		for (; i < 100; i++) {
			int currentStatus = status[0];
			Job[] result = manager.find(first);

			//if the thread is complete then all jobs must be done
			if (currentStatus == TestBarrier.STATUS_DONE) {
				assertTrue("2." + i, result.length == 0);
				break;
			}
			sleep(100);
		}
		assertTrue("2.0", i < 100);

		//cancel the second family of jobs
		manager.cancel(second);
		waitForFamilyCancel(jobs, second);

		//all the jobs should now be in the NONE state
		for (int j = 0; j < NUM_JOBS; j++) {
			assertState("3." + j, jobs[j], Job.NONE);
		}
	}

	public void testJobFamilyJoinCancelJobs() {
		//test the join method on a family of jobs, then cancel the jobs that are blocking the join call
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create two different families of jobs
		final TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need two scheduling rule so that jobs in each family would be executing one by one
		ISchedulingRule rule1 = new IdentityRule();
		ISchedulingRule rule2 = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
				jobs[i].setRule(rule1);
			} else /*if(i%2 == 1)*/{
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
				jobs[i].setRule(rule2);
			}
			jobs[i].schedule();

		}

		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_RUN);
				status[0] = TestBarrier.STATUS_RUNNING;
				manager.join(first, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		//start the thread that will join the first family of jobs
		//it will be blocked until the all jobs in the first family finish execution or are canceled
		t.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
		waitForStart(jobs[0]);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);

		assertState("2.0", jobs[0], Job.RUNNING);
		assertTrue("2.1", status[0] == TestBarrier.STATUS_RUNNING);

		//cancel the first family of jobs
		//the join call should be unblocked when all the jobs are canceled
		manager.cancel(first);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);

		//all jobs in the first family should be removed from the manager
		assertTrue("2.2", manager.find(first).length == 0);

		//cancel the second family of jobs
		manager.cancel(second);
		waitForFamilyCancel(jobs, second);

		//all the jobs should now be in the NONE state
		for (int j = 0; j < NUM_JOBS; j++) {
			assertState("3." + j, jobs[j], Job.NONE);
		}
	}

	public void testJobFamilyJoinCancelManager() {
		//test the join method on a family of jobs, then cancel the call
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create a progress monitor to cancel the join call
		final IProgressMonitor canceller = new FussyProgressMonitor();
		//create two different families of jobs
		final TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need two scheduling rule so that jobs in each family would be executing one by one
		ISchedulingRule rule1 = new IdentityRule();
		ISchedulingRule rule2 = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
				jobs[i].setRule(rule1);
			} else /*if(i%2 == 1)*/{
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
				jobs[i].setRule(rule2);
			}
			jobs[i].schedule();

		}

		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_RUN);
				status[0] = TestBarrier.STATUS_RUNNING;
				manager.join(first, canceller);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		//start the thread that will join the first family of jobs
		//it will be blocked until the cancel call is made to the thread
		t.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
		waitForStart(jobs[0]);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_RUNNING);

		assertState("2.0", jobs[0], Job.RUNNING);
		assertTrue("2.1", status[0] == TestBarrier.STATUS_RUNNING);

		//cancel the monitor that is attached to the join call
		canceller.setCanceled(true);
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);

		//the first job in the first family should still be running
		assertState("2.2", jobs[0], Job.RUNNING);
		assertTrue("2.3", status[0] == TestBarrier.STATUS_DONE);
		assertTrue("2.4", manager.find(first).length > 0);

		//cancel the second family of jobs
		manager.cancel(second);
		waitForFamilyCancel(jobs, second);

		//cancel the first family of jobs
		manager.cancel(first);
		waitForFamilyCancel(jobs, first);

		//all the jobs should now be in the NONE state
		for (int j = 0; j < NUM_JOBS; j++) {
			assertState("3." + j, jobs[j], Job.NONE);
		}
	}

	/**
	 * Asserts that the LockListener is called correctly during invocation of
	 * {@link IJobManager#join(Object, IProgressMonitor)}.
	 * See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=195839.
	 */
	public void testJobFamilyJoinLockListener() {
		final TestJobFamily family = new TestJobFamily(TestJobFamily.TYPE_ONE);
		int count = 5;
		Job[] jobs = new Job[count];
		for (int i = 0; i < jobs.length; i++) {
			jobs[i] = new FamilyTestJob("TestJobFamilyJoinLockListener" + i, 5, 500, family.getType());
			jobs[i].schedule();
		}
		TestLockListener lockListener = new TestLockListener();
		try {
			manager.setLockListener(lockListener);
			manager.join(family, new FussyProgressMonitor());
		} catch (OperationCanceledException | InterruptedException e) {
			fail("4.99", e);
		} finally {
			manager.setLockListener(null);
		}
		lockListener.assertNotWaiting("1.0");
	}

	public void testJobFamilyJoinNothing() {
		//test joining a bogus family, and the monitor should be used up
		try {
			final FussyProgressMonitor monitor = new FussyProgressMonitor();
			monitor.prepare();
			manager.join(new Object(), monitor);
			monitor.sanityCheck();
			monitor.assertUsedUp();
		} catch (OperationCanceledException | InterruptedException e) {
			fail("4.99", e);
		}
	}

	/**
	 * Tests joining a job that repeats in a loop
	 */
	public void testJobFamilyJoinRepeating() {
		Object family = new Object();
		int count = 25;
		RepeatingJob job = new RepeatingJob("testJobFamilyJoinRepeating", count);
		job.setFamily(family);
		job.schedule();
		try {
			Job.getJobManager().join(family, null);
		} catch (OperationCanceledException e) {
			fail("1.0", e);
		} catch (InterruptedException e) {
			fail("1.1", e);
		}
		//ensure the job has run the expected number of times
		assertEquals("1.2", count, job.getRunCount());
	}

	/**
	 * Tests joining a job family that repeats but returns false to shouldSchedule
	 */
	public void testJobFamilyJoinShouldSchedule() {
		Object family = new Object();
		final int count = 1;
		RepeatingJob job = new RepeatingJob("testJobFamilyJoinShouldSchedule", count) {
			@Override
			public boolean shouldSchedule() {
				return shouldRun();
			}
		};
		job.setFamily(family);
		job.schedule();
		try {
			Job.getJobManager().join(family, null);
		} catch (OperationCanceledException e) {
			fail("1.0", e);
		} catch (InterruptedException e) {
			fail("1.1", e);
		}
		//ensure the job has run the expected number of times
		assertEquals("1.2", count, job.getRunCount());
	}

	/**
	 * Tests simple usage of the IJobManager.join() method.
	 */
	public void testJobFamilyJoinSimple() {
		//test the join method on a family of jobs that is empty
		final int[] status = new int[1];
		status[0] = TestBarrier.STATUS_WAIT_FOR_START;
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create three different families of jobs
		final TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		final TestJobFamily third = new TestJobFamily(TestJobFamily.TYPE_THREE);
		//need two scheduling rule so that jobs in each family would be executing one by one
		ISchedulingRule rule1 = new IdentityRule();
		ISchedulingRule rule2 = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
				jobs[i].setRule(rule1);
			} else /*if(i%2 == 1)*/{
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
				jobs[i].setRule(rule2);
			}

			jobs[i].schedule();
		}

		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_WAIT_FOR_RUN);
				status[0] = TestBarrier.STATUS_RUNNING;
				manager.join(third, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		//try joining the third family of jobs, which is empty
		//join method should return without blocking
		waitForStart(jobs[0]);
		t.start();

		//let the thread execute the join call
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		assertTrue("1.0", status[0] == TestBarrier.STATUS_START);
		long startTime = now();
		status[0] = TestBarrier.STATUS_WAIT_FOR_RUN;
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);
		long endTime = now();

		assertTrue("2.0", status[0] == TestBarrier.STATUS_DONE);
		assertTrue("2.1", endTime > startTime);

		//the join call should take no actual time (join call should not block thread at all)
		if (PEDANTIC) {
			assertTrue("2.2 start time: " + startTime + " end time: " + endTime, (endTime - startTime) < 300);
		}

		//cancel all jobs
		manager.cancel(first);
		manager.cancel(second);
		waitForFamilyCancel(jobs, first);
		waitForFamilyCancel(jobs, second);

		//all the jobs should now be in the NONE state
		for (int j = 0; j < NUM_JOBS; j++) {
			assertState("3." + j, jobs[j], Job.NONE);
		}
	}

	/**
	 * Tests scenario 1 described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=403271#c0:
	 *  - join is called when job manager is suspended
	 *  - waiting job is scheduled when job manager is suspended
	 * In this scenario main job should not wait for the waiting job.
	 */
	public void testJobFamilyJoinWhenSuspended_1() throws InterruptedException {
		final Object family = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final int[] familyJobsCount = new int[] {-1};
		final TestBarrier barrier = new TestBarrier();
		final Job waiting = new FamilyTestJob("waiting job", 1000000, 10, TestJobFamily.TYPE_ONE);
		final Job running = new FamilyTestJob("running job", 200, 10, TestJobFamily.TYPE_ONE);
		final IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				}
			}

			@Override
			public void running(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.setStatus(TestBarrier.STATUS_RUNNING);
				}
			}
		};
		Job job = new Job("main job") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					manager.addJobChangeListener(listener);
					running.schedule();
					// wait until running job is actually running
					barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
					manager.setLockListener(new LockListener() {
						private boolean scheduled = false;

						@Override
						public boolean aboutToWait(Thread lockOwner) {
							// aboutToWait will be called when main job will start joining the running job
							if (!scheduled) {
								waiting.schedule();
								barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
							}
							return super.aboutToWait(lockOwner);
						}
					});
					// suspend before join
					manager.suspend();
					manager.join(family, null);
					familyJobsCount[0] = manager.find(family).length;
					barrier.setStatus(TestBarrier.STATUS_DONE);
				} catch (InterruptedException e) {
					// ignore
				} finally {
					// clean up
					manager.removeJobChangeListener(listener);
					manager.setLockListener(null);
					running.cancel();
					waiting.cancel();
					try {
						running.join();
						waiting.join();
					} catch (InterruptedException e) {
						// ignore
					}
					manager.resume();
				}
				return Status.OK_STATUS;
			}
		};
		try {
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			assertEquals(1, familyJobsCount[0]);
		} catch (AssertionFailedError e) {
			// interrupt to avoid deadlock and perform cleanup
			job.getThread().interrupt();
			// re-throw since the test failed
			throw e;
		} finally {
			// wait until cleanup is done
			job.join();
		}
	}

	/**
	 * Tests scenario 2 - verifies if the suspended flag is checked each time a job is scheduled:
	 *  - join is called when job manager is NOT suspended
	 *  - waiting job is scheduled when job manager is suspended
	 * In this scenario main job should not wait for the waiting job.
	 */
	public void testJobFamilyJoinWhenSuspended_2() throws InterruptedException {
		final Object family = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final int[] familyJobsCount = new int[] {-1};
		final TestBarrier barrier = new TestBarrier();
		final Job waiting = new FamilyTestJob("waiting job", 1000000, 10, TestJobFamily.TYPE_ONE);
		final Job running = new FamilyTestJob("running job", 200, 10, TestJobFamily.TYPE_ONE);
		final IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				}
			}

			@Override
			public void running(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.setStatus(TestBarrier.STATUS_RUNNING);
				}
			}
		};
		Job job = new Job("main job") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					manager.addJobChangeListener(listener);
					running.schedule();
					// wait until running job is actually running
					barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
					manager.setLockListener(new LockListener() {
						private boolean scheduled = false;

						@Override
						public boolean aboutToWait(Thread lockOwner) {
							// aboutToWait will be called when main job will start joining the running job
							if (!scheduled) {
								// suspend before scheduling new job
								getJobManager().suspend();
								waiting.schedule();
								barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
							}
							return super.aboutToWait(lockOwner);
						}
					});
					manager.join(family, null);
					familyJobsCount[0] = manager.find(family).length;
					barrier.setStatus(TestBarrier.STATUS_DONE);
				} catch (InterruptedException e) {
					// ignore
				} finally {
					// clean up
					manager.removeJobChangeListener(listener);
					manager.setLockListener(null);
					running.cancel();
					waiting.cancel();
					try {
						running.join();
						waiting.join();
					} catch (InterruptedException e) {
						// ignore
					}
					manager.resume();
				}
				return Status.OK_STATUS;
			}
		};
		try {
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			assertEquals(1, familyJobsCount[0]);
		} catch (AssertionFailedError e) {
			// interrupt to avoid deadlock and perform cleanup
			job.getThread().interrupt();
			// re-throw since the test failed
			throw e;
		} finally {
			// wait until cleanup is done
			job.join();
		}
	}

	/**
	 * Tests scenario 3:
	 *  - join is called when job manager is NOT suspended
	 *  - waiting job is scheduled when job manager is suspended
	 *  - job manager is resumed causing waiting job to start
	 * In this scenario main thread should wait for the waiting job since the job was started before the join ended.
	 */
	public void testJobFamilyJoinWhenSuspended_3() throws InterruptedException {
		final Object family = new TestJobFamily(TestJobFamily.TYPE_ONE);
		final TestBarrier barrier = new TestBarrier();
		final Job waiting = new FamilyTestJob("waiting job", 400, 10, TestJobFamily.TYPE_ONE);
		final Job running = new FamilyTestJob("running job", 200, 10, TestJobFamily.TYPE_ONE);
		final IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				}
			}

			@Override
			public void running(IJobChangeEvent event) {
				if (event.getJob() == running) {
					barrier.setStatus(TestBarrier.STATUS_RUNNING);
				} else if (event.getJob() == waiting) {
					barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				}
			}
		};
		try {
			manager.addJobChangeListener(listener);
			running.schedule();
			// wait until the running job is actually running
			barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
			manager.setLockListener(new LockListener() {
				private boolean scheduled = false;

				@Override
				public boolean aboutToWait(Thread lockOwner) {
					// aboutToWait will be called when main thread will start joining the running job
					if (!scheduled) {
						// suspend before scheduling the waiting job
						manager.suspend();
						waiting.schedule();
						// resume to start the waiting job
						manager.resume();
						scheduled = true;
					}
					return super.aboutToWait(lockOwner);
				}
			});
			manager.join(family, null);
			assertEquals(0, manager.find(family).length);
		} finally {
			// clean up
			manager.removeJobChangeListener(listener);
			manager.setLockListener(null);
			running.cancel();
			waiting.cancel();
			running.join();
			waiting.join();
			manager.resume();
		}
	}

	public void testJobFamilyNULL() {
		//test methods that accept the null job family (i.e. all jobs)
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create two different families of jobs
		TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need one common scheduling rule so that the jobs would be executed one by one
		ISchedulingRule rule = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
			} else {
				/*if(i%2 == 1)*/
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
			}

			jobs[i].setRule(rule);
			jobs[i].schedule();
		}

		waitForStart(jobs[0]);
		assertState("1.0", jobs[0], Job.RUNNING);

		//put all jobs to sleep
		manager.sleep(null);
		//the first job should still be running
		assertState("2.0", jobs[0], Job.RUNNING);

		//all the other jobs should be sleeping
		for (int i = 1; i < NUM_JOBS; i++) {
			assertState("2." + i, jobs[i], Job.SLEEPING);
		}

		//wake up all the jobs
		manager.wakeUp(null);
		//the first job should still be running
		assertState("3.0", jobs[0], Job.RUNNING);

		//all the other jobs should be waiting
		for (int i = 1; i < NUM_JOBS; i++) {
			assertState("3." + i, jobs[i], Job.WAITING);
		}

		//cancel all the jobs
		manager.cancel(first);
		manager.cancel(second);
		waitForFamilyCancel(jobs, first);
		waitForFamilyCancel(jobs, second);

		//all the jobs should now be in the NONE state
		for (int i = 0; i < NUM_JOBS; i++) {
			assertState("4." + i, jobs[i], Job.NONE);
		}

	}

	public void testJobFamilySleep() {
		//test the sleep method on a family of jobs
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		//create two different families of jobs
		TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need a common scheduling rule so that the jobs would be executed one by one
		ISchedulingRule rule = new IdentityRule();
		for (int i = 0; i < NUM_JOBS; i++) {
			//assign half the jobs to the first family, the other half to the second family
			if (i % 2 == 0) {
				jobs[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
			} else {
				/*if(i%2 == 1)*/
				jobs[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
			}

			jobs[i].setRule(rule);
			jobs[i].schedule();
		}

		waitForStart(jobs[0]);

		assertState("1.0", jobs[0], Job.RUNNING);

		//first job is running, the rest are waiting
		for (int i = 1; i < NUM_JOBS; i++) {
			assertState("1." + i, jobs[i], Job.WAITING);
		}

		//set the first family of jobs to sleep
		manager.sleep(first);

		//the running job should still be running
		assertState("2.0", jobs[0], Job.RUNNING);

		for (int i = 1; i < NUM_JOBS; i++) {
			//all other jobs in the first family should be sleeping
			//they can now be canceled
			if (jobs[i].belongsTo(first)) {
				assertState("2." + i, jobs[i], Job.SLEEPING);
				jobs[i].cancel();
			}
			//all jobs in the second family should still be in the waiting queue
			else {
				assertState("3." + i, jobs[i], Job.WAITING);
			}
		}

		manager.sleep(second);
		//cancel the running job
		jobs[0].cancel();
		waitForCancel(jobs[0]);

		//no job should now be running
		assertTrue("4.0", manager.currentJob() == null);

		for (int i = 1; i < NUM_JOBS; i++) {
			//all other jobs in the second family should be sleeping
			//they can now be canceled
			if (jobs[i].belongsTo(second)) {
				assertState("4." + i, jobs[i], Job.SLEEPING);
				jobs[i].cancel();
			}
		}

		//all the jobs should now be in the NONE state
		for (int i = 0; i < NUM_JOBS; i++) {
			assertState("5." + i, jobs[i], Job.NONE);
		}
	}

	/**
	 * Tests the API method IJobManager.wakeUp(family)
	 */
	public void testJobFamilyWakeUp() {
		final int JOBS_PER_FAMILY = 10;
		//create two different families of jobs
		Job[] family1 = new Job[JOBS_PER_FAMILY];
		Job[] family2 = new Job[JOBS_PER_FAMILY];
		TestJobFamily first = new TestJobFamily(TestJobFamily.TYPE_ONE);
		TestJobFamily second = new TestJobFamily(TestJobFamily.TYPE_TWO);
		//need one common scheduling rule so that the jobs would be executed one by one
		ISchedulingRule rule = new IdentityRule();
		//create and schedule a seed job that will cause all others to be blocked
		TestJob seedJob = new FamilyTestJob("SeedJob", 1000000, 10, TestJobFamily.TYPE_THREE);
		seedJob.setRule(rule);
		seedJob.schedule();
		waitForStart(seedJob);
		assertState("1.0", seedJob, Job.RUNNING);

		//create jobs in first family and put them to sleep
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			family1[i] = new FamilyTestJob("TestFirstFamily", 1000000, 10, TestJobFamily.TYPE_ONE);
			family1[i].setRule(rule);
			family1[i].schedule();
			assertState("1.1." + i, family1[i], Job.WAITING);
			assertTrue("1.2." + i, family1[i].sleep());
			assertState("1.3." + i, family1[i], Job.SLEEPING);
		}
		//create jobs in second family and put them to sleep
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			family2[i] = new FamilyTestJob("TestSecondFamily", 1000000, 10, TestJobFamily.TYPE_TWO);
			family2[i].setRule(rule);
			family2[i].schedule();
			assertState("2.1." + i, family2[i], Job.WAITING);
			assertTrue("2.2." + i, family2[i].sleep());
			assertState("2.3." + i, family2[i], Job.SLEEPING);
		}

		//cancel the seed job
		seedJob.cancel();
		waitForCancel(seedJob);
		assertState("3.0", seedJob, Job.NONE);

		//all family jobs should still be sleeping
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("3.1." + i, family1[i], Job.SLEEPING);
		}
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("3.2." + i, family2[i], Job.SLEEPING);
		}

		//wake-up the second family of jobs
		manager.wakeUp(second);

		//jobs in the first family should still be in the sleep state
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("4.1." + i, family1[i], Job.SLEEPING);
		}
		//ensure all jobs in second family are either running or waiting
		int runningCount = 0;
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			int state = family2[i].getState();
			if (state == Job.RUNNING) {
				runningCount++;
			} else if (state != Job.WAITING) {
				assertTrue("4.2." + i + ": expected state: " + printState(Job.WAITING) + " actual state: " + printState(state), false);
			}
		}
		//ensure only one job is running (it is possible that none have started yet)
		assertTrue("4.running", runningCount <= 1);

		//cycle through the jobs in the second family and cancel them
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			//the running job may not respond immediately
			if (!family2[i].cancel()) {
				waitForCancel(family2[i]);
			}
			assertState("5." + i, family2[i], Job.NONE);
		}

		//all jobs in the first family should still be sleeping
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("6.1." + i, family1[i], Job.SLEEPING);
		}

		//wake up the first family
		manager.wakeUp(first);

		//ensure all jobs in first family are either running or waiting
		runningCount = 0;
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			int state = family1[i].getState();
			if (state == Job.RUNNING) {
				runningCount++;
			} else if (state != Job.WAITING) {
				assertTrue("7.1." + i + ": expected state: " + printState(Job.WAITING) + " actual state: " + printState(state), false);
			}
		}
		//ensure only one job is running (it is possible that none have started yet)
		assertTrue("7.running", runningCount <= 1);

		//cycle through the jobs in the first family and cancel them
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			//the running job may not respond immediately
			if (!family1[i].cancel()) {
				waitForCancel(family1[i]);
			}
			assertState("8." + i, family1[i], Job.NONE);
		}

		//all jobs should now be in the NONE state
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("9.1." + i, family1[i], Job.NONE);
		}
		for (int i = 0; i < JOBS_PER_FAMILY; i++) {
			assertState("9.2." + i, family2[i], Job.NONE);
		}
	}

	public void testMutexRule() {
		final int JOB_COUNT = 10;
		TestJob[] jobs = new TestJob[JOB_COUNT];
		ISchedulingRule mutex = new IdentityRule();
		for (int i = 0; i < JOB_COUNT; i++) {
			jobs[i] = new TestJob("testMutexRule", 1000000, 10);
			jobs[i].setRule(mutex);
			jobs[i].schedule();
		}
		//first job should be running, all others should be waiting
		waitForStart(jobs[0]);
		assertState("1.0", jobs[0], Job.RUNNING);
		for (int i = 1; i < JOB_COUNT; i++) {
			assertState("1.1." + i, jobs[i], Job.WAITING);
		}
		//cancel job i, then i+1 should run and all others should wait
		for (int i = 0; i < JOB_COUNT - 1; i++) {
			jobs[i].cancel();
			waitForStart(jobs[i + 1]);
			assertState("2.0." + i, jobs[i + 1], Job.RUNNING);
			for (int j = i + 2; j < JOB_COUNT; j++) {
				assertState("2.1" + i + "." + j, jobs[j], Job.WAITING);
			}
		}
		//cancel the final job
		jobs[JOB_COUNT - 1].cancel();
	}

	public void testOrder() {
		//ensure jobs are run in order from lowest to highest sleep time.
		final List<Job> done = Collections.synchronizedList(new ArrayList<Job>());
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob() instanceof TestJob) {
					done.add(event.getJob());
				}
			}
		};
		int[] sleepTimes = new int[] {50, 250, 500, 800, 1000, 1500};
		Job[] jobs = new Job[sleepTimes.length];
		manager.addJobChangeListener(listener);
		try {
			for (int i = 0; i < sleepTimes.length; i++) {
				jobs[i] = new TestJob("testOrder(" + i + ")", 1, 1);
			}
			for (int i = 0; i < sleepTimes.length; i++) {
				jobs[i].schedule(sleepTimes[i]);
			}
			waitForCompletion();
			//make sure listener has had a chance to process the finished job
			while (done.size() != jobs.length) {
				Thread.yield();
				sleep(100);
			}
			Job[] doneOrder = done.toArray(new Job[done.size()]);
			assertEquals("1.0", jobs.length, doneOrder.length);
			for (int i = 0; i < doneOrder.length; i++) {
				assertEquals("1.1." + i, jobs[i], doneOrder[i]);
			}
		} finally {
			manager.removeJobChangeListener(listener);
		}
	}

	public void testReverseOrder() {
		//ensure jobs are run in order from lowest to highest sleep time.
		final List<Job> done = Collections.synchronizedList(new ArrayList<Job>());
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob() instanceof TestJob) {
					//add at start of list to get reverse order
					done.add(0, event.getJob());
				}
			}
		};
		int[] sleepTimes = new int[] {4000, 3000, 2000, 1000, 500};
		Job[] jobs = new Job[sleepTimes.length];
		manager.addJobChangeListener(listener);
		try {
			for (int i = 0; i < sleepTimes.length; i++) {
				jobs[i] = new TestJob("testReverseOrder(" + i + ")", 0, 1);
			}
			for (int i = 0; i < sleepTimes.length; i++) {
				jobs[i].schedule(sleepTimes[i]);
			}
			waitForCompletion();
			//make sure listener has had a chance to process the finished job
			while (done.size() != jobs.length) {
				Thread.yield();
				sleep(100);
			}
			Job[] doneOrder = done.toArray(new Job[done.size()]);
			assertEquals("1.0", jobs.length, doneOrder.length);
			for (int i = 0; i < doneOrder.length; i++) {
				assertEquals("1.1." + i, jobs[i], doneOrder[i]);
			}
		} finally {
			manager.removeJobChangeListener(listener);
		}
	}

	/**
	 * Tests conditions where there is a race to schedule the same job multiple times.
	 */
	public void testScheduleRace() {
		final int[] count = new int[1];
		final boolean[] running = new boolean[] {false};
		final boolean[] failure = new boolean[] {false};
		final Job testJob = new Job("testScheduleRace") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					synchronized (running) {
						//indicate job is running, and assert the job is not already running
						if (running[0]) {
							failure[0] = true;
						} else {
							running[0] = true;
						}
					}
					//sleep for awhile to let duplicate job start running
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					//ignore
				} finally {
					synchronized (running) {
						running[0] = false;
					}
				}
				return Status.OK_STATUS;
			}
		};
		testJob.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void scheduled(IJobChangeEvent event) {
				while (count[0]++ < 2) {
					testJob.schedule();
				}
			}
		});
		testJob.schedule();
		waitForCompletion(testJob, 5000);
		assertTrue("1.0", !failure[0]);
	}

	public void testSimple() {
		final int JOB_COUNT = 10;
		for (int i = 0; i < JOB_COUNT; i++) {
			new TestJob("testSimple").schedule();
		}
		waitForCompletion();
		//
		for (int i = 0; i < JOB_COUNT; i++) {
			new TestJob("testSimple").schedule(50);
		}
		waitForCompletion();
	}

	/**
	 * Tests setting various kinds of invalid rules on jobs.
	 */
	public void testSetInvalidRule() {
		class InvalidRule implements ISchedulingRule {
			@Override
			public boolean isConflicting(ISchedulingRule rule) {
				return false;
			}

			@Override
			public boolean contains(ISchedulingRule rule) {
				return false;
			}
		}

		InvalidRule rule1 = new InvalidRule();
		InvalidRule rule2 = new InvalidRule();
		ISchedulingRule multi = MultiRule.combine(rule1, rule2);

		Job job = new Job("job with invalid rule") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				return Status.OK_STATUS;
			}
		};

		try {
			job.setRule(rule1);
			fail("invalid rule");
		} catch (IllegalArgumentException e) {
			//expected
		}
		try {
			job.setRule(rule2);
			fail("invalid rule");
		} catch (IllegalArgumentException e) {
			//expected
		}
		try {
			job.setRule(multi);
			fail("invalid rule");
		} catch (IllegalArgumentException e) {
			//expected
		}
	}

	public void testSleep() {
		TestJob job = new TestJob("ParentJob", 10, 100);
		//sleeping a job that isn't scheduled should have no effect
		assertEquals("1.0", Job.NONE, job.getState());
		assertTrue("1.1", job.sleep());
		assertEquals("1.2", Job.NONE, job.getState());

		//sleeping a job that is already running should not work
		job.schedule();
		//give the job a chance to start
		waitForStart(job);
		assertState("2.0", job, Job.RUNNING);
		assertTrue("2.1", !job.sleep());
		assertState("2.2", job, Job.RUNNING);

		waitForCompletion();

		//sleeping a job that is already sleeping should make sure it never runs
		job.schedule(500);
		assertState("3.0", job, Job.SLEEPING);
		assertTrue("3.1", job.sleep());
		assertState("3.2", job, Job.SLEEPING);
		//wait awhile and ensure the job is still sleeping
		Thread.yield();
		sleep(600);
		Thread.yield();
		assertState("3.3", job, Job.SLEEPING);
		assertTrue("3.4", job.cancel()); //should be possible to cancel a sleeping job
	}

	public void testSleepOnWait() {
		final ISchedulingRule rule = new PathRule("testSleepOnWait");
		TestJob blockingJob = new TestJob("Long Job", 1000000, 10);
		blockingJob.setRule(rule);
		blockingJob.schedule();

		TestJob job = new TestJob("Long Job", 1000000, 10);
		job.setRule(rule);
		job.schedule();
		//we know this job is waiting, so putting it to sleep should prevent it from running
		assertState("1.0", job, Job.WAITING);
		assertTrue("1.1", job.sleep());
		assertState("1.2", job, Job.SLEEPING);

		//cancel the blocking job, thus freeing the pool for the waiting job
		blockingJob.cancel();

		//make sure the job is still sleeping
		assertState("1.3", job, Job.SLEEPING);

		//now wake the job up
		job.wakeUp();
		waitForStart(job);
		assertState("2.0", job, Job.RUNNING);

		//finally cancel the job
		job.cancel();
		waitForCompletion(job);
	}

	public void testSuspend() {
		assertTrue("1.0", !manager.isSuspended());
		manager.suspend();
		try {
			assertTrue("1.1", manager.isSuspended());
		} finally {
			manager.resume();
		}
		assertTrue("1.1", !manager.isSuspended());
	}

	/**
	 * Tests the following sequence:
	 * [Thread[main,6,main]]Suspend rule: R/
	 * [Thread[main,6,main]]Begin rule: R/
	 * [Thread[Worker-3,5,main]]Begin rule: L/JUnit/junit/tests/framework/Failure.java
	 * [Thread[main,6,main]]End rule: R/
	 * [Thread[main,6,main]]Resume rule: R/
	 * [Thread[Worker-3,5,main]]End rule: L/JUnit/junit/tests/framework/Failure.java
	 * @deprecated tests deprecated API
	 */
	@Deprecated
	public void testSuspendMismatchedBegins() {
		PathRule rule1 = new PathRule("/TestSuspendMismatchedBegins");
		PathRule rule2 = new PathRule("/TestSuspendMismatchedBegins/Child");
		manager.suspend(rule1, null);

		//start a job that acquires a child rule
		TestBarrier barrier = new TestBarrier();
		JobRuleRunner runner = new JobRuleRunner("TestSuspendJob", rule2, barrier, 1, true);
		runner.schedule();
		barrier.waitForStatus(TestBarrier.STATUS_START);
		//let the job start the rule
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);

		//now try to resume the rule in this thread
		manager.resume(rule1);

		//finally let the test runner resume the rule
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		barrier.waitForStatus(TestBarrier.STATUS_DONE);
		waitForCompletion(runner);

	}

	/**
	 * Tests IJobManager suspend and resume API
	 * @deprecated tests deprecated API
	 */
	@Deprecated
	public void testSuspendMultiThreadAccess() {
		PathRule rule1 = new PathRule("/TestSuspend");
		PathRule rule2 = new PathRule("/TestSuspend/Child");
		manager.suspend(rule1, null);

		//should not be able to run a job that uses the rule
		Job job = new Job("TestSuspend") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				return Status.OK_STATUS;
			}
		};
		job.setRule(rule1);
		job.schedule();
		//give the job a chance to run
		sleep(200);
		assertNull("1.0", job.getResult());

		//should be able to run a thread that begins the rule
		int[] status = new int[1];
		SimpleRuleRunner runner = new SimpleRuleRunner(rule1, status, null);
		new Thread(runner).start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);

		//should be able to run a thread that begins a conflicting rule
		status[0] = 0;
		runner = new SimpleRuleRunner(rule2, status, null);
		new Thread(runner).start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);

		//now begin the rule in this thread
		manager.beginRule(rule1, null);

		//should still be able to run a thread that begins the rule
		status[0] = 0;
		runner = new SimpleRuleRunner(rule1, status, null);
		new Thread(runner).start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);

		//our job should still not have executed
		sleep(100);
		assertNull("1.1", job.getResult());

		//even ending the rule in this thread should not allow the job to continue
		manager.endRule(rule1);
		sleep(100);
		assertNull("1.2", job.getResult());

		//should still be able to run a thread that begins the rule
		status[0] = 0;
		runner = new SimpleRuleRunner(rule1, status, null);
		new Thread(runner).start();
		TestBarrier.waitForStatus(status, TestBarrier.STATUS_DONE);

		//finally resume the rule in this thread
		manager.resume(rule1);

		//job should now complete
		waitForCompletion(job);

	}

	/**
	 * Tests IJobManager#transfer(ISchedulingRule, Thread) failure conditions.
	 */
	public void testTransferFailure() {
		PathRule rule = new PathRule("/testTransferFailure");
		PathRule subRule = new PathRule("/testTransferFailure/Sub");
		Thread other = new Thread();
		//can't transfer a rule this thread doesn't own it
		try {
			manager.transferRule(rule, other);
			fail("1.0");
		} catch (RuntimeException e) {
			//expected
		}
		try {
			manager.beginRule(rule, null);
			//can't transfer a child rule of a rule currently owned by the caller
			try {
				manager.transferRule(subRule, other);
				fail("1.1");
			} catch (RuntimeException e) {
				//expected
			}
			//TODO This test is failing
			//can't transfer a rule when the destination already owns an unrelated rule
			TestBarrier barrier = new TestBarrier();
			ISchedulingRule unrelatedRule = new PathRule("UnrelatedRule");
			JobRuleRunner ruleRunner = new JobRuleRunner("testTransferFailure", unrelatedRule, barrier, 1, false);
			ruleRunner.schedule();
			//wait for runner to start
			barrier.waitForStatus(TestBarrier.STATUS_START);
			//let it acquire the rule
			barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
			barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
			//transferring the calling thread's rule to the background job should fail
			//because the destination thread already owns a rule
			try {
				manager.transferRule(rule, ruleRunner.getThread());
				fail("1.2");
			} catch (RuntimeException e) {
				//expected
			}
			//let the background job finish
			barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			try {
				ruleRunner.join();
			} catch (InterruptedException e1) {
				fail("1.99", e1);
			}
		} finally {
			manager.endRule(rule);
		}
	}

	/**
	 * Tests transferring a scheduling rule from one job to another
	 */
	public void testTransferJobToJob() {
		final PathRule ruleToTransfer = new PathRule("testTransferJobToJob");
		final TestBarrier barrier = new TestBarrier();
		final Thread[] sourceThread = new Thread[1];
		final Job destination = new Job("testTransferJobToJob.destination") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				return Status.OK_STATUS;
			}
		};
		final Job source = new Job("testTransferJobToJob.source") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				sourceThread[0] = Thread.currentThread();
				//schedule the destination job and wait until it is running
				destination.schedule();
				barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
				IJobManagerTest.this.sleep(100);

				//transferring the rule will fail because it must have been acquired by beginRule
				manager.transferRule(ruleToTransfer, destination.getThread());
				return Status.OK_STATUS;
			}
		};
		source.setRule(ruleToTransfer);
		source.schedule();
		waitForCompletion(source);
		//source job should have failed due to illegal use of transferRule
		assertTrue("1.0", !source.getResult().isOK());
		assertTrue("1.1", source.getResult().getException() instanceof RuntimeException);

		//let the destination finish
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		waitForCompletion(destination);
		if (!destination.getResult().isOK()) {
			fail("1.2", destination.getResult().getException());
		}
	}

	/**
	 * Tests transferring a scheduling rule to the same thread
	 */
	public void testTransferSameThread() {
		PathRule rule = new PathRule("testTransferSameThread");
		try {
			manager.beginRule(rule, null);
			//transfer to same thread is ok
			manager.transferRule(rule, Thread.currentThread());
		} catch (Exception e) {
			fail("1.0", e);
		} finally {
			manager.endRule(rule);
		}
	}

	/**
	 * Simple test of rule transfer
	 */
	public void testTransferSimple() {
		class RuleEnder implements Runnable {
			Exception error;
			private final ISchedulingRule rule;

			RuleEnder(ISchedulingRule rule) {
				this.rule = rule;
			}

			@Override
			public void run() {
				try {
					manager.endRule(rule);
				} catch (Exception e) {
					this.error = e;
				}
			}
		}
		PathRule rule = new PathRule("testTransferSimple");
		manager.beginRule(rule, null);
		RuleEnder ender = new RuleEnder(rule);
		Thread destination = new Thread(ender);
		manager.transferRule(rule, destination);
		destination.start();
		try {
			destination.join();
		} catch (InterruptedException e) {
			fail("1.99", e);
		}
		if (ender.error != null) {
			fail("1.0", ender.error);
		}
	}

	/**
	 * Tests transferring a scheduling rule to a job and back again.
	 */
	public void testTransferToJob() {
		final PathRule rule = new PathRule("testTransferToJob");
		final TestBarrier barrier = new TestBarrier();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		final Exception[] failure = new Exception[1];
		final Thread testThread = Thread.currentThread();
		//create a job that the rule will be transferred to
		Job job = new Job("testTransferSimple") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);

				//sleep a little to ensure the test thread is waiting
				IJobManagerTest.this.sleep(100);
				//at this point we should own the rule so we can transfer it back
				try {
					manager.transferRule(rule, testThread);
				} catch (RuntimeException e) {
					//should not fail
					failure[0] = e;
				}
				return Status.OK_STATUS;
			}
		};
		job.schedule();
		//wait until the job starts
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);

		//now begin and transfer the rule
		manager.beginRule(rule, null);
		manager.transferRule(rule, job.getThread());

		//kick the job to allow it to transfer the rule back
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);

		//try to begin the rule again, which will block until the rule is transferred back
		manager.beginRule(rule, null);
		manager.endRule(rule);

		//ensure the job didn't fail, and finally end the rule to unwind the initial beginRule
		if (failure[0] != null) {
			fail("1.0", failure[0]);
		}
		try {
			manager.endRule(rule);
		} catch (Exception e) {
			//we should own the rule so this shouldn't fail
			fail("2.00", e);
		}
	}

	/**
	 * Tests transferring a scheduling rule to a job that is waiting for a child of
	 * the transferred rule.
	 */
	public void testTransferToJobWaitingOnChildRule() {
		final PathRule rule = new PathRule("testTransferToJobWaitingOnChildRule");
		final TestBarrier barrier = new TestBarrier();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		final Exception[] failure = new Exception[1];
		final Thread testThread = Thread.currentThread();
		//create a job that the rule will be transferred to
		Job job = new Job("testTransferToJobWaitingOnChildRule") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				//this will block until the rule is transferred
				PathRule child = new PathRule(rule.getFullPath().append("child"));
				try {
					manager.beginRule(child, null);
				} finally {
					manager.endRule(child);
				}
				//at this point we should own the rule so we can transfer it back
				try {
					manager.transferRule(rule, testThread);
				} catch (RuntimeException e) {
					//should not fail
					failure[0] = e;
				}
				return Status.OK_STATUS;
			}
		};
		manager.beginRule(rule, null);

		job.schedule();
		//wait until the job starts
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
		//wait a bit longer to ensure the job is blocked
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			//ignore
		}

		//now transfer the rule, allowing the job to complete
		manager.transferRule(rule, job.getThread());
		waitForCompletion(job);

		//ensure the job didn't fail, and finally end the rule to assert we own it
		if (failure[0] != null) {
			fail("1.0", failure[0]);
		}
		try {
			manager.endRule(rule);
		} catch (Exception e) {
			//we should own the rule so this shouldn't fail
			fail("2.00", e);
		}
	}

	/**
	 * Tests transferring a scheduling rule to a job that is waiting for that rule.
	 */
	public void testTransferToWaitingJob() {
		final PathRule rule = new PathRule("testTransferToWaitingJob");
		final TestBarrier barrier = new TestBarrier();
		barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_START);
		final Exception[] failure = new Exception[1];
		final Thread testThread = Thread.currentThread();
		//create a job that the rule will be transferred to
		Job job = new Job("testTransferToWaitingJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_RUNNING);
				//this will block until the rule is transferred
				try {
					manager.beginRule(rule, null);
				} finally {
					manager.endRule(rule);
				}
				//at this point we should own the rule so we can transfer it back
				try {
					manager.transferRule(rule, testThread);
				} catch (RuntimeException e) {
					//should not fail
					failure[0] = e;
				}
				return Status.OK_STATUS;
			}
		};
		manager.beginRule(rule, null);

		job.schedule();
		//wait until the job starts
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
		//wait a bit longer to ensure the job is blocked
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			//ignore
		}

		//now transfer the rule, allowing the job to complete
		manager.transferRule(rule, job.getThread());
		waitForCompletion(job);

		//ensure the job didn't fail, and finally end the rule to assert we own it
		if (failure[0] != null) {
			fail("1.0", failure[0]);
		}
		try {
			manager.endRule(rule);
		} catch (Exception e) {
			//we should own the rule so this shouldn't fail
			fail("2.00", e);
		}
	}

	/**
	 * Tests a batch of jobs that use two mutually exclusive rules.
	 */
	public void testTwoRules() {
		final int JOB_COUNT = 10;
		TestJob[] jobs = new TestJob[JOB_COUNT];
		ISchedulingRule evens = new IdentityRule();
		ISchedulingRule odds = new IdentityRule();
		for (int i = 0; i < JOB_COUNT; i++) {
			jobs[i] = new TestJob("testSimpleRules", 1000000, 10);
			jobs[i].setRule(((i & 0x1) == 0) ? evens : odds);
			jobs[i].schedule();
		}
		//first two jobs should be running, all others should be waiting
		waitForStart(jobs[0]);
		waitForStart(jobs[1]);
		assertState("1.0", jobs[0], Job.RUNNING);
		assertState("1.1", jobs[1], Job.RUNNING);
		for (int i = 2; i < JOB_COUNT; i++) {
			assertState("1.2." + i, jobs[i], Job.WAITING);
		}
		//cancel job i then i+1 and i+2 should run and all others should wait
		for (int i = 0; i < JOB_COUNT; i++) {
			jobs[i].cancel();
			try {
				waitForStart(jobs[i + 1]);
				assertState("2.0." + i, jobs[i + 1], Job.RUNNING);
				waitForStart(jobs[i + 2]);
				assertState("2.1." + i, jobs[i + 2], Job.RUNNING);
			} catch (ArrayIndexOutOfBoundsException e) {
				//ignore
			}
			for (int j = i + 3; j < JOB_COUNT; j++) {
				assertState("2.2." + i + "." + j, jobs[j], Job.WAITING);
			}
		}
	}

	/**
	 * A job has been canceled.  Pause this thread so that a worker thread
	 * has a chance to receive the cancel event.
	 */
	private void waitForCancel(Job job) {
		int i = 0;
		while (job.getState() == Job.RUNNING) {
			Thread.yield();
			sleep(100);
			Thread.yield();
			//sanity test to avoid hanging tests
			if (i++ > 1000) {
				dumpState();
				assertTrue("Timeout waiting for job to cancel", false);
			}
		}
	}

	private synchronized void waitForCompletion() {
		int i = 0;
		assertTrue("Jobs completed that weren't scheduled", completedJobs <= scheduledJobs);
		while (completedJobs < scheduledJobs) {
			try {
				wait(500);
			} catch (InterruptedException e) {
				//ignore
			}
			//sanity test to avoid hanging tests
			if (i++ > 1000) {
				dumpState();
				assertTrue("Timeout waiting for job to complete", false);
			}
		}
	}

	/**
	 * A family of jobs have been canceled. Pause this thread until all of the jobs
	 * in the family are canceled
	 */
	private void waitForFamilyCancel(Job[] jobs, TestJobFamily type) {

		for (Job job : jobs) {
			int i = 0;
			while (job.belongsTo(type) && (job.getState() != Job.NONE)) {
				Thread.yield();
				sleep(100);
				Thread.yield();
				//sanity test to avoid hanging tests
				if (i++ > 100) {
					dumpState();
					assertTrue("Timeout waiting for job in family " + type.getType() + "to be canceled ", false);
				}
			}
		}
	}

	private void waitForRunCount(TestJob job, int runCount) {
		int i = 0;
		while (job.getRunCount() < runCount) {
			Thread.yield();
			sleep(100);
			Thread.yield();
			//sanity test to avoid hanging tests
			if (i++ >= 1000) {
				dumpState();
				assertTrue("Timeout waiting for job to start. Job: " + job + ", state: " + job.getState(), false);
			}
		}
	}

	/**
	 * A job has been scheduled.  Pause this thread so that a worker thread
	 * has a chance to pick up the new job.
	 */
	private void waitForStart(TestJob job) {
		waitForRunCount(job, 1);
	}
}