/*******************************************************************************
 * Copyright (c) 2012, 2013 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0, which accompanies this distribution
 * and is available at https://www.eclipse.org/legal/epl-2.0/.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.common.core.internal.utility;

import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jpt.common.core.JptCommonCoreMessages;
import org.eclipse.jpt.common.core.internal.plugin.JptCommonCorePlugin;
import org.eclipse.jpt.common.core.utility.ValidationMessage;
import org.eclipse.jpt.common.utility.exception.ExceptionHandler;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.exception.ExceptionHandlerAdapter;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugTrace;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.util.tracker.ServiceTracker;

/**
 * Common Dali plug-in behavior:<ul>
 * <li>plug-in lifecycle
 * <li>content types
 * <li>resource (project) persistent properties
 * <li>preferences
 * <li>logging
 * <li>statuses
 * <li>exception handler
 * <li>debug options
 * <li>tracing
 * </ul>
 * <strong>NB:</strong> The following plug-in state is read-write and any change
 * to the {@link #getPluginID() plug-in's ID} must consider backward and forward
 * compatibility (i.e. {@link #getOriginalPluginID_() it may be wise to continue
 * using the original plug-in ID} - In particular, forward-compatibility is necessary
 * for a team of developers to use different versions of the same plug-in when
 * reading and writing this state.):<ul>
 * <li>resource (project) persistent properties
 * <li>preferences
 * </ul>
 */
public abstract class JptPlugin
	implements BundleActivator
{
	private volatile Bundle bundle;

	// NB: the plug-in must be synchronized whenever accessing any of this state
	private ExceptionHandler exceptionHandler;
	private ServiceTracker<DebugOptions, DebugOptions> debugOptionsTracker;
	private DebugTrace debugTrace;


	/**
	 * Default constructor is required. Of course, subclass constructors must
	 * be <code>public</code>.
	 */
	protected JptPlugin() {
		super();
	}


	// ********** plug-in lifecycle **********

	/**
	 * Subclass should call <code>super.start(context)</code> at the beginning
	 * of its override implementation.
	 * <p>
	 * <strong>NB:</strong> Most state should be built lazily....
	 */
	public void start(BundleContext context) throws Exception {
		this.bundle = context.getBundle();
		// make the instance available immediately; although nothing *should*
		// retrieve it during start-up, as most state should be populated lazily...
		this.setInstance(this);
	}

	/**
	 * Set the plug-in's singleton instance.
	 */
	protected abstract void setInstance(JptPlugin plugin);

	/**
	 * Subclass should call <code>super.stop(context)</code> at the end
	 * of its override implementation.
	 * <p>
	 * <strong>NB:</strong> the plug-in should not return from this method
	 * until all its outstanding processes are finished.
	 */
	public void stop(BundleContext context) throws Exception {
		// the service tracker must be rebuilt with a valid bundle context if the plug-in is restarted
		this.closeDebugOptionsTracker();
		// seems like we can leave 'exceptionHandler' in place...
	}


	// ********** content type **********

	/**
	 * Return the content type corresponding to the
	 * specified context type within the scope of the plug-in; i.e prefix the
	 * specified content type with the
	 * {@link #getContentTypeScope() plug-in's content type scope}.
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	public IContentType getContentType(String contentType) {
		StringBuilder scope = this.getContentTypeScope();
		return (scope == null) ? null : Platform.getContentTypeManager().getContentType(scope.append(contentType).toString());
	}

	/**
	 * Return the name of the plug-in's {@link IContentType content type} scope.
	 * Include an appended <code>'.'</code>.
	 * By default, this is in the form
	 * <em>&lt;plug-in ID&gt;.content.</em>
	 * (e.g. <code>"org.eclipse.jpt.common.core.content."</code>).
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	protected StringBuilder getContentTypeScope() {
		String id = this.getPluginID();
		if (id == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder(id);
		sb.append('.');
		sb.append(this.getRelativeContentTypeScope());
		sb.append('.');
		return sb;
	}

	/**
	 * @see #RELATIVE_CONTENT_TYPE_SCOPE
	 */
	protected String getRelativeContentTypeScope() {
		return RELATIVE_CONTENT_TYPE_SCOPE;
	}
	/**
	 * Value: <code>{@value}</code>
	 */
	protected static final String RELATIVE_CONTENT_TYPE_SCOPE = "content"; //$NON-NLS-1$


	// ********** resource persistent properties **********

	/**
	 * Return the specified {@link IResource#getPersistentProperty(QualifiedName)
	 * resource's persistent property}, relative to the plug-in's ID.
	 * Return <code>null</code> if the plug-in has no bundle
	 * or if there are any problems retrieving the property.
	 */
	public String getPersistentProperty(IResource resource, String key) {
		QualifiedName qName = this.buildPersistentPropertyQualifiedName(key);
		try {
			return (qName == null) ? null : resource.getPersistentProperty(qName);
		} catch (CoreException ex) {
			this.logError(ex);
			return null;
		}
	}

	/**
	 * Set the specified {@link IResource#setPersistentProperty(QualifiedName, String)
	 * resource's persistent property}, relative to the plug-in's ID.
	 */
	public void setPersistentProperty(IResource resource, String key, String value) {
		QualifiedName qName = this.buildPersistentPropertyQualifiedName(key);
		try {
			if (qName != null) {
				resource.setPersistentProperty(qName, value);
			}
		} catch (CoreException ex) {
			this.logError(ex);
		}
	}

	/**
	 * Remove the specified {@link IResource#getPersistentProperties()
	 * resource's persistent properties}, relative to the plug-in's ID.
	 */
	public void removePersistentProperties(IResource resource) {
		try {
			this.removePersistentProperties_(resource);
		} catch (CoreException ex) {
			this.logError(ex);
		}
	}

	protected void removePersistentProperties_(IResource resource) throws CoreException {
		String id = this.getPersistentPropertyPluginID();
		Map<QualifiedName, String> props = resource.getPersistentProperties();
		for (QualifiedName key : props.keySet()) {
			if (ObjectTools.equals(key.getQualifier(), id)) {
				resource.setPersistentProperty(key, null);
			}
		}
	}

	/**
	 * Qualify the specified relative name with the plug-in's ID.
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	protected QualifiedName buildPersistentPropertyQualifiedName(String relativeName) {
		String id = this.getPersistentPropertyPluginID();
		return (id == null) ? null : new QualifiedName(id, relativeName);
	}

	/**
	 * @see #getOriginalPluginID_()
	 */
	protected String getPersistentPropertyPluginID() {
		return this.getOriginalPluginID();
	}


	// ********** preferences **********

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return <code>null</code> if the specified preference is not found.
	 */
	public String getPreference(String key) {
		return this.getPreference(key, null);
	}

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return the specified default value if the specified preference is not found.
	 */
	public String getPreference(String key, String defaultValue) {
		return this.searchPreferences(key, this.getPreferenceSearchPath(), defaultValue);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return <code>null</code> if the specified preference is not found.
	 */
	public String getPreference(IProject project, String key) {
		return this.getPreference(project, key, null);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return the specified default value if the specified preference is not found.
	 */
	public String getPreference(IProject project, String key, String defaultValue) {
		return this.searchPreferences(key, this.getPreferenceSearchPath(project), defaultValue);
	}

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return <code>false</code> if the specified preference is not found.
	 */
	public boolean getBooleanPreference(String key) {
		return this.getBooleanPreference(key, false);
	}

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return the specified default value if the specified preference is not found.
	 */
	public boolean getBooleanPreference(String key, boolean defaultValue) {
		return this.searchBooleanPreferences(key, this.getPreferenceSearchPath(), defaultValue);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return <code>false</code> if the specified preference is not found.
	 */
	public boolean getBooleanPreference(IProject project, String key) {
		return this.getBooleanPreference(project, key, false);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return the specified default value if the specified preference is not found.
	 */
	public boolean getBooleanPreference(IProject project, String key, boolean defaultValue) {
		return this.searchBooleanPreferences(key, this.getPreferenceSearchPath(project), defaultValue);
	}

	/**
	 * Search the specified sets of preferences and return the value of the
	 * first occurrence of the specified key. Return the specified default
	 * value if none of the specified preference trees contain the specified
	 * key.
	 */
	protected boolean searchBooleanPreferences(String key, IEclipsePreferences[] searchPath, boolean defaultValue) {
		String value = this.searchPreferences(key, searchPath);
		return (value == null) ? defaultValue : Boolean.parseBoolean(value);
	}

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return <code>-1</code> if the specified preference is not found.
	 */
	public int getIntPreference(String key) {
		return this.getIntPreference(key, -1);
	}

	/**
	 * Return the value of the specified preference, searching the plug-in's
	 * workspace and default preferences.
	 * Return the specified default value if the specified preference is not found.
	 */
	public int getIntPreference(String key, int defaultValue) {
		return this.searchIntPreferences(key, this.getPreferenceSearchPath(), defaultValue);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return <code>-1</code> if the specified preference is not found.
	 */
	public int getIntPreference(IProject project, String key) {
		return this.getIntPreference(project, key, -1);
	}

	/**
	 * Return the value of the plug-in's specified project preference.
	 * Return the specified default value if the specified preference is not found.
	 */
	public int getIntPreference(IProject project, String key, int defaultValue) {
		return this.searchIntPreferences(key, this.getPreferenceSearchPath(project), defaultValue);
	}

	/**
	 * Search the specified sets of preferences and return the value of the
	 * first occurrence of the specified key. Return the specified default
	 * value if none of the specified preference trees contain the specified
	 * key.
	 */
	protected int searchIntPreferences(String key, IEclipsePreferences[] searchPath, int defaultValue) {
		String value = this.searchPreferences(key, searchPath);
		if (value == null) {
			return defaultValue;
		}
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			return defaultValue;
		}
	}

	/**
	 * Search the specified sets of preferences and return the value of the
	 * first occurrence of the specified key. Return the specified default
	 * value if none of the specified preference trees contain the specified
	 * key.
	 */
	protected String searchPreferences(String key, IEclipsePreferences[] searchPath, String defaultValue) {
		String value = this.searchPreferences(key, searchPath);
		return (value != null) ? value : defaultValue;
	}

	/**
	 * Search the specified sets of preferences and return the value of the
	 * first occurrence of the specified key. Return <code>null</code> if none
	 * of the specified preference trees contain the specified key.
	 */
	protected String searchPreferences(String key, IEclipsePreferences[] searchPath) {
		for (IEclipsePreferences prefs : searchPath) {
			if (prefs != null) {  // prefs can be null if the plug-in is inactive
				String value = prefs.get(key, null);
				if (value != null) {
					return value;
				}
			}
		}
		return null;
	}

	/**
	 * Return the plug-in's preference search path (typically, the plug-in's
	 * workspace preferences followed by its default preferences).
	 */
	protected IEclipsePreferences[] getPreferenceSearchPath() {
		return new IEclipsePreferences[] {
				this.getWorkspacePreferences(),
				this.getDefaultPreferences(),  // "original" preferences
				this.getCurrentDefaultPreferences()  // may be the same as the "original" preferences
			};
	}

	/**
	 * Return the plug-in's preference search path (typically, only the
	 * plug-in's project preferences).
	 */
	protected IEclipsePreferences[] getPreferenceSearchPath(IProject project) {
		return ArrayTools.add(this.getPreferenceSearchPath(), 0, this.getProjectPreferences(project));
	}

	/**
	 * Set the value of the plug-in's specified project preference.
	 * If the new value is <code>null</code>, remove the preference.
	 */
	public void setPreference(IProject project, String key, String value) {
		IEclipsePreferences prefs = this.getProjectPreferences(project);
		if (prefs != null) {
			if (value == null) {
				prefs.remove(key);
			} else {
				prefs.put(key, value);
			}
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified workspace preference.
	 * If the new value is <code>null</code>, remove the preference.
	 */
	public void setPreference(String key, String value) {
		IEclipsePreferences prefs = this.getWorkspacePreferences();
		if (prefs != null) {
			if (value == null) {
				prefs.remove(key);
			} else {
				prefs.put(key, value);
			}
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified default preference.
	 * Typically called during default preferences initialization
	 * (as configured by an extension of
	 * <code>org.eclipse.core.runtime.preferences</code>).
	 * If the new value is <code>null</code>, remove the preference.
	 */
	public void setDefaultPreference(String key, String value) {
		IEclipsePreferences prefs = this.getCurrentDefaultPreferences();
		if (prefs != null) {
			if (value == null) {
				prefs.remove(key);
			} else {
				prefs.put(key, value);
			}
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified project preference.
	 */
	public void setBooleanPreference(IProject project, String key, boolean value) {
		IEclipsePreferences prefs = this.getProjectPreferences(project);
		if (prefs != null) {
			prefs.putBoolean(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified workspace preference.
	 */
	public void setBooleanPreference(String key, boolean value) {
		IEclipsePreferences prefs = this.getWorkspacePreferences();
		if (prefs != null) {
			prefs.putBoolean(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified default preference.
	 * Typically called during default preferences initialization
	 * (as configured by an extension of
	 * <code>org.eclipse.core.runtime.preferences</code>).
	 */
	public void setBooleanDefaultPreference(String key, boolean value) {
		IEclipsePreferences prefs = this.getCurrentDefaultPreferences();
		if (prefs != null) {
			prefs.putBoolean(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified project preference.
	 */
	public void setIntPreference(IProject project, String key, int value) {
		IEclipsePreferences prefs = this.getProjectPreferences(project);
		if (prefs != null) {
			prefs.putInt(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified workspace preference.
	 */
	public void setIntPreference(String key, int value) {
		IEclipsePreferences prefs = this.getWorkspacePreferences();
		if (prefs != null) {
			prefs.putInt(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Set the value of the plug-in's specified default preference.
	 * Typically called during default preferences initialization
	 * (as configured by an extension of
	 * <code>org.eclipse.core.runtime.preferences</code>).
	 */
	public void setIntDefaultPreference(String key, int value) {
		IEclipsePreferences prefs = this.getCurrentDefaultPreferences();
		if (prefs != null) {
			prefs.putInt(key, value);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Remove the value of the plug-in's specified project preference.
	 */
	public void removePreference(IProject project, String key) {
		IEclipsePreferences prefs = this.getProjectPreferences(project);
		if (prefs != null) {
			prefs.remove(key);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Remove the value of the plug-in's specified workspace preference.
	 */
	public void removePreference(String key) {
		IEclipsePreferences prefs = this.getWorkspacePreferences();
		if (prefs != null) {
			prefs.remove(key);
			this.flushPreferences(prefs);
		}
	}

	/**
	 * Remove the plug-in's preferences for the specified project.
	 */
	public void removePreferences(IProject project) {
		this.removePreferences(this.getProjectPreferences(project));
	}

	/**
	 * Remove the plug-in's workspace preferences.
	 */
	public void removePreferences() {
		this.removePreferences(this.getWorkspacePreferences());
	}

	protected void removePreferences(IEclipsePreferences prefs) {
		try {
			if (prefs != null) {
				prefs.removeNode();
			}
		} catch (BackingStoreException ex) {
			this.logError(ex);
		}
	}

	/**
	 * Return the plug-in's workspace preferences. These preferences are written
	 * to disk when the workspace is closed.
	 * Return <code>null</code> if the plug-in has no bundle.
	 * These preferences are stored the file<br>
	 * <code>
	 * <em>&lt;workspace dir&gt;</em>/<em>&lt;project dir&gt;</em>/.settings/<em>&lt;plug-in ID&gt;</em>.prefs
	 * </code>
	 */
	protected IEclipsePreferences getProjectPreferences(IProject project) {
		return this.getPreferences(new ProjectScope(project));
	}

	/**
	 * Return the plug-in's workspace preferences. These preferences are written
	 * to disk when the workspace is closed.
	 * Return <code>null</code> if the plug-in has no bundle.
	 * These preferences are stored the file<br>
	 * <code>
	 * <em>&lt;workspace dir&gt;</em>/.metadata/.plugins/org.eclipse.core.runtime/.settings/<em>&lt;plug-in ID&gt;</em>.prefs
	 * </code>
	 */
	protected IEclipsePreferences getWorkspacePreferences() {
		return this.getPreferences(InstanceScope.INSTANCE);
	}

	/**
	 * Return the plug-in's <em>current</em> default preferences.
	 * These preferences are initialized
	 * during default preferences initialization and are not saved to disk.
	 * Return <code>null</code> if the plug-in has no bundle.
	 * <p>
	 * These preferences must use the <em>current</em> plug-in ID as the
	 * extension is associated with the plug-in.
	 * <p>
	 * Default preferences are calculated upon first reference. The precedence
	 * is:<ul>
	 * <li>command-line
	 * <li>product
	 * <li>bundle
	 * <li>run-time
	 * </ul>
	 * @see org.eclipse.core.internal.preferences.DefaultPreferences#load()
	 * @see <a href="http://www.eclipse.org/eclipse/platform-core/documents/user_settings/plugin_customization.html">
	 *      Plug-in Customization documentation</a>
	 */
	@SuppressWarnings("restriction")
	protected IEclipsePreferences getCurrentDefaultPreferences() {
		String qualifier = this.getPluginID();
		return (qualifier == null) ? null : DefaultScope.INSTANCE.getNode(qualifier);
	}

	/**
	 * Return the plug-in's default preferences, as determined by the
	 * {@link #getPreferencesPluginID() "preferences plug-in ID"} which,
	 * by default, is the {@link #getOriginalPluginID() "original plug-in ID"}.
	 * This is used only to <em>read</em> default preferences that may be
	 * set via product customization using the original plug-in ID.
	 */
	protected IEclipsePreferences getDefaultPreferences() {
		return this.getPreferences(DefaultScope.INSTANCE);
	}

	/**
	 * Return the plug-in's preferences for the specified context.
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	protected IEclipsePreferences getPreferences(IScopeContext context) {
		String qualifier = this.getPreferencesPluginID();
		return (qualifier == null) ? null : context.getNode(qualifier);
	}

	/**
	 * Return <code>null</code> if the plug-in has no bundle.
	 * @see #getOriginalPluginID_()
	 */
	protected String getPreferencesPluginID() {
		return this.getOriginalPluginID();
	}

	/**
	 * Flush the specified preferences in an asynchronous
	 * {@link FlushPreferencesJob job}
	 * because the flush request can trigger a lock on the project,
	 * which can cause deadlocks (e.g. when deleting the metamodel source
	 * folder).
	 * <p>
	 * Note: The flush will also remove the preferences node if it is empty.
	 */
	protected void flushPreferences(IEclipsePreferences prefs) {
		if (FlushPreferences) {
			new FlushPreferencesJob(prefs).schedule();
		}
	}

	/**
	 * This flag is set to <code>false</code> when the test plug-in is loaded.
	 * The preferences end up getting flushed after the test case has deleted
	 * its project, resulting in resource exceptions in the log, e.g.
	 * <pre>
	 *     Resource '/JpaProjectManagerTests' is not open.
	 * </pre>
	 * See <code>JptJpaCoreTestsPlugin.start_()</code>
	 */
	public static volatile boolean FlushPreferences = true;

	protected static class FlushPreferencesJob
		extends Job
	{
		private final IEclipsePreferences prefs;

		FlushPreferencesJob(IEclipsePreferences prefs) {
			super(NLS.bind(JptCommonCoreMessages.PREFERENCES_FLUSH_JOB_NAME, prefs.absolutePath()));
			this.prefs = prefs;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			try {
				this.prefs.flush();
			} catch(BackingStoreException ex) {
				return JptCommonCorePlugin.instance().logError(ex);
			}
			return Status.OK_STATUS;
		}
	}


	// ********** validation preferences **********

	/**
	 * Return whether the specified project has project-specific preferences
	 * for its validation messages.
	 */
	public boolean getWorkspaceValidationPreferencesOverridden(IProject project) {
		String legacyPref = this.getPreference(project, LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
		if (legacyPref != null) {
			boolean legacyBooleanPref = this.getBooleanPreference(project, LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
			this.setWorkspaceValidationPreferencesOverridden(project, legacyBooleanPref);
			this.removePreference(project, LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
		}
		return this.getBooleanPreference(project, WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
	}

	// unfortunate legacy typo :-(
	private static final String LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN = "workspace_preferences_overriden"; //$NON-NLS-1$

	/**
	 * @see #getWorkspaceValidationPreferencesOverridden(IProject)
	 */
	public void setWorkspaceValidationPreferencesOverridden(IProject project, boolean value) {
		String legacyPref = this.getPreference(project, LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
		if (legacyPref != null) {
			this.removePreference(project, LEGACY_WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN);
		}
		this.setBooleanPreference(project, WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN, value);
	}

	private static final String WORKSPACE_VALIDATION_PREFERENCES_OVERRIDDEN = "workspace_validation_preferences_overridden"; //$NON-NLS-1$

	/**
	 * Return the severity for the specified validation message within the
	 * specified project. If there are no workspace- or project-level
	 * preferences specified for the message, return the specified default
	 * severity.
	 * @see IMessage#getSeverity()
	 * @see ValidationMessage#IGNORE_SEVERITY
	 */
	public int getValidationMessageSeverity(IProject project, String messageID, int defaultSeverity) {
		int prefSeverity = this.getValidationMessageSeverityPreference(project, messageID);
		return (prefSeverity != ValidationMessage.UNSET_SEVERITY_PREFERENCE) ? prefSeverity : defaultSeverity;
	}

	/**
	 * Return the project-level preference for the specified validation
	 * message's severity.
	 * @see IMessage#getSeverity()
	 * @see ValidationMessage#IGNORE_SEVERITY
	 * @see ValidationMessage#UNSET_SEVERITY_PREFERENCE
	 */
	public int getValidationMessageSeverityPreference(IProject project, String messageID) {
		return this.convertPreferenceValueToMessageSeverity(this.getValidationMessageSeverityPreference_(project, messageID));
	}

	private String getValidationMessageSeverityPreference_(IProject project, String messageID) {
		return this.getPreference(project, PROBLEM_ + messageID);
	}

	/**
	 * @see #getValidationMessageSeverityPreference(IProject, String)
	 */
	public void setValidationMessageSeverityPreference(IProject project, String messageID, int value) {
		this.setValidationMessageSeverityPreference_(project, messageID, this.convertMessageSeverityToPreferenceValue(value));
	}

	private void setValidationMessageSeverityPreference_(IProject project, String messageID, String value) {
		this.setPreference(project, PROBLEM_ + messageID, value);
	}

	/**
	 * Return the workspace-level preference for the specified validation
	 * message's severity.
	 * @see IMessage#getSeverity()
	 * @see ValidationMessage#IGNORE_SEVERITY
	 * @see ValidationMessage#UNSET_SEVERITY_PREFERENCE
	 */
	public int getValidationMessageSeverityPreference(String messageID) {
		return this.convertPreferenceValueToMessageSeverity(this.getValidationMessageSeverityPreference_(messageID));
	}

	private String getValidationMessageSeverityPreference_(String messageID) {
		return this.getPreference(PROBLEM_ + messageID);
	}

	/**
	 * @see #getValidationMessageSeverityPreference(String)
	 */
	public void setValidationMessageSeverityPreference(String messageID, int value) {
		this.setValidationMessageSeverityPreference_(messageID, this.convertMessageSeverityToPreferenceValue(value));
	}

	private void setValidationMessageSeverityPreference_(String messageID, String value) {
		this.setPreference(PROBLEM_ + messageID, value);
	}

	private static final String PROBLEM = "problem"; //$NON-NLS-1$
	private static final String PROBLEM_ = PROBLEM + '.';

	/**
	 * Convert the specified severity preference value to the corresponding
	 * problem validation message severity.
	 * @see IMessage#getSeverity()
	 * @see org.eclipse.jpt.common.core.utility.ValidationMessage#getDefaultSeverity()
	 */
	private int convertPreferenceValueToMessageSeverity(String prefSeverity) {
		for (PreferenceSeverityMapping mapping : PREFERENCE_SEVERITY_MAPPINGS) {
			if (ObjectTools.equals(prefSeverity, mapping.preferenceValue)) {
				return mapping.validationSeverity;
			}
		}
		throw new IllegalArgumentException("unknown preference severity: " + prefSeverity); //$NON-NLS-1$
	}

	/**
	 * Convert the specified validation message severity to the corresponding
	 * problem severity preference value.
	 * @see IMessage#getSeverity()
	 * @see org.eclipse.jpt.common.core.utility.ValidationMessage#getDefaultSeverity()
	 */
	private String convertMessageSeverityToPreferenceValue(int severity) {
		for (PreferenceSeverityMapping mapping : PREFERENCE_SEVERITY_MAPPINGS) {
			if (severity == mapping.validationSeverity) {
				return mapping.preferenceValue;
			}
		}
		throw new IllegalArgumentException("unknown severity: " + severity); //$NON-NLS-1$
	}

	/**
	 * Preference value for {@link IMessage#HIGH_SEVERITY}.
	 */
	private static final String PROBLEM_ERROR = "error"; //$NON-NLS-1$

	/**
	 * Preference value for {@link IMessage#NORMAL_SEVERITY}.
	 */
	private static final String PROBLEM_WARNING = "warning"; //$NON-NLS-1$

	/**
	 * Preference value for {@link IMessage#LOW_SEVERITY}.
	 */
	private static final String PROBLEM_INFO = "info"; //$NON-NLS-1$

	/**
	 * Preference value for {@link ValidationMessage#IGNORE_SEVERITY}.
	 */
	private static final String PROBLEM_IGNORE = "ignore"; //$NON-NLS-1$

	/**
	 * Map the problem severity preference values to their corresponding
	 * validation message severities, and vice-versa.
	 * 
	 * @see IMessage#getSeverity()
	 */
	private static final PreferenceSeverityMapping[] PREFERENCE_SEVERITY_MAPPINGS = new PreferenceSeverityMapping[] {
		new PreferenceSeverityMapping(PROBLEM_ERROR, IMessage.HIGH_SEVERITY),
		new PreferenceSeverityMapping(PROBLEM_WARNING, IMessage.NORMAL_SEVERITY),
		new PreferenceSeverityMapping(PROBLEM_INFO, IMessage.LOW_SEVERITY),
		new PreferenceSeverityMapping(PROBLEM_IGNORE, ValidationMessage.IGNORE_SEVERITY),
		new PreferenceSeverityMapping(null, ValidationMessage.UNSET_SEVERITY_PREFERENCE)
	};

	private static class PreferenceSeverityMapping {
		final String preferenceValue;
		final int validationSeverity;
		PreferenceSeverityMapping(String preferenceValue, int validationSeverity) {
			super();
			this.preferenceValue = preferenceValue;
			this.validationSeverity = validationSeverity;
		}
		@Override
		public String toString() {
			return ObjectTools.toString(this, this.preferenceValue);
		}
	}


	// ********** logging **********

	/**
	 * Log the specified message with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * Return the logged status.
	 * @see #log(int, String)
	 * @see IStatus
	 */
	public IStatus logError(String message) {
		return this.log(IStatus.ERROR, message);
	}

	/**
	 * Log the specified message with the specified severity.
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 */
	public IStatus log(int severity, String message) {
		return this.log(severity, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Log the specified message with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * Bind the message to the specified arguments.
	 * Return the logged status.
	 * @see #log(int, String, Object[])
	 * @see IStatus
	 */
	public IStatus logError(String message, Object... args) {
		return this.log(IStatus.ERROR, message, args);
	}

	/**
	 * Log the specified message with the specified severity.
	 * Bind the message to the specified arguments.
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 */
	public IStatus log(int severity, String message, Object... args) {
		return this.log(severity, (Throwable) null, message, args);
	}

	/**
	 * Log the specified exception with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * Return the logged status.
	 * @see #log(int, Throwable)
	 * @see IStatus
	 */
	public IStatus logError(Throwable throwable) {
		return this.log(IStatus.ERROR, throwable);
	}

	/**
	 * Log the specified exception with the specified severity.
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 */
	public IStatus log(int severity, Throwable throwable) {
		return this.log(severity, throwable, throwable.getLocalizedMessage());
	}

	/**
	 * Log the specified message and exception with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * Return the logged status.
	 * @see #log(int, Throwable, String)
	 * @see IStatus
	 */
	public IStatus logError(Throwable throwable, String message) {
		return this.log(IStatus.ERROR, throwable, message);
	}

	/**
	 * Log the specified message and exception with the specified severity.
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 */
	public IStatus log(int severity, Throwable throwable, String message) {
		return this.log(severity, IStatus.OK, throwable, message);
	}

	/**
	 * Log the specified message and exception with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * Bind the message to the specified arguments.
	 * Return the logged status.
	 * @see #log(int, Throwable, String, Object[])
	 * @see IStatus
	 */
	public IStatus logError(Throwable throwable, String message, Object... args) {
		return this.log(IStatus.ERROR, throwable, message, args);
	}

	/**
	 * Log the specified message and exception with the specified severity.
	 * Bind the message to the specified arguments.
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 */
	public IStatus log(int severity, Throwable throwable, String message, Object... args) {
		return this.log(severity, IStatus.OK, throwable, message, args);
	}

	/**
	 * Log the specified message and exception with the specified severity
	 * and code.
	 * If the plug-in has no {@link #getBundle() bundle}, log the information
	 * to the appropriate Java system log (instead of the Eclise platform log).
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 * @see IStatus#getCode()
	 */
	public IStatus log(int severity, int code, Throwable throwable, String message) {
		return this.log(severity, code, throwable, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Log the specified message and exception with the specified severity
	 * and code. Bind the message to the specified arguments.
	 * If the plug-in has no {@link #getBundle() bundle}, log the information
	 * to the appropriate Java system log (instead of the Eclise platform log).
	 * Return the logged status.
	 * @see IStatus#getSeverity()
	 * @see IStatus#getCode()
	 */
	public IStatus log(int severity, int code, Throwable throwable, String message, Object... args) {
		if (args.length > 0) {
			message = NLS.bind(message, args);
		}
		String id = this.getPluginID();
		IStatus status = new Status(severity, ((id != null) ? id : UNKNOWN_PLUGIN_ID), code, message, throwable);
		if (id != null) {
			ILog log = this.getLog();
			if (log != null) {
				log.log(status);
			} else {
				this.log_(status);
			}
		} else {
			this.log_(status);
		}
		return status;
	}
	protected static final String UNKNOWN_PLUGIN_ID = "unknown"; //$NON-NLS-1$

	/**
	 * Return the plug-in's log.
	 * Return <code>null</code> if the plug-in has no bundle.
	 * @see Platform#getLog(Bundle)
	 */
	public ILog getLog() {
		Bundle b = this.getBundle();
		return (b == null) ? null : Platform.getLog(b);
	}

	/**
	 * Log the specified message and exception with the specified severity
	 * and code to the appropriate Java system log.
	 * This method is called when the plug-in is inactive or the Eclipse
	 * platform log is unavailable.
	 * @see IStatus#getSeverity()
	 * @see IStatus#getCode()
	 */
	protected void log_(IStatus status) {
		PrintStream stream = System.out;
		int severity = status.getSeverity();
		if ((severity == IStatus.ERROR) || (severity == IStatus.WARNING)) {
			stream = System.err; // ???
		}
		synchronized (stream) {
			this.log_(new PrintWriter(stream), status);
		}
	}

	protected void log_(PrintWriter writer, IStatus status) {
		writer.print(this.getClass().getName());
		writer.print(':');
		writer.println();
		int severity = status.getSeverity();
		switch (severity) {
			case IStatus.CANCEL:
				writer.print("CANCEL"); //$NON-NLS-1$
				break;
			case IStatus.ERROR:
				writer.print("ERROR"); //$NON-NLS-1$
				break;
			case IStatus.WARNING:
				writer.print("WARNING"); //$NON-NLS-1$
				break;
			case IStatus.INFO:
				writer.print("INFO"); //$NON-NLS-1$
				break;
			case IStatus.OK:
				writer.print("OK"); //$NON-NLS-1$
				break;
			default:
				writer.print("SEVERITY "); //$NON-NLS-1$
				writer.print(severity);
				break;
		}
		int code = status.getCode();
		if (code != IStatus.OK) {
			writer.print(" (code="); //$NON-NLS-1$
			writer.print(code);
			writer.print(")"); //$NON-NLS-1$
		}
		String message = status.getMessage();
		if (message != null) {
			writer.print(": "); //$NON-NLS-1$
			writer.print(message);
		}
		writer.println();
		Throwable throwable = status.getException();
		if (throwable != null) {
			throwable.printStackTrace(writer);
		}
	}


	// ********** statuses **********

	/**
	 * Build a status with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * @see #buildStatus(int)
	 * @see IStatus
	 */
	public IStatus buildErrorStatus() {
		return this.buildStatus(IStatus.ERROR);
	}

	/**
	 * Build a status with a severity of
	 * {@link IStatus#OK OK}.
	 * @see #buildStatus(int)
	 * @see IStatus
	 */
	public IStatus buildOKStatus() {
		return this.buildStatus(IStatus.OK);
	}

	/**
	 * Build a status with the specified severity.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity) {
		return this.buildStatus(severity, (String) null);  // message can be null
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * @see #buildStatus(int, String)
	 * @see IStatus
	 */
	public IStatus buildErrorStatus(String message) {
		return this.buildStatus(IStatus.ERROR, message);
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#WARNING WARNING}.
	 * @see #buildStatus(int, String)
	 * @see IStatus
	 */
	public IStatus buildWarningStatus(String message) {
		return this.buildStatus(IStatus.WARNING, message);
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#INFO INFO}.
	 * @see #buildStatus(int, String)
	 * @see IStatus
	 */
	public IStatus buildInfoStatus(String message) {
		return this.buildStatus(IStatus.INFO, message);
	}

	/**
	 * Build a status with the specified severity and message.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity, String message) {
		return this.buildStatus(severity, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * @see #buildStatus(int, String, Object[])
	 * @see IStatus
	 */
	public IStatus buildErrorStatus(String message, Object... args) {
		return this.buildStatus(IStatus.ERROR, message, args);
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#WARNING WARNING}.
	 * @see #buildStatus(int, String, Object[])
	 * @see IStatus
	 */
	public IStatus buildWarningStatus(String message, Object... args) {
		return this.buildStatus(IStatus.WARNING, message, args);
	}

	/**
	 * Build a status with the specified message with a severity of
	 * {@link IStatus#INFO INFO}.
	 * @see #buildStatus(int, String, Object[])
	 * @see IStatus
	 */
	public IStatus buildInfoStatus(String message, Object... args) {
		return this.buildStatus(IStatus.INFO, message, args);
	}

	/**
	 * Build a status with the specified severity and message.
	 * Bind the message to the specified arguments.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity, String message, Object... args) {
		return this.buildStatus(severity, (Throwable) null, message, args); // exception can be null
	}

	/**
	 * Build a status with the specified exception with a severity of
	 * {@link IStatus#ERROR ERROR}.
	 * @see #buildStatus(int, Throwable)
	 * @see IStatus
	 */
	public IStatus buildErrorStatus(Throwable throwable) {
		return this.buildStatus(IStatus.ERROR, throwable);
	}

	/**
	 * Build a status with the specified severity and exception.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity, Throwable throwable) {
		return this.buildStatus(severity, throwable, throwable.getLocalizedMessage());
	}

	/**
	 * Build a status with the specified exception and message with a
	 * severity of {@link IStatus#ERROR ERROR}.
	 * @see #buildStatus(int, Throwable, String)
	 * @see IStatus
	 */
	public IStatus buildErrorStatus(Throwable throwable, String message) {
		return this.buildStatus(IStatus.ERROR, throwable, message);
	}

	/**
	 * Build a status with the specified severity, exception, and message.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity, Throwable throwable, String message) {
		return this.buildStatus(severity, throwable, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Build a status with the specified exception and message with a
	 * severity of {@link IStatus#ERROR ERROR}.
	 * Bind the message to the specified arguments.
	 * @see #buildStatus(int, Throwable, String, Object[])
	 * @see IStatus
	 */
	public IStatus buildErrorStatus(Throwable throwable, String message, Object... args) {
		return this.buildStatus(IStatus.ERROR, throwable, message, args);
	}

	/**
	 * Build a status with the specified severity, exception, and message.
	 * Bind the message to the specified arguments.
	 * @see IStatus#getSeverity()
	 */
	public IStatus buildStatus(int severity, Throwable throwable, String message, Object... args) {
		return this.buildStatus(severity, IStatus.OK, throwable, message, args);
	}

	/**
	 * Build a status with the specified severity, code, exception, and message.
	 * @see IStatus#getSeverity()
	 * @see IStatus#getCode()
	 */
	public IStatus buildStatus(int severity, int code, Throwable throwable, String message) {
		return this.buildStatus(severity, code, throwable, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Build a status with the specified severity, code, exception, and message.
	 * Bind the message to the specified arguments.
	 * @see IStatus#getSeverity()
	 * @see IStatus#getCode()
	 */
	public IStatus buildStatus(int severity, int code, Throwable throwable, String message, Object... args) {
		if (args.length > 0) {
			message = NLS.bind(message, args);
		}
		String id = this.getPluginID();
		if (id == null) {
			id = this.getClass().getName(); // seems reasonable
		}
		return new Status(severity, id, code, message, throwable);
	}


	// ********** exception handler **********

	/**
	 * Return an exception handler that logs any exceptions with the plug-in
	 * with the appropriate severity; by default, {@link IStatus#ERROR error}.
	 */
	public synchronized ExceptionHandler getExceptionHandler() {
		if (this.exceptionHandler == null) {
			this.exceptionHandler = this.buildExceptionHandler();
		}
		return this.exceptionHandler;
	}

	/**
	 * By default the plug-in's exception handler will log any exceptions
	 * as {@link IStatus#ERROR errors}.
	 */
	public ExceptionHandler buildExceptionHandler() {
		return this.buildExceptionHandler(IStatus.ERROR);
	}

	/**
	 * This public method can be used by code that would like its own exception
	 * handler, as opposed to using the plug-in's exception handler.
	 * @see #getExceptionHandler()
	 * @see PluginExceptionHandler
	 * @see IStatus#getSeverity()
	 */
	public ExceptionHandler buildExceptionHandler(int severity) {
		return new PluginExceptionHandler(severity);
	}

	/**
	 * Handle any exception by logging it with the plug-in with the configured
	 * severity.
	 */
	protected class PluginExceptionHandler
		extends ExceptionHandlerAdapter
	{
		private final int severity;
		protected PluginExceptionHandler(int severity) {
			super();
			this.severity = severity;
		}
		@Override
		public void handleException(Throwable t) {
			JptPlugin.this.log(this.severity, t);
		}
	}


	// ********** debug options **********

	/**
	 * Return whether the plug-in is in debug mode.
	 * <p>
	 * To allow a user to enable a plug-in's <em>debug</em> mode
	 * (or any other debug options)
	 * add the appropriate entry to the plug-in's trace-options file.
	 * <p>
	 * For example, to allow the user to enable the <em>debug</em> mode for
	 * the plug-in <code>org.eclipse.jpt.common.core</code>,
	 * add the following entry to the file
	 * <code>org.eclipse.jpt.common.core/.options</code>:
	 * <pre>
	 * org.eclipse.jpt.common.core/debug=true
	 * </pre>
	 * The flag can be set via either:<ul>
	 * <li>The Host Workspace's Run > Run Configurations > Tracing settings
	 * </ul>
	 * or
	 * <p><ul>
	 * <li>The Target Workspace's Window > Preferences > General > Tracing settings
	 * (This will be present because all Dali debug options have been activated
	 * via the <code>org.eclipse.jpt.common.ui</code> extension
	 * to the <code>org.eclipse.ui.trace.traceComponents</code> extension point.
	 * See <code>org.eclipse.jpt.common.ui/plugin.xml:org.eclipse.ui.trace.traceComponents</code>.)
	 * </ul>
	 */
	public boolean isDebugEnabled() {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions == null) {
			return false;
		}
		StringBuilder option = this.getDebugOptionName();
		return (option != null) && debugOptions.getBooleanOption(option.toString(), false);
	}

	/**
	 * Set whether the plug-in is in debug mode.
	 * 
	 * @see #isDebugEnabled()
	 */
	public void setDebugEnabled(boolean debug) {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions != null) {
			StringBuilder option = this.getDebugOptionName();
			if (option != null) {
				if ( ! debugOptions.isDebugEnabled()) {
					debugOptions.setDebugEnabled(true);
				}
				debugOptions.setOption(option.toString(), Boolean.toString(debug));
			}
		}
	}

	/**
	 * Return the name of the plug-in's debug option.
	 * By default, this is in the form
	 * <em>&lt;plug-in ID&gt;/debug</em>
	 * (e.g. <code>org.eclipse.jpt.common.core/debug</code>).
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	protected StringBuilder getDebugOptionName() {
		String id = this.getPluginID();
		if (id == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder(id);
		sb.append('/');
		sb.append(this.getRelativeDebugOptionName());
		return sb;
	}

	/**
	 * @see #RELATIVE_DEBUG_OPTION_NAME
	 */
	protected String getRelativeDebugOptionName() {
		return RELATIVE_DEBUG_OPTION_NAME;
	}
	/**
	 * Value: <code>{@value}</code>
	 */
	protected static final String RELATIVE_DEBUG_OPTION_NAME = "debug"; //$NON-NLS-1$

	/**
	 * Return the specified debug option as a <code>boolean</code> value.
	 * Return <code>false</code> if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public boolean getBooleanDebugOption(String option) {
		return this.getBooleanDebugOption(option, false);
	}

	/**
	 * Return the specified debug option as a <code>boolean</code> value.
	 * Return the specified default value if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public boolean getBooleanDebugOption(String option, boolean defaultValue) {
		String value = this.getDebugOption(option);
		return (value == null) ? defaultValue : Boolean.parseBoolean(value.trim());
	}

	/**
	 * Set the specified debug option to the specified <code>boolean</code>
	 * value.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public void setDebugOption(String option, boolean value) {
		this.setDebugOption(option, Boolean.toString(value));
	}

	/**
	 * Return the specified debug option as an <code>int</code> value.
	 * Return <code>-1</code> if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public int getIntegerDebugOption(String option) {
		return this.getIntegerDebugOption(option, -1);
	}

	/**
	 * Return the specified debug option as an <code>int</code> value.
	 * Return the specified default value if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public int getIntegerDebugOption(String option, int defaultValue) {
		String value = this.getDebugOption(option);
		return (value == null) ? defaultValue : Integer.parseInt(value.trim());
	}

	/**
	 * Set the specified debug option to the specified <code>int</code>
	 * value.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public void setDebugOption(String option, int value) {
		this.setDebugOption(option, Integer.toString(value));
	}

	/**
	 * Return the specified debug option.
	 * Return <code>null</code> if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public String getDebugOption(String option) {
		return this.getDebugOption(option, null);
	}

	/**
	 * Return the specified debug option.
	 * Return the specified default value if no such option is found.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 */
	public String getDebugOption(String option, String defaultValue) {
		this.checkDebugOption(option);
		return this.isDebugEnabled() ? this.getDebugOption_(option, defaultValue) : defaultValue;
	}

	/**
	 * Pre-condition: the specified option is not blank.
	 */
	protected String getDebugOption_(String option, String defaultValue) {
		String value = this.getDebugOption_(option);
		return (value != null) ? value : defaultValue;
	}

	protected String getDebugOption_(String option) {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions == null) {
			return null;
		}
		StringBuilder scope = this.getDebugOptionScope();
		return (scope == null) ? null : debugOptions.getOption(scope.append(option).toString());
	}

	/**
	 * Set the specified debug option to the specified value.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified option is not changed.
	 */
	public void setDebugOption(String option, String value) {
		this.checkDebugOption(option);
		if (this.isDebugEnabled()) {
			this.setDebugOption_(option, value);
		}
	}

	/**
	 * Pre-condition: the specified option is not blank.
	 */
	protected void setDebugOption_(String option, String value) {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions != null) {
			StringBuilder scope = this.getDebugOptionScope();
			if (scope != null) {
				debugOptions.setOption(scope.append(option).toString(), value);
			}
		}
	}

	/**
	 * Remove the specified debug option.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified option is not changed.
	 */
	public void removeDebugOption(String option) {
		this.checkDebugOption(option);
		if (this.isDebugEnabled()) {
			this.removeDebugOption_(option);
		}
	}

	/**
	 * Pre-condition: the specified option is not blank.
	 */
	protected void removeDebugOption_(String option) {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions != null) {
			StringBuilder scope = this.getDebugOptionScope();
			if (scope != null) {
				debugOptions.removeOption(scope.append(option).toString());
			}
		}
	}

	protected DebugOptions getDebugOptions() {
		ServiceTracker<DebugOptions, DebugOptions> tracker = this.getDebugOptionsTracker();
		return (tracker == null) ? null : tracker.getService();
	}

	private synchronized ServiceTracker<DebugOptions, DebugOptions> getDebugOptionsTracker() {
		if (this.debugOptionsTracker == null) {
			this.debugOptionsTracker = this.buildDebugOptionsTracker();
		}
		return this.debugOptionsTracker;
	}

	private ServiceTracker<DebugOptions, DebugOptions> buildDebugOptionsTracker() {
		try {
			return this.buildDebugOptionsTracker_();
		} catch (RuntimeException ex) {
			this.logError(ex);
			return null;
		}
	}

	/**
	 * @exception RuntimeException if the plug-in's
	 * bundle context is missing or invalid
	 */
	private ServiceTracker<DebugOptions, DebugOptions> buildDebugOptionsTracker_() {
		Bundle b = this.getBundle();
		if (b == null) {
			return null;
		}
		BundleContext bc = b.getBundleContext();
		if (bc == null) {
			return null;
		}
		ServiceTracker<DebugOptions, DebugOptions> tracker = new ServiceTracker<DebugOptions, DebugOptions>(bc, DebugOptions.class, null);
		tracker.open();
		return tracker;
	}

	protected synchronized void closeDebugOptionsTracker() {
		if (this.debugOptionsTracker != null) {
			this.debugOptionsTracker.close();
			this.debugOptionsTracker = null;
			this.debugTrace = null; // the debug trace is associated with the tracker's service(?)
		}
	}

	/**
	 * Return the name of the plug-in's debug option scope.
	 * Include an appended <code>'/'</code>.
	 * By default, this is in the form
	 * <em>&lt;plug-in ID&gt;/debug/</em>
	 * (e.g. <code>org.eclipse.jpt.common.core/debug/</code>).
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	protected StringBuilder getDebugOptionScope() {
		StringBuilder sb = this.getDebugOptionName();
		return (sb == null) ? null : sb.append('/');
	}

	protected void checkDebugOption(String option) {
		if (StringTools.isBlank(option)) {
			throw new IllegalArgumentException("debug option cannot be blank"); //$NON-NLS-1$
		}
	}


	// ********** tracing **********

	/**
	 * Trace the calling method for the specified debug option (with no message).
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 * 
	 * @see #dumpStackTrace(String)
	 */
	public void trace(String option) {
		this.trace(option, (String) null);  // message can be null
	}

	/**
	 * Trace the specified message for the specified debug option.
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 * 
	 * @see #dumpStackTrace(String, String)
	 */
	public void trace(String option, String message) {
		this.trace(option, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Trace the specified message for the specified debug option.
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * Bind the message to the specified arguments.
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 * 
	 * @see #dumpStackTrace(String, String, Object...)
	 */
	public void trace(String option, String message, Object... args) {
		this.trace(option, null, message, args);
	}

	/**
	 * Trace the specified exception for the specified debug option.
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * Only the specified exception's class name and
	 * {@link Throwable#getLocalizedMessage() message} will be recorded in the
	 * trace log (as opposed to the exception's stack trace).
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 */
	public void trace(String option, Throwable throwable) {
		this.trace(option, throwable, throwable.getLocalizedMessage());
	}

	/**
	 * Trace the specified exception and message for the specified debug option.
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * Only the specified exception's class name and
	 * {@link Throwable#getLocalizedMessage() message} will be recorded in the
	 * trace log (as opposed to the exception's stack trace).
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 */
	public void trace(String option, Throwable throwable, String message) {
		this.trace(option, throwable, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Trace the specified message and exception for the specified debug option.
	 * This method should be called directly from the method to be traced,
	 * as only the name of that single method will be recorded.
	 * Only the specified exception's class name and
	 * {@link Throwable#getLocalizedMessage() message} will be recorded in the
	 * trace log (as opposed to the exception's stack trace).
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * Bind the message to the specified arguments.
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the specified message is not traced.
	 */
	public void trace(String option, Throwable throwable, String message, Object... args) {
		this.checkDebugOption(option);
		if (this.isDebugEnabled()) {
			this.trace_(option, throwable, message, args);
		}
	}

	/**
	 * Pre-condition: the specified option is not blank.
	 */
	protected void trace_(String option, Throwable throwable, String message, Object... args) {
		if (args.length > 0) {
			message = NLS.bind(message, args);
		}
		DebugTrace trace = this.getDebugTrace();
		if (trace != null) {
			trace.trace(this.getTraceOptionScope().append(option).toString(), message, throwable);
		}
	}

	/**
	 * Dump a stack trace for the specified debug option.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the stack trace is not dumped.
	 */
	public void dumpStackTrace(String option) {
		this.dumpStackTrace(option, null);
	}

	/**
	 * Dump a stack trace for the specified debug option.
	 * Precede it with a trace for the specified message.
	 * This method should be called directly from the method to be traced,
	 * as only that single method will be recorded with the message.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the stack trace is not dumped.
	 */
	public void dumpStackTrace(String option, String message) {
		this.dumpStackTrace(option, message, ObjectTools.EMPTY_OBJECT_ARRAY);
	}

	/**
	 * Dump a stack trace for the specified debug option.
	 * Precede it with a trace for the specified message.
	 * This method should be called directly from the method to be traced,
	 * as only that single method will be recorded with the message.
	 * <p>
	 * The debug option is within the scope of the plug-in's debug options
	 * (e.g. for the plug-in <code>"org.eclipse.jpt.common.core"</code>,
	 * the specified option <code>"foo"</code> will be mapped to
	 * the {@link Platform} option
	 * <code>"org.eclipse.jpt.common.core/debug/foo"</code>).
	 * Bind the message to the specified arguments.
	 * If the plug-in is not in {@link #isDebugEnabled() debug mode},
	 * the stack trace is not dumped.
	 */
	public void dumpStackTrace(String option, String message, Object... args) {
		this.checkDebugOption(option);
		if (this.isDebugEnabled()) {
			if (message != null) {
				this.trace_(option, null, message, args);
			}
			this.dumpStackTrace_(option);
		}
	}

	/**
	 * Pre-condition: the specified option is not blank.
	 */
	// TODO file bug with Platform:
	// EclipseDebugTrace.traceDumpStack(...) should filter out trace class
	// entries like FrameworkDebugTraceEntry constructor
	protected void dumpStackTrace_(String option) {
		DebugTrace trace = this.getDebugTrace();
		if (trace != null) {
			trace.traceDumpStack(this.getTraceOptionScope().append(option).toString());
		}
	}

	/**
	 * Default value: <code>"/debug/"</code>
	 */
	protected StringBuilder getTraceOptionScope() {
		StringBuilder sb = new StringBuilder();
		sb.append('/');
		sb.append(this.getRelativeTraceOptionName());
		sb.append('/');
		return sb;
	}

	/**
	 * @see #getRelativeDebugOptionName()
	 */
	protected String getRelativeTraceOptionName() {
		return this.getRelativeDebugOptionName();
	}

	protected synchronized DebugTrace getDebugTrace() {
		if (this.debugTrace == null) {
			this.debugTrace = this.buildDebugTrace();
		}
		return this.debugTrace;
	}

	protected DebugTrace buildDebugTrace() {
		return this.buildDebugTrace(this.getDebugTraceEntryClass());
	}

	/**
	 * @see #DEBUG_TRACE_ENTRY_CLASS
	 */
	protected Class<?> getDebugTraceEntryClass() {
		return DEBUG_TRACE_ENTRY_CLASS;
	}
	/**
	 * Value: <code>JptPlugin.class</code>
	 */
	protected static final Class<?> DEBUG_TRACE_ENTRY_CLASS = JptPlugin.class;

	/**
	 * The specified trace entry class must be the class where the trace methods
	 * are <em>defined</em> (<em>not</em> the class of the object that receives
	 * the message at runtime - i.e. do not use the result of
	 * {@link #getClass()}), as that is the class captured in a stacktrace.
	 */
	protected DebugTrace buildDebugTrace(Class<?> traceEntryClass) {
		DebugOptions debugOptions = this.getDebugOptions();
		if (debugOptions == null) {
			return null;
		}
		String id = this.getPluginID();
		return (id == null) ? null : debugOptions.newDebugTrace(id, traceEntryClass);
	}


	// ********** misc **********

	/**
	 * Return the plug-in's bundle.
	 */
	public Bundle getBundle() {
		return (this.bundle  != null) ? this.bundle : this.getBundle_();
	}

	/**
	 * If the plug-in has not yet been {@link #start(BundleContext) started}, we
	 * can still get the bundle from the classloader....
	 */
	private Bundle getBundle_() {
		return FrameworkUtil.getBundle(this.getClass());
//		ClassLoader cl = this.getClass().getClassLoader();
//		return (cl instanceof BundleReference) ? ((BundleReference) cl).getBundle() : null;
	}

	/**
	 * Return the plug-in's ID (i.e. the symbolic name of the plug-in's bundle).
	 * Return <code>null</code> if the plug-in has no bundle.
	 * @see Bundle#getSymbolicName()
	 */
	public String getPluginID() {
		Bundle b = this.getBundle();
		return (b == null) ? null : b.getSymbolicName();
	}

	/**
	 * Return the plug-in's "original" ID. This is useful for backward and
	 * forward compatibility of resource persistent properties and preferences.
	 * By default return the {@link #getPluginID() current plug-in ID}.
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	public final String getOriginalPluginID() {
		Bundle b = this.getBundle();
		return (b == null) ? null : this.getOriginalPluginID_();
	}

	/**
	 * Override this method if the {@link Bundle#getSymbolicName() plug-in's ID}
	 * changes but there are previously-saved resource persistent properties
	 * and/or preferences that use the original plug-in ID and backward and/or
	 * forward compatibility is desirable.
	 */
	protected String getOriginalPluginID_() {
		return this.getPluginID();
	}

	/**
	 * Return whether the plug-in has a bundle and is active; i.e. it has been
	 * {@link #start(BundleContext) started}.
	 * <p>
	 * <strong>NB:</strong> The plug-in is <em>not</em> active during the
	 * execution of the methods {@link #start(BundleContext)} or
	 * {@link #stop(BundleContext)}.
	 * 
	 * @see Bundle#getState()
	 * @see Bundle#ACTIVE
	 */
	public boolean isActive() {
		Bundle b = this.getBundle();
		return (b != null) && (b.getState() == Bundle.ACTIVE);
	}

	/**
	 * Return whether the plug-in has no bundle or is inactive; i.e. it has been
	 * {@link #stop(BundleContext) stopped} or not yet
	 * {@link #start(BundleContext) started}.
	 * <p>
	 * <strong>NB:</strong> The plug-in is <em>not</em> active during the
	 * execution of the methods {@link #start(BundleContext)} or
	 * {@link #stop(BundleContext)}.
	 * 
	 * @see Bundle#getState()
	 * @see Bundle#ACTIVE
	 */
	public boolean isInactive() {
		return ! this.isActive();
	}

	/**
	 * Qualify the specified relative name with the plug-in's ID.
	 * Return <code>null</code> if the plug-in has no bundle.
	 */
	public QualifiedName buildQualifiedName(String relativeName) {
		String id = this.getPluginID();
		return (id == null) ? null : new QualifiedName(id, relativeName);
	}

	/**
	 * Return <code>null</code> if the plug-in has no bundle
	 * or if the platform is running with no data area (<code>-data @none</code>).
	 * @see org.eclipse.core.runtime.Plugin#getStateLocation()
	 * @see Platform#getStateLocation(Bundle)
	 */
	public IPath getStateLocation() {
		try {
			return this.getStateLocation_();
		} catch (IllegalStateException ex) {
			return null; // -data @none
		}
	}

	protected IPath getStateLocation_() {
		Bundle b = this.getBundle();
		return (b == null) ? null : Platform.getStateLocation(b);
	}

	@Override
	public String toString() {
		return ObjectTools.toString(this, this.getBundle());
	}
}
