/*******************************************************************************
 * Copyright (c) 2004, 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
 *******************************************************************************/
/*
 *  $RCSfile: ProxyLaunchSupport.java,v $
 *  $Revision: 1.31 $  $Date: 2006/02/21 17:16:44 $ 
 */
package org.eclipse.jem.internal.proxy.core;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;
import java.util.logging.Level;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.osgi.framework.Bundle;

import org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo.ContainerPaths;
import org.eclipse.jem.internal.proxy.core.ProxyPlugin.FoundIDs;
import org.eclipse.jem.util.PerformanceMonitorUtil;
import org.eclipse.jem.util.TimerTests;

 
/**
 * This is the used to launch the proxy registries.
 * This is a static helper class, it is not meant to be instantiated.
 * 
 * @since 1.0.0
 */
public class ProxyLaunchSupport {
	
	// The key for the persisten property is in ProxyPlugin so that it can set it on startup without
	// causing this class to be initialized. We don't want this class initialized until the very last
	// moment when needed. This is because it needs UI to be active when initialized to query some 
	// values and if ProxyPlugin.start() causes this class to initialize, it may be too soon.
	//
	// If a project's persistent property is set with this value, that means there is at least one
	// launch configuration with this project, but none are selected as the default. This is here
	// so that we can check in the object contribution that if not set then don't show the menu
	// item at all. This is to clean up the popup menu so not so cluttered.
	// If the property is trully not set, then there is no default and there are no configurations for it.
	public static final String NOT_SET = "...not..set..";	  //$NON-NLS-1$
		
	public static final String EXPRESSION_TRACING = "/debug/traceexpressions";	// Trace IExpressions. //$NON-NLS-1$
	
	/**
	 * Timer threshold for indicating any expressions that took longer than this.
	 * If not set, then threshold will default to 100ms.
	 * It will only be used if traceexpressions is true.
	 */
	public static final String EXPRESSION_TRACEING_TIMER_THRESHOLD = "/debug/traceexpressionstimethreshold";	 //$NON-NLS-1$
	
	/*
	 * Registry of launch key to LaunchInfo classes.
	 */
	private static Map LAUNCH_INFO = new HashMap(2);

	/**
	 * Public only for access by other launch delegates to set up if they go outside of ProxyLaunchSupport,
	 * e.g. IDE proxy. Must not be used for any purpose.
	 * 
	 * @since 1.0.0
	 */
	public static class LaunchSupportIConfigurationContributionInfo implements IConfigurationContributionInfo {
		
		/**
		 * Construct with no settings. This is to be used by other launch delegates that
		 * don't have a {@link FoundIDs} available to fill in the fields. Those 
		 * delegates must fill the fields themselves.  
		 * 
		 * 
		 * @since 1.2.0
		 */
		public LaunchSupportIConfigurationContributionInfo(IJavaProject javaProject) {
			this.javaProject = javaProject;
		}
		
		public LaunchSupportIConfigurationContributionInfo(IJavaProject javaProject, FoundIDs foundIDs) {
			this(javaProject);
			containerIds = foundIDs.containerIds;
			containers = foundIDs.containers;
			pluginIds = foundIDs.pluginIds;
			projectPaths = foundIDs.projects;
		}
		
		/* (non-Javadoc)
		 * Map of containers (IClasspathContainer) found in classpath (including required projects).
		 * This is for each project found. If there was a container in more than one project with the
		 * id, this set will contain the container from each such project. They are not considered the
		 * same because they come from a different project.
		 * <p>
		 * The key will be the containers, and the value will be a <code>Boolean</code>, where true means it
		 * is visible to the top-level project.
		 * <p>
		 * This is used for determining if a project's container implements the desired contributor.
		 * 
		 * Will be empty if no project sent in to launch configuration.
		 * 
		 * @see org.eclipse.jdt.core.IClasspathContainer
		 * 
		 */
		public Map containers = Collections.EMPTY_MAP;

		
		/* (non-Javadoc)
		 * Map of unique container id strings found in classpath (including required projects).
		 * If a container with the same id was found in more than one project, only one id will
		 * be in this set since they are the same.
		 * <p>
		 * The key will be the container ids, and the value will be ContainerPaths
		 * 
		 * Will be empty if no project sent in to launch configuration.
		 * 
		 */
		public Map containerIds = Collections.EMPTY_MAP;
		
		/* (non-Javadoc)
		 * Set of unique plugin id strings found in classpath (including required projects).
		 * If a required plugin with the same id was found in more than one project, only one id will
		 * be in this set since they are the same.
		 * <p>
		 * The key will be the plugin ids, and the value will be a <code>Boolean</code>, where true means it
		 * is visible to the top-level project.
		 * 
		 * Will be empty if no project sent in to launch configuration.
		 */		
		public Map pluginIds = Collections.EMPTY_MAP;;
		
		/* (non-Javadoc)
		 * Map of unique projects found in classpath (including required projects), but not including top-level project.
		 * <p>
		 * The key will be the <code>IPath</code> for the project, and the value will be a <code>Boolean</code>, where true means it
		 * is visible to the top-level project.
		 * 
		 * Will be <code>null</code> if no project sent in to launch configuration.
		 */		
		public Map projectPaths;
		
		/* (non-Javadoc)
		 * Java project for this launch. <code>null</code> if not for a project.
		 */
		public IJavaProject javaProject;
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getContainerIds()
		 */
		public Map getContainerIds() {
			return containerIds;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getContainers()
		 */
		public Map getContainers() {
			return containers;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getJavaProject()
		 */
		public IJavaProject getJavaProject() {
			return javaProject;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getPluginIds()
		 */
		public Map getPluginIds() {
			return pluginIds;
		}
		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getProjectPaths()
		 */
		public Map getProjectPaths() {
			return projectPaths;
		}
		
	}
		
	/**
	 * LaunchInfo for a launch. Stored by key and retrievable by the key.
	 * This is only passed to launch delegates. It should not be passed on to
	 * others, though the IConfigurationContributionInfo may be.
	 * 
	 * <p>
	 * This class is not intended to be subclassed by clients.
	 * </p>
	 * 
	 * @see ProxyLaunchSupport#getInfo(String)
	 * @see IConfigurationContributionInfo
	 * @since 1.0.0
	 */
	public static class LaunchInfo {
		/**
		 * Contributors for this launch. It will never be <code>null</code>. It may be empty.
		 */
		public IConfigurationContributor[] contributors;
		
		/**
		 * The registry returned from the launch. The launch needs to set this before it returns.
		 */
		public ProxyFactoryRegistry resultRegistry;
		

		/* (non-Javadoc)
		 * @see org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo#getJavaProject()
		 */
		public IJavaProject getJavaProject() {
			return configInfo.getJavaProject();
		}		
		
		/**
		 * Return the IConfigurationContributionInfo for this launch.
		 * @return
		 * 
		 * @since 1.0.0
		 */
		public IConfigurationContributionInfo getConfigInfo() {
			return configInfo;
		}
		
		protected IConfigurationContributionInfo configInfo;
		
	}
	
	/**
	 * Start an implementation using the default config for the given project.
	 * <p> 
	 * This will wait for build. If you
	 * know the build has been suspended by your thread, then you must use the other method that takes a waitForThread
	 * boolean, and you must pass in false. Otherwise it will deadlock.
	 * 
	 * @param project The project. It must be a java project, and it cannot be <code>null</code>.
	 * @param vmTitle title for VM. It may be <code>null</code>.
	 * @param aContribs The contributions array. It may be <code>null</code>.
	 * @param pm
	 * @return The created registry.
	 * @throws CoreException
	 * 
	 * @see ProxyLaunchSupport#startImplementation(IProject, String, IConfigurationContributor[], boolean, IProgressMonitor)
	 * @since 1.0.0
	 */
	public static ProxyFactoryRegistry startImplementation(
			IProject project,
			String vmTitle,
			IConfigurationContributor[] aContribs,
			IProgressMonitor pm)
				throws CoreException {
		return startImplementation(project, vmTitle, aContribs, true, pm);
	}
	
	/**
	 * Start an implementation using the default config for the given project.
	 * <p> 
	 * If you know the build has been suspended by your thread, then you must use call this with false for waitForThread. Otherwise it will deadlock.
	 * 
	 * @param project The project. It must be a java project, and it cannot be <code>null</code>.
	 * @param vmTitle title for VM. It may be <code>null</code>.
	 * @param aContribs The contributions array. It may be <code>null</code>.
	 * @param waitForBuild wait for the build. If caller knows that the build has been suspended by this thread, then it must call this with false. Otherwise a deadlock will occur.
	 * @param pm
	 * @return The created registry.
	 * @throws CoreException
	 * 
	 * @since 1.0.0
	 */
	public static ProxyFactoryRegistry startImplementation(
			IProject project,
			String vmTitle,
			IConfigurationContributor[] aContribs,
			boolean waitForBuild, 
			IProgressMonitor pm)
				throws CoreException {
		// First find the appropriate launch configuration to use for this project.
		// The process is:
		//	1) See if the project's persistent property has a setting for "proxyLaunchConfiguration", if it does,
		//		get the configuration of that name and create a working copy of it.
		//	2) If not, then get the "org.eclipse.jem.proxy.LocalProxyLaunchConfigurationType"
		//		and create a new instance working copy.

		IJavaProject javaProject = JavaCore.create(project);
		if (javaProject == null) {
			throw new CoreException(
					new Status(
							IStatus.WARNING,
							ProxyPlugin.getPlugin().getBundle().getSymbolicName(),
							0,
							MessageFormat.format(
									ProxyMessages.Not_Java_Project_WARN_, 
									new Object[] { project.getName()}),
							null));
		}

		// First if specific set.
		String launchName = project.getPersistentProperty(ProxyPlugin.PROPERTY_LAUNCH_CONFIGURATION);
		ILaunchConfiguration config = null;		
		if (launchName != null && !NOT_SET.equals(launchName)) {
			ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations();
			for (int i = 0; i < configs.length; i++) {
				if (configs[i].getName().equals(launchName)) {
					config = configs[i];
					break;
				}
			}
			if (config == null || !config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "").equals(project.getName())) { //$NON-NLS-1$
				project.setPersistentProperty(ProxyPlugin.PROPERTY_LAUNCH_CONFIGURATION, (String) null);	// Config not found, or for a different project, so no longer the default.
				config = null;
			}
		}
		
		if (config == null) {
			ILaunchConfigurationWorkingCopy configwc = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(IProxyConstants.LOCAL_LAUNCH_TYPE).newInstance(null, DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom("LocalProxy_"+project.getName())); //$NON-NLS-1$
			configwc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName()); 
			config = configwc;
		}
		
		return startImplementation(config, vmTitle, aContribs, waitForBuild, pm);
	}
	
	/**
	 * Launch a registry using the given configuration.
	 * <p> 
	 * This will wait for build. If you
	 * know the build has been suspended by your thread, then you must use the other method that takes a waitForThread
	 * boolean, and you must pass in false. Otherwise it will deadlock.
	 *
	 * @param config 
	 * @param vmTitle title for VM. It may be <code>null</code>.
	 * @param aContribs The contributions array. It may be <code>null</code>.
	 * @param pm
	 * @return The registry from this configuration.
	 * @throws CoreException
	 * 
	 * @see ProxyLaunchSupport#startImplementation(ILaunchConfiguration, String, IConfigurationContributor[], boolean, IProgressMonitor)
	 * @since 1.0.0
	 */
	public static ProxyFactoryRegistry startImplementation(
			ILaunchConfiguration config,
			String vmTitle,
			IConfigurationContributor[] aContribs,
			IProgressMonitor pm)
			throws CoreException {
		return startImplementation(config, vmTitle, aContribs, true, pm);
	}

	/**
	 * Launch a registry using the given configuration.
	 * <p> 
	 * If you know the build has been suspended by your thread, then you must use you must pass in false for waitForThread. Otherwise it will deadlock.
	 *
	 * @param config
	 * @param vmTitle title for VM. It may be <code>null</code>.
	 * @param aContribs The contributions array. It may be <code>null</code>.
	 * @param waitForBuild wait for the build. If caller knows that the build has been suspended by this thread, then it must call this with false. Otherwise a deadlock will occur.
	 * @param pm
	 * @return The registry from this configuration.
	 * @throws CoreException
	 * 
	 * @since 1.0.0
	 */
	public static ProxyFactoryRegistry startImplementation(
				ILaunchConfiguration config,
				String vmTitle,
				IConfigurationContributor[] aContribs,
				boolean waitForBuild,
				IProgressMonitor pm)
				throws CoreException {

		if (pm == null)
			pm = new NullProgressMonitor();
		String stepId = "Pre-launch VM ( " + vmTitle + " )"; //$NON-NLS-1$ //$NON-NLS-2$
		TimerTests.basicTest.startStep(stepId);
		if (vmTitle.equals("Beaninfo")) //$NON-NLS-1$
			PerformanceMonitorUtil.getMonitor().snapshot(125);
		final ILaunchConfigurationWorkingCopy configwc = config.getWorkingCopy();
		
		pm.beginTask("", 400); //$NON-NLS-1$
		pm.subTask(ProxyMessages.ProxyLaunch);	
		if (waitForBuild) {
			// See if build needed or waiting or inprogress, if so, wait for it to complete. We've
			// decided too difficult to determine if build would affect us or not, so just wait.		
			if (UI_RUNNER != null)
				UI_RUNNER.handleBuild(new SubProgressMonitor(pm, 100));
			else
				runBuild(new SubProgressMonitor(pm, 100));
			
			if (pm.isCanceled())
				return null;
		}
				
		if (aContribs != null) {
			IConfigurationContributor[] newContribs = new IConfigurationContributor[aContribs.length+1];
			System.arraycopy(aContribs, 0, newContribs, 1, aContribs.length);
			newContribs[0] = new ProxyContributor();
			aContribs = newContribs;
		} else
			aContribs = new IConfigurationContributor[] {new ProxyContributor()};

		String launchKey = String.valueOf(System.currentTimeMillis());
		LaunchInfo launchInfo = new LaunchInfo();
		synchronized (ProxyLaunchSupport.class) {
			while (LAUNCH_INFO.containsKey(launchKey)) {
				launchKey += 'a'; // Just add something on to make it unique.
			}
			LAUNCH_INFO.put(launchKey, launchInfo);
		}
		
		String projectName = configwc.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null);
		aContribs = fillInLaunchInfo(aContribs, launchInfo, projectName);
		
		try {		
			configwc.setAttribute(IProxyConstants.ATTRIBUTE_LAUNCH_KEY, launchKey);
			if (vmTitle != null && vmTitle.length()>0)
				configwc.setAttribute(IProxyConstants.ATTRIBUTE_VM_TITLE, vmTitle);
			
			if (ATTR_PRIVATE != null)
				configwc.setAttribute(ATTR_PRIVATE, true);			
			
			// Let contributors modify the configuration.
			final IConfigurationContributor[] contribs = aContribs;
			final LaunchInfo linfo = launchInfo;
			for (int i = 0; i < contribs.length; i++) {
				// First run the initialize.
				// Run in safe mode so that anything happens we don't go away.
				final int ii = i;
				SafeRunner.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// Don't need to do anything. Platform.run logs it for me.
					}

					public void run() throws Exception {
						contribs[ii].initialize(linfo.getConfigInfo());
					}
				});

				// Now run the contribute to configuration.
				// Run in safe mode so that anything happens we don't go away.
				SafeRunner.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// Don't need to do anything. Platform.run logs it for me.
					}

					public void run() throws Exception {
						contribs[ii].contributeToConfiguration(configwc);
					}
				});
			}
			pm.worked(100);
			
			configwc.launch(ILaunchManager.RUN_MODE, new SubProgressMonitor(pm, 100));
			
			final ProxyFactoryRegistry reg = launchInfo.resultRegistry;
			if (!pm.isCanceled() && reg == null)
				throw new CoreException(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, ProxyMessages.ProxyLaunchSupport_RegistryCouldNotStartForSomeReason_WARN_, null)); 
			if (pm.isCanceled()) {
				if (reg != null)
					reg.terminateRegistry();
				return null;
			}
			
			performExtensionRegistrations((BaseProxyFactoryRegistry) reg, launchInfo);
			
//			TimerTests.basicTest.startStep("contribute to registry");
			for (int i = 0; i < contribs.length; i++) {
				final int ii = i;
				// Run in safe mode so that anything happens we don't go away.
				SafeRunner.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// Don't need to do anything. Platform.run logs it for me.
					}

					public void run() throws Exception {
//						String stepid = "contribute to registry for " + contribs[ii].getClass();
//						TimerTests.basicTest.startStep(stepid);
						contribs[ii].contributeToRegistry(reg);
//						TimerTests.basicTest.stopStep(stepid);
					}
				});
			}
//			TimerTests.basicTest.stopStep("contribute to registry");
		} finally {
			// Clean up and return.
			LAUNCH_INFO.remove(launchKey);
		}	
		
		pm.done();
		if (vmTitle.equals("Beaninfo")) //$NON-NLS-1$
			PerformanceMonitorUtil.getMonitor().snapshot(126);
		TimerTests.basicTest.stopStep(stepId);
		return launchInfo.resultRegistry;
	}
	
	/**
	 * Create a default IConfigurationContributionInfo for the given project. This is useful info even when not launching a
	 * vm.
	 * 
	 * @param javaProject
	 * @return new contrib info.
	 * @throws JavaModelException
	 * 
	 * @since 1.1.0
	 */
	public static IConfigurationContributionInfo createDefaultConfigurationContributionInfo(IJavaProject javaProject) throws JavaModelException {
		LaunchSupportIConfigurationContributionInfo configInfo = new LaunchSupportIConfigurationContributionInfo(javaProject,
				ProxyPlugin.getPlugin().getIDsFound(javaProject));
		return configInfo;

	}
	
	/**
	 * Use in calling {@link ProxyLaunchSupport#fillInLaunchInfo(IConfigurationContributor[], LaunchInfo, String)} for the configuration
	 * contributors array if there are no incoming contributors.
	 * 
	 * @since 1.1.0
	 */
	public static final IConfigurationContributor[] EMPTY_CONFIG_CONTRIBUTORS = new IConfigurationContributor[0];
	/**
	 * Fill in the launch info config info and contribs. The contribs sent in may be expanded due to extension
	 * points and a new one created. Either the expanded copy or the original (if no change) will be stored in
	 * the launchinfo and returned from this call.
	 * 
	 * @param aContribs this should never be <code>null</code>. Pass in {@link ProxyLaunchSupport#EMPTY_CONFIG_CONTRIBUTORS} in that case.
	 * @param launchInfo
	 * @param projectName
	 * @return a modified aContribs if any change was made to it.  This will never be <code>null</code>. It will return an empty list if aContribs was null and no changes were made.
	 * @throws JavaModelException
	 * @throws CoreException
	 * 
	 * @since 1.0.0
	 */
	public static IConfigurationContributor[] fillInLaunchInfo(IConfigurationContributor[] aContribs, LaunchInfo launchInfo, String projectName) throws JavaModelException, CoreException {
		if (projectName != null) {
			projectName = projectName.trim();
			if (projectName.length() > 0) {
				IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
				IJavaProject javaProject = JavaCore.create(project);
				if (javaProject != null && javaProject.exists()) {
					launchInfo.configInfo = createDefaultConfigurationContributionInfo(javaProject);
					if (!launchInfo.configInfo.getContainerIds().isEmpty() || !launchInfo.configInfo.getContainers().isEmpty() || !launchInfo.configInfo.getPluginIds().isEmpty()) {
						List computedContributors = new ArrayList(launchInfo.configInfo.getContainerIds().size()+launchInfo.configInfo.getContainers().size()+launchInfo.configInfo.getPluginIds().size());
						// Note: We don't care about the visibility business here. For contributors to proxy it means
						// some classes in the projects/plugins/etc. need configuration whether they are visible or not.
						// This is because even though not visible, some other visible class may instantiate it. So it
						// needs the configuration.
						// First handle explicit classpath containers that implement IConfigurationContributor
						for (Iterator iter = launchInfo.configInfo.getContainers().keySet().iterator(); iter.hasNext();) {
							IClasspathContainer container = (IClasspathContainer) iter.next();
							if (container instanceof IConfigurationContributor)
								computedContributors.add(container);
						}
						
						// Second add in contributors that exist for a container id.
						for (Iterator iter = launchInfo.configInfo.getContainerIds().values().iterator(); iter.hasNext();) {
							ContainerPaths paths = (ContainerPaths) iter.next();
							IConfigurationElement[] contributors = ProxyPlugin.getPlugin().getContainerConfigurations(paths.getContainerId(), paths.getAllPaths());
							if (contributors != null)
								for (int i = 0; i < contributors.length; i++) {
									Object contributor = contributors[i].createExecutableExtension(ProxyPlugin.PI_CLASS);
									if (contributor instanceof IConfigurationContributor)
										computedContributors.add(contributor);
								}
						}
						
						// Finally add in contributors that exist for a plugin id.
						for (Iterator iter = launchInfo.configInfo.getPluginIds().keySet().iterator(); iter.hasNext();) {
							String pluginId = (String) iter.next();
							IConfigurationElement[] contributors = ProxyPlugin.getPlugin().getPluginConfigurations(pluginId);
							if (contributors != null)
								for (int i = 0; i < contributors.length; i++) {
									Object contributor = contributors[i].createExecutableExtension(ProxyPlugin.PI_CLASS);
									if (contributor instanceof IConfigurationContributor)
										computedContributors.add(contributor);
								}
						}
						
						// Now turn into array
						if (!computedContributors.isEmpty()) {
							IConfigurationContributor[] newContribs = new IConfigurationContributor[aContribs.length
									+ computedContributors.size()];
							System.arraycopy(aContribs, 0, newContribs, 0, aContribs.length);
							IConfigurationContributor[] cContribs = (IConfigurationContributor[]) computedContributors
									.toArray(new IConfigurationContributor[computedContributors.size()]);
							System.arraycopy(cContribs, 0, newContribs, aContribs.length, cContribs.length);
							aContribs = newContribs;
						}
					}
				}
			}
		}
		
		launchInfo.contributors = aContribs;
		return aContribs;
	}
	
	/**
	 * Execute the extension registrations that are valid for this type of registry and the launchinfo paths.
	 * <p>
	 * This is meant to be called only by registry implementations that do not launch through a launch configration after the registry is created but
	 * before the {@link IConfigurationContributor#contributeToRegistry(ProxyFactoryRegistry)} is called. This will be called automatically
	 * by registries that used a launch configuration to launch.
	 * 
	 * @param baseRegistry
	 * @param launchInfo
	 * @throws CoreException 
	 * 
	 * @since 1.1.0
	 */
	public static void performExtensionRegistrations(final BaseProxyFactoryRegistry baseRegistry, LaunchInfo launchInfo) throws CoreException {
		IConfigurationContributionInfo configInfo = launchInfo.configInfo;
		if (configInfo != null && (!configInfo.getContainerIds().isEmpty() || !configInfo.getPluginIds().isEmpty())) {
			String registryID = baseRegistry.getRegistryTypeID();
			// Note: We don't care about the visibility business here. For contributors to proxy it means
			// some classes in the projects/plugins/etc. need configuration whether they are visible or not.
			// This is because even though not visible, some other visible class may instantiate it. So it
			// needs the configuration.
			
			// First call registrations that exist for a container id.
			for (Iterator iter = configInfo.getContainerIds().values().iterator(); iter.hasNext();) {
				ContainerPaths paths = (ContainerPaths) iter.next();
				IConfigurationElement[] contributors = ProxyPlugin.getPlugin().getContainerExtensions(paths.getContainerId(), paths.getAllPaths());
				if (contributors != null)
					for (int i = 0; i < contributors.length; i++) {
						if (registryID.equals(contributors[i].getAttributeAsIs(ProxyPlugin.PI_REGISTRY_TYPE))) {
							try {
								final IExtensionRegistration contributor = (IExtensionRegistration) contributors[i].createExecutableExtension(ProxyPlugin.PI_CLASS);
								SafeRunner.run(new ISafeRunnable() {
								
									public void run() throws Exception {
										contributor.register(baseRegistry);
									}
								
									public void handleException(Throwable exception) {
										// Don't need to do anything, Platform logs it for me.
									}
								
								});
							} catch (ClassCastException e) {
								// If not right class, just ignore it.
							}
						}
					}
			}
			
			// Finally add in contributors that exist for a plugin id.
			for (Iterator iter = configInfo.getPluginIds().keySet().iterator(); iter.hasNext();) {
				String pluginId = (String) iter.next();
				IConfigurationElement[] contributors = ProxyPlugin.getPlugin().getPluginExtensions(pluginId);
				if (contributors != null)
					for (int i = 0; i < contributors.length; i++) {
						if (registryID.equals(contributors[i].getAttributeAsIs(ProxyPlugin.PI_REGISTRY_TYPE))) {
							try {
								final IExtensionRegistration contributor = (IExtensionRegistration) contributors[i].createExecutableExtension(ProxyPlugin.PI_CLASS);
								SafeRunner.run(new ISafeRunnable() {
								
									public void run() throws Exception {
										contributor.register(baseRegistry);
									}
								
									public void handleException(Throwable exception) {
										// Don't need to do anything, Platform logs it for me.
									}
								
								});
							} catch (ClassCastException e) {
								// If not right class, just ignore it.
							}
						}
					}
			}
	}
}


	/*
	 * Run the build. If the original launch was in the UI thread, this will
	 * be called under control of an IProgressService so that it is in a separate
	 * thread and the UI will remain responsive (in that either a busy cursor comes
	 * up or eventually a progress dialog).
	 * If the pm is canceled, this will just return, but the caller must check if the pm is canceled.
	 * 
	 * <package-protected> so that only the UI handler will access it.
	 */
	static void runBuild(IProgressMonitor pm) throws CoreException {
		boolean autobuilding = ResourcesPlugin.getWorkspace().isAutoBuilding();
		if (!autobuilding) {
			try {
				// We are not autobuilding. So kick off a build right here and
				// wait for it. (If we already within a build on this thread, then this
				// will return immediately without building. We will take that risk. If
				// some other thread is building, we will wait for it finish before we
				// can get it and do our build.
				ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, pm); 
			} catch (OperationCanceledException e) {
				// The pm is already marked canceled, so caller can check that instead.
			} 
		} else {
			pm.beginTask("", 200); //$NON-NLS-1$
			IJobManager jobManager = Platform.getJobManager();
			Job currentJob = jobManager.currentJob();
			if (currentJob == null || (!currentJob.belongsTo(ResourcesPlugin.FAMILY_AUTO_BUILD) && !currentJob.belongsTo(ResourcesPlugin.FAMILY_MANUAL_BUILD))) { 
				if (jobManager.find(ResourcesPlugin.FAMILY_AUTO_BUILD).length > 0 || jobManager.find(ResourcesPlugin.FAMILY_MANUAL_BUILD).length >0) {
					// We are not within a build job. If we were, then we don't do the build. We will take
					// that risk. The problem is that if within the build, we can't wait for it to finish because
					// we would stop the thread and so the build would not complete.
					pm.subTask(ProxyMessages.ProxyWaitForBuild); 
					try {
						while (true) {
							try {
								jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, new SubProgressMonitor(pm, 100));
								jobManager.join(ResourcesPlugin.FAMILY_MANUAL_BUILD, new SubProgressMonitor(pm, 100));
								break;
							} catch (InterruptedException e) {
							}
						}
					} catch (OperationCanceledException e) {
					}
				}
			} 
			pm.done();
		}
	}
	
	
	/*
	 * This prevents the launch from being shown. However these constants are in UI component, and we don't
	 * want to pre-req that. So we will get them reflectively instead.
	 * public but only so that launch delegate can get to it.
	 */
	public static String ATTR_PRIVATE;
	private static IUIRunner UI_RUNNER = null;

	static {
		ATTR_PRIVATE = null;
		try {
			// See if we have a UI bundle and it is active. If it exists but is not active,
			// then we won't do anything. If we were running a UI application, it should already
			// of been active before we got here.
			Bundle uiBundle = Platform.getBundle("org.eclipse.ui");	//$NON-NLS-1$
			if (uiBundle != null && uiBundle.getState() == Bundle.ACTIVE) {
				try {
					// We have a UI bundle, so we can load our UIRunner class and it will load fine.
					UI_RUNNER = (IUIRunner) Class.forName("org.eclipse.jem.internal.proxy.core.UIRunner").newInstance(); //$NON-NLS-1$
				} catch (InstantiationException e1) {
					ProxyPlugin.getPlugin().getLogger().log(e1, Level.WARNING);
				}
				
				// So that we can run headless (w/o ui), need to do class forName for debugui contants
				Bundle debuguiBundle = Platform.getBundle("org.eclipse.debug.ui"); //$NON-NLS-1$
				if (debuguiBundle != null && debuguiBundle.getState() == Bundle.ACTIVE) {
					Class debugUIConstants = debuguiBundle.loadClass("org.eclipse.debug.ui.IDebugUIConstants"); //$NON-NLS-1$
					ATTR_PRIVATE = (String) debugUIConstants.getField("ATTR_PRIVATE").get(null); //$NON-NLS-1$
				}
			}			
		} catch (SecurityException e) {
		} catch (ClassNotFoundException e) {
		} catch (NoSuchFieldException e) {
		} catch (IllegalArgumentException e) {
		} catch (IllegalAccessException e) {
		}
	}	

	/* (non-Javadoc)
	 * Only referenced by launch delegates. public because they are in other packages,
	 * or even external developers packages. Not meant to be generally available.
	 * 
	 * This is needed because we can't pass the generic info into a launch configuration
	 * because a launch configuration can't take objects. Only can take strings and numbers.  
	 */
	public static synchronized LaunchInfo getInfo(String key) {
		return (LaunchInfo) LAUNCH_INFO.get(key);
	}
	
	/**
	 * Convert the string path into a valid url.
	 * @param path
	 * @return the url or <code>null</code> if not convertable (i.e. not well-formed).
	 * 
	 * @since 1.0.0
	 */
	public static URL convertStringPathToURL(String path) {
		try {
			return path != null ? new File(path).toURL() : null;
		} catch (MalformedURLException e) {
			return null;
		}
	}

	/**
	 * Convert the string paths into a valid urls.
	 * 
	 * @param paths
	 * @return the urls or <code>null</code> if paths is null. Any path not convertable (i.e. not well-formed) will not be in the final list.
	 * So this means the result length may be smaller than the paths length.
	 * 
	 * @since 1.0.0
	 */
	public static URL[] convertStringPathsToURL(String[] paths) {
		if (paths != null) {
			URL[] result = new URL[paths.length];
			int nextURL = 0;
			for (int i = 0; i < paths.length; i++) {
				URL url = convertStringPathToURL(paths[i]);
				if (url != null)
					result[nextURL++] = url;   
			}
			if (nextURL == 0)
				return null;	// None were found.
			
			if (nextURL != result.length) {
				URL[] nr = new URL[nextURL];
				System.arraycopy(result, 0, nr, 0, nr.length);
				result = nr;
			}
			return result;
		} else
			return null;
	}

	/**
	 * Convert the urls to string array. It is assumed the urls are in file protocol. 
	 * @param urls
	 * @return string paths or <code>null</code> if urls is <code>null</code>. Any <code>null</code> entry of urls will result in 
	 * a corresponding <code>null</code> in the strings.
	 * 
	 * @since 1.0.0
	 */
	public static String[] convertURLsToStrings(URL[] urls) {
		if (urls != null) {
			String[] strings = new String[urls.length];
			for (int i = 0; i < urls.length; i++) {
				strings[i] = urls[i] != null ? urls[i].getFile() : null;
			}
			return strings;
		} else
			return null;
	}

	/* (non-Javadoc)
	 * Local contributor used to make sure that certain jars are in the path.
	 * 
	 * @since 1.0.0
	 */
	static class ProxyContributor extends ConfigurationContributorAdapter {
		public void contributeClasspaths(IConfigurationContributionController controller) {
			// Add the required jars to the end of the classpath. (We want proxyCommon and initParser (+ initParser NLS), but they are in the runtime of the proxy bundle (which is jarred up), so we contribute the bundle instead.
			controller.contributeClasspath(ProxyPlugin.getPlugin().getBundle(), (IPath) null, IConfigurationContributionController.APPEND_USER_CLASSPATH, true);	//$NON-NLS-1$
		}
	}
	
}
