Bug 229895 – [CheatSheet] NPE when opening a cheatsheet whose content file does not exist
diff --git a/org.eclipse.ua.tests/cheatsheet/org/eclipse/ua/tests/cheatsheet/parser/ParseFromString.java b/org.eclipse.ua.tests/cheatsheet/org/eclipse/ua/tests/cheatsheet/parser/ParseFromString.java
index 198c12c..aed62b4 100644
--- a/org.eclipse.ua.tests/cheatsheet/org/eclipse/ua/tests/cheatsheet/parser/ParseFromString.java
+++ b/org.eclipse.ua.tests/cheatsheet/org/eclipse/ua/tests/cheatsheet/parser/ParseFromString.java
@@ -63,7 +63,7 @@
 	public void testUrlParserInput() {
 		URL testURL = ResourceFinder.findFile(UserAssistanceTestPlugin.getDefault(), 
 			       "data/cheatsheet/valid/HelloWorld.xml");
-		ParserInput input = new ParserInput(testURL, UserAssistanceTestPlugin.getPluginId());
+		ParserInput input = new ParserInput(testURL, UserAssistanceTestPlugin.getPluginId(), null);
 		assertNull(input.getXml());
 		assertTrue(testURL.equals(input.getUrl()));
 	}
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CheatsheetTaskEditor.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CheatsheetTaskEditor.java
index 78de00d..b1c4409 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CheatsheetTaskEditor.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/composite/views/CheatsheetTaskEditor.java
@@ -63,10 +63,13 @@
 				if (id == null) { 
 					id = task.getId();
 				}
-				viewer.setInput(id, task.getName(), url, stateManager, false);				
+				if (url != null) {
+				    viewer.setInput(id, task.getName(), url, stateManager, false);	
+				} else {
+					errorBadUrl(path);
+				}
 			} catch (MalformedURLException e) {
-				String message = NLS.bind(Messages.ERROR_OPENING_FILE_IN_PARSER, (new Object[] {path}));			
-				viewer.showError(message);
+				errorBadUrl(path);
 			}
 		} else if (id != null){
 		    viewer.setInput(id, stateManager);
@@ -78,6 +81,11 @@
 		}
 		viewer.addListener(new TaskListener());
 	}
+
+	private void errorBadUrl(String path) {
+		String message = NLS.bind(Messages.ERROR_OPENING_FILE_IN_PARSER, (new Object[] {path}));			
+		viewer.showError(message);
+	}
 	
 	/*
 	 * Listener for the cheatsheet used by this class
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
index 350e91b..072d230 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/CheatSheetParser.java
@@ -866,7 +866,7 @@
 	}
 
 	public ICheatSheet parse(URL url, String pluginId, int cheatSheetKind) {
-		return parse(new ParserInput(url, pluginId), cheatSheetKind);
+		return parse(new ParserInput(url, pluginId, null), cheatSheetKind);
 	}
 	
 	public ICheatSheet parse(ParserInput input, int cheatSheetKind) {
@@ -876,6 +876,9 @@
 		if(input == null) {
 			return null;
 		}
+		if (input.getErrorMessage() != null) {
+			addStatus(IStatus.ERROR, input.getErrorMessage(), null);
+		}
 
 		InputStream is = null;
 		InputSource inputSource = null;
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ParserInput.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ParserInput.java
index 41f12e2..89c1b12 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ParserInput.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/data/ParserInput.java
@@ -23,6 +23,7 @@
 	private URL url;
 	private String xml;
 	private String pluginId;
+	private String errorMessage;
 	
 	public ParserInput() {
 		url = null;
@@ -32,6 +33,7 @@
 	public ParserInput(String xml, String basePath) {
 		this.xml = xml;
 		this.url = null;
+		this.errorMessage = null;
 		if (basePath != null) {
 			try {
 				this.url = new URL(basePath);
@@ -41,9 +43,10 @@
 		}
 	}
 	
-	public ParserInput(URL url, String pluginId) {
+	public ParserInput(URL url, String pluginId, String errorMessage) {
 		this.url = url;
 		this.xml = null;
+		this.errorMessage = errorMessage;
 		this.pluginId = pluginId;
 	}
 	
@@ -58,5 +61,9 @@
 	public String getPluginId() {
 		return pluginId;
 	}
+	
+	public String getErrorMessage() {
+		return errorMessage;
+	}
 
 }
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewer.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewer.java
index db8b42c..e615e43 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewer.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/CheatSheetViewer.java
@@ -135,6 +135,9 @@
 	}
 
 	public void advanceIntroItem() {
+		if (getViewItemAtIndex(0) == null) {
+			return;  // Cheat Sheet has no items or was not opened correctly
+		}
 		resetItemState();
 		/* LP-item event */
 		// fireManagerItemEvent(ICheatSheetItemEvent.ITEM_DEACTIVATED, introItem);
@@ -1146,6 +1149,7 @@
 		String contentXml = element.getContentXml();
 		URL contentURL = null;
 		restorePath = element.getRestorePath();
+		String errorMessage = null;
 		
 		if (contentXml != null) {
 			parserInput = new ParserInput(contentXml, element.getHref());
@@ -1163,6 +1167,9 @@
 			}
 		if (bundle != null) {
 			contentURL = FileLocator.find(bundle, new Path(element.getContentFile()), null);
+			if (contentURL == null && element.getContentFile() != null) {
+				errorMessage = NLS.bind(Messages.ERROR_OPENING_FILE_IN_PARSER, (new Object[] {element.getContentFile()}));
+			}
 		}
 
 		if (contentURL == null) {
@@ -1170,8 +1177,12 @@
 				contentURL = new URL(element.getHref());
 			} catch (MalformedURLException mue) {
 			}
+			if (contentURL == null && element.getHref() != null) {
+				errorMessage = NLS.bind(Messages.ERROR_OPENING_FILE_IN_PARSER, (new Object[] {element.getHref()}));
+			}
 		}
-		parserInput = new ParserInput(contentURL, bundle != null ? bundle.getSymbolicName() : null);
+	    String pluginId = bundle != null ? bundle.getSymbolicName() : null;
+		parserInput = new ParserInput(contentURL, pluginId, errorMessage);
 	}
 	
 	
diff --git a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ErrorPage.java b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ErrorPage.java
index 50cb839..4d691c9 100644
--- a/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ErrorPage.java
+++ b/org.eclipse.ui.cheatsheets/src/org/eclipse/ui/internal/cheatsheets/views/ErrorPage.java
@@ -106,7 +106,9 @@
 			Label imageLabel = toolkit.createLabel(form.getBody(), ""); //$NON-NLS-1$
 			imageLabel.setImage(getImage(nextStatus.getSeverity()));
 			Label messageLabel = toolkit.createLabel(form.getBody(), nextStatus.getMessage(), SWT.WRAP);
-			messageLabel.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB));		
+			TableWrapData layoutData = new TableWrapData(TableWrapData.FILL_GRAB);
+			layoutData.indent = 10;
+			messageLabel.setLayoutData(layoutData);		
 		}
 	}