/*******************************************************************************
 * Copyright (c) 2007, 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 Corporation - initial API and implementation
 *     Jeanderson Candido <http://jeandersonbc.github.io> - Bug 433603
 *******************************************************************************/

package org.eclipse.ui.tests.services;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.expressions.ExpressionInfo;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.internal.expressions.TestExpression;
import org.eclipse.core.internal.expressions.WithExpression;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.IContextActivation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.internal.handlers.HandlerPersistence;
import org.eclipse.ui.services.IEvaluationReference;
import org.eclipse.ui.services.IEvaluationService;
import org.eclipse.ui.services.ISourceProviderService;
import org.eclipse.ui.tests.SelectionProviderView;
import org.eclipse.ui.tests.commands.ActiveContextExpression;
import org.eclipse.ui.tests.harness.util.UITestCase;
import org.junit.Assume;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;

/**
 * @since 3.3
 *
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EvaluationServiceTest extends UITestCase {
	/**
	 *
	 */
	private static final String CHECK_HANDLER_ID = "org.eclipse.ui.tests.services.checkHandler";
	private static final String CONTEXT_ID1 = "org.eclipse.ui.command.contexts.evaluationService1";

	/**
	 * @param testName
	 */
	public EvaluationServiceTest(String testName) {
		super(testName);
	}

	private static class MyEval implements IPropertyChangeListener {
		public volatile int count = 0;
		public volatile boolean currentValue;

		@Override
		public void propertyChange(PropertyChangeEvent event) {
			count++;
			if (event.getProperty() == IEvaluationService.RESULT
					&& event.getNewValue() instanceof Boolean) {
				currentValue = ((Boolean) event.getNewValue()).booleanValue();
			}
		}
	}

	public void testBug334524() throws Exception {
		IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
		IPerspectiveDescriptor resourecePerspective = registry.findPerspectiveWithId("org.eclipse.ui.resourcePerspective");
		IPerspectiveDescriptor javaPerspective = registry.findPerspectiveWithId("org.eclipse.jdt.ui.JavaPerspective");
		String viewId = "org.eclipse.ui.tests.SelectionProviderView";

		IWorkbenchWindow window = openTestWindow();
		IWorkbenchPage activePage = window.getActivePage();

		// show view in resource perspective
		activePage.setPerspective(resourecePerspective);
		SelectionProviderView view = (SelectionProviderView) activePage.showView(viewId);
		processEvents();

		// show view in java perspective
		activePage.setPerspective(javaPerspective);
		activePage.showView(viewId);
		processEvents();

		// now set the selection
		IStructuredSelection selection = new StructuredSelection(new String("testing selection"));
		view.setSelection(selection);
		processEvents();

		// switch perspective & check selection
		activePage.setPerspective(resourecePerspective);
		processEvents();

		IEvaluationService service = window.getService(IEvaluationService.class);
		Object currentSelection = service.getCurrentState().getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
		assertEquals(selection, currentSelection);

	}

	public void testBasicService() throws Exception {
		IWorkbenchWindow window = openTestWindow();
		waitForJobs(500, 5000);

		boolean activeShell = forceActive(window.getShell());
		Assume.assumeTrue(activeShell);

		IEvaluationService service = window
				.getService(IEvaluationService.class);
		assertNotNull(service);

		MyEval listener = new MyEval();
		IContextActivation context1 = null;
		IEvaluationReference evalRef = null;
		IContextService contextService = null;
		try {
			contextService = window.getService(IContextService.class);
			assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			evalRef = service.addEvaluationListener(
					new ActiveContextExpression(CONTEXT_ID1,
							new String[] { ISources.ACTIVE_CONTEXT_NAME }),
					listener, IEvaluationService.RESULT);
			assertEquals(1, listener.count);
			assertFalse(listener.currentValue);


			context1 = contextService.activateContext(CONTEXT_ID1);
			processEvents();
			waitForJobs(500, 3000);
			assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			assertEquals(2, listener.count);
			assertTrue(listener.currentValue);

			contextService.deactivateContext(context1);
			context1 = null;
			assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			assertEquals(3, listener.count);
			assertFalse(listener.currentValue);

			service.removeEvaluationListener(evalRef);
			evalRef = null;
			assertEquals(4, listener.count);

			context1 = contextService.activateContext(CONTEXT_ID1);
			processEvents();
			waitForJobs(500, 3000);
			assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			assertEquals(4, listener.count);
			assertFalse(listener.currentValue);
			contextService.deactivateContext(context1);
			context1 = null;
			assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			assertEquals(4, listener.count);
			assertFalse(listener.currentValue);
		} finally {
			if (context1 != null) {
				contextService.deactivateContext(context1);
			}
			if (evalRef != null) {
				service.removeEvaluationListener(evalRef);
			}
		}
	}

	public void testTwoEvaluations() throws Exception {
		IWorkbenchWindow window = openTestWindow();
		boolean activeShell = forceActive(window.getShell());

		waitForJobs(500, 5000);

		final AtomicBoolean shellIsActive = new AtomicBoolean(activeShell);
		Assume.assumeTrue(shellIsActive.get());

		IEvaluationService service = window
				.getService(IEvaluationService.class);
		assertNotNull(service);
		MyEval listener1 = new MyEval();
		MyEval listener2 = new MyEval();
		IContextActivation context1 = null;
		IEvaluationReference evalRef1 = null;
		IEvaluationReference evalRef2 = null;
		IContextService contextService = null;
		try {
			contextService = window.getService(IContextService.class);
			assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			evalRef1 = service.addEvaluationListener(
					new ActiveContextExpression(CONTEXT_ID1,
							new String[] { ISources.ACTIVE_CONTEXT_NAME }),
					listener1, IEvaluationService.RESULT);
			assertEquals(1, listener1.count);
			assertFalse(listener1.currentValue);

			evalRef2 = service.addEvaluationListener(
					new ActiveContextExpression(CONTEXT_ID1,
							new String[] { ISources.ACTIVE_CONTEXT_NAME }),
					listener2, IEvaluationService.RESULT);
			assertEquals(1, listener2.count);
			assertFalse(listener2.currentValue);
			evalRef2.setResult(true);

			context1 = contextService.activateContext(CONTEXT_ID1);
			processEvents();
			waitForJobs(500, 3000);
			assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			int count = 0;
			while (count < 5 && listener1.count != 2) {
				count++;
				waitForJobs(100 * count, 1000);
			}

			assertEquals(2, listener1.count);
			assertTrue(listener1.currentValue);
			// we already set this guy to true, he should skip
			assertEquals(1, listener2.count);
			assertFalse(listener2.currentValue);

			evalRef1.setResult(false);
			contextService.deactivateContext(context1);
			processEvents();
			waitForJobs(500, 3000);
			assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));

			context1 = null;
			assertEquals(2, listener2.count);
			assertFalse(listener2.currentValue);

			// we already set this guy to false, so he should be the old
			// values
			assertEquals(2, listener1.count);
			assertTrue(listener1.currentValue);

		} finally {
			if (context1 != null) {
				contextService.deactivateContext(context1);
			}
			if (evalRef1 != null) {
				service.removeEvaluationListener(evalRef1);
			}
			if (evalRef2 != null) {
				service.removeEvaluationListener(evalRef2);
			}
		}
	}

	// TODO fix testRestriction
	public void TODOtestRestriction() {
		IWorkbenchWindow window = openTestWindow();
		IEvaluationService evaluationService = window
				.getService(IEvaluationService.class);
		assertNotNull(evaluationService);
		IContextService contextService = window
				.getService(IContextService.class);
		assertNotNull(contextService);

		Expression expression = new ActiveContextExpression(CONTEXT_ID1,
				new String[] { ISources.ACTIVE_CONTEXT_NAME });

		final boolean[] propertyChanged = new boolean[1];
		final boolean[] propertyShouldChange = new boolean[1];

		IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if (event.getProperty().equals("foo")) {
					propertyChanged[0] = true;
				}

			}
		};
		IEvaluationReference ref = evaluationService.addEvaluationListener(
				expression, propertyChangeListener, "foo");
		((WorkbenchWindow)window).getMenuRestrictions().add(ref);

		IPropertyChangeListener propertyShouldChangeListener = new IPropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if (event.getProperty().equals("foo")) {
					propertyShouldChange[0] = true;
				}

			}
		};
		evaluationService.addEvaluationListener(expression,
				propertyShouldChangeListener, "foo");

		propertyChanged[0] = false;
		propertyShouldChange[0] = false;

		assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));
		IContextActivation activation = contextService
				.activateContext(CONTEXT_ID1);

		assertTrue(propertyChanged[0]);
		assertTrue(propertyShouldChange[0]);
		propertyChanged[0] = false;
		propertyShouldChange[0] = false;

		contextService.deactivateContext(activation);
		assertTrue(propertyChanged[0]);
		assertTrue(propertyShouldChange[0]);
		assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));
		activation = contextService.activateContext(CONTEXT_ID1);
		propertyChanged[0] = false;
		propertyShouldChange[0] = false;
		assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1));

		// open second window
		IWorkbenchWindow window2 = openTestWindow();
		assertFalse(propertyChanged[0]);
		assertTrue(propertyShouldChange[0]);
		assertFalse(contextService.getActiveContextIds().contains(CONTEXT_ID1));
		propertyChanged[0] = false;
		propertyShouldChange[0] = false;

		window2.close();
		processEvents();

		assertTrue(contextService.getActiveContextIds().contains(CONTEXT_ID1));
		assertFalse(propertyChanged[0]);
		assertTrue(propertyShouldChange[0]);
	}

	// TODO fix testScopedService
	public void TODOtestScopedService() throws Exception {
		IWorkbenchWindow window = openTestWindow();
		IEvaluationService service = window
				.getService(IEvaluationService.class);
		assertNotNull(service);
		//assertTrue(service instanceof SlaveEvaluationService);

		MyEval listener = new MyEval();
		IContextActivation context1 = null;
		IContextService contextService = null;
		try {
			service.addEvaluationListener(
					new ActiveContextExpression(CONTEXT_ID1,
							new String[] { ISources.ACTIVE_CONTEXT_NAME }),
					listener, IEvaluationService.RESULT);
			assertEquals(1, listener.count);
			assertFalse(listener.currentValue);

			contextService = window.getWorkbench()
					.getService(IContextService.class);
			context1 = contextService.activateContext(CONTEXT_ID1);
			assertEquals(2, listener.count);
			assertTrue(listener.currentValue);

			window.close();
			processEvents();
			assertEquals(3, listener.count);
			assertTrue(listener.currentValue);

			contextService.deactivateContext(context1);
			context1 = null;
			assertEquals(3, listener.count);
			assertTrue(listener.currentValue);
		} finally {
			if (context1 != null) {
				contextService.deactivateContext(context1);
			}
		}
	}

	private static class UserExpression extends Expression {
		public String lookFor;

		public UserExpression(String lookFor) {
			this.lookFor = lookFor;
		}

		@Override
		public void collectExpressionInfo(ExpressionInfo info) {
			info.addVariableNameAccess("username");
		}

		@Override
		public EvaluationResult evaluate(IEvaluationContext context) {
			String variable = (String) context.getVariable("username");
			return lookFor.equals(variable) ? EvaluationResult.TRUE
					: EvaluationResult.FALSE;
		}
	}

	public void testSourceProvider() throws Exception {
		IWorkbenchWindow window = openTestWindow();
		IEvaluationService service = window
				.getService(IEvaluationService.class);
		assertNotNull(service);

		MyEval listener = new MyEval();
		UserExpression expression = new UserExpression("Paul");
		IEvaluationReference ref = service.addEvaluationListener(expression,
				listener, IEvaluationService.RESULT);
		assertEquals(ISources.ACTIVE_CONTEXT << 1, ref.getSourcePriority());
		assertFalse(listener.currentValue);
		assertEquals(1, listener.count);

		ISourceProviderService sps = window
				.getService(ISourceProviderService.class);
		ActiveUserSourceProvider userProvider = (ActiveUserSourceProvider) sps
				.getSourceProvider("username");

		userProvider.setUsername("John");
		assertFalse(listener.currentValue);
		assertEquals(1, listener.count);

		userProvider.setUsername("Paul");
		assertTrue(listener.currentValue);
		assertEquals(2, listener.count);

		userProvider.setUsername("guest");
		assertFalse(listener.currentValue);
		assertEquals(3, listener.count);
	}

	@SuppressWarnings("unchecked")
	public void testSourceProviderPriority() throws Exception {
		IHandlerService hs = getWorkbench().getService(IHandlerService.class);

		Collection<IHandlerActivation> activations = null;
		// fill in a set of activations
		String hsClassName = hs.getClass().getName();
		if (hsClassName.equals("org.eclipse.ui.internal.handlers.HandlerService")) {
			Field hpField = hs.getClass().getDeclaredField("handlerPersistence");
			hpField.setAccessible(true);

			HandlerPersistence hp = (HandlerPersistence) hpField.get(hs);

			Field activationsField = hp.getClass().getDeclaredField("handlerActivations");
			activationsField.setAccessible(true);
			activations = (Collection<IHandlerActivation>) activationsField.get(hp);
			assertNotNull(activations);
		} else if (hsClassName.equals("org.eclipse.ui.internal.handlers.LegacyHandlerService")) {
			Field hsField = hs.getClass().getDeclaredField("LEGACY_H_ID");
			String LEGACY_H_ID = (String) hsField.get(null);
			Field hpField = hs.getClass().getDeclaredField("eclipseContext");
			hpField.setAccessible(true);
			Object eclipseContext = hpField.get(hs);
			assertNotNull(eclipseContext);
			Method getMethod = eclipseContext.getClass().getDeclaredMethod("get", String.class);
			activations = (Collection<IHandlerActivation>) getMethod.invoke(eclipseContext,
					LEGACY_H_ID + CHECK_HANDLER_ID);
			assertNotNull(activations);
		} else {
			fail("Incorrect handler service: " + hsClassName);
		}

		IHandlerActivation activation = null;
		Iterator<IHandlerActivation> i = activations.iterator();
		while (i.hasNext()) {
			IHandlerActivation ha = i.next();
			if (CHECK_HANDLER_ID.equals(ha.getCommandId())) {
				activation = ha;
			}
		}


		assertNotNull("Could not find activation for " + CHECK_HANDLER_ID, activation);

		assertEquals(ISources.ACTIVE_CONTEXT<<1, activation.getSourcePriority());
	}

	public void testPropertyChange() throws Exception {
		IWorkbenchWindow window = openTestWindow();
		IEvaluationService service = window
				.getService(IEvaluationService.class);
		assertNotNull(service);
		MyEval listener = new MyEval();
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IConfigurationElement element = null;
		IConfigurationElement[] elements = registry
				.getConfigurationElementsFor("org.eclipse.core.expressions.definitions");
		for (int i = 0; i < elements.length && element == null; i++) {
			if (elements[i].getAttribute("id").equals(
					"org.eclipse.ui.tests.defWithPropertyTester")) {
				element = elements[i];
			}
		}

		assertNotNull(element);
		Expression expr = ExpressionConverter.getDefault().perform(element.getChildren()[0]);
		service.addEvaluationListener(expr,
				listener, IEvaluationService.RESULT);
		assertFalse(listener.currentValue);
		assertEquals(1, listener.count);

		StaticVarPropertyTester.result = true;
		assertFalse(listener.currentValue);
		assertEquals(1, listener.count);

		service.requestEvaluation("org.eclipse.ui.tests.class.method");
		assertTrue(listener.currentValue);
		assertEquals(2, listener.count);

		service.requestEvaluation("org.eclipse.ui.tests.class.method");
		assertTrue(listener.currentValue);
		assertEquals(2, listener.count);
	}

	public void testPlatformProperty() throws Exception {
		IEvaluationService evaluationService = PlatformUI
				.getWorkbench().getService(IEvaluationService.class);
		TestExpression test = new TestExpression("org.eclipse.core.runtime",
				"bundleState",
				new Object[] { "org.eclipse.core.expressions" }, "ACTIVE", false);
		WithExpression exp = new WithExpression("org.eclipse.core.runtime.Platform");
		exp.add(test);
		EvaluationResult result= exp.evaluate(evaluationService.getCurrentState());
		assertEquals(EvaluationResult.TRUE, result);
	}

	public void XtestSystemProperty() throws Exception {
		// this is not added, as the ability to test system properties with
		// no '.' seems unhelpful
		System.setProperty("isHere", "true");
		IEvaluationService evaluationService = PlatformUI
				.getWorkbench().getService(IEvaluationService.class);
		TestExpression test = new TestExpression("org.eclipse.core.runtime",
				"isHere",
				new Object[] { "true" }, null, false);
		WithExpression exp = new WithExpression(
				"java.lang.System" );
		exp.add(test);
		EvaluationResult result = exp.evaluate(evaluationService
				.getCurrentState());
		assertEquals(EvaluationResult.TRUE, result);

	}

	static class ActivePartIdExpression extends Expression {
		private String partId;

		public ActivePartIdExpression(String id) {
			partId = id;
		}

		@Override
		public void collectExpressionInfo(ExpressionInfo info) {
			info.addVariableNameAccess(ISources.ACTIVE_PART_ID_NAME);
			info.addVariableNameAccess(ISources.ACTIVE_CURRENT_SELECTION_NAME);
		}

		@Override
		public EvaluationResult evaluate(IEvaluationContext context){
			Object v = context.getVariable(ISources.ACTIVE_PART_ID_NAME);
			return EvaluationResult.valueOf(partId.equals(v));
		}
	}

	static class PartSelection {
		public ISelection selection;
		public IWorkbenchPart part;

		public PartSelection(ISelection sel, IWorkbenchPart p) {
			selection = sel;
			part = p;
		}
	}

	public void testWorkbenchProvider() throws Exception {

		IWorkbenchWindow window = openTestWindow();
		final IEvaluationService service = window
				.getWorkbench().getService(IEvaluationService.class);
		assertNotNull(service);

		// some setup
		IWorkbenchPage page = window.getActivePage();
		SelectionProviderView view1 = (SelectionProviderView) page
				.showView(org.eclipse.ui.tests.SelectionProviderView.ID);
		view1.setSelection(StructuredSelection.EMPTY);
		SelectionProviderView view2 = (SelectionProviderView) page
				.showView(org.eclipse.ui.tests.SelectionProviderView.ID_2);
		TextSelection mySelection = new TextSelection(0, 5);
		view2.setSelection(mySelection);

		processEvents();

		final ArrayList<PartSelection> selection = new ArrayList<>();
		IPropertyChangeListener listener = new IPropertyChangeListener() {
			@Override
			public void propertyChange(PropertyChangeEvent event) {
				IEvaluationContext state = service.getCurrentState();
				try {
					ISelection sel = null;
					IWorkbenchPart part = null;
					Object o = state
							.getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
					if (o instanceof ISelection) {
						sel = (ISelection) o;
					}
					o = state.getVariable(ISources.ACTIVE_PART_NAME);
					if (o instanceof IWorkbenchPart) {
						part = (IWorkbenchPart) o;
					}
					selection.add(new PartSelection(sel, part));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};

		IEvaluationReference ref = service.addEvaluationListener(
				new ActivePartIdExpression(
						org.eclipse.ui.tests.SelectionProviderView.ID),
				listener, "PROP");
		int callIdx = 0;
		try {

			// initially ID_2 is showed
			assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2);

			page.activate(view1);
			processEvents();
			callIdx++;

			assertSelection(selection, callIdx, StructuredSelection.class, SelectionProviderView.ID);

			page.activate(view2);
			processEvents();
			callIdx++;

			assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2);
			assertEquals(window.getActivePage().getActivePart().getSite().getId(),
					service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME));

			IWorkbenchWindow window2 = openTestWindow();
			IWorkbenchPage page2 = window2.getActivePage();
			processEvents();

			// no change
			assertEquals(callIdx + 1, selection.size());

			SelectionProviderView view3 = (SelectionProviderView) page2
					.showView(org.eclipse.ui.tests.SelectionProviderView.ID);
			processEvents();
			// id1 activated with default selection StructuredSelection.EMPTY
			callIdx++;

			assertSelection(selection, callIdx, StructuredSelection.class, SelectionProviderView.ID);
			assertEquals(window2.getActivePage().getActivePart().getSite().getId(),
					service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME));

			view3.setSelection(new TreeSelection(new TreePath(new Object[] {"nothing"})));
			processEvents();
			// selection changes, but view id remains the same - so no callIdx increments
			assertEquals(callIdx + 1, selection.size());

			window.getShell().forceActive();
			processEvents();
			// the shell activate should have forced another change
			callIdx++;
//			assertEquals(window.getActivePage().getActivePart().getSite().getId(),
//					service.getCurrentState().getVariable(ISources.ACTIVE_PART_ID_NAME));

//			assertSelection(selection, callIdx, TextSelection.class, SelectionProviderView.ID_2);

		} finally {
			service.removeEvaluationListener(ref);
		}
	}

	private void assertSelection(final ArrayList<PartSelection> selection, int callIdx, Class<?> clazz, String viewId) {
		assertEquals(callIdx + 1, selection.size());
		assertEquals(clazz, getSelection(selection, callIdx)
				.getClass());
		assertEquals(viewId, getPart(selection, callIdx).getSite().getId());
	}

	private ISelection getSelection(final ArrayList<PartSelection> selection, int idx) {
		return selection.get(idx).selection;
	}

	private IWorkbenchPart getPart(final ArrayList<PartSelection> selection, int idx) {
		return selection.get(idx).part;
	}
}
