[331547] Race condition on ResourceSet adapter list
diff --git a/plugins/org.eclipse.jem.util/META-INF/MANIFEST.MF b/plugins/org.eclipse.jem.util/META-INF/MANIFEST.MF
index 21b556a..67031dd 100644
--- a/plugins/org.eclipse.jem.util/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.jem.util/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jem.util; singleton:=true
-Bundle-Version: 2.1.2.qualifier
+Bundle-Version: 2.1.100.qualifier
 Bundle-Activator: org.eclipse.jem.util.plugin.JEMUtilPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.jem.util/jemutil/org/eclipse/jem/internal/util/emf/workbench/ProjectResourceSetImpl.java b/plugins/org.eclipse.jem.util/jemutil/org/eclipse/jem/internal/util/emf/workbench/ProjectResourceSetImpl.java
index 7b33466..c5fde83 100644
--- a/plugins/org.eclipse.jem.util/jemutil/org/eclipse/jem/internal/util/emf/workbench/ProjectResourceSetImpl.java
+++ b/plugins/org.eclipse.jem.util/jemutil/org/eclipse/jem/internal/util/emf/workbench/ProjectResourceSetImpl.java
@@ -8,10 +8,6 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-/*
- *  $$RCSfile: ProjectResourceSetImpl.java,v $$
- *  $$Revision: 1.34 $$  $$Date: 2010/08/11 21:47:03 $$ 
- */
 package org.eclipse.jem.internal.util.emf.workbench;
 
 import java.io.IOException;
@@ -22,8 +18,7 @@
 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.Adapter;
-import org.eclipse.emf.common.notify.Notification;
+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;
@@ -46,6 +41,247 @@
 		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> {
 
@@ -53,7 +289,7 @@
 		 * 
 		 */
 		private static final long serialVersionUID = 1L;
-		private final ILock lock = Job.getJobManager().newLock();
+		protected final ILock lock = Job.getJobManager().newLock();
 
 		public void copyInto(List list){
 			try {
@@ -351,6 +587,79 @@
 
 	}
 
+	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();
@@ -936,6 +1245,9 @@
 	}
 	
 	public EList<Resource> getResources() {
+		 return primGetResources();
+	}
+	private EList<Resource> primGetResources() {
 		 if (resources == null)
 		    {
 		      resources = new SynchronizedResourcesEList<Resource>();
@@ -946,18 +1258,9 @@
 	 * Creating a copy of the resources list
 	 * @return
 	 */
-	public List<Resource> getImmutableResources() {
-		 List <Resource> list = new ArrayList<Resource>();
-		 EList resources = getResources();
-		 if (resources instanceof SynchronizedResourcesEList)
-		 {
-			 ((SynchronizedResourcesEList)resources).copyInto(list);
-		 }
-		 else
-		 {
-			 list = Collections.synchronizedList(resources);
-		 }
-		 return list;
+	public EList<Resource> getImmutableResources() {
+		 EList<Resource> resources = primGetResources();
+		 return new ImmutableEList<Resource>(resources);
 	}
 	@Override
 	public void eNotify(Notification notification) {
@@ -973,4 +1276,14 @@
 	    }
 	  }
 
+	@Override
+	public EList eAdapters()
+	{
+		if (eAdapters == null)
+		{
+			eAdapters =  new ESynchronizedAdapterList(this);
+		}
+		return eAdapters;
+	}
+
 }