Fix PR 19540 - XMLMemento.createReadRoot can return null
diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/XMLMemento.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/XMLMemento.java
index 0526628..9190370 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/XMLMemento.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/XMLMemento.java
@@ -22,6 +22,7 @@
 import org.apache.xml.serialize.OutputFormat;
 import org.apache.xml.serialize.Serializer;
 import org.apache.xml.serialize.SerializerFactory;
+import org.eclipse.ui.internal.WorkbenchMessages;
 import org.eclipse.ui.internal.WorkbenchPlugin;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -48,25 +49,44 @@
 
 	/**
 	 * Creates a <code>Document</code> from the <code>Reader</code>
-	 * and returns a root memento for reading the document.
+	 * and returns a memento on the first <code>Element</code> for reading
+	 * the document.
 	 * 
-	 * @param reader the reader used to create the memento's document
-	 * @return the root memento for reading the document
+	 * @param reader the <code>Reader</code> used to create the memento's document
+	 * @return a memento on the first <code>Element</code> for reading the document
+	 * @throws <code>WorkbenchException</code> if IO problems, invalid format, or no element.
 	 */
-	public static XMLMemento createReadRoot(Reader reader) {
-		Document document = null;
+	public static XMLMemento createReadRoot(Reader reader) throws WorkbenchException {
+		String messageKey = "XMLMemento.noElement"; //$NON-NLS-1$
+		Exception exception = null;
+		
 		try {
 			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 			DocumentBuilder parser = factory.newDocumentBuilder();
-			document = parser.parse(new InputSource(reader));
-			Node node = document.getFirstChild();
-			if (node instanceof Element)
-				return new XMLMemento(document, (Element) node);
+			Document document = parser.parse(new InputSource(reader));
+			NodeList list = document.getChildNodes();
+			for (int i = 0; i < list.getLength(); i++) {
+				Node node = list.item(i);
+				if (node instanceof Element)
+					return new XMLMemento(document, (Element) node);
+			}
 		} catch (ParserConfigurationException e) {
+			exception = e;
+			messageKey = "XMLMemento.parserConfigError"; //$NON-NLS-1$
 		} catch (IOException e) {
+			exception = e;
+			messageKey = "XMLMemento.ioError"; //$NON-NLS-1$
 		} catch (SAXException e) {
+			exception = e;
+			messageKey = "XMLMemento.formatError"; //$NON-NLS-1$
 		}
-		return null;
+		
+		String problemText = null;
+		if (exception != null)
+			problemText = exception.getMessage();
+		if (problemText == null || problemText.length() == 0)
+			problemText = WorkbenchMessages.getString(messageKey);
+		throw new WorkbenchException(problemText, exception);
 	}
 	
 	/**
diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/Perspective.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/Perspective.java
index 0c6cd65..ddfc965 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/Perspective.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/Perspective.java
@@ -572,6 +572,14 @@
 			WorkbenchMessages.getString("Perspective.problemRestoringTitle"),  //$NON-NLS-1$

 			WorkbenchMessages.getString("Perspective.errorReadingState")); //$NON-NLS-1$

 		return;

+	} catch (WorkbenchException e) {

+		persp.deleteCustomFile();

+		ErrorDialog.openError(

+			(Shell) null, 

+			WorkbenchMessages.getString("Perspective.problemRestoringTitle"),//$NON-NLS-1$

+			WorkbenchMessages.getString("Perspective.errorReadingState"), //$NON-NLS-1$

+			e.getStatus());

+		return;

 	}

 }

 /**

diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/WorkingSetManager.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/WorkingSetManager.java
index 6e57a06..d9edc89 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/WorkingSetManager.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/WorkingSetManager.java
@@ -9,6 +9,7 @@
 
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.util.*;
 import org.eclipse.swt.widgets.Display;
@@ -239,8 +240,16 @@
 				restoreMruList(memento);
 				reader.close();
 			} catch (IOException e) {
-				MessageDialog.openError((Shell) null, WorkbenchMessages.getString("ProblemRestoringWorkingSetState.title"), //$NON-NLS-1$
-				WorkbenchMessages.getString("ProblemRestoringWorkingSetState.message")); //$NON-NLS-1$
+				MessageDialog.openError(
+					(Shell) null,
+					WorkbenchMessages.getString("ProblemRestoringWorkingSetState.title"), //$NON-NLS-1$
+					WorkbenchMessages.getString("ProblemRestoringWorkingSetState.message")); //$NON-NLS-1$
+			} catch (WorkbenchException e) {
+				ErrorDialog.openError(
+					(Shell) null, 
+					WorkbenchMessages.getString("ProblemRestoringWorkingSetState.title"),//$NON-NLS-1$
+					WorkbenchMessages.getString("ProblemRestoringWorkingSetState.message"), //$NON-NLS-1$
+					e.getStatus());
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/messages.properties b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/messages.properties
index 6ed9d43..db31551 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/messages.properties
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/messages.properties
@@ -1035,6 +1035,11 @@
 PluginAction.disabledMessage = The chosen operation is not enabled.
 ActionDescriptor.invalidLabel = Unknown Label
 
+XMLMemento.parserConfigError = Internal XML parser configuration error.
+XMLMemento.ioError = Could not read content of XML file.
+XMLMemento.formatError = Could not parse content of XML file.
+XMLMemento.noElement = Could not find root element node of XML file.
+
 # --- Workbench Errors/Problems ---
 WorkbenchWindow.exceptionMessage = Abnormal Workbench Condition
 WorkbenchPage.AbnormalWorkbenchCondition = Abnormal Workbench Condition
@@ -1046,6 +1051,9 @@
 
 DecoratorManager.ErrorActivatingDecorator = An error has occurred activating decorator {0}.
 
+EditorRegistry.errorTitle = Load Problem
+EditorRegistry.errorMessage = Unable to load editor associations.
+
 SafeRunnable.errorMessage = An error has occurred. See error log for more details.
 ActionSetLabelProvider.Unknown = Unknown
 
diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/EditorRegistry.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/EditorRegistry.java
index 8fdae85..0fe19e4 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/EditorRegistry.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/EditorRegistry.java
@@ -10,6 +10,7 @@
 

 import org.eclipse.core.resources.IFile;

 import org.eclipse.core.runtime.*;

+import org.eclipse.jface.dialogs.ErrorDialog;

 import org.eclipse.jface.dialogs.MessageDialog;

 import org.eclipse.jface.preference.IPreferenceStore;

 import org.eclipse.jface.resource.ImageDescriptor;

@@ -523,6 +524,13 @@
 		}

 		//Ignore this as the workbench may not yet have saved any state

 		return false;

+	} catch (WorkbenchException e) {

+		ErrorDialog.openError(

+			(Shell) null, 

+			WorkbenchMessages.getString("EditorRegistry.errorTitle"),//$NON-NLS-1$

+			WorkbenchMessages.getString("EditorRegistry.errorMessage"), //$NON-NLS-1$

+			e.getStatus());

+		return false;

 	}

 

 	//Get the resource types

@@ -596,8 +604,15 @@
 		}

 		MessageDialog.openError(

 			(Shell) null,

-			"Error",//$NON-NLS-1$

-			"Unable to load resource associations.");//$NON-NLS-1$

+			WorkbenchMessages.getString("EditorRegistry.errorTitle"),//$NON-NLS-1$

+			WorkbenchMessages.getString("EditorRegistry.errorMessage")); //$NON-NLS-1$

+		return false;

+	} catch (WorkbenchException e) {

+		ErrorDialog.openError(

+			(Shell) null, 

+			WorkbenchMessages.getString("EditorRegistry.errorTitle"),//$NON-NLS-1$

+			WorkbenchMessages.getString("EditorRegistry.errorMessage"), //$NON-NLS-1$

+			e.getStatus());

 		return false;

 	}

 	return true;

diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
index b5bf8b2..f4389cc 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveDescriptor.java
@@ -46,7 +46,7 @@
  * Create a descriptor from a file.

  */

 public PerspectiveDescriptor(File file)

-	throws IOException

+	throws IOException, WorkbenchException

 {

 	super();

 	InputStream stream = null;

@@ -57,11 +57,11 @@
 		IMemento memento = XMLMemento.createReadRoot(reader);

 		restoreState(memento);

 		reader.close();

+		stream = null;

 		customFile = file;

-	} catch (IOException e) {

+	} finally {

 		if (stream != null)

 			stream.close();

-		throw e;

 	}

 }

 /**

diff --git a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java
index b97020e..ad9e562 100644
--- a/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java
+++ b/bundles/org.eclipse.ui/Eclipse UI/org/eclipse/ui/internal/registry/PerspectiveRegistry.java
@@ -149,6 +149,7 @@
 					if (oldPersp == null)

 						children.add(newPersp);

 				} catch (IOException e) {

+				} catch (WorkbenchException e) {

 				}

 			}

 		}