[339900] Closing JPA project results in a deadlock if diagram editor is open
diff --git a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/modelintegration/ui/JPADiagramEditorInput.java b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/modelintegration/ui/JPADiagramEditorInput.java
index 160da2e..c0942b0 100644
--- a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/modelintegration/ui/JPADiagramEditorInput.java
+++ b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/modelintegration/ui/JPADiagramEditorInput.java
@@ -15,12 +15,20 @@
  *******************************************************************************/
 package org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.ui;
 
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
 import org.eclipse.graphiti.mm.pictograms.Diagram;
 import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
+import org.eclipse.jpt.jpadiagrameditor.ui.internal.JPADiagramEditorPlugin;
+import org.eclipse.jpt.jpadiagrameditor.ui.internal.i18n.JPAEditorMessages;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.IJPADiagramEditorInput;
 
@@ -64,6 +72,49 @@
 		}
 		if (adapter.equals(TransactionalEditingDomain.class))
 			return ModelIntegrationUtil.getTransactionalEditingDomain(diagram);
+		if (adapter.equals(IFile.class)) {
+			Resource eResource = diagram.eResource();
+			URI eUri = eResource.getURI();
+			if (eUri.isPlatformResource()) {
+				String platformString = eUri.toPlatformString(true);
+				return ResourcesPlugin.getWorkspace().getRoot()
+						.findMember(platformString);
+			} else {
+				IProject project = ModelIntegrationUtil.getProjectByDiagram(
+						diagram).getProject();
+				return findXMLFile(project);
+			}
+		}
+		return null;
+	}
+	
+	private IFile findXMLFile(IProject project){
+		try {
+			IResource[] resources = project.members();
+			for (IResource res : resources) {
+				if (res instanceof IFolder) {
+					IFile existingXMLFile = ((IFolder) res)
+							.getFile(diagram.getName()
+									+ "." + ModelIntegrationUtil.DIAGRAM_XML_FILE_EXTENSION); //$NON-NLS-1$
+					if (existingXMLFile != null && existingXMLFile.exists()) {
+						return existingXMLFile;
+					}
+				}
+			}
+		} catch (CoreException e) {
+			JPADiagramEditorPlugin
+					.logError(
+							JPAEditorMessages.EntitiesCoordinatesXML_CannotObtainProjectErrorMSG,
+							e);
+		}
+		IFile existingXMLFile = project.getFile(ModelIntegrationUtil
+				.getDiagramsXMLFolderPath(project)
+				.append(diagram.getName())
+				.addFileExtension(
+						ModelIntegrationUtil.DIAGRAM_XML_FILE_EXTENSION));
+		if (existingXMLFile != null && existingXMLFile.exists()) {
+			return existingXMLFile;
+		}
 		return null;
 	}
 	
diff --git a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JPASolver.java b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JPASolver.java
index 70aa80b..baceaf2 100644
--- a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JPASolver.java
+++ b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JPASolver.java
@@ -113,6 +113,7 @@
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.RemoveAttributeFeature;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.RemoveRelationFeature;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.feature.UpdateAttributeFeature;
+import org.eclipse.jpt.jpadiagrameditor.ui.internal.modelintegration.util.ModelIntegrationUtil;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.JPAEditorDiagramTypeProvider;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.AbstractRelation;
@@ -173,7 +174,7 @@
 	
 	public JPASolver(IEclipseFacade eclipseFacade, IJPAEditorUtil util) {
 		this.eclipseFacade = eclipseFacade;
-		eclipseFacade.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD);
+		eclipseFacade.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.POST_BUILD);
 		keyToBO = new Hashtable<String, Object>();
 		projectToEntityListener = new WeakHashMap<JpaProject, WeakReference<CollectionChangeListener>>();
 		entityToPropListener = new WeakHashMap<JavaPersistentType, WeakReference<PropertyChangeListener>>();
@@ -221,7 +222,8 @@
 		if (updateEditor) {
 			eclipseFacade.getDisplay().asyncExec(new Runnable() {
 				public void run() {
-					featureProvider.getDiagramTypeProvider().getDiagramEditor().refresh();
+					if(featureProvider != null)
+						featureProvider.getDiagramTypeProvider().getDiagramEditor().refresh();
 				}
 			});
 
@@ -1393,19 +1395,17 @@
 	}
 	
 	private void closeDiagramEditorIfProjectIsDeleted(IResourceChangeEvent event) {
-		IResourceDelta changedDelta = event.getDelta();
-		IResourceDelta[] deltas = changedDelta.getAffectedChildren();
-		for (IResourceDelta delta : deltas) {
-			final IResource resource = delta.getResource();
-			if (!resource.exists()) {
+		final IResource resource = event.getResource();
+		if (resource != null && !resource.exists() || event.getType() == IResourceChangeEvent.PRE_CLOSE || (event.getType() == IResourceChangeEvent.PRE_DELETE)) {
 			    if (resource instanceof IProject) {
 					final IDiagramTypeProvider provider = featureProvider.getDiagramTypeProvider();
 					if (provider instanceof JPAEditorDiagramTypeProvider) {
 						final JPADiagramEditor diagramBySelectedProject = ((JPAEditorDiagramTypeProvider) provider).getDiagramEditor();
+						final Diagram diagram = ((JPAEditorDiagramTypeProvider)provider).getDiagram();
 						PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
 									public void run() {
 										IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-										if (diagramBySelectedProject.getPartName().equals(resource.getName())) {
+										if ((ModelIntegrationUtil.getProjectByDiagram(diagram).getProject()).equals((IProject)resource)) {
 											page.closeEditor(diagramBySelectedProject, false);
 										}
 									}
@@ -1414,15 +1414,17 @@
 
 				}
 			}
-		}
 	}
 	
 	private void unregisterDeltedEntity(IResourceChangeEvent event) {
+		if((event.getType() == IResourceChangeEvent.PRE_CLOSE) || (event.getType() == IResourceChangeEvent.PRE_DELETE))
+			return;
+		
 		IResourceDelta changedDelta = event.getDelta();
 		IResourceDelta[] deltas = changedDelta.getAffectedChildren();
 		for (IResourceDelta delta : deltas) {
 			final IResource resource = delta.getResource();
-			if (resource.exists()) {
+			if (resource != null && resource.exists()) {
 				if (resource instanceof IProject) {
 					IProject project = (IProject) resource;
 					for (IResourceDelta deltaResource : delta.getAffectedChildren()) {
diff --git a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JpaArtifactFactory.java b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JpaArtifactFactory.java
index c2b190dc..f9bec9b 100644
--- a/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JpaArtifactFactory.java
+++ b/jpa_diagram_editor/plugins/org.eclipse.jpt.jpadiagrameditor.ui/src/org/eclipse/jpt/jpadiagrameditor/ui/internal/util/JpaArtifactFactory.java
@@ -109,6 +109,7 @@
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.OneToOneBiDirRelation;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.OneToOneUniDirRelation;
 import org.eclipse.jpt.jpadiagrameditor.ui.internal.relations.UnidirectionalRelation;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IWorkbenchWindow;
 
@@ -442,16 +443,23 @@
 		fp.restoreEntity(jpt);
 	}    	
 	
-	public void forceSaveEntityClass(JavaPersistentType jpt,
-									 IJPAEditorFeatureProvider fp) {
-		ICompilationUnit cu = fp.getCompilationUnit(jpt);			
-		if (!cu.isWorkingCopy()) 
-			JPAEditorUtil.becomeWorkingCopy(cu);
-		try {
-			cu.commitWorkingCopy(true, new NullProgressMonitor());
-			cu.save(new NullProgressMonitor(), true);
-		} catch (JavaModelException e) {}
-	}    
+	public void forceSaveEntityClass(final JavaPersistentType jpt,
+			IJPAEditorFeatureProvider fp) {
+		final ICompilationUnit cu = fp.getCompilationUnit(jpt);
+		Display.getDefault().asyncExec(new Runnable() {
+			public void run() {
+				try {
+					if (!cu.isWorkingCopy())
+						JPAEditorUtil.becomeWorkingCopy(cu);
+					cu.commitWorkingCopy(true, new NullProgressMonitor());
+					cu.save(new NullProgressMonitor(), true);
+				} catch (JavaModelException e) {
+					if (cu.getResource().getProject().isAccessible())
+						JPADiagramEditorPlugin.logError("Cannot save entity '" + jpt.getName() + "'", e);	//$NON-NLS-1$		//$NON-NLS-2$		
+				}
+			}
+		});
+	}
 	
 	public boolean deleteEntityClass(JavaPersistentType jpt, 
 									 IJPAEditorFeatureProvider fp) {