/*******************************************************************************
 *  Copyright (c) 2004, 2012 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.core.tests.runtime;

import java.io.*;
import java.util.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.preferences.legacy.PreferenceForwarder;
import org.eclipse.core.internal.runtime.RuntimeLog;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Test suite for API class org.eclipse.core.runtime.Preferences
 */
public class PreferenceForwarderTest extends RuntimeTest {

	class Tracer implements Preferences.IPropertyChangeListener {
		public StringBuffer log = new StringBuffer();

		private String typeCode(Object value) {
			if (value == null)
				return ""; //$NON-NLS-1$
			if (value instanceof Boolean)
				return "B"; //$NON-NLS-1$
			if (value instanceof Integer)
				return "I"; //$NON-NLS-1$
			if (value instanceof Long)
				return "L"; //$NON-NLS-1$
			if (value instanceof Float)
				return "F"; //$NON-NLS-1$
			if (value instanceof Double)
				return "D"; //$NON-NLS-1$
			if (value instanceof String)
				return "S"; //$NON-NLS-1$
			assertTrue("0.0", false); //$NON-NLS-1$
			return null;
		}

		public void propertyChange(Preferences.PropertyChangeEvent event) {
			log.append('[');
			log.append(event.getProperty());
			log.append(':');
			log.append(typeCode(event.getOldValue()));
			log.append(event.getOldValue() == null ? "null" : event.getOldValue()); //$NON-NLS-1$
			log.append("->"); //$NON-NLS-1$
			log.append(typeCode(event.getNewValue()));
			log.append(event.getNewValue() == null ? "null" : event.getNewValue()); //$NON-NLS-1$
			log.append(']');
		}
	}

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

	public static Test suite() {
		// all test methods are named "test..."
		return new TestSuite(PreferenceForwarderTest.class);

//				TestSuite suite = new TestSuite();
//				suite.addTest(new PreferenceForwarderTest("testListenerOnRemove"));
//				return suite;
	}

	/*
	 * @see TestCase#setUp()
	 */
	protected void setUp() {
		// do nothing
	}

	/*
	 * @see TestCase#tearDown()
	 */
	protected void tearDown() {
		// do nothing
	}

	public void testConstants() {
		// make sure that the preference store constants are defined properly
		assertEquals("1.0", false, Preferences.BOOLEAN_DEFAULT_DEFAULT);
		assertEquals("1.1", 0, Preferences.INT_DEFAULT_DEFAULT);
		assertEquals("1.2", 0L, Preferences.LONG_DEFAULT_DEFAULT);
		assertEquals("1.3", 0.0f, Preferences.FLOAT_DEFAULT_DEFAULT, 0.0f);
		assertEquals("1.4", 0.0, Preferences.DOUBLE_DEFAULT_DEFAULT, 0.0);
		assertEquals("1.5", "", Preferences.STRING_DEFAULT_DEFAULT);
	}

	public void testBasics() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final String v1 = "1";
		final String v2 = "2";
		final String v3 = "3";

		// check that a random property in a newly created store
		// appearchs to have default-default values of whatever type asked for
		assertEquals("1.0", true, ps.isDefault(k1));
		assertEquals("1.1", Preferences.BOOLEAN_DEFAULT_DEFAULT, ps.getBoolean(k1));
		assertEquals("1.2", Preferences.INT_DEFAULT_DEFAULT, ps.getInt(k1));
		assertEquals("1.3", Preferences.LONG_DEFAULT_DEFAULT, ps.getLong(k1));
		assertEquals("1.4", Preferences.FLOAT_DEFAULT_DEFAULT, ps.getFloat(k1), 0.0f);
		assertEquals("1.5", Preferences.DOUBLE_DEFAULT_DEFAULT, ps.getDouble(k1), 0.0);
		assertEquals("1.6", Preferences.STRING_DEFAULT_DEFAULT, ps.getString(k1));

		assertEquals("1.7", Preferences.BOOLEAN_DEFAULT_DEFAULT, ps.getDefaultBoolean(k1));
		assertEquals("1.8", Preferences.INT_DEFAULT_DEFAULT, ps.getDefaultInt(k1));
		assertEquals("1.9", Preferences.LONG_DEFAULT_DEFAULT, ps.getDefaultLong(k1));
		assertEquals("1.10", Preferences.FLOAT_DEFAULT_DEFAULT, ps.getDefaultFloat(k1), 0.0f);
		assertEquals("1.11", Preferences.DOUBLE_DEFAULT_DEFAULT, ps.getDefaultDouble(k1), 0.0);
		assertEquals("1.12", Preferences.STRING_DEFAULT_DEFAULT, ps.getDefaultString(k1));

		// test set/getString
		// give it a value
		ps.setValue(k1, v1);
		assertTrue("2.0", ps.isDefault(k1) == false);
		assertEquals("2.1", v1, ps.getString(k1));
		assertEquals("2.2", Preferences.STRING_DEFAULT_DEFAULT, ps.getDefaultString(k1));
		// change the value
		ps.setValue(k1, v2);
		assertTrue("2.3", ps.isDefault(k1) == false);
		assertEquals("2.4", v2, ps.getString(k1));
		assertEquals("2.5", Preferences.STRING_DEFAULT_DEFAULT, ps.getDefaultString(k1));
		// change to same value as default
		ps.setValue(k1, ps.getDefaultString(k1));
		assertTrue("2.6", ps.isDefault(k1) == true);
		assertEquals("2.7", ps.getDefaultString(k1), ps.getString(k1));
		assertEquals("2.8", Preferences.STRING_DEFAULT_DEFAULT, ps.getDefaultString(k1));
		// reset to default
		ps.setValue(k1, v2);
		ps.setToDefault(k1);
		assertTrue("2.9", ps.isDefault(k1) == true);
		assertEquals("2.10", Preferences.STRING_DEFAULT_DEFAULT, ps.getString(k1));
		assertEquals("2.11", Preferences.STRING_DEFAULT_DEFAULT, ps.getDefaultString(k1));
		// change default
		ps.setDefault(k1, v1);
		assertTrue("2.12", ps.isDefault(k1) == true);
		assertEquals("2.13", v1, ps.getString(k1));
		assertEquals("2.14", v1, ps.getDefaultString(k1));
		// set the value
		ps.setValue(k1, v2);
		assertTrue("2.15", ps.isDefault(k1) == false);
		assertEquals("2.16", v2, ps.getString(k1));
		assertEquals("2.17", v1, ps.getDefaultString(k1));
		// change to same value as default
		ps.setValue(k1, ps.getDefaultString(k1));
		assertTrue("2.18", ps.isDefault(k1) == true);
		assertEquals("2.19", ps.getDefaultString(k1), ps.getString(k1));
		assertEquals("2.20", v1, ps.getDefaultString(k1));
		// reset to default
		ps.setValue(k1, v2);
		ps.setToDefault(k1);
		assertTrue("2.21", ps.isDefault(k1) == true);
		assertEquals("2.22", v1, ps.getString(k1));
		assertEquals("2.23", v1, ps.getDefaultString(k1));
		// change default
		ps.setDefault(k1, v3);
		assertTrue("2.24", ps.isDefault(k1) == true);
		assertEquals("2.25", v3, ps.getString(k1));
		assertEquals("2.26", v3, ps.getDefaultString(k1));

	}

	public void testBoolean() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";

		assertEquals("1.0", false, Preferences.BOOLEAN_DEFAULT_DEFAULT);
		assertEquals("1.1", Preferences.BOOLEAN_DEFAULT_DEFAULT, ps.getBoolean(k1));

		ps.setValue(k1, true);
		assertEquals("1.2", true, ps.getBoolean(k1));
		ps.setValue(k1, false);
		assertEquals("1.3", false, ps.getBoolean(k1));

		ps.setDefault(k1, true);
		assertEquals("1.4", true, ps.getDefaultBoolean(k1));
		ps.setDefault(k1, false);
		assertEquals("1.5", false, ps.getDefaultBoolean(k1));

	}

	public void testInteger() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final int[] values = {0, 1002, -201788, Integer.MAX_VALUE, Integer.MIN_VALUE};

		assertEquals("1.0", 0, Preferences.INT_DEFAULT_DEFAULT);
		assertEquals("1.1", Preferences.INT_DEFAULT_DEFAULT, ps.getInt(k1));

		for (int i = 0; i < values.length; i++) {
			int v1 = values[i];
			int v2 = v1 + 1;
			ps.setValue(k1, v1);
			assertEquals("1.2", v1, ps.getInt(k1));
			ps.setDefault(k1, v2);
			assertEquals("1.3", v2, ps.getDefaultInt(k1));
		}
	}

	public void testLong() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final long[] values = {0L, 1002L, -201788L, Long.MAX_VALUE, Long.MIN_VALUE};

		assertEquals("1.0", 0L, Preferences.LONG_DEFAULT_DEFAULT);
		assertEquals("1.1", Preferences.LONG_DEFAULT_DEFAULT, ps.getLong(k1));

		for (int i = 0; i < values.length; i++) {
			long v1 = values[i];
			long v2 = v1 + 1;
			ps.setValue(k1, v1);
			assertEquals("1.2", v1, ps.getLong(k1));
			ps.setDefault(k1, v2);
			assertEquals("1.3", v2, ps.getDefaultLong(k1));
		}
	}

	public void testFloat() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final float[] values = {0.0f, 1002.5f, -201788.55f, Float.MAX_VALUE, Float.MIN_VALUE};
		final float tol = 1.0e-20f;

		assertEquals("1.0", 0.0f, Preferences.FLOAT_DEFAULT_DEFAULT, tol);
		assertEquals("1.1", Preferences.FLOAT_DEFAULT_DEFAULT, ps.getFloat(k1), tol);

		for (int i = 0; i < values.length; i++) {
			float v1 = values[i];
			float v2 = v1 + 1.0f;
			ps.setValue(k1, v1);
			assertEquals("1.2", v1, ps.getFloat(k1), tol);
			ps.setDefault(k1, v2);
			assertEquals("1.3", v2, ps.getDefaultFloat(k1), tol);
		}

		try {
			ps.setValue(k1, Float.NaN);
			assertTrue("1.4", false);
		} catch (IllegalArgumentException e) {
			// NaNs should be rejected
		}

	}

	public void testDouble() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final double[] values = {0.0, 1002.5, -201788.55, Double.MAX_VALUE, Double.MIN_VALUE};
		final double tol = 1.0e-20;

		assertEquals("1.0", 0.0, Preferences.DOUBLE_DEFAULT_DEFAULT, tol);
		assertEquals("1.1", Preferences.DOUBLE_DEFAULT_DEFAULT, ps.getDouble(k1), tol);

		for (int i = 0; i < values.length; i++) {
			double v1 = values[i];
			double v2 = v1 + 1.0;
			ps.setValue(k1, v1);
			assertEquals("1.2", v1, ps.getDouble(k1), tol);
			ps.setDefault(k1, v2);
			assertEquals("1.3", v2, ps.getDefaultDouble(k1), tol);
		}

		try {
			ps.setValue(k1, Float.NaN);
			assertTrue("1.4", false);
		} catch (IllegalArgumentException e) {
			// NaNs should be rejected
		}

	}

	public void testString() {

		Preferences ps = new PreferenceForwarder(getUniqueString());
		final String k1 = "key1";
		final String[] values = {"", "hello", " x ", "\n"};

		assertEquals("1.0", "", Preferences.STRING_DEFAULT_DEFAULT);
		assertEquals("1.1", ps.getString(k1), Preferences.STRING_DEFAULT_DEFAULT);

		for (int i = 0; i < values.length; i++) {
			String v1 = values[i];
			String v2 = v1 + "x";
			ps.setValue(k1, v1);
			assertEquals("1.2", v1, ps.getString(k1));
			ps.setDefault(k1, v2);
			assertEquals("1.3", v2, ps.getDefaultString(k1));
		}
	}

	public void testPropertyNames() {

		Preferences ps = new PreferenceForwarder(getUniqueString());

		// there are no properties initially
		assertEquals("1.0", 0, ps.propertyNames().length);

		String[] keys = {"a", "b", "c", "d"};

		// setting defaults does not add name to set
		for (int i = 0; i < keys.length; i++) {
			ps.setDefault(keys[i], "default");
		}
		assertEquals("1.1", 0, ps.propertyNames().length);

		// setting real values does add name to set
		for (int i = 0; i < keys.length; i++) {
			ps.setValue(keys[i], "actual");
		}
		assertEquals("1.2", keys.length, ps.propertyNames().length);

		Set s1 = new HashSet(Arrays.asList(keys));
		Set s2 = new HashSet(Arrays.asList(ps.propertyNames()));
		assertEquals("1.3", s1, s2);

		// setting to default does remove name from set
		for (int i = 0; i < keys.length; i++) {
			ps.setToDefault(keys[i]);
			Set s = new HashSet(Arrays.asList(ps.propertyNames()));
			assertTrue("1.4", !s.contains(keys[i]));
		}
		assertEquals("1.5", 0, ps.propertyNames().length);
	}

	public void testContains() {

		Preferences ps = new PreferenceForwarder(getUniqueString());

		// there are no properties initially
		assertEquals("1.0", false, ps.contains("a"));

		// setting defaults adds name
		ps.setDefault("a", "default");
		assertEquals("1.1", true, ps.contains("a"));

		// setting value adds name
		assertEquals("1.2", false, ps.contains("b"));
		ps.setValue("b", "any");
		assertEquals("1.3", true, ps.contains("b"));

		// setting value does not remove entry already there
		ps.setValue("a", "any");
		assertEquals("1.4", true, ps.contains("a"));
		assertEquals("1.5", true, ps.contains("b"));

		// setting to default removes name from set unless there is a default too
		ps.setToDefault("b");
		assertEquals("1.6", false, ps.contains("b"));
		ps.setToDefault("a");
		assertEquals("1.7", true, ps.contains("a"));
		
		// test bug 62586
		// fail gracefully in PreferenceForwarder.contains(null)
		try {
			assertTrue("2.0", !ps.contains(null));
		} catch (NullPointerException e) {
			fail("2.1", e);
		}
	}

	public void testDefaultPropertyNames() {

		Preferences ps = new PreferenceForwarder(getUniqueString());

		// there are no default properties initially
		assertEquals("1.0", 0, ps.defaultPropertyNames().length);

		String[] keys = {"a", "b", "c", "d"};

		// setting actual values does not add name to set
		for (int i = 0; i < keys.length; i++) {
			ps.setValue(keys[i], "actual");
		}
		assertEquals("1.1", 0, ps.defaultPropertyNames().length);

		// setting defaults does add name to set
		for (int i = 0; i < keys.length; i++) {
			ps.setDefault(keys[i], "default");
		}
		assertEquals("1.2", keys.length, ps.defaultPropertyNames().length);

		Set s1 = new HashSet(Arrays.asList(keys));
		Set s2 = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
		assertEquals("1.3", s1, s2);

		// setting to default does not remove name from set
		for (int i = 0; i < keys.length; i++) {
			ps.setToDefault(keys[i]);
			Set s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.4", s.contains(keys[i]));
		}
		assertEquals("1.5", keys.length, ps.defaultPropertyNames().length);

		// setting to default-default does not remove name from set either
		for (int i = 0; i < keys.length; i++) {
			ps.setDefault(keys[i], Preferences.STRING_DEFAULT_DEFAULT);
			Set s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.1", s.contains(keys[i]));

			ps.setDefault(keys[i], Preferences.BOOLEAN_DEFAULT_DEFAULT);
			s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.2", s.contains(keys[i]));

			ps.setDefault(keys[i], Preferences.INT_DEFAULT_DEFAULT);
			s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.3", s.contains(keys[i]));

			ps.setDefault(keys[i], Preferences.LONG_DEFAULT_DEFAULT);
			s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.4", s.contains(keys[i]));

			ps.setDefault(keys[i], Preferences.FLOAT_DEFAULT_DEFAULT);
			s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.5", s.contains(keys[i]));

			ps.setDefault(keys[i], Preferences.DOUBLE_DEFAULT_DEFAULT);
			s = new HashSet(Arrays.asList(ps.defaultPropertyNames()));
			assertTrue("1.6.6", s.contains(keys[i]));
		}
		assertEquals("1.7", keys.length, ps.defaultPropertyNames().length);
	}

	public void test55138() {
		final Preferences ps = new PreferenceForwarder(getUniqueString());

		final Tracer tracer1 = new Tracer();
		String key = "foo";

		// register one listener
		ps.addPropertyChangeListener(tracer1);
		assertEquals("1.0", "", tracer1.log.toString());

		// boolean value
		boolean booleanDefault = true;
		boolean booleanValue = false;
		ps.setDefault(key, booleanDefault);
		assertEquals("2.0", "", tracer1.log.toString());

		tracer1.log.setLength(0);
		ps.setValue(key, booleanValue);
		assertEquals("2.1", "[foo:Btrue->Bfalse]", tracer1.log.toString());

		ps.setValue(key, booleanDefault);
		assertEquals("2.2", "[foo:Btrue->Bfalse][foo:Bfalse->Btrue]", tracer1.log.toString());

		// int value
		int intDefault = 10;
		int intValue = 11;
		tracer1.log.setLength(0);
		ps.setDefault(key, intDefault);
		assertEquals("3.0", "", tracer1.log.toString());

		ps.setValue(key, intValue);
		assertEquals("3.1", "[foo:I10->I11]", tracer1.log.toString());

		ps.setValue(key, intDefault);
		assertEquals("3.2", "[foo:I10->I11][foo:I11->I10]", tracer1.log.toString());

		// double value
		double doubleDefault = 10.0;
		double doubleValue = 11.0;
		tracer1.log.setLength(0);
		ps.setDefault(key, doubleDefault);
		assertEquals("4.0", "", tracer1.log.toString());

		tracer1.log.setLength(0);
		ps.setValue(key, doubleValue);
		assertEquals("4.1", "[foo:D10.0->D11.0]", tracer1.log.toString());

		ps.setValue(key, doubleDefault);
		assertEquals("4.2", "[foo:D10.0->D11.0][foo:D11.0->D10.0]", tracer1.log.toString());

		// float value
		float floatDefault = 10.0f;
		float floatValue = 11.0f;
		tracer1.log.setLength(0);
		ps.setDefault(key, floatDefault);
		assertEquals("5.0", "", tracer1.log.toString());

		tracer1.log.setLength(0);
		ps.setValue(key, floatValue);
		assertEquals("5.1", "[foo:F10.0->F11.0]", tracer1.log.toString());

		ps.setValue(key, floatDefault);
		assertEquals("5.2", "[foo:F10.0->F11.0][foo:F11.0->F10.0]", tracer1.log.toString());

		// long value
		long longDefault = 10L;
		long longValue = 11L;
		tracer1.log.setLength(0);
		ps.setDefault(key, longDefault);
		assertEquals("6.0", "", tracer1.log.toString());

		tracer1.log.setLength(0);
		ps.setValue(key, longValue);
		assertEquals("6.1", "[foo:L10->L11]", tracer1.log.toString());

		ps.setValue(key, longDefault);
		assertEquals("6.2", "[foo:L10->L11][foo:L11->L10]", tracer1.log.toString());
	}

	public void testListeners() {

		final Preferences ps = new PreferenceForwarder(getUniqueString());

		final Tracer tracer1 = new Tracer();
		final Tracer tracer2 = new Tracer();

		// register one listener
		ps.addPropertyChangeListener(tracer1);
		assertEquals("1.0", "", tracer1.log.toString());

		// make sure it is notified in a type appropriate manner
		ps.setValue("a", "1");
		assertEquals("1.0.1", "[a:S->S1]", tracer1.log.toString());

		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", true);
		assertEquals("1.0.2", "[a:Bfalse->Btrue]", tracer1.log.toString());

		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", 100);
		assertEquals("1.0.3", "[a:I0->I100]", tracer1.log.toString());

		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", 100L);
		assertEquals("1.0.4", "[a:L0->L100]", tracer1.log.toString());

		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", 2.0f);
		assertEquals("1.0.5", "[a:F0.0->F2.0]", tracer1.log.toString());

		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", 2.0);
		assertEquals("1.0.6", "[a:D0.0->D2.0]", tracer1.log.toString());

		// make sure it is notified of a series of events
		ps.setToDefault("a");
		tracer1.log.setLength(0);
		ps.setValue("a", "1");
		assertEquals("1.1", "[a:S->S1]", tracer1.log.toString());

		ps.setValue("a", "2");
		assertEquals("1.2", "[a:S->S1][a:S1->S2]", tracer1.log.toString());

		ps.setValue("a", ps.getDefaultString("a"));
		assertEquals("1.2.1", "[a:S->S1][a:S1->S2][a:S2->S]", tracer1.log.toString());

		ps.setValue("a", "3");
		assertEquals("1.2.2", "[a:S->S1][a:S1->S2][a:S2->S][a:S->S3]", tracer1.log.toString());

		ps.setToDefault("a");
		assertEquals("1.2.3", "[a:S->S1][a:S1->S2][a:S2->S][a:S->S3][a:S3->S]", tracer1.log.toString());

		// change to same value - no one notified
		ps.setValue("a", "2");
		tracer1.log.setLength(0);
		assertEquals("1.3", "", tracer1.log.toString());

		// register second listener
		ps.addPropertyChangeListener(tracer2);

		// make sure both are notified
		ps.setValue("a", "3");
		assertEquals("1.4", "[a:S2->S3]", tracer1.log.toString());
		assertEquals("1.5", "[a:S2->S3]", tracer2.log.toString());

		// deregister is honored
		ps.removePropertyChangeListener(tracer2);
		tracer1.log.setLength(0);
		tracer2.log.setLength(0);
		ps.setValue("a", "1");
		assertEquals("1.6", "[a:S3->S1]", tracer1.log.toString());
		assertEquals("1.7", "", tracer2.log.toString());

		// duplicate deregister is ignored
		ps.removePropertyChangeListener(tracer2);
		tracer1.log.setLength(0);
		tracer2.log.setLength(0);
		ps.setValue("a", "2");
		assertEquals("1.8", "[a:S1->S2]", tracer1.log.toString());
		assertEquals("1.9", "", tracer2.log.toString());

		// duplicate register is ignored
		ps.addPropertyChangeListener(tracer1);
		tracer1.log.setLength(0);
		ps.setValue("a", "1");
		assertEquals("1.10", "[a:S2->S1]", tracer1.log.toString());

		// last deregister is honored
		ps.removePropertyChangeListener(tracer1);
		tracer1.log.setLength(0);
		ps.setValue("a", "4");
		assertEquals("1.11", "", tracer1.log.toString());

		// adds 2 and removes 1 during during callback!
		class Trouble implements Preferences.IPropertyChangeListener {
			public void propertyChange(Preferences.PropertyChangeEvent event) {
				ps.removePropertyChangeListener(tracer1);
				ps.addPropertyChangeListener(tracer2);
			}
		}

		ps.setValue("a", "0");
		ps.addPropertyChangeListener(tracer1);
		ps.addPropertyChangeListener(new Trouble());
		tracer1.log.setLength(0);
		tracer2.log.setLength(0);
		ps.setValue("a", "1");
		ps.setValue("a", "2");
		assertEquals("1.12", "[a:S0->S1]", tracer1.log.toString());
		assertEquals("1.13", "[a:S1->S2]", tracer2.log.toString());

	}

	public void testLoadStore() {

		final Preferences ps = new PreferenceForwarder(getUniqueString());

		ps.setValue("b1", true);
		ps.setValue("i1", 1);
		ps.setValue("l1", 2L);
		ps.setValue("f1", 1.0f);
		ps.setValue("d1", 1.0);
		ps.setValue("s1", "x");
		String[] keys = {"b1", "i1", "l1", "f1", "d1", "s1",};

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			ps.store(out, "test header");
		} catch (IOException e) {
			assertTrue("0.1", false);
		}

		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

		final Preferences ps2 = new PreferenceForwarder(getUniqueString());
		try {
			ps2.load(in);
		} catch (IOException e) {
			assertTrue("0.2", false);
		}

		assertEquals("1.1", true, ps2.getBoolean("b1"));
		assertEquals("1.2", 1, ps2.getInt("i1"));
		assertEquals("1.3", 2L, ps2.getLong("l1"));
		assertEquals("1.4", 1.0f, ps2.getFloat("f1"), 1e-20f);
		assertEquals("1.5", 1.0, ps2.getDouble("d1"), 1e-20);
		assertEquals("1.6", "x", ps2.getString("s1"));

		Set s1 = new HashSet(Arrays.asList(keys));
		Set s2 = new HashSet(Arrays.asList(ps2.propertyNames()));
		assertEquals("1.7", s1, s2);

		// load discards current values
		in = new ByteArrayInputStream(out.toByteArray());
		final Preferences ps3 = new PreferenceForwarder(getUniqueString());
		ps3.setValue("s1", "y");
		try {
			ps3.load(in);
			assertEquals("1.8", "x", ps3.getString("s1"));
			Set k1 = new HashSet(Arrays.asList(keys));
			Set k2 = new HashSet(Arrays.asList(ps3.propertyNames()));
			assertEquals("1.9", k1, k2);
		} catch (IOException e) {
			assertTrue("1.10", false);
		}

	}

	public void testNeedsSaving() {

		Preferences ps = new PreferenceForwarder(getUniqueString());

		// setValue dirties
		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("1.0", false, ps.needsSaving());
		ps.setValue("b1", true);
		assertEquals("1.1", true, ps.needsSaving());

		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("2.0", false, ps.needsSaving());
		ps.setValue("i1", 1);
		assertEquals("2.1", true, ps.needsSaving());

		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("3.0", false, ps.needsSaving());
		ps.setValue("l1", 2L);
		assertEquals("3.1", true, ps.needsSaving());

		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("4.0", false, ps.needsSaving());
		ps.setValue("f1", 1.0f);
		assertEquals("4.1", true, ps.needsSaving());

		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("5.0", false, ps.needsSaving());
		ps.setValue("d1", 1.0);
		assertEquals("5.1", true, ps.needsSaving());

		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("6.0", false, ps.needsSaving());
		ps.setValue("s1", "x");
		assertEquals("6.1", true, ps.needsSaving());

		// setToDefault does not dirty if value not set
		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("7.0", false, ps.needsSaving());
		ps.setToDefault("any");
		assertEquals("7.1", false, ps.needsSaving());

		// setToDefault dirties if value was set
		try {
			ps = new PreferenceForwarder(getUniqueString());
			assertEquals("7.2", false, ps.needsSaving());
			ps.setValue("any", "x");
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ps.store(out, "test header");
			ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
			ps.load(in);
			assertEquals("7.3", false, ps.needsSaving());
			ps.setToDefault("any");
			assertEquals("7.4", true, ps.needsSaving());
		} catch (IOException e) {
			assertTrue("7.5", false);
		}

		// setDefault, getT, getDefaultT do not dirty
		ps = new PreferenceForwarder(getUniqueString());
		assertEquals("8.0", false, ps.needsSaving());
		ps.setDefault("b1", true);
		ps.getBoolean("b1");
		ps.getDefaultBoolean("b1");
		ps.setDefault("i1", 1);
		ps.getInt("i1");
		ps.getDefaultInt("i1");
		ps.setDefault("l1", 1L);
		ps.getLong("l1");
		ps.getDefaultLong("l1");
		ps.setDefault("f1", 1.0f);
		ps.getFloat("f1");
		ps.getDefaultFloat("f1");
		ps.setDefault("d1", 1.0);
		ps.getDouble("d1");
		ps.getDefaultDouble("d1");
		ps.setDefault("s1", "x");
		ps.getString("s1");
		ps.getDefaultString("s1");
		assertEquals("8.1", false, ps.needsSaving());

		try {
			ps = new PreferenceForwarder(getUniqueString());
			assertEquals("9.1", false, ps.needsSaving());
			ps.setValue("b1", true);
			assertEquals("9.2", true, ps.needsSaving());
			ByteArrayOutputStream out = new ByteArrayOutputStream();

			// store makes not dirty
			ps.store(out, "test header");
			assertEquals("9.3", false, ps.needsSaving());

			// load comes in not dirty
			ps.setValue("b1", false);
			assertEquals("9.4", true, ps.needsSaving());
			ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
			ps.load(in);
			assertEquals("9.5", false, ps.needsSaving());
		} catch (IOException e) {
			assertTrue("9.0", false);
		}
	}

	/* Comment this test out until we are able to use session tests
	 * with it. - ddw
	 * 	public void testPluginPrefs() {
	 IPluginRegistry registry = InternalPlatform.getPluginRegistry();
	 IPluginDescriptor resPlugin = registry.getPluginDescriptor("org.eclipse.core.resources");
	 Preferences perfs = null;
	 try {
	 perfs = resPlugin.getPlugin().getPluginPreferences();
	 } catch (CoreException ce) {
	 fail("0.1 core exception from getPlugin");
	 }
	 boolean oneBoolean = perfs.getBoolean("OneBoolean");
	 double oneDouble = perfs.getDouble("OneDouble");
	 float oneFloat = perfs.getFloat("OneFloat");
	 int oneInt = perfs.getInt("OneInt");
	 long oneLong = perfs.getLong("OneLong");
	 String oneString = perfs.getString("OneString");
	 assertTrue("1.0 boolean", oneBoolean);
	 assertTrue("2.0 double", oneDouble == 4);
	 assertTrue("3.0 float", oneFloat ==	4.3f);
	 assertTrue("4.0 int", oneInt == 5);
	 assertTrue("5.0 long", oneLong == 6);
	 assertTrue("6.0 string", oneString.equals("A string from the plugin root directory"));
	 int a = 4;
	 int b = 3;
	 }
	 */

	/*
	 * Regression test for bug 178815.
	 */
	public void testListenerOnRemove() {
		// create a new log listener that will fail if anything is written
		ILogListener logListener = new ILogListener() {
			public void logging(IStatus status, String plugin) {
				CoreException ex = new CoreException(status);
				fail("0.99", ex);
			}
		};

		// set a preference value to get everything initialized
		String id = getUniqueString();
		Preferences ps = new PreferenceForwarder(id);
		ps.setValue("key", "value");
		
		// add a property change listener which will cause one to be 
		// added at the preference node level
		IPropertyChangeListener listener = new Preferences.IPropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent event) {
			}
		};
		ps.addPropertyChangeListener(listener);
		ps.setValue("key2", "value2");
		IEclipsePreferences node = new InstanceScope().getNode(id);
		
		// add our log listener and remove the node. nothing should be logged.
		RuntimeLog.addLogListener(logListener);
		try {
			node.removeNode();
		} catch (BackingStoreException e) {
			fail("4.99", e);
		} catch (IllegalStateException e) {
			fail("5.00", e);
		} finally {
			RuntimeLog.removeLogListener(logListener);
		}
	}
}
