/*******************************************************************************
 * Copyright (c) 2014, 2015 Google Inc 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:
 *     Thirumala Reddy Mutchukota - initial API and implementation
 *******************************************************************************/

package org.eclipse.core.tests.runtime.jobs;

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

/**
 * Tests for {@link JobGroup}.
 */
public class JobGroupTest extends AbstractJobTest {
	private IJobManager manager;
	private FussyProgressProvider progressProvider;

	@Override
	public void setUp() throws Exception {
		super.setUp();
		manager = Job.getJobManager();
		progressProvider = new FussyProgressProvider();
		manager.setProgressProvider(progressProvider);
	}

	@Override
	public void tearDown() throws Exception {
		super.tearDown();
		progressProvider.sanityCheck();
		manager.setProgressProvider(null);
	}

	public void testThrottlingWhenAllJobsAreKnown() {
		final int NUM_JOBS = 100;
		final int MAX_THREADS = 10;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		final JobGroup jobGroup = new JobGroup("JobGroup", MAX_THREADS, NUM_JOBS);
		final int[] maxThreadsUsed = new int[1];
		final TestBarrier barrier = new TestBarrier();

		// Create and schedule the long running test jobs.
		for (int i = 0; i < NUM_JOBS; i++) {
			jobs[i] = new TestJob("TestJob", 1000000, 10);
			jobs[i].setJobGroup(jobGroup);
			jobs[i].schedule();
		}

		maxThreadsUsed[0] = 0;
		// Use a thread to record the maximum number of running jobs and
		// cancel the running jobs so that the waiting jobs will be scheduled.
		final Thread t = new Thread(() -> {
			barrier.setStatus(TestBarrier.STATUS_RUNNING);
			while (jobGroup.getState() != JobGroup.NONE) {
				List<TestJob> runningJobs = new ArrayList<>();
				for (Job activeJob : jobGroup.getActiveJobs()) {
					if (activeJob.getState() == Job.RUNNING) {
						runningJobs.add((TestJob) activeJob);
					}
				}
				int runningJobsSize = runningJobs.size();
				if (runningJobsSize > maxThreadsUsed[0]) {
					maxThreadsUsed[0] = runningJobsSize;
				}
				for (Job runningJob : runningJobs) {
					runningJob.cancel();
					waitForCompletion(runningJob);
				}
			}
			barrier.setStatus(TestBarrier.STATUS_DONE);
		});

		assertEquals("1.0", JobGroup.ACTIVE, jobGroup.getState());
		// Start the thread and wait for it to complete.
		t.start();
		barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
		barrier.waitForStatus(TestBarrier.STATUS_DONE);

		assertEquals("2.0", JobGroup.NONE, jobGroup.getState());
		assertTrue("3.0", maxThreadsUsed[0] > 0);
		assertTrue("4.0", maxThreadsUsed[0] <= MAX_THREADS);
	}

	public void testSeedJobsWhenAllJobsAreKnown() {
		final int NUM_SEED_JOBS = 10;
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, NUM_SEED_JOBS);

		for (int i = 1; i <= NUM_SEED_JOBS; i++) {
			// Create and schedule a long running test job.
			TestJob job = new TestJob("TestJob", 1000000, 10);
			job.setJobGroup(jobGroup);
			job.schedule();
			waitForStart(job);
			// Job group should be in the ACTIVE state with one active job.
			assertEquals("1." + i, 1, jobGroup.getActiveJobs().size());
			assertEquals("2." + i, JobGroup.ACTIVE, jobGroup.getState());
			// Cancel the test job and wait for it to finish.
			job.cancel();
			waitForCompletion(job);
			// Verify that the group does not contain any active jobs.
			assertEquals("3." + i, 0, jobGroup.getActiveJobs().size());
			// Verify that the group will be in the ACTIVE state even when there are no active jobs
			// and transitions to NONE state only after all the seed jobs are completed.
			if (i < NUM_SEED_JOBS) {
				assertEquals("4." + i, JobGroup.ACTIVE, jobGroup.getState());
			} else {
				waitForCompletion(jobGroup);
				assertEquals("4." + i, JobGroup.NONE, jobGroup.getState());
			}
		}
	}

	public void testSeedJobsWhenSeedJobsAddNewJobs() {
		final int NUM_SEED_JOBS = 10;
		final int NUM_CHILD_JOBS = 10;
		final JobGroup jobGroup = new JobGroup("JobGroup", 10, NUM_SEED_JOBS);

		for (int i = 1; i <= NUM_SEED_JOBS; i++) {
			// Create and schedule a seed job, which creates and schedules the
			// long running child jobs belonging to the same group.
			// An example usage would be a directory digger that starts
			// with a set of root directories.
			Job job = new Job("SeedJob") {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					for (int j = 0; j < NUM_CHILD_JOBS; j++) {
						TestJob childJob = new TestJob("ChildTestJob", 1000000, 10);
						childJob.setJobGroup(getJobGroup());
						childJob.schedule();
					}
					return Status.OK_STATUS;
				}
			};
			job.setJobGroup(jobGroup);
			job.schedule();
			waitForCompletion(job);
			// Job group should be in the ACTIVE state with the active child jobs.
			assertEquals("1." + i, NUM_CHILD_JOBS, jobGroup.getActiveJobs().size());
			assertEquals("2." + i, JobGroup.ACTIVE, jobGroup.getState());
			// Cancel all the active child jobs and wait for them to finish.
			for (Job activeJob : jobGroup.getActiveJobs()) {
				activeJob.cancel();
				waitForCompletion(activeJob);
			}
			// Verify that the group does not contain any active jobs.
			assertEquals("3." + i, 0, jobGroup.getActiveJobs().size());
			// Verify that the group will be in the ACTIVE state even when there are no active jobs
			// and transitions to NONE state only after all the seed jobs are completed.
			if (i < NUM_SEED_JOBS) {
				assertEquals("4." + i, JobGroup.ACTIVE, jobGroup.getState());
			} else {
				waitForCompletion(jobGroup);
				assertEquals("4." + i, JobGroup.NONE, jobGroup.getState());
			}
		}
	}

	public void testSeedJobsWithRepeatingJobs() {
		final int NUM_SEED_JOBS = 10;
		final int REPEATING_COUNT = 5;
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, NUM_SEED_JOBS);

		RepeatingJob[] jobs = new RepeatingJob[NUM_SEED_JOBS];
		for (int i = 0; i < NUM_SEED_JOBS; i++) {
			RepeatingJob job = new RepeatingJob("RepeatingJob", REPEATING_COUNT);
			jobs[i] = job;
			job.setJobGroup(jobGroup);
			job.schedule();
		}
		waitForCompletion(jobGroup);
		for (int i = 0; i < NUM_SEED_JOBS; i++) {
			// Verify that all the repeating jobs have run the expected number of times,
			// which only happen when the job group treats the multiple executions of
			// a repeating job as a single seed job.
			assertEquals("1." + i, REPEATING_COUNT, jobs[i].getRunCount());
		}
	}

	public void testCancel() {
		final int NUM_JOBS = 20;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		// Create two different job groups. The cancel operation is performed and tested on the
		// firstJobGroup. The secondJobGroup is used to make sure that the presence of a job group
		// will not affect the working of another job group.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 1, NUM_JOBS / 2);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 1, NUM_JOBS / 2);

		for (int i = 0; i < NUM_JOBS; i++) {
			// Assign half the jobs to the first group, the other half to the second group.
			if (i % 2 == 0) {
				jobs[i] = new TestJob("TestFirstJobGroup", 1000000, 10);
				jobs[i].setJobGroup(firstJobGroup);
			} else {
				jobs[i] = new TestJob("TestSecondJobGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
			}
			jobs[i].schedule();
		}

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

		waitForStart(jobs[1]);
		assertState("2.0", jobs[1], Job.RUNNING);

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

		// Cancel the first group of jobs.
		firstJobGroup.cancel();
		waitForCompletion(firstJobGroup);

		// Verify that the the previously running job is canceled and moved to NONE state.
		assertState("2.0", jobs[0], Job.NONE);

		for (int i = 2; i < NUM_JOBS; i++) {
			// Verify that all other jobs in the first group are also canceled and moved to NONE state.
			if (jobs[i].getJobGroup() == firstJobGroup) {
				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);
			} else { // Verify that all other jobs in the second groups are in the waiting state.
				assertState("3." + i, jobs[i], Job.WAITING);
			}
		}

		// Cancel the second group of jobs.
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);

		// Verify that the running job from the second group is canceled to moved to NONE state.
		assertState("7.0", jobs[1], Job.NONE);

		for (int i = 0; i < NUM_JOBS; i++) {
			// Verify that all the jobs are canceled and moved to NONE state.
			assertState("8." + i, jobs[i], Job.NONE);
		}
	}

	public void testGetActiveJobs() {
		final int NUM_JOBS = 20;
		final int JOBS_PER_GROUP = NUM_JOBS / 5;
		TestJob[] jobs = new TestJob[NUM_JOBS];
		// Create five different job groups.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 1, JOBS_PER_GROUP);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 1, JOBS_PER_GROUP);
		final JobGroup thirdJobGroup = new JobGroup("ThirdJobGroup", 1, JOBS_PER_GROUP);
		final JobGroup fourthJobGroup = new JobGroup("FourthJobGrroup", 1, JOBS_PER_GROUP);
		final JobGroup fifthJobGroup = new JobGroup("FifthJobGroup", 1, JOBS_PER_GROUP);

		for (int i = 0; i < NUM_JOBS; i++) {
			switch (i % 5) {
			case 0:
				jobs[i] = new TestJob("TestFirstJobGroup", 1000000, 10);
				jobs[i].setJobGroup(firstJobGroup);
				break;
			case 1:
				jobs[i] = new TestJob("TestSecondJobGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
				break;
			case 2:
				jobs[i] = new TestJob("TestThirdJobGroup", 1000000, 10);
				jobs[i].setJobGroup(thirdJobGroup);
				break;
			case 3:
				jobs[i] = new TestJob("TestFourthJobGroup", 1000000, 10);
				jobs[i].setJobGroup(fourthJobGroup);
				break;
			default:
				jobs[i] = new TestJob("TestFifthJobGroup", 1000000, 10);
				jobs[i].setJobGroup(fifthJobGroup);
				break;
			}
			jobs[i].schedule();
		}

		for (int i = 0; i < 5; i++) {
			waitForStart(jobs[i]);
		}

		// Try finding all jobs by supplying the NULL parameter.
		// Note: Running the test framework may cause other system jobs to run,
		// so check that the jobs started by this test are a subset of all running jobs.
		HashSet<Job> testJobs = new HashSet<>();
		testJobs.addAll(Arrays.asList(jobs));
		Job[] allJobs = manager.find(null);
		assertTrue("1.0", allJobs.length >= NUM_JOBS);
		for (int i = 0; i < allJobs.length; i++) {
			// Only test jobs that we know about.
			if (testJobs.remove(allJobs[i])) {
				JobGroup group = allJobs[i].getJobGroup();
				assertTrue("1." + i, (group == firstJobGroup || group == secondJobGroup || group == thirdJobGroup || group == fourthJobGroup || group == fifthJobGroup));
			}
		}
		assertEquals("1.2", 0, testJobs.size());

		List<Job> activeJobs;

		// Try finding all jobs from the first job group.
		activeJobs = firstJobGroup.getActiveJobs();
		assertEquals("2.0", 4, activeJobs.size());
		for (int i = 0; i < activeJobs.size(); i++) {
			assertEquals("2." + (i + 1), firstJobGroup, activeJobs.get(i).getJobGroup());
		}

		// Try finding all jobs from the second job group.
		activeJobs = secondJobGroup.getActiveJobs();
		assertEquals("3.0", 4, activeJobs.size());
		for (int i = 0; i < activeJobs.size(); i++) {
			assertEquals("3." + (i + 1), secondJobGroup, activeJobs.get(i).getJobGroup());
		}

		// Try finding all jobs from the third job group.
		activeJobs = thirdJobGroup.getActiveJobs();
		assertEquals("4.0", 4, activeJobs.size());
		for (int i = 0; i < activeJobs.size(); i++) {
			assertEquals("4." + (i + 1), thirdJobGroup, activeJobs.get(i).getJobGroup());
		}

		// Try finding all jobs from the fourth job group.
		activeJobs = fourthJobGroup.getActiveJobs();
		assertEquals("5.0", 4, activeJobs.size());
		for (int i = 0; i < activeJobs.size(); i++) {
			assertEquals("5." + (i + 1), fourthJobGroup, activeJobs.get(i).getJobGroup());
		}

		// Try finding all jobs from the fifth job group.
		activeJobs = fifthJobGroup.getActiveJobs();
		assertEquals("6.0", 4, activeJobs.size());
		for (int i = 0; i < activeJobs.size(); i++) {
			assertEquals("6." + (i + 1), fifthJobGroup, activeJobs.get(i).getJobGroup());
		}

		// The first job should still be running.
		for (int i = 0; i < 5; i++) {
			assertState("7.0", jobs[i], Job.RUNNING);
		}

		// Cancel the first job group.
		firstJobGroup.cancel();
		waitForCompletion(firstJobGroup);

		// First job group should not contain any active jobs.
		activeJobs = firstJobGroup.getActiveJobs();
		assertEquals("7.2", 0, activeJobs.size());

		// Cancel the second job group.
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);
		// Second job group should not contain any active jobs.
		activeJobs = secondJobGroup.getActiveJobs();
		assertEquals("9.0", 0, activeJobs.size());

		// Cancel the fourth job group.
		fourthJobGroup.cancel();
		waitForCompletion(fourthJobGroup);
		// Fourth job group should not contain any active jobs.
		activeJobs = fourthJobGroup.getActiveJobs();
		assertEquals("9.1", 0, activeJobs.size());

		// Finding all jobs by supplying the NULL parameter should return at least 8 jobs
		// (4 from the 3rd family, and 4 from the 5th family)
		// Note: Running the test framework may cause other system jobs to run,
		// so check that the expected jobs started by this test are a subset of all running jobs.
		testJobs.addAll(Arrays.asList(jobs));
		allJobs = manager.find(null);
		assertTrue("11.0", allJobs.length >= 8);
		for (int i = 0; i < allJobs.length; i++) {
			// Only test jobs that we know about.
			if (testJobs.remove(allJobs[i])) {
				JobGroup group = allJobs[i].getJobGroup();
				assertTrue("11." + (i + 1), (group == thirdJobGroup || group == fifthJobGroup));
			}
		}

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

		// Cancel the fifth and third job groups.
		fifthJobGroup.cancel();
		waitForCompletion(fifthJobGroup);
		thirdJobGroup.cancel();
		waitForCompletion(thirdJobGroup);

		// Verify that all jobs are canceled and moved to NONE state
		for (int i = 0; i < NUM_JOBS; i++) {
			assertState("12." + i, jobs[i], Job.NONE);
		}

		// Finding all jobs should return no jobs from our job groups.
		// Note: Running the test framework may cause other system jobs to run,
		// so check that there no jobs started by this test are present in all running jobs.
		testJobs.addAll(Arrays.asList(jobs));
		allJobs = manager.find(null);
		for (int i = 0; i < allJobs.length; i++) {
			// Verify that no jobs that we know about are found (they should have all been removed)
			if (testJobs.remove(allJobs[i])) {
				assertTrue("14." + i, false);
			}
		}
		assertEquals("15.0", NUM_JOBS, testJobs.size());
		testJobs.clear();
	}

	public void testJoinWithoutTimeout() {
		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 job groups. The join operation is performed and tested on the
		// firstJobGroup. The secondJobGroup is used to make sure that the presence of a job group
		// will not affect the working of another job group.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 1, NUM_JOBS / 2);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 1, NUM_JOBS / 2);
		for (int i = 0; i < NUM_JOBS; i++) {
			// Assign half the jobs to the first group, the other half to the second group.
			if (i % 2 == 0) {
				jobs[i] = new TestJob("TestFirstJobGroup", 10, 10);
				jobs[i].setJobGroup(firstJobGroup);
				jobs[i].schedule(1000000);
			} else {
				jobs[i] = new TestJob("TestSecondJobGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
				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;
				firstJobGroup.join(0, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		// Start the thread that will join the first group 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
		for (Job job : firstJobGroup.getActiveJobs()) {
			job.wakeUp();
		}

		int i = 0;
		for (; i < 100; i++) {
			int currentStatus = status[0];
			List<Job> result = firstJobGroup.getActiveJobs();

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

		// Cancel the second job group.
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);

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

	public void testJoinWithTimeout() {
		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 job groups. The join operation is performed and tested on the
		// firstJobGroup. The secondJobGroup is used to make sure that the presence of a job group
		// will not affect the working of another job group.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 5, NUM_JOBS / 2);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 5, NUM_JOBS / 2);
		for (int i = 0; i < NUM_JOBS; i++) {
			// Assign half the jobs to the first group, the other half to the second group.
			if (i % 2 == 0) {
				jobs[i] = new TestJob("TestFirstGroup", 1000000, 10);
				jobs[i].setJobGroup(firstJobGroup);
				jobs[i].schedule();
			} else {
				jobs[i] = new TestJob("TestSecondGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
				jobs[i].schedule();
			}

		}

		final long timeout = 1000;
		final long duration[] = {-1};

		Thread t = new Thread(() -> {
			status[0] = TestBarrier.STATUS_START;
			try {
				long start = now();
				firstJobGroup.join(timeout, null);
				duration[0] = now() - start;
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		// Start the thread that will join the first job group and be blocked until the join call is returned.
		t.start();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_START);
		int i = 0;
		for (; i < 11; i++) {
			if (status[0] == TestBarrier.STATUS_DONE) {
				// Verify that the join call is blocked for at least for the duration of given timeout.
				assertTrue("1.0 duration: " + Arrays.toString(duration) + " timeout: " + timeout, duration[0] >= timeout);
				break;
			}
			sleep(100);
		}
		// Verify that the join call is returned is finished with in reasonable time of 1100 ms (given timeout + 100ms).
		assertTrue("2.0", i < 11);

		// Cancel both job groups.
		firstJobGroup.cancel();
		waitForCompletion(firstJobGroup);
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);

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

	/**
	 * Tests joining on a job group, and then canceling the jobs that are blocking the join call.
	 */
	public void testJoinWithCancelingJobs() {
		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 job groups. The join operation is performed and tested on the
		// firstJobGroup. The secondJobGroup is used to make sure that the presence of a job group
		// will not affect the working of another job group.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 1, NUM_JOBS / 2);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 1, NUM_JOBS / 2);
		for (int i = 0; i < NUM_JOBS; i++) {
			// Assign half the jobs to the first group, the other half to the second group.
			if (i % 2 == 0) {
				jobs[i] = new TestJob("TestFirstJobGroup", 1000000, 10);
				jobs[i].setJobGroup(firstJobGroup);
			} else {
				jobs[i] = new TestJob("TestSecondJobGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
			}
			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;
				firstJobGroup.join(0, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		// Start the thread that will join the first job group. It will be blocked
		// until all jobs in the first group 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);
		assertEquals("2.1", TestBarrier.STATUS_RUNNING, status[0]);

		// Cancel the first job group. The join call should be unblocked when
		// all the jobs are canceled.
		firstJobGroup.cancel();
		TestBarrier.waitForStatus(status, 0, TestBarrier.STATUS_DONE);

		// Verify that there are no active jobs in the the first group.
		assertEquals("2.2", 0, firstJobGroup.getActiveJobs().size());

		// Cancel the second job group.
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);

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

	/**
	 * Tests joining on a job group, and then canceling the monitor.
	 */
	public void testJoinWithCancelingMonitor() {
		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 canceler = new FussyProgressMonitor();
		// Create two different job groups. The join operation is performed and tested on the
		// firstJobGroup. The secondJobGroup is used to make sure that the presence of a job group
		// will not affect the working of another job group.
		final JobGroup firstJobGroup = new JobGroup("FirstJobGroup", 1, NUM_JOBS / 2);
		final JobGroup secondJobGroup = new JobGroup("SecondJobGroup", 1, NUM_JOBS / 2);
		for (int i = 0; i < NUM_JOBS; i++) {
			// Assign half the jobs to the first group, the other half to the second group.
			if (i % 2 == 0) {
				jobs[i] = new TestJob("TestFirstJobGroup", 1000000, 10);
				jobs[i].setJobGroup(firstJobGroup);
			} else {
				jobs[i] = new TestJob("TestSecondJobGroup", 1000000, 10);
				jobs[i].setJobGroup(secondJobGroup);
			}
			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;
				firstJobGroup.join(0, canceler);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			status[0] = TestBarrier.STATUS_DONE;
		});

		// Start the thread that will join the first job group. It will be blocked
		// until the monitor is 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);
		assertEquals("2.1", TestBarrier.STATUS_RUNNING, status[0]);

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

		// The first job in the first group should still be running.
		assertState("2.2", jobs[0], Job.RUNNING);
		assertEquals("2.3", TestBarrier.STATUS_DONE, status[0]);
		assertTrue("2.4", !firstJobGroup.getActiveJobs().isEmpty());

		// Cancel both job groups.
		secondJobGroup.cancel();
		waitForCompletion(secondJobGroup);
		firstJobGroup.cancel();
		waitForCompletion(firstJobGroup);

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

	/**
	 * Tests joining a job that repeats in a loop.
	 */
	public void testJoinWithRepeatingJobs() {
		JobGroup jobGroup = new JobGroup("JobGroup", 1, 1);
		int count = 25;
		RepeatingJob job = new RepeatingJob("RepeatingJob", count);
		job.setJobGroup(jobGroup);
		job.schedule();
		try {
			jobGroup.join(0, null);
		} catch (OperationCanceledException e) {
			fail("1.0", e);
		} catch (InterruptedException e) {
			fail("1.1", e);
		}
		// Verify that the job has run the expected number of times.
		assertEquals("1.2", count, job.getRunCount());
	}

	/**
	 * Tests that joining a job from another job that is in the same job group
	 * yields an IllegalStateException.
	 */
	public void testJoiningAJobInTheSameJobGroupFails() {
		JobGroup jobGroup = new JobGroup("JobGroup", 2, 2);
		final TestJob firstJob = new TestJob("FirstJob", 1000000, 10);
		firstJob.setJobGroup(jobGroup);
		firstJob.schedule();
		waitForStart(firstJob);

		final boolean joinFailed[] = {false};
		Job secondJob = new Job("SecondJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					firstJob.join();
				} catch (InterruptedException ie) {
					// ignore
				} catch (IllegalStateException ise) {
					// expected
					joinFailed[0] = true;
				}
				return Status.OK_STATUS;
			}
		};
		secondJob.setJobGroup(jobGroup);
		secondJob.schedule();
		waitForCompletion(secondJob);
		assertEquals("1.0", true, joinFailed[0]);

		firstJob.cancel();
		waitForCompletion(jobGroup);
	}

	/**
	 * Tests that the progress is reported on the monitor used for join.
	 */
	public void testJoinWithProgressMonitor() {
		final int NUM_JOBS = 100;
		JobGroup jobGroup = new JobGroup("JobGroup", 10, NUM_JOBS);
		final TestBarrier barrier = new TestBarrier();
		for (int i = 0; i < NUM_JOBS; i++) {
			TestJob testJob = new TestJob("TestJob", 10, 10) {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					barrier.waitForStatus(TestBarrier.STATUS_START);
					return super.run(monitor);
				}
			};
			testJob.setJobGroup(jobGroup);
			testJob.schedule();
		}
		FussyProgressMonitor monitor = new FussyProgressMonitor();
		barrier.setStatus(TestBarrier.STATUS_START);
		try {
			jobGroup.join(0, monitor);
		} catch (OperationCanceledException | InterruptedException e) {
			// ignore
		}
		// Check the progress reporting on monitor.
		monitor.sanityCheck();
		monitor.assertUsedUp();
	}

	/**
	 * Tested scenario:
	 *   - Create and add a WaitingJob to the JobGroup and schedule it when the job manager is suspended
	 *   - Join on the JobGroup when the job manager is suspended
	 *
	 * Expected result:
	 *   The join call on the JobGroup should not wait for the WaitingJob as the WaitingJob is not going
	 *   to be executed when the job manger is suspended.
	 */
	public void testJoinWithJobManagerSuspended_1() throws InterruptedException {
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, 1);
		final TestBarrier barrier = new TestBarrier();
		final int[] groupJobsCount = new int[] {-1};
		final TestJob waiting = new TestJob("WaitingJob", 1000000, 10);
		waiting.setJobGroup(jobGroup);
		final TestJob running = new TestJob("RunningJob", 200, 10);
		running.setJobGroup(jobGroup);
		Job job = new Job("MainJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_START);
				try {
					running.schedule();
					// Wait until the running job is actually running.
					waitForStart(running);
					// Suspend before join.
					manager.suspend();
					waiting.schedule();
					running.join();
					jobGroup.join(0, null);
					groupJobsCount[0] = jobGroup.getActiveJobs().size();
				} catch (InterruptedException e) {
					// ignore
				} finally {
					// clean up
					waiting.cancel();
					try {
						waiting.join();
					} catch (InterruptedException e) {
						// ignore
					}
					manager.resume();
				}
				barrier.setStatus(TestBarrier.STATUS_DONE);
				return Status.OK_STATUS;
			}
		};
		try {
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			assertEquals(1, groupJobsCount[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();
		}
	}

	/**
	 * Tested scenario:
	 *   - Join on the JobGroup when the job manager is NOT suspended
	 *   - Create and add a WaitingJob to the JobGroup and schedule it when the job manager is suspended
	 *
	 * Expected result:
	 *   The join call on the JobGroup should not wait for the WaitingJob as the WaitingJob is not going
	 *   to be executed when the job manger is suspended.
	 */
	public void testJoinWithJobManagerSuspended_2() throws InterruptedException {
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, 1);
		final TestBarrier barrier = new TestBarrier();
		final int[] groupJobsCount = new int[] {-1};
		final TestJob waiting = new TestJob("WaitingJob", 1000000, 10);
		waiting.setJobGroup(jobGroup);
		final TestJob running = new TestJob("RunningJob", 1000000, 10);
		running.setJobGroup(jobGroup);

		final Thread t = new Thread(() -> {
			barrier.setStatus(TestBarrier.STATUS_RUNNING);
			try {
				jobGroup.join(0, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		});
		Job job = new Job("MainJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_START);
				try {
					running.schedule();
					// wait until the running job is actually running
					waitForStart(running);
					t.start();
					barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
					// suspend before scheduling new job
					manager.suspend();
					waiting.schedule();
					running.cancel();
					barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
					groupJobsCount[0] = jobGroup.getActiveJobs().size();
					barrier.setStatus(TestBarrier.STATUS_DONE);
				} finally {
					// clean up
					waiting.cancel();
					try {
						waiting.join();
					} catch (InterruptedException e) {
						// ignore
					}
					manager.resume();
				}
				return Status.OK_STATUS;
			}
		};
		try {
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			assertEquals(1, groupJobsCount[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();
		}
	}

	/**
	 * Tested scenario:
	 *   - Join on the JobGroup when the job manager is NOT suspended
	 *   - Create and add a WaitingJob to the JobGroup and schedule it when the job manager is suspended
	 *   - Resume the job manager which causes the waiting job to start
	 *
	 * Expected result:
	 *   The join call on the JobGroup should wait for the WaitingJob as the WaitingJob was started
	 *   to execute before the join ended.
	 */
	public void testJoinWithJobManagerSuspended_3() throws InterruptedException {
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, 1);
		final TestBarrier barrier = new TestBarrier();
		final int[] groupJobsCount = new int[] {-1};
		final TestJob waiting = new TestJob("waiting job", 1000000, 10);
		waiting.setJobGroup(jobGroup);
		final TestJob running = new TestJob("running job", 1000000, 10);
		running.setJobGroup(jobGroup);

		final Thread t = new Thread(() -> {
			barrier.setStatus(TestBarrier.STATUS_RUNNING);
			try {
				jobGroup.join(0, null);
			} catch (OperationCanceledException | InterruptedException e) {
				// ignore
			}
			barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
		});
		Job job = new Job("MainJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_START);

				running.schedule();
				// Wait until the running job is actually running.
				waitForStart(running);
				// Start the thread to make join call.
				t.start();
				barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
				// Suspend before scheduling the waiting job.
				manager.suspend();
				waiting.schedule();
				manager.resume();
				running.cancel();
				waitForStart(waiting);
				waiting.cancel();
				barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
				groupJobsCount[0] = jobGroup.getActiveJobs().size();
				barrier.setStatus(TestBarrier.STATUS_DONE);

				return Status.OK_STATUS;
			}
		};
		try {
			job.schedule();
			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			assertEquals(0, groupJobsCount[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();
		}
	}

	/**
	 * Tested scenario:
	 *   - Add a failing job to the JobGroup between passing jobs.
	 *
	 * Expected result:
	 *   The JobGroup should be canceled when the failing job is completed, because by default
	 *   a job group is canceled when a job belonging to the group is failed.
	 */
	public void testShouldCancel_1() {
		final int NUM_SEED_JOBS = 10;
		final int NUM_ADDITIONAL_JOBs = 10;
		final Job jobs[] = new Job[NUM_SEED_JOBS + NUM_ADDITIONAL_JOBs];
		final JobGroup jobGroup = new JobGroup("JobGroup", NUM_SEED_JOBS, NUM_SEED_JOBS);
		for (int i = 0; i < NUM_SEED_JOBS - 1; i++) {
			TestJob job = new TestJob("TestJob", 1000000, 10);
			jobs[i] = job;
			job.setJobGroup(jobGroup);
			job.schedule();
			waitForStart(job);
		}
		// Verify that all the test jobs are running.
		assertEquals("1.0", JobGroup.ACTIVE, jobGroup.getState());
		assertEquals("1.1", NUM_SEED_JOBS - 1, jobGroup.getActiveJobs().size());
		for (int i = 0; i < NUM_SEED_JOBS - 1; i++) {
			assertState("2." + i, jobs[i], Job.RUNNING);
		}

		final TestBarrier barrier = new TestBarrier();
		Job failedJob = new Job("FailedJob") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_RUN);
				barrier.waitForStatus(TestBarrier.STATUS_RUNNING);
				return new Status(IStatus.ERROR, "org.eclipse.core.jobs", "Error");
			}
		};
		jobs[NUM_SEED_JOBS - 1] = failedJob;
		failedJob.setJobGroup(jobGroup);
		failedJob.schedule();
		barrier.waitForStatus(TestBarrier.STATUS_WAIT_FOR_RUN);

		// Verify that the failing job also started running.
		assertEquals("3.0", NUM_SEED_JOBS, jobGroup.getActiveJobs().size());
		assertState("3.1", failedJob, Job.RUNNING);

		for (int i = NUM_SEED_JOBS; i < NUM_SEED_JOBS + NUM_ADDITIONAL_JOBs; i++) {
			Job job = new TestJob("AdditionalJob", 1000000, 10);
			jobs[i] = job;
			job.setJobGroup(jobGroup);
			job.schedule();
		}

		// Verify that all the jobs are active.
		assertEquals("4.0", NUM_SEED_JOBS + NUM_ADDITIONAL_JOBs, jobGroup.getActiveJobs().size());
		for (int i = NUM_SEED_JOBS; i < NUM_SEED_JOBS + NUM_ADDITIONAL_JOBs; i++) {
			assertState("5." + i, jobs[i], Job.WAITING);
		}
		// Allow the failing job to complete.
		barrier.setStatus(TestBarrier.STATUS_RUNNING);
		// wait for the job group to complete.
		waitForCompletion(jobGroup);
		// Verify that all the jobs are moved to NONE state. Also verify that the failing job failed,
		// other running jobs got canceled and the waiting jobs are never allowed to run.
		for (int i = 0; i < NUM_SEED_JOBS + NUM_ADDITIONAL_JOBs; i++) {
			assertState("6." + i, jobs[i], Job.NONE);
			if (i < NUM_SEED_JOBS - 1) {
				assertEquals("6." + i, IStatus.CANCEL, jobs[i].getResult().getSeverity());
			} else if (i == NUM_SEED_JOBS - 1) {
				assertEquals("6." + i, IStatus.ERROR, jobs[i].getResult().getSeverity());
			} else if (i == NUM_SEED_JOBS) {
				// This job might have been started running before the group gets canceled.
				IStatus result = jobs[i].getResult();
				if (result != null) {
					assertEquals("6." + i, IStatus.CANCEL, result.getSeverity());
				}
			} else {
				assertEquals("6." + i, null, jobs[i].getResult());
			}
		}
	}

	/**
	 * Tested scenario:
	 *   - Record the number of times the JobGroup.shouldCancel method is invoked.
	 *
	 * Expected result:
	 *   The shouldCancel method of the JobGroup should be called after the completion of every job
	 *   belonging to that group except the last one (shouldCancel method is not called after the
	 *   completion of the last job in the jobGroup as there are no jobs left to cancel).
	 */
	public void testShouldCancel_2() {
		final int NUM_JOBS = 10;
		final int numShouldCancelCalled[] = {0};
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, NUM_JOBS) {
			@Override
			protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
				numShouldCancelCalled[0]++;
				return super.shouldCancel(lastCompletedJobResult, numberOfFailedJobs, numberOfCanceledJobs);
			}
		};
		for (int i = 0; i < NUM_JOBS; i++) {
			Job job = new TestJob("TestJob", 10, 10);
			job.setJobGroup(jobGroup);
			job.schedule();
		}
		waitForCompletion(jobGroup);
		assertEquals("1.0", NUM_JOBS - 1, numShouldCancelCalled[0]);
	}

	/**
	 * Tested scenario:
	 *   - Record the number of times the JobGroup.shouldCancel method is invoked and all the values passed to it
	 *   - Always return false from the shouldCancel method of the JobGroup to avoid the group cancellation due to failed jobs
	 *
	 * Expected result:
	 *   The shouldCancel method of the JobGroup should be called with appropriate values after
	 *   the completion of every job that belongs to that group except the last one
	 *   (the shouldCancel method is not called after the completion of the last job in the
	 *   jobGroup as there are no jobs left to cancel).
	 */
	public void testShouldCancel_3() {
		final int status[] = {IStatus.OK, IStatus.INFO, IStatus.WARNING, IStatus.ERROR, IStatus.CANCEL, IStatus.OK};
		final int numShouldCancelCalled[] = {0};
		final int failedJobsCount[] = {0};
		final int canceledJobsCount[] = {0};
		final IStatus completedJobResult[] = new Status[1];
		final TestBarrier barrier = new TestBarrier();

		final JobGroup jobGroup = new JobGroup("JobGroup", 1, status.length) {
			@Override
			protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
				numShouldCancelCalled[0]++;
				failedJobsCount[0] = numberOfFailedJobs;
				canceledJobsCount[0] = numberOfCanceledJobs;
				completedJobResult[0] = lastCompletedJobResult;
				barrier.setStatus(TestBarrier.STATUS_DONE);
				return false;
			}
		};

		for (int i = 0; i < status.length; i++) {
			final int jobNumber = i;
			final IStatus returnedStatus[] = new IStatus[1];
			Job job = new TestJob("TestJob", 10, 10) {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					super.run(monitor);
					returnedStatus[0] = new Status(status[jobNumber], "org.eclipse.core.jobs", "Job " + jobNumber);
					return returnedStatus[0];
				}
			};
			job.setJobGroup(jobGroup);
			barrier.setStatus(TestBarrier.STATUS_WAIT_FOR_DONE);
			job.schedule();

			// shouldCancel method will not be invoked for the last job.
			if (i == status.length - 1) {
				continue;
			}

			barrier.waitForStatus(TestBarrier.STATUS_DONE);
			// Verify that the shouldCancel method is called with appropriate values.
			assertEquals("1." + i, i + 1, numShouldCancelCalled[0]);
			assertEquals("2." + i, returnedStatus[0], completedJobResult[0]);
			if (i < 3) {
				assertEquals("3." + i, 0, failedJobsCount[0]);
			} else {
				assertEquals("3." + i, 1, failedJobsCount[0]);
			}
			if (i < 4) {
				assertEquals("4." + i, 0, canceledJobsCount[0]);
			} else {
				assertEquals("4." + i, 1, canceledJobsCount[0]);
			}
		}
		waitForCompletion(jobGroup);
	}

	/**
	 * Tested scenario:
	 *   - JobGroup.shouldCancel returns true after certain jobs are completed.
	 *
	 * Expected result:
	 *   The remaining jobs are canceled in a reasonable time after the shouldCancel method of the
	 *   JobGroup returns true.
	 */
	public void testShouldCancel_4() {
		final int NUM_JOBS = 1000;
		final int NUM_JOBS_LIMIT = 100;
		final int numShouldCancelCalled[] = {0};
		final TestBarrier barrier = new TestBarrier();
		final JobGroup jobGroup = new JobGroup("JobGroup", 10, NUM_JOBS) {
			@Override
			protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
				numShouldCancelCalled[0]++;
				if (numShouldCancelCalled[0] == NUM_JOBS_LIMIT) {
					return true;
				}
				return false;
			}
		};
		for (int i = 0; i < NUM_JOBS; i++) {
			final int jobNumber = i;
			Job job = new TestJob("TestJob", 10, 10) {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					barrier.waitForStatus(TestBarrier.STATUS_START);
					super.run(monitor);
					return new Status(IStatus.INFO, "org.eclipse.core.jobs", "Job " + jobNumber);
				}
			};
			job.setJobGroup(jobGroup);
			job.schedule();
		}
		// Allow the jobs to proceed to run.
		barrier.setStatus(TestBarrier.STATUS_START);
		waitForCompletion(jobGroup);
		assertTrue("1.0", numShouldCancelCalled[0] >= NUM_JOBS_LIMIT);
		// Verify that the group is canceled in a reasonable time,
		// i.e only 10 jobs are allowed to run after the shouldCancel method returned true.
		assertTrue("2.0", numShouldCancelCalled[0] < NUM_JOBS_LIMIT + 10);
	}

	public void testDefaultComputeGroupResult() {
		final int status[] = {IStatus.OK, IStatus.INFO, IStatus.WARNING, IStatus.ERROR, IStatus.CANCEL};
		final JobGroup jobGroup = new JobGroup("JobGroup", 1, status.length) {
			@Override
			protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
				// Return false always so that the group will not be canceled due to failed jobs.
				return false;
			}
		};

		for (int i = 0; i < status.length; i++) {
			final int jobNumber = i;
			Job job = new TestJob("TestJob", 10, 10) {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					super.run(monitor);
					return new Status(status[jobNumber], "org.eclipse.core.jobs", "Job " + jobNumber);
				}
			};
			job.setJobGroup(jobGroup);
			job.schedule();
		}
		waitForCompletion(jobGroup);
		IStatus[] jobResults = jobGroup.getResult().getChildren();
		// Verify that the group result contains all the job results except the OK statuses.
		assertEquals("1.0", status.length - 1, jobResults.length);
		for (int i = 1; i < status.length; i++) {
			assertEquals("2." + i, status[i], jobResults[i - 1].getSeverity());
		}
	}

	public void testCustomComputeGroupResult() {
		final MultiStatus returnedGroupResult[] = new MultiStatus[1];
		final IStatus originalJobResults[][] = {new IStatus[0]};
		final int status[] = {IStatus.OK, IStatus.INFO, IStatus.WARNING, IStatus.ERROR, IStatus.CANCEL};
		final JobGroup jobGroup = new JobGroup("group", 1, status.length) {
			@Override
			protected boolean shouldCancel(IStatus lastCompletedJobResult, int numberOfFailedJobs, int numberOfCanceledJobs) {
				return false;
			}

			@Override
			protected MultiStatus computeGroupResult(List<IStatus> jobResults) {
				// Record the original job results and return a dummy groupresult.
				originalJobResults[0] = jobResults.toArray(new IStatus[jobResults.size()]);
				returnedGroupResult[0] = new MultiStatus("org.eclipse.core.jobs", 0, new IStatus[0], "custom result", null);
				return returnedGroupResult[0];
			}
		};

		for (int i = 0; i < status.length; i++) {
			final int jobNumber = i;
			Job job = new TestJob("TestJob", 10, 10) {
				@Override
				public IStatus run(IProgressMonitor monitor) {
					super.run(monitor);
					return new Status(status[jobNumber], "org.eclipse.core.jobs", "Job " + jobNumber);
				}
			};
			job.setJobGroup(jobGroup);
			job.schedule();
		}
		waitForCompletion(jobGroup);
		// Verify that the compute group result is called with all the completed job results.
		assertEquals("2.0", status.length, originalJobResults[0].length);
		for (int i = 0; i < status.length; i++) {
			assertEquals("3." + i, status[i], originalJobResults[0][i].getSeverity());
		}
		// Verify that JobGroup.getResult returns the status returned by JobGroup.computeGroupResult method.
		assertEquals("4.0", returnedGroupResult[0], jobGroup.getResult());
	}

	// https://bugs.eclipse.org/461621
	public void testSlowComputeGroupResult() throws Exception {
		final JobGroup jobGroup = new JobGroup("group", 1, 1) {
			@Override
			protected MultiStatus computeGroupResult(List<IStatus> jobResults) {
				sleep(500);
				return new MultiStatus("org.eclipse.core.jobs", 0, new IStatus[0], "custom result", null);
			}
		};

		Job job = new Job("TestJob") {
			@Override
			public IStatus run(IProgressMonitor monitor) {
				return Status.OK_STATUS;
			}
		};
		job.setJobGroup(jobGroup);
		job.schedule();
		waitForCompletion(job, 100);

		boolean completed = jobGroup.join(1000, null);
		assertTrue("2.0", completed);
		MultiStatus result = jobGroup.getResult();
		assertNotNull("3.0", result);
	}

	/**
	 * Tests that job groups work fine with normal jobs that are not belonging to any group.
	 */
	public void testJobGroupAlongWithNormalJobs() {
		final int NUM_GROUP_JOBS = 1000;
		final int NUM_NORMAL_JOBS = 100;
		JobGroup jobGroup = new JobGroup("JobGroup", 1, NUM_GROUP_JOBS);
		for (int i = 0; i < NUM_GROUP_JOBS; i++) {
			TestJob testJob = new TestJob("GroupJob", 1000000, 10);
			testJob.setJobGroup(jobGroup);
			testJob.schedule();
		}
		assertEquals("1.0", JobGroup.ACTIVE, jobGroup.getState());
		assertEquals("2.0", NUM_GROUP_JOBS, jobGroup.getActiveJobs().size());

		TestJob normalJobs[] = new TestJob[NUM_NORMAL_JOBS];
		for (int i = 0; i < NUM_NORMAL_JOBS; i++) {
			TestJob testJob = new TestJob("NormalJob", 10, 10);
			normalJobs[i] = testJob;
			testJob.schedule();
		}
		for (int i = 0; i < NUM_NORMAL_JOBS; i++) {
			waitForCompletion(normalJobs[i]);
		}

		// Tests that the normal jobs are completed fine while the group jobs are still running.
		assertEquals("3.0", JobGroup.ACTIVE, jobGroup.getState());
		assertEquals("4.0", NUM_GROUP_JOBS, jobGroup.getActiveJobs().size());
		jobGroup.cancel();
		waitForCompletion(jobGroup);
	}

	/**
	 * Tests that the JobManager publishes a final job group status to IJobChangeListeners.
	 */
	public void testJobManagerPublishesJobGroupResults() {
		final int NUM_GROUP_JOBS = 3;
		final String GROUP_NAME = "TestJobGroup";
		final JobGroup jobGroup = new JobGroup(GROUP_NAME, 1, NUM_GROUP_JOBS);

		// Record job completion events for all jobs in this job group.
		final List<IJobChangeEvent> events = new ArrayList<>(NUM_GROUP_JOBS);
		IJobChangeListener listener = new JobChangeAdapter() {
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getJob().getJobGroup() == jobGroup) {
					events.add(event);
				}
			}
		};
		manager.addJobChangeListener(listener);

		// Execute all jobs in the job group and validate that the last job includes the job group result.
		try {
			for (int i = 0; i < NUM_GROUP_JOBS; i++) {
				TestJob testJob = new TestJob("GroupJob", 10, 1);
				testJob.setJobGroup(jobGroup);
				testJob.schedule();
			}
			waitForCompletion(jobGroup);

			assertEquals("Should have seen as many job completion events as the count of jobs in the job group.", NUM_GROUP_JOBS, events.size());
			for (int i = 0; i < NUM_GROUP_JOBS; i++) {
				IJobChangeEvent event = events.get(i);
				assertNotNull("All job completion events should have a job status.", event.getResult());
				if (i < NUM_GROUP_JOBS - 1) {
					assertNull("Only the last job competion event shoud have a job group status.", event.getJobGroupResult());
				} else {
					assertNotNull("The last job competion event shoud have a job group status.", event.getJobGroupResult());
				}
			}
		} finally {
			manager.removeJobChangeListener(listener);
		}
	}

	private 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);
		}
	}

	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";
	}

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

	private void waitForCompletion(JobGroup jobGroup) {
		int i = 0;
		while (jobGroup.getState() != JobGroup.NONE) {
			Thread.yield();
			sleep(100);
			Thread.yield();
			// Sanity test to avoid hanging tests.
			if (i++ >= 100) {
				dumpState();
				fail("Timeout waiting for job group " + jobGroup.getName() + " to be completed");
			}
		}
	}
}
