/*******************************************************************************
 * Copyright (c) 2003, 2005 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.jst.j2ee.internal.plugin;


import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;

import org.eclipse.core.internal.boot.PlatformURLConnection;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.UIContextDetermination;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.jst.j2ee.application.ApplicationFactory;
import org.eclipse.jst.j2ee.application.ApplicationPackage;
import org.eclipse.jst.j2ee.application.internal.impl.ApplicationFactoryImpl;
import org.eclipse.jst.j2ee.applicationclient.internal.modulecore.util.AppClientEditAdapterFactory;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEResourceFactoryRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveInit;
import org.eclipse.jst.j2ee.internal.common.VirtualArchiveComponentAdapterFactory;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater;
import org.eclipse.jst.j2ee.internal.modulecore.util.EarEditAdapterFactory;
import org.eclipse.jst.j2ee.internal.validation.ResourceUtil;
import org.eclipse.jst.j2ee.internal.xml.J2EEXmlDtDEntityResolver;
import org.eclipse.jst.j2ee.refactor.listeners.J2EEElementChangedListener;
import org.eclipse.jst.j2ee.refactor.listeners.ProjectRefactoringListener;
import org.eclipse.wst.common.componentcore.internal.ArtifactEditModel;
import org.eclipse.wst.common.componentcore.internal.impl.ReferencedComponentXMIResourceFactory;
import org.eclipse.wst.common.componentcore.internal.impl.WTPResourceFactoryRegistry;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.frameworks.internal.WTPPlugin;
import org.eclipse.wst.common.frameworks.internal.operations.IHeadlessRunnableWithProgress;
import org.eclipse.wst.common.internal.emf.resource.ReferencedXMIFactoryImpl;
import org.eclipse.wst.common.internal.emf.utilities.DOMUtilities;
import org.eclipse.wst.common.internal.emfworkbench.integration.EditModel;
import org.eclipse.wst.validation.internal.operations.ValidatorManager;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

/**
 * This is a top-level class of the j2ee plugin.
 * 
 * @see AbstractUIPlugin for additional information on UI plugins
 */

public class J2EEPlugin extends WTPPlugin implements ResourceLocator {

	public static final String PLUGIN_ID = "org.eclipse.jst.j2ee"; //$NON-NLS-1$
	public static final String UI_PLUGIN_ID = "org.eclipse.jst.j2ee.ui"; //$NON-NLS-1$
	protected final IPath iconsFolder = new Path(Platform.getBundle(PLUGIN_ID).getEntry("icons").getPath()); //$NON-NLS-1$
	// LibDir Change Listener
	public static final String LIBDIRCHANGE_BUILDER_ID = "org.eclipse.jst.j2ee.web.LibDirBuilder"; //$NON-NLS-1$
	// LibCopy builder ID
	public static final String LIBCOPY_BUILDER_ID = PLUGIN_ID + ".LibCopyBuilder"; //$NON-NLS-1$
	// Validation part of the plugin
	public static final String VALIDATION_BUILDER_ID = ValidationPlugin.VALIDATION_BUILDER_ID; // plugin
//	private static final String KEY_PREFIX = "%"; //$NON-NLS-1$
//	private static final String KEY_DOUBLE_PREFIX = "%%"; //$NON-NLS-1$	
	// id
	// of
	// the
	// validation
	// builder//$NON-NLS-1$
	//Global ResourceSet (somewhat global)
	private static boolean defaultIsWorkspaceRelativeSchema = false;

	private List fextendedEditModels;
	private static IPath location;

	public static IStatus OK_STATUS = new Status(IStatus.OK, PLUGIN_ID, 0, "OK", null); //$NON-NLS-1$

	public static final String[] ICON_DIRS = new String[]{"icons/full/obj16", //$NON-NLS-1$
				"icons/full/cview16", //$NON-NLS-1$
				"icons/full/ctool16", //$NON-NLS-1$
				"icons/full/clcl16", //$NON-NLS-1$
				"icons/full/ovr16", //$NON-NLS-1$
				"icons/full/extra", //$NON-NLS-1$
				"icons/full/wizban", //$NON-NLS-1$
				"icons", //$NON-NLS-1$
				""}; //$NON-NLS-1$

	protected static Boolean EJB_AVAILABLE = null;
	private static Boolean HAS_DEV_ROLE;

	private J2EEPreferences preferences = null;
	public static J2EEPlugin INSTANCE;

	/**
	 * Create the J2EE plugin and cache its default instance
	 */
	public J2EEPlugin() {
		super();
		if (INSTANCE == null)
			INSTANCE = this;
		try {
			resourceBundle = ResourceBundle.getBundle("org.eclipse.jst.j2ee"); //$NON-NLS-1$
		} catch (MissingResourceException x) {
			resourceBundle = null;
			
		}
	}

	/**
	 * Insert the method's description here. Creation date: (7/16/2001 7:38:56 PM)
	 * 
	 * @return boolean
	 */
	public static boolean defaultIsWorkspaceRelativeSchema() {
		return defaultIsWorkspaceRelativeSchema;
	}

	/**
	 * Get the one application factory.
	 */
	public ApplicationFactory getApplicationFactory() {
		return (ApplicationFactory) getApplicationPackage().getEFactoryInstance();
	}

	/**
	 * Get the one ejb package.
	 */
	public ApplicationPackage getApplicationPackage() {
		return ApplicationFactoryImpl.getPackage();
	}

	/**
	 * Get the plugin singleton.
	 */
	static public J2EEPlugin getDefault() {
		return INSTANCE;
	}

	/*
	 * Javadoc copied from interface.
	 */
	public URL getBaseURL() {
		return getBundle().getEntry("/"); //$NON-NLS-1$
	}


	public Object[] getJ2EEWebProjectMigrationExtensions() {

		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint pct = registry.getExtensionPoint("J2EEWebProjectMigrationExtension"); //$NON-NLS-1$
		List ret = new Vector();
		if (pct != null) {
			IExtension[] extension = pct.getExtensions();
			for (int l = 0; l < extension.length; ++l) {
				IExtension config = extension[l];

				IConfigurationElement[] cElems = config.getConfigurationElements();
				for (int i = 0; i < cElems.length; i++) {
					IConfigurationElement d = cElems[i];
					if (d.getName().equals("migration")) { //$NON-NLS-1$ 
						try {
							Object me = d.createExecutableExtension("run"); //$NON-NLS-1$

							ret.add(me);
						} catch (Exception ex) {
							// ignore this extension, keep going
						}
					}
				}
			}
		}
		return ret.toArray();
	}

	public EditModel getExtendedEditModel(String editModelKey) {

		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint pct = registry.getExtensionPoint("EditModelExtension"); //$NON-NLS-1$

		IExtension[] extension = pct.getExtensions();
		for (int l = 0; l < extension.length; ++l) {
			IExtension config = extension[l];

			IConfigurationElement[] cElems = config.getConfigurationElements();
			for (int i = 0; i < cElems.length; i++) {
				IConfigurationElement d = cElems[i];
				if (d.getName().equals("editmodel") && editModelKey.equals(d.getAttribute("key"))) //$NON-NLS-1$ //$NON-NLS-2$
				{ // editmodel class
					try {
						return (EditModel) d.createExecutableExtension("run"); //$NON-NLS-1$

					} catch (Exception ex) {
						return null;
					}
				}
			}
		}

		return null;
	}

	public List getExtendedEditModels() {

		if (fextendedEditModels != null)
			return fextendedEditModels;
		List editModels = new ArrayList();
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint pct = registry.getExtensionPoint("EditModelExtension"); //$NON-NLS-1$

		IExtension[] extension = pct.getExtensions();
		for (int l = 0; l < extension.length; ++l) {
			IExtension config = extension[l];

			IConfigurationElement[] cElems = config.getConfigurationElements();
			for (int i = 0; i < cElems.length; i++) {
				IConfigurationElement d = cElems[i];
				if (d.getName().equals("editmodel")) //$NON-NLS-1$
				{
					// editmodel class
					try {
						editModels.add(d.createExecutableExtension("run")); //$NON-NLS-1$

					} catch (Exception ex) {
						return null;
					}
				}
			}
		}
		fextendedEditModels = editModels;
		return fextendedEditModels;
	}

	/**
	 * This gets a .gif from the icons folder.
	 */
	public static URL getImageURL(String key, Bundle bundle) {
		String gif = "/" + key + ".gif"; //$NON-NLS-1$ //$NON-NLS-2$
		IPath path = null;
		for (int i = 0; i < ICON_DIRS.length; i++) {
			path = new Path(ICON_DIRS[i]).append(gif);
			if (Platform.find(bundle,path) == null)
				continue;
			try {
				return new URL( bundle.getEntry("/"), path.toString()); //$NON-NLS-1$ 
			} catch (MalformedURLException exception) {
				org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(J2EEPluginResourceHandler.getString("Load_Image_Error_", new Object[]{key})); //$NON-NLS-1$
				exception.printStackTrace();
				continue;
			}
		}
		return null;
	}

	/**
	 * This gets a .gif from the icons folder.
	 */
	public Object getImage(String key) {
		return getImageURL(key,this.getBundle());
	}

	public static IPath getInstallLocation() {
		if (location == null) {
			URL url = getInstallURL();
			try {
				String installLocation = ((PlatformURLConnection) url.openConnection()).getURLAsLocal().getFile();
				location = new Path(installLocation);
			} catch (IOException e) {
				org.eclipse.jem.util.logger.proxy.Logger.getLogger().logWarning(J2EEPluginResourceHandler.getString("Install_Location_Error_", new Object[]{url}) + e); //$NON-NLS-1$
			}
		}
		return location;
	}

	public static URL getInstallURL() {
		return getDefault().getBundle().getEntry("/"); //$NON-NLS-1$ 
	}

	protected static IJavaModel getJavaModel() {
		return JemProjectUtilities.getJavaModel();
	}

	protected static IJavaModel getJavaModel(IProject aProject) {
		if (aProject != null)
			return JemProjectUtilities.getJavaModel();
		return null;
	}

	public static IJavaProject getJavaProject(IProject project) {
		IJavaModel model = getJavaModel(project);
		if (model != null)
			return model.getJavaProject(project.getName());
		return null;
	}

	/**
	 * Retrieves a hashtable of a logger's preferences initially from the
	 * com.ibm.etools.logging.util.loggingDefaults extension point if specified in the
	 * com.ibm.etools.logging.util plugin.xml file. If specified, the
	 * com.ibm.etools.logging.util.loggingOptions extension point preferences in the parameter
	 * plugin's plugin.xml file are returned.
	 * 
	 * The logger's preferences are stored in the return hashtable using the static instance
	 * variables in LoggerStateHashKeys as keys.
	 * 
	 * @param plugin
	 *            the Plugin polled for their logger's preferences in the plugin.xml file
	 * @return hashtable of a logger's preferences
	 */
	/*
	 * public java.util.Hashtable getMsgLoggerConfig(org.eclipse.core.runtime.Plugin plugin) {
	 * return (new PluginHelperImpl().getMsgLoggerConfig(plugin)); }
	 */
	/**
	 * Get the singleton instance.
	 */
	public static J2EEPlugin getPlugin() {
		return INSTANCE;
	}

	/**
	 * Return the plugin directory location- the directory that all the plugins are located in (i.e.
	 * d:\installdir\plugin)
	 */
	public static IPath getPluginLocation(String pluginId) {
		//IExtensionRegistry registry = Platform.getExtensionRegistry();
		Bundle bundle = Platform.getBundle(pluginId);
		if (bundle != null) {
			try {
				IPath installPath = new Path(bundle.getEntry("/").toExternalForm()).removeTrailingSeparator(); //$NON-NLS-1$ 
				String installStr = Platform.asLocalURL(new URL(installPath.toString())).getFile();
				return new Path(installStr);
			} catch (IOException e) {
			};
		}
		return null;
	}

	protected void initializeDefaultPluginPreferences() {
		getJ2EEPreferences().initializeDefaultPreferences();
	}

	public static IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	/**
	 * If this is called from an operation, in response to some other exception that was caught,
	 * then the client code should throw {@link com.ibm.etools.wft.util.WFTWrappedException};
	 * otherwise this can still be used to signal some other error condition within the operation,
	 * or to throw a core exception in a context other than executing an operation
	 * 
	 * Create a new IStatus of type ERROR using the J2EEPlugin ID. aCode is just an internal code.
	 */
	public static IStatus newErrorStatus(int aCode, String aMessage, Throwable exception) {
		return newStatus(IStatus.ERROR, aCode, aMessage, exception);
	}

	/**
	 * If this is called from an operation, in response to some other exception that was caught,
	 * then the client code should throw {@link com.ibm.etools.wft.util.WFTWrappedException};
	 * otherwise this can still be used to signal some other error condition within the operation,
	 * or to throw a core exception in a context other than executing an operation
	 * 
	 * Create a new IStatus of type ERROR, code OPERATION_FAILED, using the J2EEPlugin ID
	 */
	public static IStatus newErrorStatus(String aMessage, Throwable exception) {
		return newErrorStatus(0, aMessage, exception);
	}

	/**
	 * If this is called from an operation, in response to some other exception that was caught,
	 * then the client code should throw {@link com.ibm.etools.wft.util.WFTWrappedException};
	 * otherwise this can still be used to signal some other error condition within the operation.
	 * 
	 * Create a new IStatus of type ERROR, code OPERATION_FAILED, using the J2EEPlugin ID
	 */
	public static IStatus newOperationFailedStatus(String aMessage, Throwable exception) {
		return newStatus(IStatus.ERROR, IResourceStatus.OPERATION_FAILED, aMessage, exception);
	}

	/**
	 * Create a new IStatus with a severity using the J2EEPlugin ID. aCode is just an internal code.
	 */
	public static IStatus newStatus(int severity, int aCode, String aMessage, Throwable exception) {
		return new Status(severity, PLUGIN_ID, aCode, aMessage, exception);
	}

	/*
	 * Javadoc copied from interface.
	 */
	public String getString(String key) {
		try {
			return Platform.getResourceString(getBundle(), key);
		} catch (MissingResourceException ex) {
			//TODO Don't throw error - just show unresolved key
			//Logger.getLogger().logError(ex);
			return '!' + key + '!';
		}
	}

	/*
	 * Javadoc copied from interface.
	 */
	public String getString(String key, Object[] substitutions) {
		return MessageFormat.format(getString(key), substitutions);
	}

	/**
	 * Insert the method's description here. Creation date: (7/16/2001 7:38:56 PM)
	 * 
	 * @param newDefaultIsWorkspaceRelativeSchema
	 *            boolean
	 */
	public static void setDefaultIsWorkspaceRelativeSchema(boolean newDefaultIsWorkspaceRelativeSchema) {
		defaultIsWorkspaceRelativeSchema = newDefaultIsWorkspaceRelativeSchema;
	}

	/**
	 * This method should be used to determine if the EJB UI support is currently packaged in the
	 * image.
	 */
	public static boolean isEJBSupportAvailable() {
		if (EJB_AVAILABLE == null) {
			//TODO We need a better mechanism for the detection of the EJB support.
			//IPluginDescriptor desc =
			// Platform.getPluginRegistry().getPluginDescriptor("org.eclipse.jst.j2ee.internal.internal.ejb.ui");
			// //$NON-NLS-1$
			// EJB_AVAILABLE = new Boolean(desc != null);
			EJB_AVAILABLE = Boolean.TRUE;
		}
		return EJB_AVAILABLE.booleanValue();
	}

	/**
	 * This method should be used to determine if the workbench is running in UI or Headless
	 * 
	 * @deprecated use {@link org.eclipse.wst.common.frameworks.internal.UIContextDetermination}
	 */
	public static boolean isHeadless() {
		return UIContextDetermination.getCurrentContext() == UIContextDetermination.HEADLESS_CONTEXT;
	}


	public void start(BundleContext context) throws Exception {
		super.start(context);
				
		J2EEXmlDtDEntityResolver.INSTANCE = new CatalogJ2EEXmlDtDEntityResolver();
		DOMUtilities.setDefaultEntityResolver(J2EEXmlDtDEntityResolver.INSTANCE); 
		//Have to do the next line immediately to fix timing problems with factory registration
		ArchiveInit.init(false);
			
		//ModuleMaps are the maps from modules in an ear project to the j2ee projects for the
		// modules
		org.eclipse.jst.j2ee.internal.earcreation.modulemap.ModulemapInit.init(false);
		ensureFactoryRegistration();
		ValidatorManager.setResourceUtilClass(ResourceUtil.class);
		IAdapterManager manager = Platform.getAdapterManager();
		manager.registerAdapters(new EarEditAdapterFactory(), ArtifactEditModel.class);
		manager.registerAdapters(new AppClientEditAdapterFactory(), ArtifactEditModel.class);
		manager.registerAdapters(new VirtualArchiveComponentAdapterFactory(), VirtualArchiveComponent.class );
		
		final ProjectRefactoringListener listener = new ProjectRefactoringListener();//ProjectDependencyCache.getCache());
		// register the project rename/delete refactoring listener
		ResourcesPlugin.getWorkspace().addResourceChangeListener(listener,
				IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_DELETE);
		
		// register the IElementChangedLister that updates the .component file in 
		// response to .classpath changes
		JavaCore.addElementChangedListener(new J2EEElementChangedListener(), ElementChangedEvent.POST_CHANGE);
		
		ResourcesPlugin.getWorkspace().addResourceChangeListener(J2EEComponentClasspathUpdater.getInstance(), IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE);
	}
	
	public void stop(BundleContext context) throws Exception {
		super.stop(context);
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(J2EEComponentClasspathUpdater.getInstance());
		try {
			org.eclipse.core.runtime.Platform.getJobManager().join( J2EEElementChangedListener.PROJECT_COMPONENT_UPDATE_JOB_FAMILY,
					new NullProgressMonitor() );
		} catch (OperationCanceledException e) {
			Logger.getLogger().logError(e.getMessage());
		} catch (InterruptedException e) {
			Logger.getLogger().logError(e.getMessage());
		}		
	}

	/*
	 * need to make sure the correct factories get loaded when we are in the UI
	 */
	private void ensureFactoryRegistration() {
		//Inside the workbench we do not want the global override defined here.
		ensureDefaultReferencedXMIResourceFactoryRegistration();
	}

	/**
	 *  
	 */
	private void ensureDefaultReferencedXMIResourceFactoryRegistration() {
		J2EEResourceFactoryRegistry reg1 = J2EEResourceFactoryRegistry.INSTANCE;
		WTPResourceFactoryRegistry reg2 = WTPResourceFactoryRegistry.INSTANCE;
		ReferencedXMIFactoryImpl factory = new ReferencedComponentXMIResourceFactory();
		reg1.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, factory);
		reg2.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, factory);
		// add xmi because other plugins are registering it globally
		reg1.getExtensionToFactoryMap().put("xmi", factory); //$NON-NLS-1$
		reg2.getExtensionToFactoryMap().put("xmi", factory); //$NON-NLS-1$
	}

	/**
	 * This is currently just a convenience api for the AAW to turn off unwanted actions. It will
	 * currently be initialized based on the existence of the AAW plugin.
	 */
	public static boolean hasDevelopmentRole() {
		if (HAS_DEV_ROLE == null) {
			Bundle desc = Platform.getBundle("org.eclipse.jst.j2ee.assembly"); //$NON-NLS-1$
			HAS_DEV_ROLE = desc != null ? Boolean.FALSE : Boolean.TRUE;
		}
		return HAS_DEV_ROLE.booleanValue();
	}

	public static IWorkspaceRunnable getWorkspaceRunnable(final IHeadlessRunnableWithProgress op) {
		return new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				try {
					op.run(monitor);
				} catch (InvocationTargetException e) {
					throw new CoreException(newErrorStatus(0, e.getMessage(), e));
				} catch (InterruptedException e) {
					throw new CoreException(newErrorStatus(0, e.getMessage(), e));
				}
			}
		};
	}

	public String getPluginID() {
		return PLUGIN_ID;
	}

	/**
	 * @return Returns the preferences.
	 */
	public J2EEPreferences getJ2EEPreferences() {
		if (this.preferences == null)
			this.preferences = new J2EEPreferences(this);
		return this.preferences;
	}
	public String getString(String key, boolean translate) {
		// TODO For now...  translate not supported
		return getString(key);
	}

	public String getString(String key, Object[] substitutions, boolean translate) {
		// TODO For now...  translate not supported
		return getString(key,substitutions);
	}
	

	/**
	 * Record an error against this plugin's log. 
	 * 
	 * @param aCode
	 * @param aMessage
	 * @param anException
	 */
	public static void logError(int aCode, String aMessage,
			Throwable anException) {
		getDefault().getLog().log(
				createErrorStatus(aCode, aMessage, anException));
	}

	/**
	 * 
	 * Record a message against this plugin's log. 
	 * 
	 * @param severity
	 * @param aCode
	 * @param aMessage
	 * @param exception
	 */
	public static void log(int severity, int aCode, String aMessage,
			Throwable exception) {
		log(createStatus(severity, aCode, aMessage, exception));
	}

	/**
	 * 
	 * Record a status against this plugin's log. 
	 * 
	 * @param aStatus
	 */
	public static void log(IStatus aStatus) {
		getDefault().getLog().log(aStatus);
	}

	/**
	 * Create a status associated with this plugin.
	 *  
	 * @param severity
	 * @param aCode
	 * @param aMessage
	 * @param exception
	 * @return A status configured with this plugin's id and the given parameters.
	 */
	public static IStatus createStatus(int severity, int aCode,
			String aMessage, Throwable exception) {
		return new Status(severity, PLUGIN_ID, aCode,
				aMessage != null ? aMessage : "No message.", exception); //$NON-NLS-1$
	}

	/**
	 * 
	 * @param aCode
	 * @param aMessage
	 * @param exception
	 * @return A status configured with this plugin's id and the given parameters.
	 */
	public static IStatus createErrorStatus(int aCode, String aMessage,				
			Throwable exception) { 
		return createStatus(IStatus.ERROR, aCode, aMessage != null ? aMessage : exception.toString(), exception);
	} 

}