/*******************************************************************************
 * Copyright (c) 2000, 2010 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.runtime;

import java.io.*;
import java.util.*;
import org.eclipse.core.internal.preferences.PreferencesService;
import org.eclipse.core.internal.preferences.PrefsMessages;
import org.eclipse.core.runtime.preferences.*;
import org.eclipse.osgi.util.NLS;

/**
 * A table of preference settings, mapping named properties to values. Property
 * names are non-empty strings; property values can be either booleans,
 * non-null strings, or values of one of the primitive number types.
 * The table consists of two, sparse, layers: the lower layer holds default values 
 * for properties, and the upper layer holds explicitly set values for properties.
 * Normal retrieval looks for an explicitly set value for the given property in
 * the upper layer; if there is nothing for that property in the upper layer, it
 * next looks for a default value for the given property in the lower layer; if
 * there is nothing for that property in the lower layer, it returns a standard
 * default-default value. The default-default values for the primitive types are
 * as follows:
 * <ul>
 * 	<li><code>boolean</code> = <code>false</code></li>
 * 	<li><code>double</code> = <code>0.0</code></li>
 * 	<li><code>float</code> = <code>0.0f</code></li>
 * 	<li><code>int</code> = <code>0</code></li>
 *  <li><code>long</code> = <code>0L</code></li>
 * 	<li><code>String</code> = <code>""</code> (the empty string)</li>
 * </ul>
 * <p>
 * Internally, all properties values (in both layers) are stored as strings.
 * Standard conversions to and from numeric and boolean types are performed on
 * demand.
 * </p>
 * <p>
 * The typical usage is to establish the defaults for all known properties
 * and then restore previously stored values for properties whose values 
 * were explicitly set. The existing settings can be changed and new properties
 * can be set (<code>setValue</code>). If the values specified is the same as 
 * the default value, the explicit setting is deleted from the top layer.
 * It is also possible to reset a property value back to the default value 
 * using <code>setToDefault</code>. After the properties have been modified, 
 * the properties with explicit settings are written to disk. The default values
 * are never saved. This two-tiered approach
 * to saving and restoring property setting minimizes the number of properties
 * that need to be persisted; indeed, the normal starting state does not require
 * storing any properties at all. It also makes it easy to use different 
 * default settings in different environments while maintaining just those
 * property settings the user has adjusted.
 * </p>
 * <p>
 * A property change event is reported whenever a property's value actually
 * changes (either through <code>setValue</code>, <code>setToDefault</code>).
 * Note, however, that manipulating default values (with <code>setDefault</code>)
 * does not cause any events to be reported.
 * </p>
 * <p>
 * Clients may instantiate this class.
 * </p>
 * <p>
 * The implementation is based on a pair of internal 
 * <code>java.util.Properties</code> objects, one holding explicitly set values
 * (set using <code>setValue</code>), the other holding the default values
 * (set using <code>setDefaultValue</code>). The <code>load</code> and
 * <code>store</code> methods persist the non-default property values to 
 * streams (the default values are not saved).
 * </p>
 * <p>
 * If a client sets a default value to be equivalent to the default-default for that
 * type, the value is still known to the preference store as having a default value.
 * That is, the name will still be returned in the result of the <code>defaultPropertyNames</code>
 * and <code>contains</code> methods.
 * </p>
 * 
 * @since 2.0
 * @noextend This class is not intended to be subclassed by clients.
 * @deprecated This class is replaced by {@link IEclipsePreferences}. Setting a default
 * value is accomplished by a setting a value in the {@link DefaultScope}, and setting
 * an explicit non-default value is accomplished by setting a value in the {@link InstanceScope}.
 * To obtain a preference value, use the preference accessor methods on {@link IPreferencesService}.
 */
public class Preferences {

	/**
	 * The default-default value for boolean properties (<code>false</code>).
	 */
	public static final boolean BOOLEAN_DEFAULT_DEFAULT = false;

	/**
	 * The default-default value for double properties (<code>0.0</code>).
	 */
	public static final double DOUBLE_DEFAULT_DEFAULT = 0.0;

	/**
	 * The default-default value for float properties (<code>0.0f</code>).
	 */
	public static final float FLOAT_DEFAULT_DEFAULT = 0.0f;

	/**
	 * The default-default value for int properties (<code>0</code>).
	 */
	public static final int INT_DEFAULT_DEFAULT = 0;

	/**
	 * The default-default value for long properties (<code>0L</code>).
	 */
	public static final long LONG_DEFAULT_DEFAULT = 0L;

	/**
	 * The default-default value for String properties (<code>""</code>).
	 */
	public static final String STRING_DEFAULT_DEFAULT = ""; //$NON-NLS-1$

	/**
	 * The string representation used for <code>true</code>
	 * (<code>"true"</code>).
	 */
	protected static final String TRUE = "true"; //$NON-NLS-1$

	/**
	 * The string representation used for <code>false</code>
	 * (<code>"false"</code>).
	 */
	protected static final String FALSE = "false"; //$NON-NLS-1$

	/**
	 * Singleton empty string array (optimization)
	 */
	private static final String[] EMPTY_STRING_ARRAY = new String[0];

	/** 
	 * The simple identifier constant (value "<code>preferences</code>") of
	 * the extension point of the Core Runtime plug-in where plug-ins declare
	 * extensions to the preference facility. A plug-in may define any number
	 * of preference extensions.
	 * 
	 * @since 3.2
	 */
	public static final String PT_PREFERENCES = "preferences"; //$NON-NLS-1$

	/**
	 * An event object describing a change to a named property.
	 * <p>
	 * The preferences object reports property change events for internal state
	 * changes that may be of interest to external parties. A special listener
	 * interface (<code>Preferences.IPropertyChangeListener</code>) is 
	 * defined for this purpose. Listeners are registered via the
	 * <code>Preferences.addPropertyChangeListener</code> method.
	 * </p>
	 * <p>
	 * Clients cannot instantiate or subclass this class.
	 * </p>
	 *
	 * @see Preferences#addPropertyChangeListener(Preferences.IPropertyChangeListener)
	 * @see Preferences.IPropertyChangeListener
	 */
	public static class PropertyChangeEvent extends EventObject {
		/**
		 * All serializable objects should have a stable serialVersionUID
		 */
		private static final long serialVersionUID = 1L;

		/**
		 * The name of the changed property.
		 */
		private String propertyName;

		/**
		 * The old value of the changed property, or <code>null</code> if
		 * not known or not relevant.
		 */
		private Object oldValue;

		/**
		 * The new value of the changed property, or <code>null</code> if
		 * not known or not relevant.
		 */
		private Object newValue;

		/**
		 * Creates a new property change event.
		 *
		 * @param source the object whose property has changed
		 * @param property the property that has changed (must not be 
		 *    <code>null</code>)
		 * @param oldValue the old value of the property, or 
		 *    <code>null</code> if none
		 * @param newValue the new value of the property, or 
		 *    <code>null</code> if none
		 */
		protected PropertyChangeEvent(Object source, String property, Object oldValue, Object newValue) {

			super(source);
			if (property == null) {
				throw new IllegalArgumentException();
			}
			this.propertyName = property;
			this.oldValue = oldValue;
			this.newValue = newValue;
		}

		/**
		 * Returns the name of the property that changed.
		 * <p>
		 * Warning: there is no guarantee that the property name returned
		 * is a constant string.  Callers must compare property names using
		 * <code>equals</code>, not ==.
		 *</p>
		 * 
		 * @return the name of the property that changed
		 */
		public String getProperty() {
			return propertyName;
		}

		/**
		 * Returns the new value of the property.
		 *
		 * @return the new value, or <code>null</code> if not known
		 *  or not relevant
		 */
		public Object getNewValue() {
			return newValue;
		}

		/**
		 * Returns the old value of the property.
		 *
		 * @return the old value, or <code>null</code> if not known
		 *  or not relevant
		 */
		public Object getOldValue() {
			return oldValue;
		}
	}

	/**
	 * Listener for property changes.
	 * <p>
	 * Usage:
	 * <pre>
	 * Preferences.IPropertyChangeListener listener =
	 *   new Preferences.IPropertyChangeListener() {
	 *      public void propertyChange(Preferences.PropertyChangeEvent event) {
	 *         ... // code to deal with occurrence of property change
	 *      }
	 *   };
	 * emitter.addPropertyChangeListener(listener);
	 * ...
	 * emitter.removePropertyChangeListener(listener);
	 * </pre>
	 * </p>
	 * <p>
	 * <em>Note:</em> Depending on the means in which the property
	 * values changed, the old and new values for the property can 
	 * be either typed, a string representation of the value, or <code>null</code>.
	 * Clients who wish to behave properly in all cases should all
	 * three cases in their implementation of the property change listener.
	 * </p>
	 */
	public interface IPropertyChangeListener extends EventListener {

		/**
		 * Notification that a property has changed.
		 * <p>
		 * This method gets called when the observed object fires a property
		 * change event.
		 * </p>
		 *
		 * @param event the property change event object describing which
		 *    property changed and how
		 */
		public void propertyChange(Preferences.PropertyChangeEvent event);
	}

	/** 
	 * List of registered listeners (element type: 
	 * <code>IPropertyChangeListener</code>).
	 * These listeners are to be informed when the current value of a property
	 * changes.
	 */
	protected ListenerList listeners = new ListenerList();

	/**
	 * The mapping from property name to
	 * property value (represented as strings).
	 */
	private Properties properties;

	/**
	 * The mapping from property name to
	 * default property value (represented as strings);
	 * <code>null</code> if none.
	 */
	private Properties defaultProperties;

	/**
	 * Indicates whether a value has been changed by <code>setToDefault</code>
	 * or <code>setValue</code>; initially <code>false</code>.
	 */
	protected boolean dirty = false;

	/**
	 * Exports all non-default-valued preferences for all installed plugins to the 
	 * provided file. If a file already exists at the given location, it will be deleted.
	 * If there are no preferences to export, no file will be written.
	 * <p>
	 * The file that is written can be read later using the importPreferences method.
	 * </p>
	 * @param path The absolute file system path of the file to export preferences to.
	 * @exception CoreException if this method fails. Reasons include:
	 * <ul>
	 * <li> The file could not be written.</li>
	 * </ul>
	 * @see #importPreferences(IPath)
	 * @see #validatePreferenceVersions(IPath)
	 */
	public static void exportPreferences(IPath path) throws CoreException {
		File file = path.toFile();
		if (file.exists())
			file.delete();
		file.getParentFile().mkdirs();
		IPreferencesService service = PreferencesService.getDefault();
		OutputStream output = null;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(file);
			output = new BufferedOutputStream(fos);
			IEclipsePreferences node = (IEclipsePreferences) service.getRootNode().node(InstanceScope.SCOPE);
			service.exportPreferences(node, output, (String[]) null);
			output.flush();
			fos.getFD().sync();
		} catch (IOException e) {
			String message = NLS.bind(PrefsMessages.preferences_errorWriting, file, e.getMessage());
			IStatus status = new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e);
			throw new CoreException(status);
		} finally {
			if (output != null)
				try {
					output.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	/**
	 * Loads the plugin preferences from the given file, and replaces all 
	 * non-default-valued preferences for all plugins with the values from this file.
	 * <p>
	 * If the file contains preferences for plug-ins that don't exist in the current
	 * install, they are ignored.  This method does not validate if the plug-in
	 * versions in the preference file match the currently installed plug-ins.
	 * Clients should first call validatePreferenceVersions on the file to ensure
	 * that the versions are compatible.
	 * </p>
	 * <p>
	 * The file must have been written by the exportPreferences method.
	 * </p>
	 * @param path The absolute file system path of the file to import preferences from.
	 * @exception CoreException if this method fails. Reasons include:
	 * <ul>
	 * <li> The file does not exist.</li>
	 * <li> The file could not be read.</li>
	 * </ul>
	 * @see #exportPreferences(IPath)
	 * @see #validatePreferenceVersions(IPath)
	 */
	public static void importPreferences(IPath path) throws CoreException {
		if (!path.toFile().exists()) {
			String msg = NLS.bind(PrefsMessages.preferences_fileNotFound, path.toOSString());
			throw new CoreException(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, 1, msg, null));
		}
		IPreferencesService service = PreferencesService.getDefault();
		InputStream input = null;
		try {
			input = new BufferedInputStream(new FileInputStream(path.toFile()));
			service.importPreferences(input);
		} catch (FileNotFoundException e) {
			String msg = NLS.bind(PrefsMessages.preferences_fileNotFound, path.toOSString());
			throw new CoreException(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, 1, msg, e));
		} finally {
			if (input != null)
				try {
					input.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	/**
	 * Validates that the preference versions in the given file match the versions
	 * of the currently installed plugins.  Returns an OK status if all preferences match 
	 * the currently installed plugins, otherwise a MultiStatus describing what 
	 * plugins have preferences that don't match.  
	 * <p>
	 * If the returned status has a <code>IStatus.WARNING</code> severity, 
	 * it means that some preferences may not be applicable but for the most 
	 * part they will be compatible.  If the returned status has a 
	 * <code>IStatus.ERROR</code> severity, it means that the preferences 
	 * will probably not be compatible.
	 * <p>
	 * If the file contains preferences for plug-ins that don't exist in the current
	 * install, they are ignored.
	 * </p>
	 * <p>
	 * The file must have been written by the exportPreferences method.
	 * </p>
	 * @param file The absolute file system path of the preference file to validate.
	 * @see #exportPreferences(IPath)
	 * @see #importPreferences(IPath)
	 */
	public static IStatus validatePreferenceVersions(IPath file) {
		PreferencesService service = PreferencesService.getDefault();
		return service.validateVersions(file);
	}

	/**
	 * Creates an empty preference table.
	 * <p>
	 * Use the methods <code>load(InputStream)</code> and
	 * <code>store(InputStream)</code> to load and store these preferences.
	 * </p>
	 * @see #load(InputStream)
	 * @see #store(OutputStream, String)
	 */
	public Preferences() {
		defaultProperties = new Properties();
		properties = new Properties(defaultProperties);
	}

	/**
	 * Adds a property change listener to this preference object.
	 * Has no effect if the identical listener is already registered.
	 * <p>
	 * <em>Note:</em> Depending on the means in which the property
	 * values changed, the old and new values for the property can 
	 * be either typed, a string representation of the value, or <code>null</code>.
	 * Clients who wish to behave properly in all cases should all
	 * three cases in their implementation of the property change listener.
	 * </p>
	 * @param listener a property change listener
	 */
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		listeners.add(listener);
	}

	/**
	 * Removes the given listener from this preference object.
	 * Has no effect if the listener is not registered.
	 *
	 * @param listener a property change listener
	 */
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		listeners.remove(listener);
	}

	/**
	 * Returns whether the given property is known to this preference object,
	 * either by having an explicit setting or by having a default
	 * setting. Returns <code>false</code> if the given name is <code>null</code>.
	 *
	 * @param name the name of the property, or <code>null</code>
	 * @return <code>true</code> if either a current value or a default
	 *  value is known for the named property, and <code>false</code>otherwise
	 */
	public boolean contains(String name) {
		return (properties.containsKey(name) || defaultProperties.containsKey(name));
	}

	/**
	 * Fires a property change event corresponding to a change to the
	 * current value of the property with the given name.
	 *
	 * @param name the name of the property, to be used as the property
	 *  in the event object
	 * @param oldValue the old value, or <code>null</code> if not known or not
	 *    relevant
	 * @param newValue the new value, or <code>null</code> if not known or not
	 *    relevant
	 */
	protected void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
		if (name == null)
			throw new IllegalArgumentException();
		Object[] changeListeners = this.listeners.getListeners();
		// Do we even need to fire an event?
		if (changeListeners.length == 0)
			return;
		final PropertyChangeEvent pe = new PropertyChangeEvent(this, name, oldValue, newValue);
		for (int i = 0; i < changeListeners.length; ++i) {
			final IPropertyChangeListener l = (IPropertyChangeListener) changeListeners[i];
			ISafeRunnable job = new ISafeRunnable() {
				public void handleException(Throwable exception) {
					// already being logged in SafeRunner#run()
				}

				public void run() throws Exception {
					l.propertyChange(pe);
				}
			};
			SafeRunner.run(job);
		}
	}

	/**
	 * Returns the current value of the boolean-valued property with the
	 * given name.
	 * Returns the default-default value (<code>false</code>) if there
	 * is no property with the given name, or if the current value 
	 * cannot be treated as a boolean.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the boolean-valued property
	 */
	public boolean getBoolean(String name) {
		String value = properties.getProperty(name);
		if (value == null) {
			return BOOLEAN_DEFAULT_DEFAULT;
		}
		return value.equals(Preferences.TRUE);
	}

	/**
	 * Sets the current value of the boolean-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property
	 */
	public void setValue(String name, boolean value) {
		boolean defaultValue = getDefaultBoolean(name);
		boolean oldValue = getBoolean(name);
		if (value == defaultValue) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, value ? Preferences.TRUE : Preferences.FALSE);
		}
		if (oldValue != value) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, oldValue ? Boolean.TRUE : Boolean.FALSE, value ? Boolean.TRUE : Boolean.FALSE);
		}
	}

	/**
	 * Returns the default value for the boolean-valued property
	 * with the given name.
	 * Returns the default-default value (<code>false</code>) if there
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as a boolean.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public boolean getDefaultBoolean(String name) {
		String value = defaultProperties.getProperty(name);
		if (value == null) {
			return BOOLEAN_DEFAULT_DEFAULT;
		}
		return value.equals(Preferences.TRUE);
	}

	/**
	 * Sets the default value for the boolean-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property
	 */
	public void setDefault(String name, boolean value) {
		defaultProperties.put(name, value ? Preferences.TRUE : Preferences.FALSE);
	}

	/**
	 * Returns the current value of the double-valued property with the
	 * given name.
	 * Returns the default-default value (<code>0.0</code>) if there
	 * is no property with the given name, or if the current value 
	 * cannot be treated as a double.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the double-valued property
	 */
	public double getDouble(String name) {
		return convertToDouble(properties.getProperty(name), DOUBLE_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the current value of the double-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property; must be 
	 *   a number (not a NaN)
	 */
	public void setValue(String name, double value) {
		if (Double.isNaN(value)) {
			throw new IllegalArgumentException();
		}
		double defaultValue = getDefaultDouble(name);
		double oldValue = getDouble(name);
		if (value == defaultValue) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, Double.toString(value));
		}
		if (oldValue != value) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, new Double(oldValue), new Double(value));
		}
	}

	/**
	 * Returns the default value for the double-valued property
	 * with the given name.
	 * Returns the default-default value (<code>0.0</code>) if there
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as a double.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public double getDefaultDouble(String name) {
		return convertToDouble(defaultProperties.getProperty(name), DOUBLE_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the default value for the double-valued property with the
	 * given name. The given name must not be <code>null</code>. 
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property; must be 
	 *   a number (not a NaN)
	 */
	public void setDefault(String name, double value) {
		if (Double.isNaN(value)) {
			throw new IllegalArgumentException();
		}
		defaultProperties.put(name, Double.toString(value));
	}

	/**
	 * Converts the given raw property value string to a double.
	 * 
	 * @param rawPropertyValue the raw property value, or <code>null</code>
	 *   if none
	 * @param defaultValue the default value
	 * @return the raw value converted to a double, or the given 
	 *    <code>defaultValue</code> if the raw value is <code>null</code> or
	 *    cannot be parsed as a double
	 */
	private double convertToDouble(String rawPropertyValue, double defaultValue) {
		double result = defaultValue;
		if (rawPropertyValue != null) {
			try {
				result = Double.parseDouble(rawPropertyValue);
			} catch (NumberFormatException e) {
				// raw value cannot be treated as one of these
			}
		}
		return result;
	}

	/**
	 * Returns the current value of the float-valued property with the
	 * given name.
	 * Returns the default-default value (<code>0.0f</code>) if there
	 * is no property with the given name, or if the current value 
	 * cannot be treated as a float.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the float-valued property
	 */
	public float getFloat(String name) {
		return convertToFloat(properties.getProperty(name), FLOAT_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the current value of the float-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property; must be 
	 *   a number (not a NaN)
	 */
	public void setValue(String name, float value) {
		if (Float.isNaN(value)) {
			throw new IllegalArgumentException();
		}
		float defaultValue = getDefaultFloat(name);
		float oldValue = getFloat(name);
		if (value == defaultValue) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, Float.toString(value));
		}
		if (oldValue != value) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, new Float(oldValue), new Float(value));
		}
	}

	/**
	 * Returns the default value for the float-valued property
	 * with the given name.
	 * Returns the default-default value (<code>0.0f</code>) if there
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as a float.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public float getDefaultFloat(String name) {
		return convertToFloat(defaultProperties.getProperty(name), FLOAT_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the default value for the float-valued property with the
	 * given name. The given name must not be <code>null</code>. 
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property; must be 
	 *   a number (not a NaN)
	 */
	public void setDefault(String name, float value) {
		if (Float.isNaN(value)) {
			throw new IllegalArgumentException();
		}
		defaultProperties.put(name, Float.toString(value));
	}

	/**
	 * Converts the given raw property value string to a float.
	 * 
	 * @param rawPropertyValue the raw property value, or <code>null</code>
	 *   if none
	 * @param defaultValue the default value
	 * @return the raw value converted to a float, or the given 
	 *    <code>defaultValue</code> if the raw value is <code>null</code> or
	 *    cannot be parsed as a float
	 */
	private float convertToFloat(String rawPropertyValue, float defaultValue) {
		float result = defaultValue;
		if (rawPropertyValue != null) {
			try {
				result = Float.parseFloat(rawPropertyValue);
			} catch (NumberFormatException e) {
				// raw value cannot be treated as one of these
			}
		}
		return result;
	}

	/**
	 * Returns the current value of the integer-valued property with the
	 * given name.
	 * Returns the default-default value (<code>0</code>) if there
	 * is no property with the given name, or if the current value 
	 * cannot be treated as an integer.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the int-valued property
	 */
	public int getInt(String name) {
		return convertToInt(properties.getProperty(name), INT_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the current value of the integer-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property
	 */
	public void setValue(String name, int value) {
		int defaultValue = getDefaultInt(name);
		int oldValue = getInt(name);
		if (value == defaultValue) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, Integer.toString(value));
		}
		if (oldValue != value) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, new Integer(oldValue), new Integer(value));
		}
	}

	/**
	 * Returns the default value for the integer-valued property
	 * with the given name.
	 * Returns the default-default value (<code>0</code>) if there
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as an integer.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public int getDefaultInt(String name) {
		return convertToInt(defaultProperties.getProperty(name), INT_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the default value for the integer-valued property with the
	 * given name. The given name must not be <code>null</code>. 
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property
	 */
	public void setDefault(String name, int value) {
		defaultProperties.put(name, Integer.toString(value));
	}

	/**
	 * Converts the given raw property value string to an int.
	 * 
	 * @param rawPropertyValue the raw property value, or <code>null</code>
	 *   if none
	 * @param defaultValue the default value
	 * @return the raw value converted to an int, or the given 
	 *    <code>defaultValue</code> if the raw value is <code>null</code> or
	 *    cannot be parsed as an int
	 */
	private int convertToInt(String rawPropertyValue, int defaultValue) {
		int result = defaultValue;
		if (rawPropertyValue != null) {
			try {
				result = Integer.parseInt(rawPropertyValue);
			} catch (NumberFormatException e) {
				// raw value cannot be treated as one of these
			}
		}
		return result;
	}

	/**
	 * Returns the current value of the long-valued property with the
	 * given name.
	 * Returns the default-default value (<code>0L</code>) if there
	 * is no property with the given name, or if the current value 
	 * cannot be treated as a long.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the long-valued property
	 */
	public long getLong(String name) {
		return convertToLong(properties.getProperty(name), LONG_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the current value of the long-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property
	 */
	public void setValue(String name, long value) {
		long defaultValue = getDefaultLong(name);
		long oldValue = getLong(name);
		if (value == defaultValue) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, Long.toString(value));
		}
		if (oldValue != value) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, new Long(oldValue), new Long(value));
		}
	}

	/**
	 * Returns the default value for the long-valued property
	 * with the given name.
	 * Returns the default-default value (<code>0L</code>) if there
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as a long.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public long getDefaultLong(String name) {
		return convertToLong(defaultProperties.getProperty(name), LONG_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the default value for the long-valued property with the
	 * given name. The given name must not be <code>null</code>. 
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property
	 */
	public void setDefault(String name, long value) {
		defaultProperties.put(name, Long.toString(value));
	}

	/**
	 * Converts the given raw property value string to a long.
	 * 
	 * @param rawPropertyValue the raw property value, or <code>null</code>
	 *   if none
	 * @param defaultValue the default value
	 * @return the raw value converted to a long, or the given 
	 *    <code>defaultValue</code> if the raw value is <code>null</code> or
	 *    cannot be parsed as a long
	 */
	private long convertToLong(String rawPropertyValue, long defaultValue) {
		long result = defaultValue;
		if (rawPropertyValue != null) {
			try {
				result = Long.parseLong(rawPropertyValue);
			} catch (NumberFormatException e) {
				// raw value cannot be treated as one of these
			}
		}
		return result;
	}

	/**
	 * Returns the current value of the string-valued property with the
	 * given name.
	 * Returns the default-default value (the empty string <code>""</code>)
	 * if there is no property with the given name.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the string-valued property
	 */
	public String getString(String name) {
		String value = properties.getProperty(name);
		return (value != null ? value : STRING_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the current value of the string-valued property with the
	 * given name. The given name must not be <code>null</code>.
	 * <p>
	 * A property change event is reported if the current value of the 
	 * property actually changes from its previous value. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are wrapped as objects.
	 * </p>
	 * <p>
	 * If the given value is the same as the corresponding default value
	 * for the given property, the explicit setting is deleted.
	 * Note that the recommended way of re-initializing a property to its
	 * default value is to call <code>setToDefault</code>.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new current value of the property
	 */
	public void setValue(String name, String value) {
		if (value == null) {
			throw new IllegalArgumentException();
		}
		String defaultValue = getDefaultString(name);
		String oldValue = getString(name);
		if (value.equals(defaultValue)) {
			Object removed = properties.remove(name);
			if (removed != null) {
				// removed an explicit setting
				dirty = true;
			}
		} else {
			properties.put(name, value);
		}
		if (!oldValue.equals(value)) {
			// mark as dirty since value did really change
			dirty = true;
			// report property change if getValue now returns different value
			firePropertyChangeEvent(name, oldValue, value);
		}
	}

	/**
	 * Returns the default value for the string-valued property
	 * with the given name.
	 * Returns the default-default value (the empty string <code>""</code>) 
	 * is no default property with the given name, or if the default 
	 * value cannot be treated as a string.
	 * The given name must not be <code>null</code>.
	 *
	 * @param name the name of the property
	 * @return the default value of the named property
	 */
	public String getDefaultString(String name) {
		String value = defaultProperties.getProperty(name);
		return (value != null ? value : STRING_DEFAULT_DEFAULT);
	}

	/**
	 * Sets the default value for the string-valued property with the
	 * given name. The given name must not be <code>null</code>. 
	 * <p>
	 * Note that the current value of the property is affected if
	 * the property's current value was its old default value, in which
	 * case it changes to the new default value. If the property's current
	 * is different from its old default value, its current value is
	 * unaffected. No property change events are reported by changing default
	 * values.
	 * </p>
	 *
	 * @param name the name of the property
	 * @param value the new default value for the property
	 */
	public void setDefault(String name, String value) {
		if (value == null) {
			throw new IllegalArgumentException();
		}
		defaultProperties.put(name, value);
	}

	/**
	 * Returns whether the property with the given name has the default value in
	 * virtue of having no explicitly set value.
	 * Returns <code>false</code> if the given name is <code>null</code>.
	 *
	 * @param name the name of the property, or <code>null</code>
	 * @return <code>true</code> if the property has no explicitly set value,
	 * and <code>false</code> otherwise (including the case where the property
	 * is unknown to this object)
	 */
	public boolean isDefault(String name) {
		return !properties.containsKey(name);
	}

	/**
	 * Sets the current value of the property with the given name back
	 * to its default value. Has no effect if the property does not have
	 * its own current value. The given name must not be <code>null</code>.
	 * <p>
	 * Note that the recommended way of re-initializing a property to the
	 * appropriate default value is to call <code>setToDefault</code>.
	 * This is implemented by removing the named value from the object, 
	 * thereby exposing the default value.
	 * </p>
	 * <p>
	 * A property change event is always reported. In the event
	 * object, the property name is the name of the property, and the
	 * old and new values are either strings, or <code>null</code> 
	 * indicating the default-default value.
	 * </p>
	 *
	 * @param name the name of the property
	 */
	public void setToDefault(String name) {
		Object oldPropertyValue = properties.remove(name);
		if (oldPropertyValue != null) {
			dirty = true;
		}
		String newValue = defaultProperties.getProperty(name, null);
		// n.b. newValue == null if there is no default value
		// can't determine correct default-default without knowing type
		firePropertyChangeEvent(name, oldPropertyValue, newValue);
	}

	/**
	 * Returns a list of all properties known to this preference object which
	 * have current values other than their default value.
	 *
	 * @return an array of property names 
	 */
	public String[] propertyNames() {
		return (String[]) properties.keySet().toArray(EMPTY_STRING_ARRAY);
	}

	/**
	 * Returns a list of all properties known to this preference object which
	 * have an explicit default value set.
	 *
	 * @return an array of property names 
	 */
	public String[] defaultPropertyNames() {
		return (String[]) defaultProperties.keySet().toArray(EMPTY_STRING_ARRAY);
	}

	/**
	 * Returns whether the current values in this preference object
	 * require saving.
	 *
	 * @return <code>true</code> if at least one of the properties
	 *  known to this preference object has a current value different from its
	 *  default value, and <code>false</code> otherwise
	 */
	public boolean needsSaving() {
		return dirty;
	}

	/**
	 * Saves the non-default-valued properties known to this preference object to
	 * the given output stream using 
	 * <code>Properties.store(OutputStream,String)</code>.
	 * <p>
	 * Note that the output is unconditionally written, even when
	 * <code>needsSaving</code> is <code>false</code>.
	 * </p>
	 *
	 * @param out the output stream 
	 * @param header a comment to be included in the output, or 
	 *    <code>null</code> if none
	 * @exception IOException if there is a problem saving this preference object
	 * @see Properties#store(OutputStream,String)
	 */
	public void store(OutputStream out, String header) throws IOException {
		properties.store(out, header);
		dirty = false;
	}

	/**
	 * Loads the non-default-valued properties for this preference object from the
	 * given input stream using 
	 * <code>java.util.Properties.load(InputStream)</code>. Default property
	 * values are not affected.
	 *
	 * @param in the input stream
	 * @exception IOException if there is a problem loading this preference
	 *    object
	 * @see java.util.Properties#load(InputStream)
	 */
	public void load(InputStream in) throws IOException {
		properties.load(in);
		dirty = false;
	}
}
