/*******************************************************************************
 * Copyright (c) 2001, 2006 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.jem.internal.beaninfo.core;
/*
 *  $RCSfile: BeaninfoPlugin.java,v $
 *  $Revision: 1.22 $  $Date: 2006/05/17 20:13:00 $ 
 */


import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.JavaCore;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

import org.eclipse.jem.internal.beaninfo.adapters.BeaninfoNature;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.core.ContainerPathContributionMapping.ContainerContributionEntry;
import org.eclipse.jem.internal.proxy.core.IConfigurationContributionInfo.ContainerPaths;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.util.logger.proxyrender.EclipseLogger;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;


/**
 * The plugin class for the org.eclipse.jem.internal.proxy.core plugin.
 */

public class BeaninfoPlugin extends Plugin {
	public static final String PI_BEANINFO_PLUGINID = "org.eclipse.jem.beaninfo";	// Plugin ID, used for QualifiedName. //$NON-NLS-1$
	public static final String PI_BEANINFO_OVERRIDES = "overrides";	// ID of the overrides extension point. //$NON-NLS-1$
	
	private static BeaninfoPlugin BEANINFO_PLUGIN = null;
		
	public BeaninfoPlugin() {	
		BEANINFO_PLUGIN = this;
	}
	
	/**
	 * Accessor method to get the singleton plugin.
	 */
	public static BeaninfoPlugin getPlugin() {
		return BEANINFO_PLUGIN;
	}
	
	/**
	 * Special Override file name used when need to apply an override to a class that is at the root.
	 * A root is one that doesn't have a super type. These are <code>java.lang.Object</code>, interfaces, and any
	 * undefined classes (i.e. classes that don't actually exist).
	 */
	public static final String ROOT = "..ROOT.."; //$NON-NLS-1$
	

	/**
	 * Special override scheme to refer to the current java class. (As in "X:ROOT#//@root").
	 * @since 1.2.0
	 */
	public static final String ROOT_SCHEMA = "X"; //$NON-NLS-1$
	
	/**
	 * Special override opaque part to refer to the current java class. (As in "X:ROOT#//@root").
	 * @since 1.2.0
	 */
	public static final String ROOT_OPAQUE = "ROOT"; //$NON-NLS-1$
	
	/**
	 * The extension used on any override file when you pass in a path through the method that takes a string.
	 */
	public static final String OVERRIDE_EXTENSION = "override";	//$NON-NLS-1$
		
	
	/*
	 * Map of open natures. This map is needed because on shutdown of beaninfo plugin we need
	 * to shutdown the natures. If we don't do that there is a slight possibility of an error
	 * because proxy plugin will shutdown and this can cause a callback into beaninfo which has
	 * already been shutdown. It calls back through the registry listener that BeaninfoNature
	 * added to the registry to notify that the registry is being shutdown.
	 * 
	 * Also BeanInfoCacheController needs to know so that it can tell it the project is closing or
	 * being deleted or that it needs to be cleared due to a clear request.
	 */
	private Map openNatures;
	
	private ContainerPathContributionMapping beaninfoEntryContributionsMapping;
	private ContainerPathContributionMapping contributorContributionsMapping;
	private Map pluginToBeaninfoEntryContributions;
	private Map pluginToContributors;
	
	/*
	 * Override contributions from extension point.
	 * ocFragments: Array of fragments paths. When a match is found for a path, the index
	 * 		is the index into the ocContainerIds and ocPluginIds array for the contributions.
	 * ocContainerIds: The first dimension is the index of the fragment that the list of OverrideContributions is for.
	 * 		The second dimension is the array of contributions for that fragment, one per container id.
	 * ocPluginIds: The first dimension is the index of the fragment that the list of OverrideContributions is for.
	 * 		The second dimension is the array of contributions for that fragment, one per plugin id.
	 * 
	 * If a particular fragment doesn't have any entries of container and/or plugin, then EMPTY_OC is used for that
	 * entry so that we don't need to check for null.
	 * 
	 * How this is used is for a particular path requested, the ocFragments will be searched for the fragments that
	 * are appropriate, then the index of the entry is used to walk through the OC[] array returned from the ocContainerIds
	 * or ocPluginIds. Each contribution would be checked to see if the container id/plugin id is in the visible classpath (through 
	 * the info data stored in the persistent property). If it is, then the overrides from that contribution will be used.
	 */
	private IPath ocFragments[];
	private OverrideContribution[][] ocContainerIds;
	private OverrideContribution[][] ocPluginIds;
	
	private static final OverrideContribution[] EMPTY_OC = new OverrideContribution[0];	// Used for an empty contribution list for a fragment.

	public synchronized BeaninfoEntry[] getContainerIdBeanInfos(String containerID, String[] containerPaths) {
		if (beaninfoEntryContributionsMapping == null)
			processBeanInfoContributionExtensionPoint();
		return (BeaninfoEntry[]) beaninfoEntryContributionsMapping.getContributors(containerID, containerPaths);
	}
	
	public synchronized BeaninfoEntry[] getPluginBeanInfos(String pluginid) {
		if (pluginToBeaninfoEntryContributions == null)
			processBeanInfoContributionExtensionPoint();
		return (BeaninfoEntry[]) pluginToBeaninfoEntryContributions.get(pluginid);
	}
	
	public synchronized IConfigurationElement[] getPluginContributors(String pluginid) {
		if (pluginToContributors == null)
			processBeanInfoContributionExtensionPoint();
		return (IConfigurationElement[]) pluginToContributors.get(pluginid);
	}	
	
	public synchronized IConfigurationElement[] getContainerIdContributors(String containerID, String[] containerPaths) {
		if (contributorContributionsMapping == null)
			processBeanInfoContributionExtensionPoint();
		return (IConfigurationElement[]) contributorContributionsMapping.getContributors(containerID, containerPaths);
	}	
	
	public static final String PI_BEANINFO_CONTRIBUTION_EXTENSION_POINT = PI_BEANINFO_PLUGINID+".registrations"; //$NON-NLS-1$
	public static final String PI_REGISTRATION = "registration"; //$NON-NLS-1$
	public static final String PI_BEANINFO = "beaninfo";  //$NON-NLS-1$
	public static final String PI_OVERRIDE = "override"; //$NON-NLS-1$
	public static final String PI_CONTRIBUTOR = "contributor"; //$NON-NLS-1$
	public static final String PI_PACKAGE = "package"; //$NON-NLS-1$
	public static final String PI_PATH = "path"; //$NON-NLS-1$
	
	protected synchronized void processBeanInfoContributionExtensionPoint() {
		ContributorExtensionPointInfo info = ProxyPlugin.processContributionExtensionPoint(PI_BEANINFO_CONTRIBUTION_EXTENSION_POINT);
		ConfigurationElementReader reader = new ConfigurationElementReader();
		// Process the container IDs first. We can't use the info directly because the actual configuration elements of interest are
		// sub-elements of the info. The info contains the container path that we need.
		beaninfoEntryContributionsMapping = new ContainerPathContributionMapping(BeaninfoEntry.class);
		contributorContributionsMapping = new ContainerPathContributionMapping(IConfigurationElement.class);

		Map fragmentsToIds = new HashMap();
		for (Iterator iter = info.containerPathContributions.containerIdToContributions.entrySet().iterator(); iter.hasNext();) {
			Map.Entry entry= (Map.Entry) iter.next();
			String containerid = (String) entry.getKey();
			ContainerContributionEntry[] contribElements = (ContainerContributionEntry[]) entry.getValue();
			for (int i = 0; i < contribElements.length; i++) {
				ContainerContributionEntry contribElement = contribElements[i];
				IConfigurationElement element = (IConfigurationElement) contribElement.getContribution();
				if (PI_REGISTRATION.equals(element.getName())) {
					IConfigurationElement[] children = element.getChildren();
					for (int j = 0; j < children.length; j++) {
						IConfigurationElement child = children[j];
						if (PI_BEANINFO.equals(child.getName())) {
							// This is a beaninfo entry
							BeaninfoEntry be = BeaninfoEntry.readEntry(reader, child, null);
							if (be != null)
								beaninfoEntryContributionsMapping.addContribution(containerid, contribElement.getContainerPathPattern(), be);
						} else if (PI_OVERRIDE.equals(child.getName())) {
							addOverrideEntry(fragmentsToIds, true, containerid, contribElement.getContainerPathPattern(), child);
						}
					}
				} else if (PI_CONTRIBUTOR.equals(element.getName())) {
					contributorContributionsMapping.addContribution(containerid, contribElement.getContainerPathPattern(), element);
				}
			}
		}
			
		beaninfoEntryContributionsMapping.finalizeMapping();
		contributorContributionsMapping.finalizeMapping();
		
		// Now process the plugin IDs.
		pluginToBeaninfoEntryContributions = new HashMap(info.pluginToContributions.size());		
		for (Iterator iter = info.pluginToContributions.entrySet().iterator(); iter.hasNext();) {
			Map.Entry entry= (Map.Entry) iter.next();
			String pluginId = (String) entry.getKey();
			IConfigurationElement[] configElements = (IConfigurationElement[]) entry.getValue();
			for (int i = 0; i < configElements.length; i++) {
				IConfigurationElement element = configElements[i];
				if (PI_REGISTRATION.equals(element.getName())) {
					IConfigurationElement[] children = element.getChildren();
					for (int j = 0; j < children.length; j++) {
						IConfigurationElement child = children[j];
						if (PI_BEANINFO.equals(child.getName())) {
							// This is a beaninfo entry
							BeaninfoEntry be = BeaninfoEntry.readEntry(reader, child, null);
							if (be != null)
								addEntry(pluginToBeaninfoEntryContributions, pluginId, be);
						} else if (PI_OVERRIDE.equals(child.getName())) {
							addOverrideEntry(fragmentsToIds, false, pluginId, null, child);
						}
					}
				} else if (PI_CONTRIBUTOR.equals(element.getName())) {
						if (pluginToContributors == null)
							pluginToContributors = new HashMap(5);	// These are rare, don't create until necessary.
						addEntry(pluginToContributors, pluginId, element);
					}
				}
			}
			
		// Now go through and turn all of the contribution lists into arrays.
		for (Iterator iter = pluginToBeaninfoEntryContributions.entrySet().iterator(); iter.hasNext();) {
			Map.Entry entry = (Map.Entry) iter.next();
			entry.setValue(((List) entry.getValue()).toArray(new BeaninfoEntry[((List) entry.getValue()).size()]));
		}
		
		if (pluginToContributors == null)
				pluginToContributors = Collections.EMPTY_MAP;	// Since we don't have any.
		else {
			for (Iterator iter = pluginToContributors.entrySet().iterator(); iter.hasNext();) {
				Map.Entry entry = (Map.Entry) iter.next();
				entry.setValue(((List) entry.getValue()).toArray(new IConfigurationElement[((List) entry.getValue()).size()]));
			}			
		}
		
		// Now handle the entire list of fragments.
		ocFragments = new IPath[fragmentsToIds.size()];
		ocContainerIds = new OverrideContribution[ocFragments.length][];
		ocPluginIds = new OverrideContribution[ocFragments.length][];
		Iterator iter;
		int fragIndex;
		for (iter = fragmentsToIds.entrySet().iterator(), fragIndex=0; iter.hasNext(); fragIndex++) {
			Map.Entry mapEntry = (Map.Entry) iter.next();
			ocFragments[fragIndex] = (IPath) mapEntry.getKey();
			Map[] mapValue = (Map[]) mapEntry.getValue();
			if (mapValue[0] == null)
				ocContainerIds[fragIndex] = EMPTY_OC;
			else {
				Map containers = mapValue[0];
				List ocContributions = new ArrayList();
				for (Iterator ocIterator = containers.entrySet().iterator(); ocIterator.hasNext();) {
					Map.Entry containerEntry = (Map.Entry) ocIterator.next();
					String containerID = (String) containerEntry.getKey();
					for (Iterator patternIterator = ((Map) containerEntry.getValue()).entrySet().iterator(); patternIterator.hasNext();) {
						Map.Entry patternEntry = (Entry) patternIterator.next();
						OverrideContribution oc = new OverrideContribution();
						oc.id = containerID;
						oc.pattern = (Pattern) patternEntry.getKey();
						List[] ocLists = (List[]) patternEntry.getValue();
						oc.pluginIds = (String[]) ocLists[0].toArray(new String[ocLists[0].size()]);
						oc.paths = (String[]) ocLists[1].toArray(new String[ocLists[1].size()]);
						ocContributions.add(oc);
					}
				}
				ocContainerIds[fragIndex] = (OverrideContribution[]) ocContributions.toArray(new OverrideContribution[ocContributions.size()]);
			}
			if (mapValue[1] == null)
				ocPluginIds[fragIndex] = EMPTY_OC;
			else {
				Map plugins = mapValue[1];
				OverrideContribution[] ocContribution = ocPluginIds[fragIndex] = new OverrideContribution[plugins.size()];
				int ocIndex;
				Iterator ocIterator;
				for (ocIterator = plugins.entrySet().iterator(), ocIndex=0; ocIterator.hasNext(); ocIndex++) {
					Map.Entry pluginEntry = (Map.Entry) ocIterator.next();
					OverrideContribution oc = ocContribution[ocIndex] = new OverrideContribution();
					oc.id = (String) pluginEntry.getKey();
					List[] ocLists = (List[]) pluginEntry.getValue();
					oc.pluginIds = (String[]) ocLists[0].toArray(new String[ocLists[0].size()]);
					oc.paths = (String[]) ocLists[1].toArray(new String[ocLists[1].size()]);
				}
			}			
		}
	}
	
	/*
	 * Add an entry to the map. If the key doesn't exist, create an entry as an array. Then add the entry to array.
	 */
	private void addEntry(Map map, Object key, Object entry) {
		List mapEntry = (List) map.get(key);
		if (mapEntry == null) {
			mapEntry = new ArrayList(1);
			map.put(key, mapEntry);
		}
		mapEntry.add(entry);
	}
	
	/*
	 * Add an entry to the map.
	 * id is the container path pattern/plugin id.
	 * 
	 * The structure of the map is:
	 * 	key: fragment name
	 * 	value: Map[2], where [0] is for container id, and [1] is for plugin ids.
	 * 		Map[x]:
	 * 			key: container/plugin id
	 * 			value: Map(pattern->List(FinalOverride)) for container, of FinalOverride for plugin. 
	 * 
	 * FinalOverride: List[2], where [0] is list of plugin ids for the override, and [1] is list of paths for the override files relative to that plugin id.
	 * 
	 * After all done these maps/list will be boiled down to the arrays that will be used for lookup.
	 */
	private void addOverrideEntry(Map map, boolean container, Object id, Pattern pattern, IConfigurationElement entry) {
		
		String packageName = entry.getAttributeAsIs(PI_PACKAGE);
		String plugin = null;
		String pathString = entry.getAttributeAsIs(PI_PATH);
		IPath fragment = null; 
		if (packageName != null && packageName.length() > 0 && pathString != null && pathString.length() > 0) { 
			fragment = new Path(packageName.replace('.', '/'));
			if (pathString.charAt(pathString.length()-1) != '/')
				pathString += '/';
			if (pathString.charAt(0) != '/')
				plugin = entry.getDeclaringExtension().getContributor().getName();
			else {
				if (pathString.length() > 4) {
					int pend = pathString.indexOf('/', 1);
					if (pend == -1 || pend >= pathString.length()-1)
						return;	// invalid
					plugin = pathString.substring(1, pend);
					pathString = pathString.substring(pend+1);
				} else
					return;	// invalid
			}
		}
		if (pathString.length() < 2)
			return;	// invalid

		Map[] mapEntry = (Map[]) map.get(fragment);
		if (mapEntry == null) {
			mapEntry = new HashMap[2];
			map.put(fragment, mapEntry);
		}
		List[] idEntry;
		if (container) {
			if (mapEntry[0] == null)
				mapEntry[0] = new HashMap(2);
			
			Map patternMap = (Map) mapEntry[0].get(id);
			if (patternMap == null)
				mapEntry[0].put(id, patternMap = new HashMap());
			
			idEntry = (List[]) patternMap.get(pattern);
			if (idEntry == null) {
				patternMap.put(pattern, idEntry = new List[] { new ArrayList(1), new ArrayList(1)});
			}
		} else {
			if (mapEntry[1] == null)
				mapEntry[1] = new HashMap(2);

			idEntry = (List[]) mapEntry[1].get(id);
			if (idEntry == null) {
				mapEntry[1].put(id, idEntry = new List[] { new ArrayList(1), new ArrayList(1)});
			}
		}
		idEntry[0].add(plugin);
		idEntry[1].add(pathString);


	}	
			
	/*
	 * This is an list of overrides that are available as a contribution for a specific fragment.
	 * <ul>
	 * <li>The id of this contribution. Either container (Pattern) or plugin id depending on which list it was in..
	 * <li>The plugins array lists the plugin ids for all of the paths in this contribution.
	 * <li>The paths array lists the folder path under that corresponding plugin from "pluginIds".
	 * </ul> 
	 * <p>
	 * 
	 * @since 1.0.0
	 */
	private static class OverrideContribution {
		public String id;
		public Pattern pattern;	// Used only for containers.
		public String[] pluginIds;
		public String[] paths;
	}
	
	/**
	 * The runnable is to used to apply override. 
	 * <p>
	 * This will be called in sequence for each override path found. It is send in on the apply overrides call. This
	 * interface implementation is private.
	 * <p>
	 * Clients (implementers of the IBeanInfoContributor) will be passed in the subinterface <code>IContributorOverrideRunnable</code> which
	 * inherits from this interface.
	 * <p>
	 * This interface is not intended to be implemented by clients. 
	 * 
	 * @since 1.0.0
	 * @see BeaninfoPlugin#applyOverrides(IProject, String, String, ResourceSet, IOverrideRunnable)
	 */
	public interface IOverrideRunnable {
		/**
		 * This will be called with the directory path to use. It will be called over and over for every
		 * override path found for a package. The path will be complete, including trailing '/'.
		 * It will be in a URI format for a directory. The overriderunnable implementation will then append the filename call (i.e. classbeingintrospected.override) to get a complete path.
		 * <p>
		 * Clients (IBeanInfoContributor implementers) can call this to apply a specific override file to the current
		 * class being processed.
		 * 
		 * @param overridePath the path will be complete, including trailing '/'. It will be in a URI format for a directory. The override file name (classname.override) will be appended to this and retrieved and applied.
		 * 
		 * @since 1.0.0
		 */
		public void run(String overridePath);
		
		/**
		 * This will be called with the actual resource to use. This will be called by special contributors that want
		 * a special explicit override resource to be used.
		 * <p>
		 * Contributors should use the ResourceSet that was passed into them. This is so that anything java class that
		 * the override resource points to will be found.
		 * <p>
		 * This resource will be automatically removed by BeanInfo after being applied. It must not be left around because
		 * in the process of being applied it will be modified, so it could not be reused. 
		 *  
		 * @param overrideResource the resource to apply to the current class. NOTE: This resource WILL be removed from
		 * the resource set it is in automatically by this call. It won't be left around because the action of apply
		 * will actually modify the resource.
		 * 
		 * @since 1.0.0
		 */
		public void run(Resource overrideRes);
	}
	
	/**
	 * IBeanInfoContributor runnable to use to apply overrides.
	 * <p>
	 * An implementation of this will be passed in to IBeanInfoContributor's so that they can call back to apply the overrides. They
	 * should call the appropriate run method once for each override to be applied. The run can be called more than once from each IBeanInfoContributor.
	 * <p>
	 * It inherits from <code>IOverrideRunnable</code>, so see that for more methods to call.
	 * <p>
	 * This interface is not intended to be implemented by clients.
	 * 
	 * @see BeaninfoPlugin.IOverrideRunnable for more methods that can be called.
	 * @since 1.0.0
	 */
	public interface IContributorOverrideRunnable extends IOverrideRunnable {
		
		/**
		 * Tests if path has already been contributed once for the current class.
		 * <p>
		 * This can be called by the IBeanInfoContributor for overrides to test if the path (same path as for the IOverrideRunnable.run(String) method)
		 * has already been contributed once for this class. It can be used to save time. However it is not necessary because
		 * BeanInfo will not permit it to be contributed more than once for a class.
		 * 
		 * @param path
		 * @return <code>true</code> if used already.
		 * 
		 * @see IOverrideRunnable#run(String)
		 * @since 1.0.0
		 */
		public boolean pathContributed(String path);
		
		/**
		 * Tests if the URI has already been contributed once for the current class.
		 * <p>
		 * This can be called by an IBeanInfoContributor for overrides to see if the URI (same path as the URI from the IOverrideRunnable.run(Resource) method)
		 * has already been contributed once for this class. It can be used to save time. However, not necessary because
		 * BeanInfo will not permit the URI to be contributed more than once for a class.
		 * 
		 * @param resourceURI
		 * @return <code>true</code> if used already.
		 * 
		 * @see IOverrideRunnable#run(Resource)
		 * @since 1.0.0
		 */
		public boolean resourceContributed(URI resourceURI);
	}
	
	private static final String[] NO_PATHS = new String[0];
	
	/**
	 * Return just the contributed override paths (through the BeanInfo registrations). Does not include any paths that are contributed from
	 * IBeanInfoContributor's. This is used by the BeanInfoClassAdapter to load the overrides files into one cache file so that it can
	 * be done at one time the next time it is needed.
	 * 
	 * @param project
	 * @param packageName
	 * @return array of path strings to the override. The files may not exist, they is just possible overrides. 
	 * 
	 * @since 1.1.0
	 */
	public String[] getOverridePaths(IProject project, String packageName) {
		final IPath packagePath = new Path(packageName.replace('.', '/')+'/');
		List overridePaths = new ArrayList();
		try {
			IConfigurationContributionInfo info = (IConfigurationContributionInfo) project.getSessionProperty(BeaninfoNature.CONFIG_INFO_SESSION_KEY);
			if (info == null) {
				// It hasn't been created yet, so we need to create our own internal version here.
				info = ProxyLaunchSupport.createDefaultConfigurationContributionInfo(JavaCore.create(project));					
				BeaninfoNature.computeBeanInfoConfigInfo(info);
			}
			synchronized (this) {
				if (ocFragments == null)
					processBeanInfoContributionExtensionPoint(); // We haven't processed them yet.
			}
			
			// Cache of tested patterns. (Pattern->Boolean). If a pattern has been tested against all visible container paths we don't need to test the
			// pattern again if it is found again. (Note: This works for efficiency because ProxyPlugin uses the same pattern instance for
			// same pattern found while processing one extension point). The value is true if the pattern matches a visible container path.
			Map testedPatterns = new HashMap();	
			for (int fragmentIndex = 0; fragmentIndex < ocFragments.length; fragmentIndex++) {
				if (ocFragments[fragmentIndex].isPrefixOf(packagePath)) {
					String leftOver = null;	// The left over portion of the package. This will be set first time needed. 
					OverrideContribution[] cntrContributions = ocContainerIds[fragmentIndex];
					for (int ocindex = 0; ocindex < cntrContributions.length; ocindex++) {
						OverrideContribution contribution = cntrContributions[ocindex];
						Boolean tested = (Boolean) testedPatterns.get(contribution.pattern);
						if (tested == null) {
							tested = Boolean.FALSE;
							ContainerPaths containerPaths = (ContainerPaths) info.getContainerIds().get(contribution.id);
							if (containerPaths != null) {
								String[] visible = containerPaths.getVisibleContainerPaths();
								for (int i = 0; i < visible.length; i++) {
									if (contribution.pattern.matcher(visible[i]).matches()) {
										tested = Boolean.TRUE;
										break;
									}
								}
							}
							testedPatterns.put(contribution.pattern, tested);
						}
						
						if (tested.booleanValue()) {
							for (int cindex = 0; cindex < contribution.pluginIds.length; cindex++) {
								// Because of URIConverters and normalization in org.eclipse.jem.util stuff, we
								// need to have plugin uri's in the form "platform:/plugin/pluginname".
								// Bundle's don't return this format. They return bundle:/stuff
								// So we will simple create it of the platform:/plugin format.
								// To save time, we will first see if we have the bundle.
								Bundle bundle = Platform.getBundle(contribution.pluginIds[cindex]);
								if (bundle != null) {
									if (leftOver == null)
										leftOver = getLeftOver(ocFragments[fragmentIndex], packagePath);
									overridePaths.add(JEMUtilPlugin.PLATFORM_PROTOCOL+":/"+JEMUtilPlugin.PLATFORM_PLUGIN+'/'+bundle.getSymbolicName()+'/'+contribution.paths[cindex]+leftOver); //$NON-NLS-1$
								}
							}
						}
					}
					
					OverrideContribution[] pluginContributions = ocPluginIds[fragmentIndex];
					for (int ocindex = 0; ocindex < pluginContributions.length; ocindex++) {
						OverrideContribution contribution = pluginContributions[ocindex];
						Boolean visible = (Boolean) info.getPluginIds().get(contribution.id);
						if (visible != null && visible.booleanValue()) {
							for (int cindex = 0; cindex < contribution.pluginIds.length; cindex++) {
								Bundle bundle = Platform.getBundle(contribution.pluginIds[cindex]);
								if (bundle != null) {
									if (leftOver == null)
										leftOver = getLeftOver(ocFragments[fragmentIndex], packagePath);
									overridePaths.add(JEMUtilPlugin.PLATFORM_PROTOCOL+":/"+JEMUtilPlugin.PLATFORM_PLUGIN+'/'+bundle.getSymbolicName()+'/'+contribution.paths[cindex]+leftOver); //$NON-NLS-1$
								}
							}
						}
					}
				}
			}
		} catch (CoreException e) {
			getLogger().log(e, Level.INFO);
		}
		return overridePaths.isEmpty() ? NO_PATHS : (String[]) overridePaths.toArray(new String[overridePaths.size()]);
	}
	
	/**
	 * Apply the runnable to all of the override paths that are applicable to the 
	 * given package name. It will run through the explicit contributors and the IContainers that implement IBeanInfoContributor.
	 * <p>
	 * The package name uses '.' to delineate the fragments of the name,
	 * i.e. use "<code>java.lang</code>" as a package name.
	 * <p>
	 * Note: This is not meant to be called by clients. It is public only because an internal class in another package needs to call it.
	 * TODO This should be package-protected. Later the other class will be moved into this package.
	 * 
	 * @param project the project to run against.
	 * @param packageName
	 * @param className class name of the class that is being overridden.
	 * @param javaClass the java class the overrides will be applied to.
	 * @param resource set that contributors can use to temporarily load dynamic override files.
	 * @param runnable use this runnable to actually apply overrides.
	 * 
	 * @since 1.0.0
	 */
	public void applyOverrides(final IProject project, String packageName, final String className, final JavaClass javaClass, final ResourceSet rset, final IOverrideRunnable runnable) {
		final IPath packagePath = new Path(packageName.replace('.', '/')+'/');
		try {
			IConfigurationContributionInfo info = (IConfigurationContributionInfo) project.getSessionProperty(BeaninfoNature.CONFIG_INFO_SESSION_KEY);
			if (info == null) {
				// It hasn't been created yet, so we need to create our own internal version here.
				info = ProxyLaunchSupport.createDefaultConfigurationContributionInfo(JavaCore.create(project));					
				BeaninfoNature.computeBeanInfoConfigInfo(info);
			}
			final IBeanInfoContributor[] explicitContributors = (IBeanInfoContributor[]) project.getSessionProperty(BeaninfoNature.BEANINFO_CONTRIBUTORS_SESSION_KEY);
			synchronized (this) {
				if (ocFragments == null)
					processBeanInfoContributionExtensionPoint(); // We haven't processed them yet.
			}

			final Set usedPaths = new HashSet(10);	// Set of used paths. So that the contributors don't supply a path already used. This could cause problems if they did.
			final IContributorOverrideRunnable contribRunnable = new IContributorOverrideRunnable() {
				public void run(String overridePath) {
					if (!usedPaths.contains(overridePath)) {
						usedPaths.add(overridePath);
						runnable.run(overridePath);
					}
				}
				
				public void run(Resource overrideRes) {
					if (!usedPaths.contains(overrideRes.getURI())) {
						usedPaths.add(overrideRes.getURI());
						try {
							runnable.run(overrideRes);
						} finally {
							overrideRes.getResourceSet().getResources().remove(overrideRes);
						}
					}
				}
				
				public boolean pathContributed(String path) {
					return usedPaths.contains(path);
				}
				
				public boolean resourceContributed(URI resourceURI) {
					return usedPaths.contains(resourceURI);
				}
			};
			
			// Run through the containers that implement IBeanInfoContributor.
			for (Iterator iter = info.getContainers().entrySet().iterator(); iter.hasNext();) {
				Map.Entry mapEntry = (Map.Entry) iter.next();
				final IClasspathContainer container = (IClasspathContainer) mapEntry.getKey();
				if (container instanceof IBeanInfoContributor && ((Boolean) mapEntry.getValue()).booleanValue()) {
					SafeRunner.run(new ISafeRunnable() {
						public void handleException(Throwable exception) {
							// Standard run logs to .log
						}
						public void run() throws Exception {
							((IBeanInfoContributor) container).runOverrides(packagePath, className, javaClass, rset, contribRunnable);						
						}
					});
				}
			}
			
			// Run through the explicit contributors.
			for (int i=0; i<explicitContributors.length; i++) {
				final int ii = i;
				SafeRunner.run(new ISafeRunnable() {
					public void handleException(Throwable exception) {
						// Standard run logs to .log
					}
					public void run() throws Exception {
						explicitContributors[ii].runOverrides(packagePath, className, javaClass, rset, contribRunnable);						
					}
				});
			}			
		} catch (CoreException e) {
			getLogger().log(e, Level.INFO);
		}
	}
	
	private String getLeftOver(IPath fragment, IPath packagePath) {
		return packagePath.removeFirstSegments(fragment.segmentCount()).toString();
	}
	
	private Logger logger;
	public Logger getLogger() {
		if (logger == null)
			logger = EclipseLogger.getEclipseLogger(this);
		return logger;
	}
	
	/**
	 * Add that a BeanInfo nature is active. This is used to tell it to shutdown when beaninfo shuts down.
	 * TODO <package-protected> because only BeanInfoNature should call it. (public for now but when we make
	 * BeanInfoNature an API it will be moved into the same package as BeanInfoPlugin).
	 * 
	 * @param nature
	 * 
	 * @since 1.0.0
	 */
	public void addBeanInfoNature(BeaninfoNature nature) {
		if (openNatures == null)
			openNatures = new HashMap();
		openNatures.put(nature.getProject(), nature);
	}
	
	/**
	 * Mark that a BeanInfo nature is not active. This is used to tell it to shutdown when beaninfo shuts down.
	 * TODO <package-protected> because only BeanInfoNature should call it. (public for now but when we make
	 * BeanInfoNature an API it will be moved into the same package as BeanInfoPlugin).
	 * 
	 * @param nature
	 * 
	 * @since 1.0.0
	 */
	public void removeBeanInfoNature(BeaninfoNature nature) {
		if (openNatures != null)
			openNatures.remove(nature.getProject());
	}
	
	/**
	 * Return the registered nature, if any, for the project. This will not cause the
	 * nature to be created.
	 * <p>
	 * <package-protected> because only BeanInfoCacheController should access it.
	 * @param project
	 * @return nature for project or <code>null</code> if not registered.
	 * 
	 * @since 1.1.0
	 */
	BeaninfoNature getNature(IProject project) {
		return (BeaninfoNature) openNatures.get(project);
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		if (openNatures != null && !openNatures.isEmpty()) {
			for (Iterator natureItr = openNatures.values().iterator(); natureItr.hasNext();) {
				BeaninfoNature nature = (BeaninfoNature) natureItr.next();
				nature.shutdown();
			}
		}
			
		super.stop(context);
	}
}


