Bug 163357 [Viewers] NullPointerException on AbstractTreeViewer.remove(path, index)
I20061102-1715 It's possible to get an NPE when removing an element from a tree viewer. The remove API accepts a "parent path" and "child index". It is possible to specify an empty tree path for the parent to indicate the root element. However, the remove code eventually trys to find the widget associated with the "last segment" of the parent path. This results in null, and an NPE: Caused by: java.lang.NullPointerException at org.eclipse.jface.viewers.CustomHashtable.hashCode(CustomHashtable.java:265) at org.eclipse.jface.viewers.CustomHashtable.get(CustomHashtable.java:237) at org.eclipse.jface.viewers.StructuredViewer.findItems(StructuredViewer.java:769) at org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItem(AbstractTreeViewer.java:173) at org.eclipse.jface.viewers.AbstractTreeViewer.internalFindItems(AbstractTreeViewer.java:153) at org.eclipse.jface.viewers.TreeViewer$8.run(TreeViewer.java:1017) at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1326) at org.eclipse.jface.viewers.TreeViewer.remove(TreeViewer.java:1005) at org.eclipse.debug.internal.ui.viewers.model.ChildrenUpdate.performUpdate(ChildrenUpdate.java:62) at org.eclipse.debug.internal.ui.viewers.model.ViewerUpdateMonitor$1.runInUIThread(ViewerUpdateMonitor.java:43) at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:94) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:123) ... 20 more
bundles/org.eclipse.jface/src/org/eclipse/jface/viewers/TreeViewer.java
if (contentProviderIsLazy) {
			Object data = item.getData();
			int itemCount = 0;
			if (data != null) {
				
				itemCount = ((TreeItem) item).getItemCount();
			}
			virtualLazyUpdateHasChildren(item, itemCount);
		} else {
			super.updatePlus(item, element);
		}
	}
	/**
	 * Removes the element at the specified index of the parent.  The selection is updated if required.
	 * 
	 * @param parentOrTreePath the parent element, the input element, or a tree path to the parent element 
	 * @param index child index
	 * @since 3.3
	 */
	public void remove(final Object parentOrTreePath, final int index) {
		preservingSelection(new Runnable() {
			public void run() {
				if (parentOrTreePath.equals(getInput())) {
					Tree tree = (Tree) getControl();
					if (index < tree.getItemCount()) {
						TreeItem item = tree.getItem(index);
						if (item.getData() != null) {
							disassociate(item);
						}
						item.dispose();