/*******************************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.tests.keys;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.Category;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandManager;
import org.eclipse.core.commands.IParameter;
import org.eclipse.core.commands.IParameterValues;
import org.eclipse.core.commands.ParameterValuesException;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.contexts.Context;
import org.eclipse.core.commands.contexts.ContextManager;
import org.eclipse.jface.bindings.Binding;
import org.eclipse.jface.bindings.BindingManager;
import org.eclipse.jface.bindings.BindingManagerEvent;
import org.eclipse.jface.bindings.IBindingManagerListener;
import org.eclipse.jface.bindings.Scheme;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.bindings.keys.KeyBinding;
import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.ui.tests.harness.util.UITestCase;

/**
 * <p>
 * This test case covers the general functionality of the binding manager's API
 * methods. This is not intended to test the interactions between bindings
 * themselves (e.g., solving a binding set). For tests dealing with
 * interactions, please look at <code>BindingInteractionsTest</code>.
 * </p>
 * <p>
 * The listener code is tested throughout the various tests. There is no
 * individual test method for the listener code.
 * </p>
 * 
 * @see org.eclipse.ui.tests.keys.BindingInteractionsTest
 * @since 3.1
 */
public final class BindingManagerTest extends UITestCase {

	/**
	 * A test listener that should be attached to the binding manager. The
	 * listener records the last fired event.
	 * 
	 * @since 3.1
	 */
	private static final class TestListener implements IBindingManagerListener {

		/**
		 * The last event that this listener saw. <code>null</code> if none.
		 */
		private BindingManagerEvent event = null;

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.bindings.IBindingManagerListener#bindingManagerChanged(org.eclipse.jface.bindings.BindingManagerEvent)
		 */
		public void bindingManagerChanged(BindingManagerEvent e) {
			this.event = e;
		}

		/**
		 * Returns the last event.
		 * 
		 * @return The last event; may be <code>null</code> if none.
		 */
		public final BindingManagerEvent getLastEvent() {
			return event;
		}
	}

	/**
	 * The binding manager to use in each test case. A new binding manager is
	 * created for each test case, and it is disposed when the test is over.
	 */
	private BindingManager bindingManager = null;

	/**
	 * The command manager for the currently running test. <code>null</code>
	 * if no test is running.
	 */
	private CommandManager commandManager = null;

	/**
	 * The context manager to use in each test case. A new context manager is
	 * created for each test case, and it is disposed when the test is over.
	 */
	private ContextManager contextManager = null;

	/**
	 * The listener attached to the binding manager. This listener is attached
	 * at the beginning of each test case, and it is disposed when the test is
	 * over.
	 */
	private TestListener listener = null;

	/**
	 * Constructor for <code>BindingInteractionsTest</code>.
	 * 
	 * @param name
	 *            The name of the test
	 */
	public BindingManagerTest(final String name) {
		super(name);
	}

	/**
	 * Creates a new context manager and a binding manager for use in the test
	 * cases.
	 */
	protected final void doSetUp() {
		commandManager = new CommandManager();
		contextManager = new ContextManager();
		bindingManager = new BindingManager(contextManager, commandManager);
		listener = new TestListener();
		bindingManager.addBindingManagerListener(listener);
	}

	/**
	 * Releases the context manager and binding manager for garbage collection.
	 */
	protected final void doTearDown() {
		bindingManager.removeBindingManagerListener(listener);
		listener = null;
		bindingManager = null;
		contextManager = null;
		commandManager = null;
	}

	/**
	 * Tests that the constructor disallows a null context manager.
	 */
	public final void testConstructor() {
		try {
			new BindingManager(null, null);
			fail("A binding manager cannot be constructed with a null context manager");
		} catch (final NullPointerException e) {
			// Success
		}
	}

	/**
	 * Tests that it is not possible to add a null binding. Tests that adding a
	 * binding forces a recomputation.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 */
	public final void testAddBinding() throws NotDefinedException {
		// Set up a state in which a binding may become active.
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// Try to add a null binding.
		try {
			bindingManager.addBinding(null);
			fail("It should not be possible to add a null binding");
		} catch (final NullPointerException e) {
			// Success.
		}

		// Try to add a binding that should become active.
		final Binding binding = new TestBinding("conflict1", "na", "na", null,
				null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding);
		assertSame("The binding should be active", binding, bindingManager
				.getPerfectMatch(TestBinding.TRIGGER_SEQUENCE));
	}

	/**
	 * Tests that <code>getActiveBindingsDisregardingContext()</code> never
	 * returns <code>null</code>. The rest of the functionality is tested in
	 * <code>BindingInteractionsTest</code>.
	 * 
	 * @see BindingInteractionsTest
	 */
	public final void testGetActiveBindingsDisregardingContext() {
		final Map activeBindings = bindingManager
				.getActiveBindingsDisregardingContext();
		assertNotNull("The active bindings should never be null",
				activeBindings);
		assertTrue("The active bindings should start empty", activeBindings
				.isEmpty());
	}

	/**
	 * Tests that <code>getActiveBindingsDisregardingContextFlat()</code>
	 * never returns <code>null</code>. The rest of the functionality is
	 * tested in <code>BindingInteractionsTest</code>.
	 * 
	 * @see BindingInteractionsTest
	 */
	public final void testGetActiveBindingsDisregardingContextFlat() {
		final Collection activeBindings = bindingManager
				.getActiveBindingsDisregardingContextFlat();
		assertNotNull("The active bindings should never be null",
				activeBindings);
		assertTrue("The active bindings should start empty", activeBindings
				.isEmpty());
	}

	/**
	 * Tests whether the method works with a null argument. Tests that it works
	 * in a simple case.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 */
	public final void testGetActiveBindingsFor() throws NotDefinedException {
		// Test with a null argument.
		final TriggerSequence[] activeBindingsForNull = bindingManager
				.getActiveBindingsFor((ParameterizedCommand) null);
		assertNotNull("The active bindings for a command should never be null",
				activeBindingsForNull);
		assertTrue(
				"The active binding for a null command should always be empty",
				activeBindingsForNull.length == 0);

		// Test a simple case.
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);

		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);

		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		final String commandId = "commandId";
		final Binding binding = new TestBinding(commandId, "na", "na", null,
				null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding);

		final TriggerSequence[] bindings = bindingManager
				.getActiveBindingsFor(binding.getParameterizedCommand());
		assertEquals("There should be one binding", 1, bindings.length);
		assertSame("The binding should match", TestBinding.TRIGGER_SEQUENCE,
				bindings[0]);
	}

	/**
	 * Tests that the active scheme starts off <code>null</code>. The rest of
	 * the active scheme testing happens in <code>testSetActiveScheme()</code>.
	 * 
	 * @see BindingManagerTest#testSetActiveScheme()
	 */
	public final void testGetActiveScheme() {
		assertNull("The active scheme should start null", bindingManager
				.getActiveScheme());
	}

	/**
	 * Tests that <code>getBindings</code> first returns <code>null</code>.
	 * It then verifies that an added binding is return from this method.
	 */
	public final void testGetBindings() {
		// Check the starting condition.
		assertNull("The bindings should start off null", bindingManager
				.getBindings());

		// Check that an added binding is included.
		final Binding binding = new TestBinding(null, "schemeId", "contextId",
				null, null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding);
		final Binding[] bindings = bindingManager.getBindings();
		assertEquals("There should be one binding", 1, bindings.length);
		assertSame("The binding should be the same", binding, bindings[0]);

		/*
		 * Check that modifying this set does not modify the internal data
		 * structures.
		 */
		bindings[0] = null;
		assertNotNull("There should be no change",
				bindingManager.getBindings()[0]);
	}

	/**
	 * Tests that the list of defined schemes stays up-to-date
	 */
	public final void testGetDefinedSchemeIds() {
		// Starting condition.
		assertTrue("The set of defined schemes should start empty",
				bindingManager.getDefinedSchemes().length == 0);

		// Retrieving a scheme shouldn't change anything.
		final Scheme scheme = bindingManager.getScheme("schemeId");
		assertTrue(
				"The set of defined schemes should still be empty after a get",
				bindingManager.getDefinedSchemes().length == 0);

		// Defining the scheme should change things.
		scheme.define("name", "description", null);
		Scheme[] definedSchemes = bindingManager.getDefinedSchemes();
		assertEquals("There should be one defined scheme id", 1,
				definedSchemes.length);
		assertSame("The defined scheme id should match", scheme,
				definedSchemes[0]);

		definedSchemes[0] = null;
		definedSchemes = bindingManager.getDefinedSchemes();
		assertSame("The API should not expose internal collections", scheme,
				definedSchemes[0]);

		// Undefining the scheme should also change things.
		scheme.undefine();
		assertTrue(
				"The set of defined schemes should be empty after an undefine",
				bindingManager.getDefinedSchemes().length == 0);
	}

	/**
	 * Tests that the active locale is never <code>null</code>.
	 */
	public final void testGetLocale() {
		assertNotNull("The locale should never be null", bindingManager
				.getLocale());
	}

	/**
	 * Tests that this method returns the expected list of sequences for a
	 * couple of scenarios. In the first scenario, there is one perfect match
	 * bindings and a partial match binding. In the second scenario, there are
	 * two partial match bindings. In the third scenario, we are checking that
	 * all bindings match an empty trigger sequence.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 * @throws ParseException
	 *             If the hard-coded strings aren't constructed properly.
	 */
	public final void testGetPartialMatches() throws NotDefinedException,
			ParseException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SCENARIO 1
		final KeySequence perfectMatch = KeySequence.getInstance("CTRL+F");
		final Command perfectCommand = commandManager.getCommand("perfect");
		final ParameterizedCommand perfectParameterizedCommand = new ParameterizedCommand(
				perfectCommand, null);
		final Binding perfectMatchBinding = new KeyBinding(perfectMatch,
				perfectParameterizedCommand, "na", "na", null, null, null,
				Binding.SYSTEM);
		final KeySequence partialMatch1 = KeySequence
				.getInstance("CTRL+F CTRL+F");
		final Command partialCommand1 = commandManager.getCommand("partial1");
		final ParameterizedCommand partialParameterizedCommand1 = new ParameterizedCommand(
				partialCommand1, null);
		final Binding partialMatchBinding1 = new KeyBinding(partialMatch1,
				partialParameterizedCommand1, "na", "na", null, null, null,
				Binding.SYSTEM);
		final Binding[] bindings = new Binding[2];
		bindings[0] = perfectMatchBinding;
		bindings[1] = partialMatchBinding1;
		bindingManager.setBindings(bindings);
		Map partialMatches = bindingManager.getPartialMatches(perfectMatch);
		assertTrue("A partial match should override a perfect match",
				!partialMatches.isEmpty());
		assertTrue("A partial match should override a perfect match",
				partialMatches.containsKey(partialMatch1));

		// SCENARIO 2
		final KeySequence partialMatch2 = KeySequence
				.getInstance("CTRL+F CTRL+F CTRL+F");
		final Command partialCommand2 = commandManager.getCommand("partial2");
		final ParameterizedCommand partialParameterizedCommand2 = new ParameterizedCommand(
				partialCommand2, null);
		final Binding partialMatchBinding2 = new KeyBinding(partialMatch2,
				partialParameterizedCommand2, "na", "na", null, null, null,
				Binding.SYSTEM);
		bindings[0] = partialMatchBinding1;
		bindings[1] = partialMatchBinding2;
		bindingManager.setBindings(bindings);
		partialMatches = bindingManager.getPartialMatches(perfectMatch);
		assertEquals("There should be two partial matches", 2, partialMatches
				.size());
		assertSame("The partial match should be the one defined",
				partialMatchBinding1, partialMatches.get(partialMatch1));
		assertSame("The partial match should be the one defined",
				partialMatchBinding2, partialMatches.get(partialMatch2));

		// SCENARIO 3
		bindingManager.addBinding(perfectMatchBinding);
		partialMatches = bindingManager.getPartialMatches(KeySequence
				.getInstance());
		assertEquals("There should be three partial matches", 3, partialMatches
				.size());
		assertSame("The partial match should be the one defined",
				perfectMatchBinding, partialMatches.get(perfectMatch));
		assertSame("The partial match should be the one defined",
				partialMatchBinding1, partialMatches.get(partialMatch1));
		assertSame("The partial match should be the one defined",
				partialMatchBinding2, partialMatches.get(partialMatch2));
	}

	/**
	 * Tests that this method returns the expected command identifier. In the
	 * first scenario, there is one perfect match bindings and a partial match
	 * binding. In the second scenario, there are two partial match bindings. In
	 * the third scenario, we are checking that nothing matches an empty
	 * sequence.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 * @throws ParseException
	 *             If the hard-coded strings aren't constructed properly.
	 */
	public final void testGetPerfectMatch() throws NotDefinedException,
			ParseException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SCENARIO 1
		final KeySequence perfectMatch = KeySequence.getInstance("CTRL+F");
		final Command perfectCommand = commandManager.getCommand("perfect");
		final ParameterizedCommand perfectParameterizedCommand = new ParameterizedCommand(
				perfectCommand, null);
		final Binding perfectMatchBinding = new KeyBinding(perfectMatch,
				perfectParameterizedCommand, "na", "na", null, null, null,
				Binding.SYSTEM);
		final KeySequence partialMatch1 = KeySequence
				.getInstance("CTRL+F CTRL+F");
		final Command partialCommand1 = commandManager.getCommand("partial1");
		final ParameterizedCommand partialParameterizedCommand1 = new ParameterizedCommand(
				partialCommand1, null);
		final Binding partialMatchBinding1 = new KeyBinding(partialMatch1,
				partialParameterizedCommand1, "na", "na", null, null, null,
				Binding.SYSTEM);
		final Binding[] bindings = new Binding[2];
		bindings[0] = perfectMatchBinding;
		bindings[1] = partialMatchBinding1;
		bindingManager.setBindings(bindings);
		Binding actualBinding = bindingManager.getPerfectMatch(perfectMatch);
		assertSame("This should be a perfect match", perfectMatchBinding,
				actualBinding);

		// SCENARIO 2
		final KeySequence partialMatch2 = KeySequence
				.getInstance("CTRL+F CTRL+F CTRL+F");
		final Command partialCommand2 = commandManager.getCommand("partial2");
		final ParameterizedCommand partialParameterizedCommand2 = new ParameterizedCommand(
				partialCommand2, null);
		final Binding partialMatchBinding2 = new KeyBinding(partialMatch2,
				partialParameterizedCommand2, "na", "na", null, null, null,
				Binding.SYSTEM);
		bindings[0] = partialMatchBinding1;
		bindings[1] = partialMatchBinding2;
		bindingManager.setBindings(bindings);
		actualBinding = bindingManager.getPerfectMatch(perfectMatch);
		assertNull("There should be no perfect matches", actualBinding);

		// SCENARIO 3
		bindingManager.addBinding(perfectMatchBinding);
		actualBinding = bindingManager.getPerfectMatch(KeySequence
				.getInstance());
		assertNull("This should be no perfect matches for an empty sequence",
				actualBinding);
	}

	/**
	 * Tests that the platform is never <code>null</code>.
	 */
	public final void testGetPlatform() {
		assertNotNull("The platform can never be null", bindingManager
				.getPlatform());
	}

	/**
	 * Tests that when a scheme is first retrieved, it is undefined. Tests that
	 * a second access to a scheme returns the same scheme.
	 */
	public final void testGetScheme() {
		final String schemeId = "schemeId";
		final Scheme firstScheme = bindingManager.getScheme(schemeId);
		assertTrue("A scheme should start undefined", !firstScheme.isDefined());
		final Scheme secondScheme = bindingManager.getScheme(schemeId);
		assertSame("The two scheme should be the same", firstScheme,
				secondScheme);
	}

	/**
	 * Tests that this method returns <code>true</code> when expected. In the
	 * first scenario, there is one perfect match bindings and a partial match
	 * binding. In the second scenario, there are two partial match bindings. In
	 * the third scenario, we are checking that all bindings match an empty
	 * trigger sequence.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 * @throws ParseException
	 *             If the hard-coded strings aren't constructed properly.
	 */
	public final void testIsPartialMatch() throws NotDefinedException,
			ParseException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SCENARIO 1
		final KeySequence perfectMatch = KeySequence.getInstance("CTRL+F");
		final Command perfectCommand = commandManager.getCommand("perfect");
		final ParameterizedCommand perfectParameterizedCommand = new ParameterizedCommand(
				perfectCommand, null);
		final Binding perfectMatchBinding = new KeyBinding(perfectMatch,
				perfectParameterizedCommand, "na", "na", null, null, null,
				Binding.SYSTEM);
		final KeySequence partialMatch1 = KeySequence
				.getInstance("CTRL+F CTRL+F");
		final Command partialCommand1 = commandManager.getCommand("partial1");
		final ParameterizedCommand partialParameterizedCommand1 = new ParameterizedCommand(
				partialCommand1, null);
		final Binding partialMatchBinding1 = new KeyBinding(partialMatch1,
				partialParameterizedCommand1, "na", "na", null, null, null,
				Binding.SYSTEM);
		final Binding[] bindings = new Binding[2];
		bindings[0] = perfectMatchBinding;
		bindings[1] = partialMatchBinding1;
		bindingManager.setBindings(bindings);
		assertTrue("A perfect match should be overridden by a partial",
				bindingManager.isPartialMatch(perfectMatch));

		// SCENARIO 2
		final KeySequence partialMatch2 = KeySequence
				.getInstance("CTRL+F CTRL+F CTRL+F");
		final Command partialCommand2 = commandManager.getCommand("partial2");
		final ParameterizedCommand partialParameterizedCommand2 = new ParameterizedCommand(
				partialCommand2, null);
		final Binding partialMatchBinding2 = new KeyBinding(partialMatch2,
				partialParameterizedCommand2, "na", "na", null, null, null,
				Binding.SYSTEM);
		bindings[0] = partialMatchBinding1;
		bindings[1] = partialMatchBinding2;
		bindingManager.setBindings(bindings);
		assertTrue("Two partial matches should count as a partial",
				bindingManager.isPartialMatch(perfectMatch));

		// SCENARIO 3
		bindingManager.addBinding(perfectMatchBinding);
		bindingManager.setBindings(bindings);
		assertTrue("An empty sequence matches everything partially",
				bindingManager.isPartialMatch(KeySequence.getInstance()));
	}

	/**
	 * Tests that this method returns <code>true</code> when expected. In the
	 * first scenario, there is one perfect match bindings and a partial match
	 * binding. In the second scenario, there are two partial match bindings. In
	 * the third scenario, we are checking that nothing matches an empty
	 * sequence.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 * @throws ParseException
	 *             If the hard-coded strings aren't constructed properly.
	 */
	public final void testIsPerfectMatch() throws NotDefinedException,
			ParseException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SCENARIO 1
		final KeySequence perfectMatch = KeySequence.getInstance("CTRL+F");
		final Command perfectCommand = commandManager.getCommand("perfect");
		final ParameterizedCommand perfectParameterizedCommand = new ParameterizedCommand(
				perfectCommand, null);
		final Binding perfectMatchBinding = new KeyBinding(perfectMatch,
				perfectParameterizedCommand, "na", "na", null, null, null,
				Binding.SYSTEM);
		final KeySequence partialMatch1 = KeySequence
				.getInstance("CTRL+F CTRL+F");
		final Command partialCommand1 = commandManager.getCommand("partial1");
		final ParameterizedCommand partialParameterizedCommand1 = new ParameterizedCommand(
				partialCommand1, null);
		final Binding partialMatchBinding1 = new KeyBinding(partialMatch1,
				partialParameterizedCommand1, "na", "na", null, null, null,
				Binding.SYSTEM);
		final Binding[] bindings = new Binding[2];
		bindings[0] = perfectMatchBinding;
		bindings[1] = partialMatchBinding1;
		bindingManager.setBindings(bindings);
		assertTrue("This should be a perfect match", bindingManager
				.isPerfectMatch(perfectMatch));

		// SCENARIO 2
		final KeySequence partialMatch2 = KeySequence
				.getInstance("CTRL+F CTRL+F CTRL+F");
		final Command partialCommand2 = commandManager.getCommand("perfect");
		final ParameterizedCommand partialParameterizedCommand2 = new ParameterizedCommand(
				partialCommand2, null);
		final Binding partialMatchBinding2 = new KeyBinding(partialMatch2,
				partialParameterizedCommand2, "na", "na", null, null, null,
				Binding.SYSTEM);
		bindings[0] = partialMatchBinding1;
		bindings[1] = partialMatchBinding2;
		bindingManager.setBindings(bindings);
		assertTrue("This should be no perfect matches", !bindingManager
				.isPerfectMatch(perfectMatch));

		// SCENARIO 3
		bindingManager.addBinding(perfectMatchBinding);
		assertTrue("This should be no perfect matches", !bindingManager
				.isPerfectMatch(KeySequence.getInstance()));
	}

	/**
	 * Tests that you can remove binding, and that it will change the active
	 * bindings as well.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 */
	public final void testRemoveBindings() throws NotDefinedException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// ADD SOME BINDINGS
		final Binding binding1 = new TestBinding("command1", "na", "na", null,
				null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding1);
		final Binding binding2 = new TestBinding("command2", "na", "na", "zh",
				null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding2);
		final Binding binding3 = new TestBinding("command3", "na", "na", null,
				"gtk", Binding.SYSTEM, null);
		bindingManager.addBinding(binding3);
		final Binding binding4 = new TestBinding("command4", "na", "na", null,
				"gtk", Binding.USER, null);
		bindingManager.addBinding(binding4);
		final Binding binding5 = new TestBinding("command5", "na", "na", "zh",
				"gtk", Binding.USER, null);
		bindingManager.addBinding(binding5);
		assertNotNull("There should be three active bindings", bindingManager
				.getActiveBindingsFor(binding1.getParameterizedCommand()));
		assertNotNull("There should be three active bindings", bindingManager
				.getActiveBindingsFor(binding2.getParameterizedCommand()));
		assertNotNull("There should be three active bindings", bindingManager
				.getActiveBindingsFor(binding4.getParameterizedCommand()));

		// REMOVE SOME BINDINGS
		bindingManager.removeBindings(TestBinding.TRIGGER_SEQUENCE, "na", "na",
				"zh", "gtk", null, Binding.USER);
		assertEquals("There should be four bindings left", 4, bindingManager
				.getBindings().length);
		assertNotNull("There should be four active bindings", bindingManager
				.getActiveBindingsFor(binding1.getParameterizedCommand()));
		assertNotNull("There should be four active bindings", bindingManager
				.getActiveBindingsFor(binding2.getParameterizedCommand()));
		assertNotNull("There should be four active bindings", bindingManager
				.getActiveBindingsFor(binding3.getParameterizedCommand()));
		assertNotNull("There should be four active bindings", bindingManager
				.getActiveBindingsFor(binding4.getParameterizedCommand()));
	}

	/**
	 * Verifies that selecting an undefimned scheme doesn't work. Verifies that
	 * selecting a scheme works. Verifies that undefining scheme removes it as
	 * the active scheme.
	 */
	public final void testSetActiveScheme() {
		// SELECT UNDEFINED
		final String schemeId = "schemeId";
		final Scheme scheme = bindingManager.getScheme(schemeId);
		try {
			bindingManager.setActiveScheme(scheme);
			fail("Cannot activate an undefined scheme");
		} catch (final NotDefinedException e) {
			// Success
		}

		// SELECT DEFINED
		scheme.define("name", "description", null);
		try {
			bindingManager.setActiveScheme(scheme);
			assertSame("The schemes should match", scheme, bindingManager
					.getActiveScheme());
		} catch (final NotDefinedException e) {
			fail("Should be able to activate a scheme");
		}

		// UNDEFINE SELECTED
		scheme.undefine();
		assertNull("The scheme should have become unselected", bindingManager
				.getActiveScheme());
	}

	/**
	 * Verifies that you can set the bindings to null. Verifies that setting the
	 * bindings clears the cache.
	 * 
	 * @throws NotDefinedException
	 *             If this test doesn't properly define a scheme.
	 */
	public final void testSetBindings() throws NotDefinedException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SET NULL
		bindingManager.setBindings(null);
		assertTrue("There should be no active bindings", bindingManager
				.getActiveBindingsFor((ParameterizedCommand) null).length == 0);

		// ADD BINDING
		final String commandId = "commandId";
		final Binding binding = new TestBinding(commandId, "na", "na", null,
				null, Binding.SYSTEM, null);
		final Binding[] bindings = new Binding[1];
		bindings[0] = binding;
		bindingManager.setBindings(bindings);
		final TriggerSequence[] activeBindings = bindingManager
				.getActiveBindingsFor(binding.getParameterizedCommand());
		assertEquals("There should be one active binding", 1,
				activeBindings.length);
		assertSame("The binding should be the one we set",
				TestBinding.TRIGGER_SEQUENCE, activeBindings[0]);
	}

	/**
	 * Verifies that it cannot be set to <code>null</code>. Verifies that it
	 * clears the cache.
	 * 
	 * @throws NotDefinedException
	 *             If this test doesn't properly define a scheme.
	 */
	public final void testSetLocale() throws NotDefinedException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SET TO NULL
		try {
			bindingManager.setLocale(null);
			fail("Cannot set the locale to null");
		} catch (final NullPointerException e) {
			// Success
		}

		// SET TO SOMETHING
		final String commandId = "commandId";
		final Binding binding = new TestBinding(commandId, "na", "na", "xx",
				null, Binding.SYSTEM, null);
		bindingManager.addBinding(binding);
		assertTrue("The binding shouldn't be active",
				bindingManager.getActiveBindingsFor(binding
						.getParameterizedCommand()).length == 0);
		bindingManager.setLocale("xx_XX");
		final TriggerSequence[] activeBindings = bindingManager
				.getActiveBindingsFor(binding.getParameterizedCommand());
		assertEquals("The binding should become active", 1,
				activeBindings.length);
		assertSame("The binding should be the same",
				TestBinding.TRIGGER_SEQUENCE, activeBindings[0]);
	}

	/**
	 * Verifies that it cannot be set to <code>null</code>. Verifies that it
	 * clears the cache.
	 * 
	 * @throws NotDefinedException
	 *             If this test doesn't properly define a scheme.
	 */
	public final void testSetPlatform() throws NotDefinedException {
		// GENERAL SET-UP
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);
		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);
		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		// SET TO NULL
		try {
			bindingManager.setPlatform(null);
			fail("Cannot set the platform to null");
		} catch (final NullPointerException e) {
			// Success
		}

		// SET TO SOMETHING
		final String commandId = "commandId";
		final Binding binding = new TestBinding(commandId, "na", "na", null,
				"atari", Binding.SYSTEM, null);
		bindingManager.addBinding(binding);
		assertTrue("The binding shouldn't be active",
				bindingManager.getActiveBindingsFor(binding
						.getParameterizedCommand()).length == 0);
		bindingManager.setPlatform("atari");
		final TriggerSequence[] activeBindings = bindingManager
				.getActiveBindingsFor(binding.getParameterizedCommand());
		assertEquals("The binding should become active", 1,
				activeBindings.length);
		assertSame("The binding should be the same",
				TestBinding.TRIGGER_SEQUENCE, activeBindings[0]);
	}

	/**
	 * Tests whether the method works with a null argument. Tests that it works
	 * in a simple case.
	 * 
	 * @throws NotDefinedException
	 *             If the scheme we try to activate is not defined.
	 */
	public final void testGetBestActiveBindingFor() throws Exception {
		// Test with a null argument.
		final TriggerSequence[] activeBindingsForNull = bindingManager
				.getActiveBindingsFor((ParameterizedCommand) null);
		assertNotNull("The active bindings for a command should never be null",
				activeBindingsForNull);
		assertTrue(
				"The active binding for a null command should always be empty",
				activeBindingsForNull.length == 0);

		// Test a simple case.
		final Context context = contextManager.getContext("na");
		context.define("name", "description", null);

		final Scheme scheme = bindingManager.getScheme("na");
		scheme.define("name", "description", null);

		bindingManager.setActiveScheme(scheme);
		final Set activeContextIds = new HashSet();
		activeContextIds.add("na");
		contextManager.setActiveContextIds(activeContextIds);

		final String commandId = "commandId";
		final String categoryId = "cat";
		Category cat = commandManager.getCategory(categoryId);
		cat.define("cat", "cat");
		Command cmd = commandManager.getCommand(commandId);
		IParameter[] parms = new IParameter[1];
		parms[0] = new IParameter() {
			public String getId() {
				return "viewId";
			}

			public String getName() {
				return "View Id";
			}

			public IParameterValues getValues() throws ParameterValuesException {
				return null;
			}

			public boolean isOptional() {
				return false;
			}
		};
		cmd.define("na", "NA", cat, parms);
		Map map = new HashMap();
		map.put("viewId", "outline");
		ParameterizedCommand outline = ParameterizedCommand.generateCommand(
				cmd, map);
		map = new HashMap();
		map.put("viewId", "console");
		ParameterizedCommand console = ParameterizedCommand.generateCommand(
				cmd, map);
		assertFalse(outline.equals(console));

		final Binding b2 = new KeyBinding(KeySequence.getInstance("M1+M2+V"),
				outline, "na", "na", null, null, null, Binding.SYSTEM);
		bindingManager.addBinding(b2);

		final Binding binding = new KeyBinding(KeySequence.getInstance("M1+V"),
				outline, "na", "na", null, null, null, Binding.SYSTEM);
		bindingManager.addBinding(binding);

		final Binding b3 = new KeyBinding(KeySequence.getInstance("M1+M2+C"),
				console, "na", "na", null, null, null, Binding.SYSTEM);
		bindingManager.addBinding(b3);

		// - above is all done as part of startup

		final TriggerSequence[] bindings = bindingManager
				.getActiveBindingsFor(binding.getParameterizedCommand());
		assertEquals(2, bindings.length);
		
		final TriggerSequence bestBinding = bindingManager.getBestActiveBindingFor(outline);
		assertEquals(binding.getTriggerSequence(), bestBinding);
		
		final TriggerSequence bestBinding2 = bindingManager.getBestActiveBindingFor(console);
		assertEquals(b3.getTriggerSequence(), bestBinding2);
	}
}
