/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.jem.internal.util.emf.workbench;

import java.io.IOException;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.notify.*;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.emf.ecore.resource.Resource.Factory;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.emf.ecore.xmi.XMLResource;

import org.eclipse.jem.util.emf.workbench.*;
import org.eclipse.jem.util.emf.workbench.nature.EMFNature;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;

public class ProjectResourceSetImpl extends ResourceSetImpl implements FlexibleProjectResourceSet {
	public static interface ModuleURI {
		public static final int SUB_PROTOCOL_INDX = 0;
		public static final int PROJECT_NAME_INDX = 1;
		public static final int MODULE_NAME_INDX = 2;
		public static final int CONTENT_TYPE_INDX = 3;
	}
	public class ImmutableEList<E extends Object & Resource> extends ResourcesEList<E> implements EList<E> {
		
		
		private SynchronizedResourcesEList delegate;

		public ImmutableEList(Collection<? extends E> collection) {

		    size = collection.size();

		    // Conditionally create the data.
		    //
		    if (size > 0)
		    { 
		      // Allow for a bit-shift of growth.
		      //
		      data = newData(size + size / 8 + 1); 
		      collection.toArray(data);
		    
		    }
			delegate = (SynchronizedResourcesEList)collection;
			
		}

		@Override
		public void setData(int size, Object[] data) {
			super.setData(size, data);
			delegate.lock.acquire();
			delegate.setData(size, data);
			delegate.lock.release();
		}

		@Override
		public E setUnique(int index, E object) {
			Object temp;
			super.setUnique(index, object);
			delegate.lock.acquire();
			temp = delegate.setUnique(index, object);
			delegate.lock.release();
			return (E) temp;
		}

		@Override
		public void addUnique(E object) {
			super.addUnique(object);
			delegate.lock.acquire();
			delegate.addUnique(object);
			delegate.lock.release();
		}

		@Override
		public void addUnique(int index, E object) {
			super.addUnique(index, object);
			delegate.lock.acquire();
			delegate.addUnique(index, object);
			delegate.lock.release();
		}

		@Override
		public boolean addAllUnique(Collection<? extends E> collection) {
			boolean temp;
			super.addAllUnique(collection);
			delegate.lock.acquire();
			temp = delegate.addAllUnique(collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean addAllUnique(int index, Collection<? extends E> collection) {
			boolean temp;
			super.addAllUnique(index, collection);
			delegate.lock.acquire();
			temp = delegate.addAllUnique(index, collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean addAllUnique(Object[] objects, int start, int end) {
			boolean temp;
			super.addAllUnique(objects, start, end);
			delegate.lock.acquire();
			temp = delegate.addAllUnique(objects, start, end);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean addAllUnique(int index, Object[] objects, int start, int end) {
			boolean temp;
			super.addAllUnique(index, objects, start, end);
			delegate.lock.acquire();
			temp = delegate.addAllUnique(index, objects, start, end);
			delegate.lock.release();
			return temp;
		}

		@Override
		public E remove(int index) {
			Object temp;
			super.remove(index);
			delegate.lock.acquire();
			temp = delegate.remove(index);
			delegate.lock.release();
			return (E)temp;
		}

		@Override
		public E move(int targetIndex, int sourceIndex) {
			Object temp;
			super.move(targetIndex, sourceIndex);
			delegate.lock.acquire();
			temp = delegate.move(targetIndex, sourceIndex);
			delegate.lock.release();
			return (E) temp;
		}

		@Override
		public E set(int index, E object) {
			Object temp;
			super.set(index, object);
			delegate.lock.acquire();
			temp = delegate.set(index, object);
			delegate.lock.release();
			return (E) temp;
		}

		@Override
		public boolean add(E object) {
			boolean temp;
			super.add(object);
			delegate.lock.acquire();
			temp = delegate.add(object);
			delegate.lock.release();
			return temp;
		}

		@Override
		public void add(int index, E object) {
			super.add(index, object);
			delegate.lock.acquire();
			delegate.add(index, object);
			delegate.lock.release();
		}

		@Override
		public boolean addAll(Collection<? extends E> collection) {
			boolean temp;
			super.addAll(collection);
			delegate.lock.acquire();
			temp = delegate.addAll(collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean addAll(int index, Collection<? extends E> collection) {
			boolean temp;
			super.addAll(index, collection);
			delegate.lock.acquire();
			temp = delegate.addAll(index, collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean remove(Object object) {
			boolean temp;
			super.remove(object);
			delegate.lock.acquire();
			temp = delegate.remove(object);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean removeAll(Collection<?> collection) {
			boolean temp;
			super.removeAll(collection);
			delegate.lock.acquire();
			temp = delegate.removeAll(collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public boolean retainAll(Collection<?> collection) {
			boolean temp;
			super.retainAll(collection);
			delegate.lock.acquire();
			temp = delegate.retainAll(collection);
			delegate.lock.release();
			return temp;
		}

		@Override
		public void move(int index, E object) {
			super.move(index, object);
			delegate.lock.acquire();
			delegate.move(index, object);
			delegate.lock.release();
		}

		private static final long serialVersionUID = 1L;

		@Override
		public NotificationChain basicAdd(E object, NotificationChain notifications) {
			NotificationChain temp = super.basicAdd(object, notifications);
			delegate.lock.acquire();
			delegate.basicAdd(object, notifications);
			delegate.lock.release();
			return temp;
			
		}

		@Override
		public NotificationChain basicRemove(Object object, NotificationChain notifications) {
			NotificationChain temp = super.basicRemove(object, notifications);
			delegate.lock.acquire();
			delegate.basicRemove(object, notifications);
			delegate.lock.release();
			return temp;
		}

		@Override
		public void clear() {
			super.clear();
			delegate.lock.acquire();
			delegate.clear();
			delegate.lock.release();
		}

		@Override
		public NotificationChain basicSet(int index, E object, NotificationChain notifications) {
			NotificationChain temp = super.basicSet(index, object, notifications);
			delegate.lock.acquire();
			delegate.basicSet(index, object, notifications);
			delegate.lock.release();
			return temp;
		}
	}
	
	public class SynchronizedResourcesEList<E extends Object & Resource> extends ResourcesEList<E> implements EList<E> {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		protected final ILock lock = Job.getJobManager().newLock();

		public void copyInto(List list){
			try {
				lock.acquire();
				list.addAll(this);
			} finally {
				lock.release();
			}
		}
		
		public void move(int newPosition, E object) {
			
			try {
				lock.acquire();
				super.move(newPosition, object);
			} finally {
				lock.release();
			}
		}

		public E move(int newPosition, int oldPosition) {

			try {
				lock.acquire();
				return super.move(newPosition, oldPosition);
			} finally {
				lock.release();
			}
		}

		public boolean add(E o) {
			
			try {
				lock.acquire();
				return super.add(o);
			} finally {
				lock.release();
			}
		}

		public void add(int index, E element) {
			
			try {
				lock.acquire();
				super.add(index, element);
			} finally {
				lock.release();
			}
		}

		public boolean addAll(Collection<? extends E> c) {
			
			try {
				lock.acquire();
				return super.addAll(c);
			} finally {
				lock.release();
			}
		}

		public boolean addAll(int index, Collection<? extends E> c) {
			
			try {
				lock.acquire();
				return super.addAll(index, c);
			} finally {
				lock.release();
			}
		}

		public void clear() {
			
			try {
				lock.acquire();
				super.clear();
			} finally {
				lock.release();
			}
		}

		public boolean contains(Object o) {
			
			try {
				lock.acquire();
				return super.contains(o);
			} finally {
				lock.release();
			}
		}

		public boolean containsAll(Collection<?> c) {
			
			try {
				lock.acquire();
				return super.containsAll(c);
			} finally {
				lock.release();
			}
		}

		public boolean equals(Object o) {
			
			try {
				lock.acquire();
				return super.equals(o);
			} finally {
				lock.release();
			}
		}

		public E get(int index) {
			
			try {
				lock.acquire();
				return super.get(index);
			} finally {
				lock.release();
			}
		}

		public int hashCode() {
			
			try {
				lock.acquire();
				return super.hashCode();
			} finally {
				lock.release();
			}
		}

		public int indexOf(Object o) {
			
			try {
				lock.acquire();
				return super.indexOf(o);
			} finally {
				lock.release();
			}
		}

		public boolean isEmpty() {
			
			try {
				lock.acquire();
				return super.isEmpty();
			} finally {
				lock.release();
			}
		}

		public Iterator<E> iterator() {
			
			try {
				lock.acquire();
				return super.iterator();
			} finally {
				lock.release();
			}
		}

		public int lastIndexOf(Object o) {
			
			try {
				lock.acquire();
				return super.lastIndexOf(o);
			} finally {
				lock.release();
			}
		}

		public ListIterator<E> listIterator() {
			
			try {
				lock.acquire();
				return super.listIterator();
			} finally {
				lock.release();
			}
		}

		public ListIterator<E> listIterator(int index) {
			
			try {
				lock.acquire();
				return super.listIterator(index);
			} finally {
				lock.release();
			}
		}

		public boolean remove(Object o) {
			
			try {
				lock.acquire();
				return super.remove(o);
			} finally {
				lock.release();
			}
		}

		public E remove(int index) {
			
			try {
				lock.acquire();
				return super.remove(index);
			} finally {
				lock.release();
			}
		}

		public boolean removeAll(Collection<?> c) {
			
			try {
				lock.acquire();
				return super.removeAll(c);
			} finally {
				lock.release();
			}
		}

		public boolean retainAll(Collection<?> c) {
			
			try {
				lock.acquire();
				return super.retainAll(c);
			} finally {
				lock.release();
			}
		}

		public E set(int index, E element) {
			
			try {
				lock.acquire();
				return super.set(index, element);
			} finally {
				lock.release();
			}
		}

		public int size() {
			
			try {
				lock.acquire();
				return super.size();
			} finally {
				lock.release();
			}
		}

		public List<E> subList(int fromIndex, int toIndex) {
			
			try {
				lock.acquire();
				return super.subList(fromIndex, toIndex);
			} finally {
				lock.release();
			}
		}

		public Object[] toArray() {
			
			try {
				lock.acquire();
				return super.toArray();
			} finally {
				lock.release();
			}
		}

		public <T> T[] toArray(T[] a) {
			
			try {
				lock.acquire();
				return super.toArray(a);
			} finally {
				lock.release();
			}
		}

		// release lock during notifications
		protected void dispatchNotification(Notification notification) {

			int lockDepth;
			lockDepth = lock.getDepth();
			try {
				for(int i=0; i<lockDepth; i++)
                    lock.release();
				super.dispatchNotification(notification);
			} finally {
				for(int i=0; i<lockDepth; i++)
                    lock.acquire();  // Re-acquire lock after notify
			}
		}

	}

	public static class ESynchronizedAdapterList extends EAdapterList
	{

/**
 * 
 */
		private static final long serialVersionUID = 7855438339187540718L;

		public ESynchronizedAdapterList(Notifier notifier) {
			super(notifier);
		}

		@Override
		public synchronized boolean add(Object object)
		{
			return super.add(object);
		}

		@Override
		public synchronized void add(int index, Object object)
		{
			super.add(index, object);
		}

		@Override
		public synchronized boolean addAll(Collection collection)
		{
			return super.addAll(collection);
		}

		@Override
		public synchronized boolean remove(Object object)
		{
			return super.remove(object);
		}

		@Override
		public synchronized Object remove(int index)
		{
			return super.remove(index);
		}

		@Override
		public synchronized boolean removeAll(Collection collection)
		{
			return super.removeAll(collection);
		}

		@Override
		public synchronized void clear()
		{
			super.clear();
		}

		@Override
		public synchronized Object set(int index, Object object)
		{
			return super.set(index, object);
		}

		@Override
		public synchronized void move(int newPosition, Object object)
		{
			super.move(newPosition, object);
		}

		@Override
		public synchronized Object move(int newPosition, int oldPosition)
		{
			return super.move(newPosition, oldPosition);
		}
	}

	private boolean isReleasing = false;
	private IProject project;
	protected List resourceHandlers = new ArrayList();
	private Object resourcesLock = new Object();
	protected ResourceSetWorkbenchSynchronizer synchronizer;
	protected ProjectResourceSetImpl() {
		setURIResourceMap(new HashMap(10));	// Tell it to cache uri->resource access.
		getLoadOptions().put(XMLResource.OPTION_USE_PARSER_POOL, EMFNature.SHARED_PARSER_POOL);
	}
	public ProjectResourceSetImpl(IProject aProject) {
		this();
		setProject(aProject);
		initializeSharedCacheListener();
	}
	protected void initializeSharedCacheListener() {
		JEMUtilPlugin.getSharedCache().beginListening(this);
	}
	protected boolean isReleasing() {
		return isReleasing;
	}
	/**
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#delegatedGetResource(URI, boolean)
	 */
	protected Resource delegatedGetResource(URI uri, boolean loadOnDemand) {
		Resource res = super.delegatedGetResource(uri, loadOnDemand);
		if (res == null)
			res = getResourceFromHandlers(uri);
		return res;
	}

	public Resource createResource(URI uri, String contentType) {
		if (isReleasing) return null;
		//Check the map first when creating the resource and do not
		//normalize if a value is found.
		boolean isMapped = detectURIMapping(uri);
		String contentTypeName = getContentTypeName(uri);
		boolean hasContentType = (contentTypeName != null);
		URI converted = uri;
		if (!isMapped)
			converted = getURIConverter().normalize(uri);
		else if (hasContentType)
			converted = getURIConverter().normalize(uri);
		
		if (!hasContentType) {// Check if actual project file exists, and can determine contenttype
			IContentDescription description = null;
			IFile file = WorkbenchResourceHelperBase.getIFile(uri);
			if (file != null && file.exists()) {
				try {
					description = file.getContentDescription();
					if (description != null)
						contentTypeName = description.getContentType().getId();
				} catch (CoreException e) {
					JEMUtilPlugin.getLogger().logError(e);
				}
			} else {// Now check if uri contains project, then add if needed
				URIConverter converter = getURIConverter();
				URI convertedUri = converter.normalize(uri);
				if (!uri.equals(convertedUri)) {
					file = WorkbenchResourceHelperBase.getIFile(convertedUri);
					if (file != null && file.exists()) {
						try {
							description = file.getContentDescription();
							if (description != null)
								contentTypeName = description.getContentType().getId();
						} catch (CoreException e) {
							JEMUtilPlugin.getLogger().logError(e);
						}
					}
				}
			}
		}
		if(contentTypeName == null)
			contentTypeName = contentType;
		
		
		Resource result = createResourceFromHandlers(converted);
		if (result == null) {
			Resource.Factory resourceFactory = (contentTypeName == null) ? 
					getResourceFactoryRegistry().getFactory(uri):
					getResourceFactoryRegistry().getFactory(uri,contentTypeName);
						
		    if (resourceFactory != null)
		    {//We got the right factory, now use the right URI
		      result = resourceFactory.createResource(converted);
		      getResources().add(result);
		    }
		}
			
		
		return result;
	}

	public Resource createResource(URI uri) {
		return createResource(uri, ContentHandler.UNSPECIFIED_CONTENT_TYPE);
	}

	private boolean detectURIMapping(URI uri) {
		if (uri == null) return false;
		return !(((URIConverterImpl.URIMap)getURIConverter().getURIMap()).getURI(uri).equals(uri));
	}
	/**
	 * Return the IFile for the <code>uri</code> within the Workspace. This URI is assumed to be
	 * absolute in the following format: platform:/resource/....
	 */
	private IFile getPlatformFile(URI uri) {
		if (WorkbenchResourceHelperBase.isPlatformResourceURI(uri)) {
			String fileString = URI.decode(uri.path());
			fileString = fileString.substring(JEMUtilPlugin.PLATFORM_RESOURCE.length() + 1);
			return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fileString));
		}
		return null;
	}
	public Resource createResource(URI uri, Resource.Factory resourceFactory) {
		if (isReleasing) return null;
		//Check the map first when creating the resource and do not
		//normalize if a value is found.
		boolean isMapped = detectURIMapping(uri);
		boolean hasContentType = (getContentTypeName(uri) != null);
		URI converted = uri;
		if (!isMapped)
			converted = getURIConverter().normalize(uri);
		else if (hasContentType)
			converted = getURIConverter().normalize(uri);
		Resource result = createResourceFromHandlers(converted);
		if (result == null) {

		    if (resourceFactory != null)
		    {
		      result = resourceFactory.createResource(converted);
		      getResources().add(result);
		      synchronized (resourcesLock) {
		          getURIResourceMap().put(uri, result);
		      }
		      return result;
		    }
		    else
		    {
		      return null;
		    }
		  
		}
		return result;
	}
	/**
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#demandLoad(Resource)
	 */
	protected void demandLoad(Resource resource) throws IOException {
		if (!isReleasing)
			super.demandLoad(resource);
	}
	
	/**
	 * See if any resource handlers from the WorkbenchContext
	 * decide to create the Resource in another manner.
	 */
	protected Resource createResourceFromHandlers(URI uri) {
		Resource resource = null;
		ResourceHandler handler = null;
		for (int i = 0; i < resourceHandlers.size(); i++) {
			handler = (ResourceHandler) resourceHandlers.get(i);
			resource = handler.createResource(this, uri);
			if (resource != null)
				return resource;
		}
		return null;
	}
	/**
	 * See if any resource handlers from the WorkbenchContext
	 * can return a Resource from a <code>uri</code>.
	 */
	protected Resource getResourceFromHandlers(URI uri) {
		if (isReleasing) return null;
		for (int i = 0; i < resourceHandlers.size(); i++) {
			Resource resource = ((ResourceHandler) resourceHandlers.get(i)).getResource(this, uri);
			if (resource != null)
				return resource;
		}
		return null;
	}
	
	public void release() {
		// Send out notification of release.
		if (eNotificationRequired()) {
			eNotify(new NotificationImpl(SPECIAL_NOTIFICATION_TYPE, null, null, Notification.NO_INDEX, false) {
				/* (non-Javadoc)
				 * @see org.eclipse.emf.common.notify.impl.NotificationImpl#getFeatureID(java.lang.Class)
				 */
				public int getFeatureID(Class expectedClass) {
					return PROJECTRESOURCESET_ABOUT_TO_RELEASE_ID;
				}
				
				/* (non-Javadoc)
				 * @see org.eclipse.emf.common.notify.impl.NotificationImpl#getNotifier()
				 */
				public Object getNotifier() {
					return ProjectResourceSetImpl.this;
				}
			});
		}
		setIsReleasing(true);
		if (synchronizer != null)
			synchronizer.dispose();
		synchronizer = null;
		removeAndUnloadAllResources();
		resourceHandlers = null;
		eAdapters().clear();
		setProject(null);
		JEMUtilPlugin.getSharedCache().stopListening(this);
	}
	protected void removeAndUnloadAllResources() {
		boolean caughtException = false;
		List list = null;
		synchronized (resourcesLock) {
			if (getResources().isEmpty()) return;
			list = new ArrayList(getResources());	
			getResources().clear();
		}
		Resource res;
		int size = list.size();
		for (int i = 0; i < size; i++) {
			res = (Resource) list.get(i);
			try {
				res.unload();
			} catch (RuntimeException ex) {
				Logger.getLogger().logError(ex);
				caughtException = true;
			}
		}
		if (caughtException)
			throw new RuntimeException("Exception(s) unloading resources - check log files"); //$NON-NLS-1$
	}
	protected void setIsReleasing(boolean aBoolean) {
		isReleasing = aBoolean;
	}
	/**
	 * Gets the project.
	 * @return Returns a IProject
	 */
	public IProject getProject() {
		return project;
	}
	/**
	 * Sets the project.
	 * @param project The project to set
	 */
	protected void setProject(IProject project) {
		this.project = project;
	}
	/*
	 * Javadoc copied from interface.
	 */
	public EObject getEObject(URI uri, boolean loadOnDemand) {
		if (isReleasing) return null;
		Resource resource = getResource(uri.trimFragment(), loadOnDemand);
		EObject result = null;
		if (resource != null && resource.isLoaded())
			result = resource.getEObject(uri.fragment());
		if (result == null)
			result = getEObjectFromHandlers(uri, loadOnDemand);
		return result;
	}
	/**
	 * See if any resource handlers from the WorkbenchContext
	 * can return a EObject from a <code>uri</code> after
	 * failing to find it using the normal mechanisms.
	 */
	protected EObject getEObjectFromHandlers(URI uri, boolean loadOnDemand) {
		EObject obj = null;
		ResourceHandler handler = null;
		for (int i = 0; i < resourceHandlers.size(); i++) {
			handler = (ResourceHandler) resourceHandlers.get(i);
			obj = handler.getEObjectFailed(this, uri, loadOnDemand);
			if (obj != null)
				return obj;
		}
		return null;
	}
	
	public boolean add(ResourceHandler resourceHandler) {
		return resourceHandlers.add(resourceHandler);
	}
	public void addFirst(ResourceHandler resourceHandler) {
		resourceHandlers.add(0, resourceHandler);
	}
	public boolean remove(ResourceHandler resourceHandler) {
		return resourceHandlers.remove(resourceHandler);
	}
	/**
	 * Returns the synchronizer.
	 * @return ResourceSetWorkbenchSynchronizer
	 */
	public ResourceSetWorkbenchSynchronizer getSynchronizer() {
		return synchronizer;
	}
	/**
	 * Sets the synchronizer.
	 * @param synchronizer The synchronizer to set
	 */
	public void setSynchronizer(ResourceSetWorkbenchSynchronizer synchronizer) {
		this.synchronizer = synchronizer;
	}
	/**
	 * @see org.eclipse.emf.ecore.resource.ResourceSet#setResourceFactoryRegistry(Resource.Factory.Registry)
	 */
	public void setResourceFactoryRegistry(Resource.Factory.Registry factoryReg) {
		if (resourceFactoryRegistry != null && factoryReg != null) {
			preserveEntries(factoryReg.getExtensionToFactoryMap(), resourceFactoryRegistry.getExtensionToFactoryMap());
			preserveEntries(factoryReg.getProtocolToFactoryMap(), resourceFactoryRegistry.getProtocolToFactoryMap());
			preserveEntries(factoryReg.getContentTypeToFactoryMap(), resourceFactoryRegistry.getContentTypeToFactoryMap());
		}
		super.setResourceFactoryRegistry(factoryReg);
	}
	/*
	 * Preserve the entries from map2 in map1 if no collision.
	 */
	protected void preserveEntries(Map map1, Map map2) {
		if (map2.isEmpty())
			return;
		Iterator it = map2.entrySet().iterator();
		Map.Entry entry;
		while (it.hasNext()) {
			entry = (Map.Entry) it.next();
			if (!map1.containsKey(entry.getKey()))
				map1.put(entry.getKey(), entry.getValue());
		}
	}
	/*
	 * Javadoc copied from interface.
	 */
	public Resource getResource(URI uri, boolean loadOnDemand) {
		if (isReleasing) return null;

	    Map<URI, Resource> map = getURIResourceMap();
	    if (map != null)
	    {
	      Resource resource = map.get(uri);
	      if (resource != null)
	      {
	        if (loadOnDemand && !resource.isLoaded())
	        {
	          demandLoadHelper(resource);
	        }        
	        return resource;
	      }
	    }
	    
	    URIConverter theURIConverter = getURIConverter();
	    URI normalizedURI = theURIConverter.normalize(uri);
	    List resourcesToRemove = new ArrayList();
	    synchronized (resourcesLock) {
	    	List<Resource> c = getImmutableResources();
	        
	        synchronized(c) {
				for (Resource resource : c) {
					if (theURIConverter.normalize(resource.getURI()).equals(normalizedURI)) {
	
						if (getContentTypeName(uri) == null) { // loading from legacy archive api or non-typed resource
							if (loadOnDemand && !resource.isLoaded()) {
								demandLoadHelper(resource);
							}
	
							if (map != null) {
								map.put(uri, resource);
							}
							return resource;
						} else {
							Resource loadedRes = loadWithContentType(resource, uri, map, loadOnDemand, resourcesToRemove);
							if (loadedRes != null)
								return loadedRes;
						}
					}
				}
	        }
		}
	    synchronized (resourcesLock) {
	    // Cleanup invalid resources
	    	getResources().removeAll(resourcesToRemove);
	    }
	    Resource delegatedResource = delegatedGetResource(uri, loadOnDemand);
	    if (delegatedResource != null)
	    {
	      if (map != null)
	      {
	        map.put(uri, delegatedResource);
	      }
	      return delegatedResource;
	    }

	    if (loadOnDemand)
	    {
	      Resource resource = demandCreateResource(uri);
	      if (resource == null)
	      {
	        throw new RuntimeException("Cannot create a resource for '" + uri + "'; a registered resource factory is needed");
	      }
	      
	      if (map != null)
	      {
	        map.put(uri, resource);
	      }  

	      demandLoadHelper(resource);

	          
	      return resource;
	    }

	    return null;
	  
	}
	private Resource loadWithContentType(Resource resource, URI uri, Map<URI, Resource> map, boolean loadOnDemand, List resourcesToRemove) {
		// content type is known
		boolean resourceExists = false;
		IFile file = getPlatformFile(resource);
		if (file != null)
			resourceExists = file.exists();
		String resourceContentTypeID = getContentTypeID(resource);
		String uriContentTypeID = getContentTypeName(uri);
		String existingMapKeyType = (findKey(resource) != null) ? getContentTypeName(findKey(resource)) : null;
		if((!map.containsValue(resource) || ((map.get(uri) != null) && map.get(uri).equals(resource))) // existing resource  with alternate mapping doesn't exist in map
			||  ((resourceContentTypeID != null && resourceContentTypeID.equals(uriContentTypeID)))) {
				if (loadOnDemand && !resource.isLoaded()) {
					demandLoadHelper(resource);
				} // if embedded uri content type is different than resource content type, continue searching
				if (resourceContentTypeID != null
						&& uriContentTypeID != null) {
					if ((resourceContentTypeID.equals(uriContentTypeID)) && existingMapKeyType == null) return null;
					if ((!resourceContentTypeID.equals(uriContentTypeID)) || (existingMapKeyType != null && !existingMapKeyType
							.equals(uriContentTypeID)))
						return null;
					else if (existingMapKeyType == null && !resourceExists) {
						resourcesToRemove.add(resource);
						return null;
					}
				} else if (uriContentTypeID != null && resourceContentTypeID == null && !resourceExists) {
					resourcesToRemove.add(resource);
					return null;
				}		
				if (map != null && (map.get(uri) == null)) {
					map.put(uri, resource);
				}
				return resource;
			}
		return null;
	}
	private IFile getPlatformFile(Resource res) {
		IFile file = null;
		file = getPlatformFile(res.getURI());
		if (file == null) {
			if (res.getResourceSet() != null) {
				URIConverter converter = res.getResourceSet().getURIConverter();
				URI convertedUri = converter.normalize(res.getURI());
				if (!res.getURI().equals(convertedUri))
					file = getPlatformFile(convertedUri);
			}
		}
		return file;
	}
	
	private String getContentTypeID(Resource resource) {
		IFile file = getPlatformFile(resource);
		IContentDescription desc = null;
		try {
			desc = file.getContentDescription();
		} catch (CoreException e) {
		}
		if (desc != null && desc.getContentType() != null)
			return desc.getContentType().getId();
		return null;
	}
	
	private URI findKey(Resource resource) {
		Map aMap = getURIResourceMap();
		Set keys = aMap.keySet();
		for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
			URI name = (URI) iterator.next();
			if (aMap.get(name).equals(resource))
				return name;
		}
		return null;
	}
	protected static String getContentTypeName(URI uri) {
		
		if (WorkbenchResourceHelperBase.isPlatformResourceURI(uri) || !isValidFullyQualifiedModuleURI(uri))
			return null;
		String contentTypeIdentifier = (uri.segmentCount() > 3 ? uri.segment(ModuleURI.CONTENT_TYPE_INDX) : null);
		if (contentTypeIdentifier != null && Platform.getContentTypeManager().getContentType(uri.segment(ModuleURI.CONTENT_TYPE_INDX)) != null)
			return contentTypeIdentifier;
		else
			return null;
	}
	public static boolean isValidFullyQualifiedModuleURI(URI aModuleURI) {
		if (aModuleURI.segmentCount() < 3) {
			return false;
		}
		return true;
	}
	/*
	 * Javadoc copied from interface.
	 */
	public Resource getResource(URI uri, boolean loadOnDemand, Resource.Factory resourceFactory) {
		if (isReleasing) return null;
		

	    Map<URI, Resource> map = getURIResourceMap();
	    if (map != null)
	    {
	      Resource resource = map.get(uri);
	      if (resource != null)
	      {
	        if (loadOnDemand && !resource.isLoaded())
	        {
	          demandLoadHelper(resource);
	        }        
	        return resource;
	      }
	    }
	    
	    URIConverter theURIConverter = getURIConverter();
	    URI normalizedURI = theURIConverter.normalize(uri);
	    synchronized (resourcesLock) {
	    	List<Resource> c = getImmutableResources();
	        
	        synchronized(c) {
	        	
				for (Resource resource : c) {
					if (theURIConverter.normalize(resource.getURI()).equals(normalizedURI)) {
						if (loadOnDemand && !resource.isLoaded()) {
							demandLoadHelper(resource);
						}
	
						if (map != null) {
							map.put(uri, resource);
						}
						return resource;
					}
				}
	        }
		}
	    
	    Resource delegatedResource = delegatedGetResource(uri, loadOnDemand);
	    if (delegatedResource != null)
	    {
	      if (map != null)
	      {
	        map.put(uri, delegatedResource);
	      }
	      return delegatedResource;
	    }

	    if (loadOnDemand)
	    {
	      Resource resource = demandCreateResource(uri,resourceFactory);
	      if (resource == null)
	      {
	        throw new RuntimeException("Cannot create a resource for '" + uri + "'; a registered resource factory is needed");
	      }

	      demandLoadHelper(resource);

	      if (map != null)
	      {
	        map.put(uri, resource);
	      }      
	      return resource;
	    }

	    return null;
	  
	}

	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.util.emf.workbench.ProjectResourceSet#resetNormalizedURICache()
	 */
	public void resetNormalizedURICache() {
		if (getURIResourceMap() != null)
			getURIResourceMap().clear();
	}
	
	protected Resource demandCreateResource(URI uri, Factory resourceFactory) {
		return createResource(uri,resourceFactory);
	}
	
	public EList<Resource> getResources() {
		 return primGetResources();
	}
	private EList<Resource> primGetResources() {
		 if (resources == null)
		    {
		      resources = new SynchronizedResourcesEList<Resource>();
		    }
		    return resources;
	}
	/**
	 * Creating a copy of the resources list
	 * @return
	 */
	public EList<Resource> getImmutableResources() {
		 EList<Resource> resources = primGetResources();
		 return new ImmutableEList<Resource>(resources);
	}
	@Override
	public void eNotify(Notification notification) {
	    Adapter[] eAdapters = eBasicAdapterArray();
	    if (eAdapters != null && eDeliver())
	    {
	      for (int i = 0, size = eAdapters.length; i < size; ++i)
	      {
	      	Adapter temp;
	    	  if ((temp = eAdapters[i]) != null)
	    		  temp.notifyChanged(notification);
	      }
	    }
	  }

	@Override
	public EList eAdapters()
	{
		if (eAdapters == null)
		{
			eAdapters =  new ESynchronizedAdapterList(this);
		}
		return eAdapters;
	}

}
