/*******************************************************************************
 * Copyright (c) 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: BeanInfoCacheController.java,v $
 *  $Revision: 1.9 $  $Date: 2005/05/18 20:59:17 $ 
 */
package org.eclipse.jem.internal.beaninfo.core;

import java.io.*;
import java.util.*;
import java.util.logging.Level;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.impl.EObjectToChangesMapEntryImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.jdt.core.*;

import org.eclipse.jem.internal.beaninfo.adapters.BeaninfoClassAdapter;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.util.emf.workbench.ProjectResourceSet;
import org.eclipse.jem.util.logger.proxy.Logger;

/**
 * Controller of the BeanInfo cache. There is one per workspace (it is a static).
 * 
 * The cache is stored on a per IPackageFragmentRoot basis. Each package fragment root will be:
 * 
 * <pre>
 * 
 *  root{999}/classname.xmi
 *  
 * </pre>
 * 
 * "root{999}" will be a unigue name (root appended with a number}, one for each package fragment root. The "classname.xmi" will be the BeanInfo cache
 * for a class in the root. A root can't have more than one class with the same name, so there shouldn't be any collisions.
 * <p>
 * Now roots can either be in a project, or they can be an external jar (which can be shared between projects).
 * <p>
 * Now all roots for a project will be stored in the project's working location
 * {@link org.eclipse.core.resources.IProject#getWorkingLocation(java.lang.String)}under the ".cache" directory. It will be this format in each
 * project location (under the org.eclipse.jem.beaninfo directory):
 * 
 * <pre>
 * 
 *  .index
 *  root{999}/...
 *  
 * </pre>
 * 
 * The ".index" file will be stored/loaded through an ObjectStream. It will be a {@link BeanInfoCacheController.Index}. It is the index to all of the
 * root's in the directory.
 * <p>
 * All of the external jar roots will be stored in the org.eclipse.jem.beaninfo plugin's state location
 * {@link org.eclipse.core.runtime.Platform#getStateLocation(org.osgi.framework.Bundle)}under the ".cache" directory. The format of this directory
 * will be the same as for each project. And the roots will be for each unique shared external jar (such as the differnt jre's rt.jars).
 * <p>
 * Note: There are so many places where synchronization is needed, so it is decided to synchronize only on BeanInfoCacheController.INSTANCE. It would
 * be too easy to get a dead-lock because the order of synchronizations can't be easily controlled. Since each piece of sync control is very short
 * (except for save of the indices, but that is ok because we don't want them changing while saving) it shouldn't block a lot. There is one place we
 * violate this and that is we do a sync on ClassEntry instance when working with the pending. This is necessary because we don't want the cache write
 * job to hold up everything while writing, so we sync on the entry being written instead. There we must be very careful that we never to
 * BeanInfoCacheControler.INSTANCE sync and then a ClassEntry sync because we could deadlock. The CE access under the covers may do a CE sync and then
 * a BeanInfoCacheController.INSTANCE sync.
 * 
 * @since 1.1.0
 */
public class BeanInfoCacheController {

	/**
	 * Singleton cache controller.
	 * 
	 * @since 1.1.0
	 */
	public static final BeanInfoCacheController INSTANCE = new BeanInfoCacheController();

	private BeanInfoCacheController() {
		// Start up save participent.
		// TODO For now it only handles final save. It doesn't handle deltas and crashes.
		// It should actually be a job that handles in the background, with a way of cache entries being accessed even when it isn't finished. Such
		// as until finished when checking mod stamp it will check actual file and compare to cache entry to determine if stale.
		saveParticipant = new SaveParticipant();
		try {
			ResourcesPlugin.getWorkspace().addSaveParticipant(BeaninfoPlugin.getPlugin(), saveParticipant);
		} catch (CoreException e) {
			BeaninfoPlugin.getPlugin().getLogger().log(e.getStatus());
		}
	}

	protected SaveParticipant saveParticipant;

	/**
	 * An index structure for the Main and Project indexes. Access to the index contents and methods should synchronize on the index itself.
	 * <p>
	 * Getting to the index instance should only be through the <code>getMainIndex()</code> and <code>getProjectIndex(IProject)</code> accessors
	 * so that synchronization and serialization is controlled.
	 * 
	 * @since 1.1.0
	 */
	protected static class Index implements Serializable {

		private static final long serialVersionUID = 1106864425465L;

		/*
		 * Is this a dirty index, i.e. it has been changed and needs to be saved.
		 */
		transient private boolean dirty;

		/**
		 * The highest root number used. It is incremented everytime one is needed. It doesn't ever decrease to recover removed roots.
		 * 
		 * @since 1.1.0
		 */
		public int highRootNumber;

		/**
		 * Map of root names to the root Index. The key is a {@link IPath}. The path will be relative to the workspace if a project root, or an
		 * absolute local path to the archive if it is an external archive. It is the IPath to package fragment root (either a folder or a jar file).
		 * <p>
		 * The value will be a {@link BeanInfoCacheController.RootIndex}. This is the index for the contents of that root.
		 * 
		 * @since 1.1.0
		 */
		transient public Map rootToRootIndex;

		/**
		 * @param dirty
		 *            The dirty to set.
		 * 
		 * @since 1.1.0
		 */
		public void setDirty(boolean dirty) {
			synchronized (BeanInfoCacheController.INSTANCE) {
				this.dirty = dirty;
			}
		}

		/**
		 * @return Returns the dirty.
		 * 
		 * @since 1.1.0
		 */
		public boolean isDirty() {
			synchronized (BeanInfoCacheController.INSTANCE) {
				return dirty;
			}
		}

		private void writeObject(ObjectOutputStream os) throws IOException {
			os.defaultWriteObject();
			// Now write out the root to root index map. We are not serializing the Map directly using normal Map serialization because
			// the key of the map is an IPath (which is a Path under the covers) and Path is not serializable.
			os.writeInt(rootToRootIndex.size());
			for (Iterator mapItr = rootToRootIndex.entrySet().iterator(); mapItr.hasNext();) {
				Map.Entry entry = (Map.Entry) mapItr.next();
				os.writeUTF(((IPath) entry.getKey()).toString());
				os.writeObject(entry.getValue());
			}
		}

		private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
			is.defaultReadObject();
			int size = is.readInt();
			rootToRootIndex = new HashMap(size < 100 ? 100 : size);
			while (size-- > 0) {
				rootToRootIndex.put(new Path(is.readUTF()), is.readObject());
			}
		}
	}

	/**
	 * An index for a root. It has an entry for each class in this root. The class cache entry describes the cache, whether it is stale, what the
	 * current mod stamp is, etc.
	 * 
	 * @since 1.1.0
	 */
	public static abstract class RootIndex implements Serializable {

		private static final long serialVersionUID = 1106868674823L;

		transient private IPath cachePath; // Absolute local filesystem IPath to the root cache directory. Computed at runtime because it may change
										   // if workspace relocated.

		protected Map classNameToClassEntry; // Map of class names to class entries.

		private String rootName; // Name of the root directory in the cache (e.g. "root1").

		protected Index index; // Index containing this root index.

		protected RootIndex() {
		}

		public RootIndex(String rootName, Index index) {
			this.rootName = rootName;
			classNameToClassEntry = new HashMap(100); // When created brand new, put in a map. Otherwise object stream will create the map.
			this.index = index;
		}

		/**
		 * Return the root directory name
		 * 
		 * @return rootname
		 * 
		 * @since 1.1.0
		 */
		public String getRootName() {
			return rootName;
		}

		/**
		 * Set this RootIndex (and the containing Index) as being dirty and in need of saving.
		 * 
		 * 
		 * @since 1.1.0
		 */
		public void setDirty() {
			index.setDirty(true);
		}

		/*
		 * Setup for index. It will initialize the path. Once set it won't set it again. This will be called repeatedly by the cache controller
		 * because there is no way to know if it was lazily created or was brought in from file. When brought in from file the path is not set because
		 * it should be relocatable and we don't want absolute paths out on the disk caches, and we don't want to waste time creating the path at load
		 * time because it may not be needed for a while. So it will be lazily created. <p> If the project is set, then the path will be relative to
		 * the project's working location. If project is <code> null </code> then it will be relative to the BeanInfo plugin's state location. <p>
		 * This is <package-protected> because only the creator (BeanInfoCacheController class) should set this up.
		 * 
		 * @param project
		 * 
		 * @since 1.1.0
		 */
		void setupIndex(IProject project) {
			if (getCachePath() == null)
				cachePath = getCacheDir(project).append(rootName);
		}

		/**
		 * @return Returns the path of the cache directory for the root.
		 * 
		 * @since 1.1.0
		 */
		public IPath getCachePath() {
			return cachePath;
		}

		/**
		 * Return whether this is a root for a archive or a folder.
		 * 
		 * @return <code>true</code> if archive for a root. <code>false</code> if archive for a folder.
		 * 
		 * @since 1.1.0
		 */
		public abstract boolean isArchiveRoot();
	}

	/**
	 * A root index that is for an archive, either internal or external. It contains the archive's modification stamp. Each class cache entry will
	 * have this same modification stamp. If the archive is changed then all of the class cache entries will be removed because they are all possibly
	 * stale. No way to know which may be stale and which not.
	 * 
	 * @since 1.1.0
	 */
	public static class ArchiveRootIndex extends RootIndex {

		private static final long serialVersionUID = 110686867456L;

		private long archiveModificationStamp;

		/*
		 * For serializer to call.
		 */
		protected ArchiveRootIndex() {
		}

		public ArchiveRootIndex(String rootName, long archiveModificationStamp, Index index) {
			super(rootName, index);
			this.archiveModificationStamp = archiveModificationStamp;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jem.internal.beaninfo.core.BeanInfoCacheController.RootIndex#isArchiveRoot()
		 */
		public boolean isArchiveRoot() {
			return true;
		}

		/*
		 * Set the modification stamp. <p> <package-protected> because only the cache controller should change it.
		 * 
		 * @param archiveModificationStamp The archiveModificationStamp to set.
		 * 
		 * @see BeanInfoCacheController#MODIFICATION_STAMP_STALE
		 * @since 1.1.0
		 */
		void setArchiveModificationStamp(long archiveModificationStamp) {
			this.archiveModificationStamp = archiveModificationStamp;
			setDirty();
		}

		/**
		 * Returns the modification stamp.
		 * 
		 * @return Returns the archiveModificationStamp.
		 * @see BeanInfoCacheController#MODIFICATION_STAMP_STALE
		 * @since 1.1.0
		 */
		public long getArchiveModificationStamp() {
			return archiveModificationStamp;
		}
	}

	/**
	 * This is a root index for a folder (which will be in the workspace). Each class cache entry can have a different modification stamp with a
	 * folder root index.
	 * 
	 * @since 1.1.0
	 */
	public static class FolderRootIndex extends RootIndex {

		private static final long serialVersionUID = 1106868674842L;

		/*
		 * For serialization.
		 */
		protected FolderRootIndex() {
		}

		/**
		 * @param rootName
		 * 
		 * @since 1.1.0
		 */
		public FolderRootIndex(String rootName, Index index) {
			super(rootName, index);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jem.internal.beaninfo.core.BeanInfoCacheController.RootIndex#isArchiveRoot()
		 */
		public boolean isArchiveRoot() {
			return false;
		}
	}

	/**
	 * An individual class entry from the cache. It has an entry for each class in the root. The class cache entry describes the cache, whether it is
	 * stale, what the current mod stamp is, etc.
	 * <p>
	 * There is a method to call to see if deleted. This should only be called if entry is being held on to because
	 * <code>getClassEntry(JavaClass)</code> will never return a deleted entry. There is a method to get the modification stamp of the current cache
	 * entry. This is the time stamp of the cooresponding class resource (or archive file) that the cache file was created from. If the value is
	 * <code>IResource.NULL_STAMP</code>, then the cache file is known to be stale. Otherwise if the value is less than a modification stamp of a
	 * super class then the cache file is stale.
	 * 
	 * @see ClassEntry#isDeleted()
	 * @see ClassEntry#getModificationStamp()
	 * @see BeanInfoCacheController#getClassEntry(JavaClass)
	 * @since 1.1.0
	 */
	public static class ClassEntry implements Serializable {

		private static final long serialVersionUID = 1106868674666L;

		public static final long DELETED_MODIFICATION_STAMP = Long.MIN_VALUE; // This flag won't be seen externally. It is used to indicate the entry
																			  // has been deleted for those that have been holding a CE.

		private long modificationStamp;
		private long superModificationStamp;	// Stamp of superclass, if any, at time of cache creation.
		private String[] interfaceNames;	// Interfaces names (null if no interfaces)
		private long[] interfaceModicationStamps;	// Modification stamps of interfaces, if any. (null if no interfaces).
		private transient Resource pendingResource;	// Resource is waiting to be saved, but the timestamps are for this pending resource so that we know what it will be ahead of time. At this point the class will be introspected. 

		private RootIndex rootIndex; // The root index this class entry is in, so that any changes can mark the entry as dirty.

		private String className; // The classname for this entry.
		
		private boolean saveOperations;	// Flag for saving operations. Once this is set, it will continue to save operations in the cache in addition to everything else.

		private long configurationModificationStamp;	// Modification stamp of the Eclipse configuration. Used to determine if the cache of override files is out of date due to a config change.
		private boolean overrideCacheExists;	// Flag that there is an override cache to load. This is orthogonal to the config mod stamp because it simply means that on the current configuration there is no override cache.
		private transient Resource pendingOverrideResource;	// Override resource is waiting to be saved.
		
		protected ClassEntry() {
		}

		ClassEntry(RootIndex rootIndex, String className) {
			this.setRootIndex(rootIndex);
			this.className = className;
			modificationStamp = IResource.NULL_STAMP;
			rootIndex.classNameToClassEntry.put(className, this);
		}

		/**
		 * 
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public String getClassName() {
			return className;
		}

		/**
		 * Return whether the entry has been deleted. This will never be seen in an entry that is still in an index. It is used for entries that have
		 * been removed from the index. It is for classes (such as the BeanInfoClassAdapter) which are holding onto a copy of entry to let them know.
		 * <p>
		 * Holders of entries should call isDeleted if they don't need to further check the mod stamp. Else they should call getModificationStamp and
		 * check of deleted, stale, or mod stamp. That would save extra synchronizations. If entry is deleted then it should throw the entry away.
		 * 
		 * @return <code>true</code> if the entry has been deleted, <code>false</code> if still valid.
		 * 
		 * @see ClassEntry#getModificationStamp()
		 * @see ClassEntry#isStale()
		 * @see ClassEntry#DELETED_MODIFICATION_STAMP
		 * @since 1.1.0
		 */
		public boolean isDeleted() {
			return getModificationStamp() == DELETED_MODIFICATION_STAMP;
		}

		/**
		 * Mark the entry as deleted. It will also be removed from root index in that case.
		 * <p>
		 * Note: It is public only so that BeanInfoClassAdapter can access it. It should not be called by anyone else outside of BeanInfo.
		 */
		public synchronized void markDeleted() {
			if (!isDeleted()) {
				getRootIndex().classNameToClassEntry.remove(className);
				setModificationStamp(DELETED_MODIFICATION_STAMP); // Also marks index as dirty.
			}
		}

		/**
		 * Return whether the entry is stale or not. This orthoganal to isDeleted. isDeleted will not be true if isStale and isStale will not be true
		 * if isDeleted. Normally you should use getModificationStamp and check the value for IResource.NULL_STAMP and other values to bring it down
		 * to only one synchronized call to CE, but if only needing to know if stale, you can use this.
		 * 
		 * @return
		 * 
		 * @since 1.1.0
		 * @see IResource#NULL_STAMP
		 * @see ClassEntry#getModificationStamp()
		 * @see ClassEntry#isDeleted()
		 */
		public boolean isStale() {
			return getModificationStamp() == IResource.NULL_STAMP;
		}

		/**
		 * Return the modification stamp. For those holding onto an entry, and they need to know more than if just deleted, then they should just the
		 * return value from getModificationStamp. Else they should use isDeleted or isStale.
		 * 
		 * @return modification stamp, or {@link IResource#NULL_STAMP}if stale or not yet created, or {@link ClassEntry#DELETED_MODIFICATION_STAMP}
		 *         if deleted.
		 * 
		 * @see ClassEntry#isDeleted()
		 * @see ClassEntry#isStale()
		 * @since 1.1.0
		 */
		public synchronized long getModificationStamp() {
			return modificationStamp;
		}
		
		/**
		 * Return the super modification stamp.
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public synchronized long getSuperModificationStamp() {
			return superModificationStamp;
		}
		
		/**
		 * Return the interface names or <code>null</code> if no interface names.
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public synchronized String[] getInterfaceNames() {
			return interfaceNames;
		}

		/**
		 * Return the interface modification stamps or <code>null</code> if no interfaces.
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public synchronized long[] getInterfaceModificationStamps() {
			return interfaceModicationStamps;
		}
		
		/*
		 * Set the modification stamp. <p> <package-protected> because only the cache controller should set it. @param modificationStamp
		 * 
		 * @since 1.1.0
		 */
		void setModificationStamp(long modificationStamp) {
			if (this.modificationStamp != modificationStamp) {
				this.modificationStamp = modificationStamp;
				getRootIndex().setDirty();
			}
		}

		/**
		 * Answer whether operations are also stored in the cache for this class. By default they are not. Once turned on they
		 * will always be stored for this class until the class is deleted.
		 * 
		 * @return <code>true</code> if operations are cached, <code>false</code> if they are not cached.
		 * 
		 * @since 1.1.0
		 */
		public synchronized boolean isOperationsStored() {
			return saveOperations;
		}
		
		/*
		 * Set the operations stored flag.
		 * @param storeOperations
		 * 
		 * @see BeanInfoCacheController.ClassEntry#isOperationsStored()
		 * @since 1.1.0
		 */
		void setOperationsStored(boolean storeOperations) {
			saveOperations = storeOperations;
		}
		
		/**
		 * Get the configuration modification stamp of the last saved override cache.
		 * 
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public synchronized long getConfigurationModificationStamp() {
			return configurationModificationStamp;
		}

		/* 
		 * Set the configuration modification stamp.
		 * <p> <package-protected> because only the cache controller should access it.
		 * 
		 * @param configurationModificationStamp
		 * 
		 * @since 1.1.0
		 */
		void setConfigurationModificationStamp(long configurationModificationStamp) {
			this.configurationModificationStamp = configurationModificationStamp;
			getRootIndex().setDirty();
		}
		
		/**
		 * Answer whether there is an override cache available.
		 * @return
		 * 
		 * @since 1.1.0
		 */
		public synchronized boolean overrideCacheExists() {
			return overrideCacheExists;
		}
		
		/*
		 * Set the override cache exists flag.
		 * <p> <package-protected> because only the cache controller should access it.
		 * @param overrideCacheExists
		 * 
		 * @since 1.1.0
		 */
		void setOverrideCacheExists(boolean overrideCacheExists) {
			this.overrideCacheExists = overrideCacheExists;
		}
		
		/**
		 * Get the pending resource or <code>null</code> if not pending.
		 * 
		 * @return the pending resource or <code>null</code> if not pending.
		 * 
		 * @since 1.1.0
		 */
		public synchronized Resource getPendingResource() {
			return pendingResource;
		}
		
		/*
		 * Set the entry. The sequence get,do something,set must be grouped within a synchronized(ClassEntry). 
		 * <p> <package-protected> because only the cache controller should access it. 
		 * @param cacheResource The cacheResource to set.
		 * 
		 * @since 1.1.0
		 */
		void setPendingResource(Resource pendingResource) {
			this.pendingResource = pendingResource;
		}

		/**
		 * Get the pending override resource or <code>null</code> if not pending.
		 * 
		 * @return the pending override resource or <code>null</code> if not pending.
		 * 
		 * @since 1.1.0
		 */
		public synchronized Resource getPendingOverrideResource() {
			return pendingOverrideResource;
		}
		
		/*
		 * Set the entry. The sequence get,do something,set must be grouped within a synchronized(ClassEntry). 
		 * <p> <package-protected> because only the cache controller should access it. 
		 * @param cacheResource The cacheResource to set.
		 * 
		 * @since 1.1.0
		 */
		void setPendingOverrideResource(Resource pendingOverrideResource) {
			this.pendingOverrideResource = pendingOverrideResource;
		}

		/*
		 * <package-protected> because only the cache controller should access it. @param rootIndex The rootIndex to set.
		 * 
		 * @since 1.1.0
		 */
		void setRootIndex(RootIndex rootIndex) {
			this.rootIndex = rootIndex;
		}

		/*
		 * <package-protected> because only the cache controller should access it. @return Returns the rootIndex.
		 * 
		 * @since 1.1.0
		 */
		RootIndex getRootIndex() {
			return rootIndex;
		}
		
		/*
		 * <package-protected> because only the cache controller should access it.
		 * 
		 * @since 1.1.0
		 */
		void setSuperModificationStamp(long superModificationStamp) {
			this.superModificationStamp = superModificationStamp;
		}

		/*
		 * <package-protected> because only the cache controller should access it.
		 * 
		 * @since 1.1.0
		 */
		void setInterfaceNames(String[] interfaceNames) {
			this.interfaceNames = interfaceNames;
		}

		/*
		 * <package-protected> because only the cache controller should access it.
		 * 
		 * @since 1.1.0
		 */
		void setInterfaceModificationStamps(long[] interfaceModificationStamps) {
			this.interfaceModicationStamps = interfaceModificationStamps;
		}
		
	}

	/*
	 * Main index for the external jars. This variable should not be referenced directly except through the getMainIndex() accessor. That controls
	 * synchronization and restoration as needed.
	 */
	private static Index MAIN_INDEX;

	/*
	 * Map of project indexes. They are read in as needed. The key will be an IProject and the value will be an Index. This variable should not be
	 * referenced directly except through the getProjectIndex(IProject) accessor. That controls synchronization and restoration as needed.
	 */
	private static Map PROJECT_INDEXES = new HashMap();

	/*
	 * Suffix for class cache files.
	 */
	private static final String CLASS_CACHE_SUFFIX = ".xmi"; //$NON-NLS-1$
	/*
	 * Suffic for class override cache files.
	 */
	private static final String OVERRIDE_CACHE_SUFFIX = ".override.xmi"; //$NON-NLS-1$

	/**
	 * Return the current class entry for the JavaClass, or <code>null</code> if no current entry.
	 * 
	 * @param jclass
	 * @return class entry or <code>null</code> if no current entry.
	 * 
	 * @since 1.1.0
	 */
	public ClassEntry getClassEntry(JavaClass jclass) {
		IType type = (IType) jclass.getReflectionType();
		RootIndex rootIndex = getRootIndex(type);
		String className = jclass.getQualifiedNameForReflection();
		return getClassEntry(rootIndex, className, false);
	}

	/**
	 * Enumeration for newCache: Signals that this cache is the Reflection Cache with no operations in it.
	 * @since 1.1.0
	 */
	public final static int REFLECTION_CACHE = 1;
	/**
	 * Enumeration for newCache: Signals that this cache is the Reflection Cache with operations in it.
	 * @since 1.1.0
	 */
	public final static int REFLECTION_OPERATIONS_CACHE = 2;
	/**
	 * Enumeration for newCache: Signals that this cache is the Overrides cache.
	 * @since 1.1.0
	 */
	public final static int OVERRIDES_CACHE = 3;
	/**
	 * A new cache entry for the given class has been created. Need to write it out.
	 * 
	 * @param jclass
	 *            the JavaClass the cache is for.
	 * @param cache
	 *            the ChangeDescription to put out if cacheType is Reflection types, a List if override cache type.
	 * @param cacheType
	 *            {@link BeanInfoCacheController.ClassEntry#REFLECTION_CACHE} for the enum values.
	 * @return new class entry (or old one if same one). Should always replace one being held by this one. <code>null</code> if cache could not be
	 *         updated for some reason.
	 * @since 1.1.0
	 */
	public ClassEntry newCache(JavaClass jclass, Object cache, int cacheType) {
		if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER)) {
			Logger logger = BeaninfoPlugin.getPlugin().getLogger();
			String type = cacheType!=OVERRIDES_CACHE?"Class":"Overrides"; //$NON-NLS-1$ //$NON-NLS-2$
			if (cacheType == OVERRIDES_CACHE && cache == null)
				type+="  empty"; //$NON-NLS-1$
			logger.log("Creating cache for class "+jclass.getQualifiedNameForReflection()+" cache type="+type, Level.FINER); //$NON-NLS-1$ //$NON-NLS-2$
		}
		ChangeDescription cd = null;
		if (cacheType != OVERRIDES_CACHE) {
			// First go through the cd and remove any empty changes. This is because we created the feature change before we knew what went into
			// it, and at times nothing goes into it.
			cd = (ChangeDescription) cache;
			for (Iterator iter = cd.getObjectChanges().iterator(); iter.hasNext();) {
				EObjectToChangesMapEntryImpl fcEntry = (EObjectToChangesMapEntryImpl) iter.next();
				if (((List) fcEntry.getValue()).isEmpty())
					iter.remove(); // Empty changes, remove it.
			}
		}
		IType type = (IType) jclass.getReflectionType();
		RootIndex rootIndex = getRootIndex(type);
		String className = jclass.getQualifiedNameForReflection();
		ClassEntry ce = getClassEntry(rootIndex, className, true); // Create it if not existing.
		// Sync on ce so that only can create a cache for a class at a time and so that writing (if occurring at the same time for the class) can be
		// held up.
		// this is a violation of the agreement to only sync on THIS, but it is necessary or else the write job would lock everything out while it is
		// writing. This way it only locks out one class, if the class is at the same time.
		// We shouldn't have deadlock because here we lock ce and then THIS (maybe). The write job will lock ce, and then lock THIS. Everywhere else
		// we must
		// also do lock ce then THIS. Mustn't do other way around or possibility of deadlock. Be careful that any synchronized methods in this class
		// do
		// not lock an existing ce.
		ResourceSet cacheRset = null;
		synchronized (ce) {
			Resource cres;
			if (cacheType != OVERRIDES_CACHE) {
				cres = ce.getPendingResource();
				if (cres != null) {
					// We have a pending, so clear and reuse the resource.
					cres.getContents().clear();
				} else {
					// Not currently writing or waiting to write, so create a new resource.
					cres = jclass.eResource().getResourceSet().createResource(
							URI.createFileURI(rootIndex.getCachePath().append(className + CLASS_CACHE_SUFFIX).toString()));
				}
				cacheRset = cres.getResourceSet();
				ce.setOperationsStored(cacheType == REFLECTION_OPERATIONS_CACHE);
				ce.setPendingResource(cres);
				cres.getContents().add(cd);
				// Archives use same mod as archive (retrieve from rootindex), while non-archive use the underlying resource's mod stamp.
				if (rootIndex.isArchiveRoot())
					ce.setModificationStamp(((ArchiveRootIndex) rootIndex).getArchiveModificationStamp());
				else {
					try {
						ce.setModificationStamp(type.getUnderlyingResource().getModificationStamp());
					} catch (JavaModelException e) {
						BeaninfoPlugin.getPlugin().getLogger().log(e);
						ce.markDeleted(); // Mark as deleted in case this was an existing that someone is holding.
						return null; // Couldn't do it, throw cache entry away. This actually should never occur.
					}
				}
				// Need to get the supers info. 
				List supers = jclass.getESuperTypes();
				if (!supers.isEmpty()) {
					// We assume that they all have been introspected. This was done back in main introspection. If they are introspected they will have a class entry.
					BeaninfoClassAdapter bca = BeaninfoClassAdapter.getBeaninfoClassAdapter((EObject) supers.get(0));
					ce.setSuperModificationStamp(bca.getClassEntry().getModificationStamp());
					if(supers.size() == 1) {
						ce.setInterfaceNames(null);
						ce.setInterfaceModificationStamps(null);
					} else {
						String[] interNames = new String[supers.size()-1];
						long[] interMods = new long[interNames.length];
						for (int i = 1, indx = 0; i < interNames.length; i++, indx++) {
							JavaClass javaClass = (JavaClass) supers.get(i);
							bca = BeaninfoClassAdapter.getBeaninfoClassAdapter(javaClass);
							bca.introspectIfNecessary();	// Force introspection to get a valid super mod stamp.
							interNames[indx] = javaClass.getQualifiedNameForReflection();
							interMods[indx] = bca.getClassEntry().getModificationStamp();
						}
						ce.setInterfaceNames(interNames);
						ce.setInterfaceModificationStamps(interMods);
					}
				} else {
					ce.setSuperModificationStamp(IResource.NULL_STAMP);
					ce.setInterfaceNames(null);
					ce.setInterfaceModificationStamps(null);
				}
			} else {
				// We are an override cache.
				if (cache != null) { 
					cres = ce.getPendingOverrideResource();
					if (cres != null) {
						// We have a pending, so clear and reuse the resource.
						cres.getContents().clear();
					} else {
						// Not currently writing or waiting to write, so create a new resource.
						cres = jclass.eResource().getResourceSet().createResource(
								URI.createFileURI(rootIndex.getCachePath().append(className + OVERRIDE_CACHE_SUFFIX).toString()));
					}
					cacheRset = cres.getResourceSet();
					cres.getContents().addAll((List) cache);
					ce.setPendingOverrideResource(cres);
					ce.setOverrideCacheExists(true);
				} else {
					ce.setPendingOverrideResource(null);
					ce.setOverrideCacheExists(false);
				}
				ce.setConfigurationModificationStamp(Platform.getPlatformAdmin().getState(false).getTimeStamp());
			}
		}
		queueClassEntry(ce, cacheRset); // Now queue it up.
		return ce;
	}

	/**
	 * Get the cache resource for the given java class.
	 * <p>
	 * NOTE: It is the responsibility of the caller to ALWAYS remove the Resource from its resource set when done with it.
	 * 
	 * @param jclass
	 * @param ce the class entry for the jclass
	 * @param reflectCache <code>true</code> if this the reflection/introspection cache or <code>false</code> if this is the override cache.
	 * @return the loaded cache resource, or <code>null</code> if not there (for some reason) or an error trying to load it.
	 * 
	 * @since 1.1.0
	 */
	public Resource getCache(JavaClass jclass, ClassEntry ce, boolean reflectCache) {
		String className = jclass.getQualifiedNameForReflection();
		if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER)) {
			Logger logger = BeaninfoPlugin.getPlugin().getLogger();
			String type = reflectCache?"Class":"Overrides"; //$NON-NLS-1$ //$NON-NLS-2$
			logger.log("Loading cache for class "+className+" cache type="+type, Level.FINER); //$NON-NLS-1$ //$NON-NLS-2$
		}

		if (reflectCache) {
			boolean waitForJob = false;
			synchronized (ce) {
				if (ce.getPendingResource() != null) {
					// We have one pending. So wait until write cache job is done, and then load it in.
					// Note: Can't just copy the pending resource because it has references to JavaClasses
					// and these could be in a different project (since this could be a workspace wide class).
					// We would get the wrong java classes then when we apply it. 
					waitForJob = true;
					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
						BeaninfoPlugin.getPlugin().getLogger().log("Using pending class cache.", Level.FINER); //$NON-NLS-1$
				}
			}
			if (waitForJob)
				waitForCacheSaveJob();	

			try {
				return jclass.eResource().getResourceSet().getResource(
						URI.createFileURI(ce.getRootIndex().getCachePath().append(
								className + CLASS_CACHE_SUFFIX).toString()), true);
			} catch (Exception e) {
				// Something happened and couldn't load it.
				// TODO - need to remove the Level.INFO arg when the beaninfo cache is working dynamically
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.INFO);
				return null;
			}
		} else {
			boolean waitForJob = false;
			synchronized (ce) {
				if (ce.getPendingOverrideResource() != null) {
					// We have one pending. So wait until write cache job is done, and then load it in.
					// Note: Can't just copy the pending resource because it has references to JavaClasses
					// and these could be in a different project (since this could be a workspace wide class).
					// We would get the wrong java classes then when we apply it. 
					waitForJob = true;
					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
						BeaninfoPlugin.getPlugin().getLogger().log("Using pending override cache.", Level.FINER); //$NON-NLS-1$
				}
			}
			if (waitForJob)
				waitForCacheSaveJob();	

			try {
				return jclass.eResource().getResourceSet().getResource(
						URI.createFileURI(ce.getRootIndex().getCachePath().append(
								className + OVERRIDE_CACHE_SUFFIX).toString()), true);
			} catch (Exception e) {
				// Something happened and couldn't load it.
				// TODO - need to remove the Level.INFO arg when the beaninfo cache is working dynamically
				BeaninfoPlugin.getPlugin().getLogger().log(e, Level.INFO);
				return null;
			}
		}
	}

	private synchronized ClassEntry getClassEntry(RootIndex rootIndex, String className, boolean createEntry) {
		ClassEntry ce = (ClassEntry) rootIndex.classNameToClassEntry.get(className);
		if (createEntry && ce == null) {
			// Need to create one.
			ce = new ClassEntry(rootIndex, className);
			// Don't actually mark the rootIndex dirty until the cache for it is actually saved out.
		}
		return ce;
	}

	private static final String ROOT_PREFIX = "root"; //$NON-NLS-1$

	/*
	 * Get the root index for the appropriate cache for the given java class.
	 */
	private RootIndex getRootIndex(IType type) {
		IPackageFragmentRoot root = (IPackageFragmentRoot) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
		if (!root.isExternal()) {
			// So it is in a project. Get the project index.
			return getRootIndex(root, root.getJavaProject().getProject());
		} else {
			// It is an external jar (archive), so needs to come from main index, no project.
			return getRootIndex(root, null);
		}
	}

	/*
	 * Get the root index for the given root. A Project index if project is not null.
	 */
	private synchronized RootIndex getRootIndex(IPackageFragmentRoot root, IProject project) {
		Index index = project != null ? getProjectIndex(project) : getMainIndex();
		IPath rootPath = root.getPath();
		RootIndex rootIndex = (RootIndex) index.rootToRootIndex.get(rootPath);
		if (rootIndex == null) {
			// Need to do a new root path.
			String rootName = ROOT_PREFIX + (++index.highRootNumber);
			rootIndex = root.isArchive() ? createArchiveRootIndex(root, rootName, index) : new FolderRootIndex(rootName, index);
			index.rootToRootIndex.put(rootPath, rootIndex);
			// Don't set index dirty until we actually save a class cache file. Until then it only needs to be in memory.
		}
		rootIndex.setupIndex(project); // Set it up, or may already be set, so it will do nothing in that case.
		return rootIndex;
	}

	/*
	 * Create an archive root with the given root number and root.
	 */
	private RootIndex createArchiveRootIndex(IPackageFragmentRoot rootArchive, String rootName, Index index) {
		long modStamp = IResource.NULL_STAMP;
		if (rootArchive.isExternal()) {
			modStamp = rootArchive.getPath().toFile().lastModified();
		} else {
			try {
				modStamp = rootArchive.getUnderlyingResource().getModificationStamp();
			} catch (JavaModelException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e);
			}
		}
		return new ArchiveRootIndex(rootName, modStamp, index);
	}

	private static final String INDEXFILENAME = ".index"; //$NON-NLS-1$

	private static final String CACHEDIR = ".cache"; // Cache directory (so as not to conflict with any future BeanInfo Plugin specific data files. //$NON-NLS-1$

	/*
	 * Get the cache directory for the project (or if project is null, the main plugin cache directory).
	 */
	// TODO: make this one private
	public static IPath getCacheDir(IProject project) {
		if (project != null)
			return project.getWorkingLocation(BeaninfoPlugin.getPlugin().getBundle().getSymbolicName()).append(CACHEDIR);
		else
			return BeaninfoPlugin.getPlugin().getStateLocation().append(CACHEDIR);
	}

	/*
	 * Get the project index. Synchronized so that we can create it if necessary and not get race conditions.
	 */
	private synchronized Index getProjectIndex(IProject project) {
		Index index = (Index) PROJECT_INDEXES.get(project);
		if (index == null) {
			// Read the index in.
			File indexDirFile = getCacheDir(project).append(INDEXFILENAME).toFile();
			if (indexDirFile.canRead()) {
				ObjectInputStream ois = null;
				try {
					ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(indexDirFile)));
					index = (Index) ois.readObject();
				} catch (IOException e) {
					BeaninfoPlugin.getPlugin().getLogger().log(e);
				} catch (ClassNotFoundException e) {
					BeaninfoPlugin.getPlugin().getLogger().log(e);
				} finally {
					if (ois != null)
						try {
							ois.close();
						} catch (IOException e) {
							BeaninfoPlugin.getPlugin().getLogger().log(e);
						}
				}
			}

			if (index == null) {
				// Doesn't yet exist or it couldn't be read for some reason, or it was downlevel cache in which case we just throw it away and create
				// new).
				index = new Index();
				index.highRootNumber = 0;
				index.rootToRootIndex = new HashMap();
			}

			PROJECT_INDEXES.put(project, index); // We either created a new one, or we were able to load it. Put it into the map of projects.
		}
		return index;
	}

	/*
	 * Get the main index. Synchronized so that we can create it if necessary and not get race conditions.
	 */
	private synchronized Index getMainIndex() {
		if (MAIN_INDEX == null) {
			// Read the index in.
			File indexDirFile = getCacheDir(null).append(INDEXFILENAME).toFile();
			if (indexDirFile.canRead()) {
				ObjectInputStream ois = null;
				try {
					ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(indexDirFile)));
					MAIN_INDEX = (Index) ois.readObject();
				} catch (IOException e) {
					BeaninfoPlugin.getPlugin().getLogger().log(e);
				} catch (ClassNotFoundException e) {
					BeaninfoPlugin.getPlugin().getLogger().log(e);
				} finally {
					if (ois != null)
						try {
							ois.close();
						} catch (IOException e) {
							BeaninfoPlugin.getPlugin().getLogger().log(e);
						}
				}
			}

			if (MAIN_INDEX == null) {
				// Doesn't yet exist or it couldn't be read for some reason, or it was downlevel cache in which case we just throw it away and create
				// new).
				MAIN_INDEX = new Index();
				MAIN_INDEX.highRootNumber = 0;
				MAIN_INDEX.rootToRootIndex = new HashMap();
			}

		}
		return MAIN_INDEX;
	}

	// -------------- Save Participant code -----------------

	protected class SaveParticipant implements ISaveParticipant {

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
		 */
		public void doneSaving(ISaveContext context) {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
		 */
		public void prepareToSave(ISaveContext context) throws CoreException {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
		 */
		public void rollback(ISaveContext context) {
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
		 */
		public void saving(ISaveContext context) throws CoreException {
			boolean fullsave = false;
			switch (context.getKind()) {
				case ISaveContext.PROJECT_SAVE:
					IProject project = context.getProject();
					synchronized (BeanInfoCacheController.INSTANCE) {
						Index projectIndex = (Index) PROJECT_INDEXES.get(project);
						if (projectIndex != null && projectIndex.isDirty())
							if (cleanIndexDirectory(project, projectIndex))
								writeIndex(project, projectIndex);
							else {
								// It was empty, just get rid of it the index.
								PROJECT_INDEXES.remove(project);
							}
					}
					break;
				case ISaveContext.FULL_SAVE:
					fullsave = true;
					waitForCacheSaveJob();
				// Now flow into the snapshot save to complete the fullsave.
				case ISaveContext.SNAPSHOT:
					// For a snapshot, just the dirty indexes, no clean up. If fullsave, cleanup the indexes, but only save the dirty.
					synchronized (BeanInfoCacheController.INSTANCE) {
						try {
							if (MAIN_INDEX != null) {
								if (fullsave) {
									if (cleanIndexDirectory(null, MAIN_INDEX)) {
										if (MAIN_INDEX.isDirty())
											writeIndex(null, MAIN_INDEX);
									} else {
										// It was empty, just get rid of the index.
										MAIN_INDEX = null;
									}
								} else if (MAIN_INDEX.isDirty())
									writeIndex(null, MAIN_INDEX);
							}
							// Now do the project indexes.
							for (Iterator projectIndexEntryItr = PROJECT_INDEXES.entrySet().iterator(); projectIndexEntryItr.hasNext();) {
								Map.Entry entry = (Map.Entry) projectIndexEntryItr.next();
								project = (IProject) entry.getKey();
								Index index = (Index) entry.getValue();
								if (fullsave) {
									if (cleanIndexDirectory(project, index)) {
										if (index.isDirty())
											writeIndex(project, index);
									} else {
										// It was empty, just get rid of the index.
										projectIndexEntryItr.remove();
									}
								} else if (index.isDirty())
									writeIndex(project, index);
							}
						} catch (RuntimeException e) {
							e.printStackTrace();
							// TODO Need to fix the case whereas the cache has been removed
							// by Project-->Clean but the memory cache still thinks it exists.
							// This try/catch should be remove once that is fixed.
						}
					}
			}
		}

		/*
		 * Write an index. Project if not null indicates a project index.
		 */
		private void writeIndex(IProject project, Index index) {
			ObjectOutputStream oos = null;
			try {
				File indexDirFile = getCacheDir(project).append(INDEXFILENAME).toFile();
				oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(indexDirFile)));
				oos.writeObject(index);
				index.setDirty(false);
			} catch (IOException e) {
				BeaninfoPlugin.getPlugin().getLogger().log(e);
			} finally {
				if (oos != null)
					try {
						oos.close();
					} catch (IOException e) {
						BeaninfoPlugin.getPlugin().getLogger().log(e);
					}
			}
		}

		/*
		 * Clean the index directory of unused root directories. If after cleaning the index is empty, then it will delete the index file too. @return
		 * true if index not empty, false if index was empty and was erased too.
		 */
		private boolean cleanIndexDirectory(IProject project, Index index) {
			// clean out unused rootIndexes
			File indexDir = getCacheDir(project).toFile();
			// Create a set of all root names for quick look up.
			if (index.rootToRootIndex.isEmpty()) {
				// It is empty, clear everything, including index file.
				cleanDirectory(indexDir, false);
				return false;
			} else {
				// Need a set of the valid rootnames for quick lookup of names in the directory list.
				// And while accumulating this list, clean out the root indexes cache too (i.e. the class cache files).
				final Set validFiles = new HashSet(index.rootToRootIndex.size());
				validFiles.add(INDEXFILENAME);
				for (Iterator itr = index.rootToRootIndex.values().iterator(); itr.hasNext();) {
					RootIndex rootIndex = (RootIndex) itr.next();
					if (cleanClassCacheDirectory(rootIndex, project)) {
						// The class cache has been cleaned, and there are still some classes left, so keep the root index.
						validFiles.add(rootIndex.getRootName());
					} else {
						itr.remove(); // The root index is empty, so get rid of it. Since not a valid name, it will be deleted in next step.
						index.setDirty(true); // Also set it dirty in case it wasn't because we need to write out the container Index since it was
											  // changed.
					}
				}
				// Get list of files and delete those that are not a valid name (used root name, or index file)
				String[] fileNames = indexDir.list();
				for (int i = 0; i < fileNames.length; i++) {
					if (!validFiles.contains(fileNames[i])) {
						File file = new File(indexDir, fileNames[i]);
						if (file.isDirectory())
							cleanDirectory(file, true);
						else
							file.delete();
					}
				}
				return true;
			}
		}

		/*
		 * Clean out the class cache directory for the root index. Return true if cleaned good but not empty. Return false if the class cache
		 * directory is now empty. In this case we should actually get rid of the entire root index.
		 */
		private boolean cleanClassCacheDirectory(RootIndex rootIndex, IProject project) {
			if (rootIndex.classNameToClassEntry.isEmpty())
				return false; // There are no classes, so get rid the entire root index.
			else {
				final Set validFiles = rootIndex.classNameToClassEntry.keySet(); // The keys (classnames) are the filenames (without extension)
																					// that
				// should be kept.
				File indexDir = getCacheDir(project).append(rootIndex.getRootName()).toFile();
				// Get list of files that are not a valid name (used classname)
				String[] fileNames = indexDir.list();
				if (fileNames != null) {
					for (int i = 0; i < fileNames.length; i++) {
						String fileName = fileNames[i];
						if (fileName.endsWith(OVERRIDE_CACHE_SUFFIX)) {
							// Ends with out class cache extension, see if valid classname.
							String classname = fileName.substring(0, fileName.length() - OVERRIDE_CACHE_SUFFIX.length());
							ClassEntry ce = (ClassEntry) rootIndex.classNameToClassEntry.get(classname);
							if (ce != null && ce.overrideCacheExists())
								continue; // It is one of ours. Keep it.
						} else if (fileName.endsWith(CLASS_CACHE_SUFFIX)) {
							// Ends with out class cache extension, see if valid classname.
							if (validFiles.contains(fileName.substring(0, fileName.length() - CLASS_CACHE_SUFFIX.length()))) // Strip down to just
																																// class and see if
																																// one of ours.
								continue; // It is one of ours. Keep it.
						}
						// Not valid, get rid of it.
						File file = new File(indexDir, fileName);
						if (file.isDirectory())
							cleanDirectory(file, true);
						else
							file.delete();

					}
				}
				return true;
			}
		}

		private void cleanDirectory(File dir, boolean eraseDir) {
			File[] files = dir.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory())
					cleanDirectory(files[i], true);
				else
					files[i].delete();
			}
			if (eraseDir)
				dir.delete();
		}
	}

	//-------------- Save Class Cache Entry Job -------------------
	// This is write queue for class caches. It is a FIFO queue. It is sychronized so that adds/removes are controlled.
	// Entries are ClassEntry's. The class entry has the resource that needs to be written out. It will be set to null
	// by the job when it is written. The job will have a ClassEntry locked while it is retrieving and resetting the resource
	// field in the entry.
	//
	// The process is the new cache will lock, create resource, set resource into the CE and release lock. Then add the CE to the queue
	// and schedule the job (in case job is not running).
	//
	// The job will lock the CE, get resource from the CE, write it out, set it back to null, release the CE). If the resource is null,
	// then it was already processed (this could happen if the job didn't get a chance to save it before another entry was posted
	// and this is the second request and it was actually processed by the first request).
	// IE:
	// 1) resource created, queue entry added
	// 2) 2nd req, job not processed yet, resource recreated and put back into CE, new queue entry.
	// 3) job pulls from queue, locks ce, grabs resource, writes out the resource, sets back to null, release ce.
	// 4) job pulls from queue. This time the resoure is null so it skips it.
	//
	// Need to lock Ce during entire create and write because the resource set is not reentrant so can't be writing it while creating it.

	private List cacheWriteQueue = null;

	void waitForCacheSaveJob() {
		// For a full save we want to get the class cache files written too, so we need to manipulate the job to get it to finish ASAP.
		if (cacheWriteJob != null) {
			if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
				BeaninfoPlugin.getPlugin().getLogger().log("Forcing a cache save job to start early.", Level.FINER); //$NON-NLS-1$
			switch (cacheWriteJob.getState()) {
				case Job.SLEEPING:
					// It could be waiting a long time, so we need to wake it up at a high priority to get it running ASAP.
					cacheWriteJob.setPriority(Job.INTERACTIVE); // Need to get it going right away
					cacheWriteJob.wakeUp();
					// Now drop into the wait.
				default:
					// Now wait for it (if not running this will return right away).
					try {
						cacheWriteJob.join();
					} catch (InterruptedException e) {
					}
			}
		}
	}

	static final Map SAVE_CACHE_OPTIONS;
	static {
		SAVE_CACHE_OPTIONS = new HashMap(3);
		SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_SAVE_TYPE_INFORMATION, Boolean.TRUE);
		SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE, Boolean.TRUE);
        SAVE_CACHE_OPTIONS.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
	}

	protected Job cacheWriteJob = null;
	protected Adapter projectReleaseAdapter = new AdapterImpl() {
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#isAdapterForType(java.lang.Object)
		 */
		public boolean isAdapterForType(Object type) {
			return type == BeanInfoCacheController.this;	// We're making the BeanInfoCacheController.this be the adapter type.
		}
		
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification msg) {
			if (msg.getEventType() == ProjectResourceSet.SPECIAL_NOTIFICATION_TYPE && msg.getFeatureID(BeanInfoCacheController.class) == ProjectResourceSet.PROJECTRESOURCESET_ABOUT_TO_RELEASE_ID) {
				// This is an about to be closed. If we have an active write job, bring it up to top priority and wait for it to finish.
				// This will make sure any resources in the project are written. There may not be any waiting, but this is doing a close
				// project, which is slow already relatively speaking, that waiting for the cache write job to finish is not bad.
				waitForCacheSaveJob();
			}
		}
	};

	private void queueClassEntry(ClassEntry ce, ResourceSet rset) {
		if (cacheWriteQueue == null) {
			cacheWriteQueue = Collections.synchronizedList(new LinkedList());
			cacheWriteJob = new Job(BeaninfoCoreMessages.getString("BeanInfoCacheController.Job.WriteBeaninfoCache.Title")) { //$NON-NLS-1$

				protected IStatus run(IProgressMonitor monitor) {
					monitor.beginTask("", cacheWriteQueue.size() + 10); // This is actually can change during the run, so we add 10 for the heck of it. //$NON-NLS-1$
					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
						BeaninfoPlugin.getPlugin().getLogger().log("Starting write BeanInfo Cache files.", Level.FINER); //$NON-NLS-1$
					while (!monitor.isCanceled() && !cacheWriteQueue.isEmpty()) {
						ClassEntry ce = (ClassEntry) cacheWriteQueue.remove(0); // Get first one.
						synchronized (ce) {
							Resource cres = ce.getPendingResource();
							if (cres != null) {
								try {
									cres.save(SAVE_CACHE_OPTIONS);
								} catch (IOException e) {
									BeaninfoPlugin.getPlugin().getLogger().log(e);
								} finally {
									// Remove the resource from resource set, clear out the pending.
									cres.getResourceSet().getResources().remove(cres);
									ce.setPendingResource(null);
								}
							}
							cres = ce.getPendingOverrideResource();
							if (cres != null) {
								try {
									cres.save(SAVE_CACHE_OPTIONS);
								} catch (IOException e) {
									BeaninfoPlugin.getPlugin().getLogger().log(e);
								} finally {
									// Remove the resource from resource set, clear out the pending.
									cres.getResourceSet().getResources().remove(cres);
									ce.setPendingOverrideResource(null);
								}
							}
							
							monitor.worked(1);
						}
					}
					monitor.done();
					if (BeaninfoPlugin.getPlugin().getLogger().isLoggingLevel(Level.FINER))
						BeaninfoPlugin.getPlugin().getLogger().log("Finished write BeanInfo Cache files.", Level.FINER); //$NON-NLS-1$
					return Status.OK_STATUS;
				}
			};
			cacheWriteJob.setPriority(Job.SHORT);
			cacheWriteJob.setSystem(true);
		}
		if (rset != null && EcoreUtil.getExistingAdapter(rset, this) == null) {
			// If it is a project resource set, then add ourselves as listeners so we know when released.
			if (rset instanceof ProjectResourceSet)
				rset.eAdapters().add(projectReleaseAdapter);
		}
		cacheWriteQueue.add(ce);
		cacheWriteJob.schedule(60 * 1000L); // Put off for 1 minute to let other stuff go on. Not important that it happens immediately.
	}
}