[SourceEditor] Revise editor outlines
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementInfoController.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementInfoController.java
index eceea03..415ef96 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementInfoController.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ElementInfoController.java
@@ -25,6 +25,7 @@
 import org.eclipse.statet.jcommons.collections.ImCollections;
 import org.eclipse.statet.jcommons.collections.ImIdentityList;
 import org.eclipse.statet.jcommons.lang.Disposable;
+import org.eclipse.statet.jcommons.lang.Nullable;
 
 import org.eclipse.statet.ltk.ast.core.AstInfo;
 import org.eclipse.statet.ltk.core.WorkingContext;
@@ -38,7 +39,7 @@
 /**
  * Controller implementation for input of a part and its model updates.
  */
-public class ElementInfoController implements IModelElementInputProvider, Disposable {
+public class ElementInfoController implements ModelElementInputProvider, Disposable {
 	
 	private static int NEWINPUT_DELAY= 100;
 	
@@ -47,8 +48,8 @@
 	private final WorkingContext modelContext;
 	private final ElementChangedListener elementChangeListener;
 	
-	private final CopyOnWriteIdentityListSet<IModelElementInputListener> listenerList= new CopyOnWriteIdentityListSet<>();
-	private final CopyOnWriteIdentityListSet<IModelElementInputListener> newListenerList= new CopyOnWriteIdentityListSet<>();
+	private final CopyOnWriteIdentityListSet<ModelElementInputListener> listenerList= new CopyOnWriteIdentityListSet<>();
+	private final CopyOnWriteIdentityListSet<ModelElementInputListener> newListenerList= new CopyOnWriteIdentityListSet<>();
 	
 	private final Object inputLock= new Object();
 	private volatile SourceUnit input;
@@ -78,7 +79,7 @@
 		@Override
 		protected IStatus run(final IProgressMonitor monitor) {
 			SourceUnit input;
-			ImIdentityList<IModelElementInputListener> listeners;
+			ImIdentityList<ModelElementInputListener> listeners;
 			synchronized (ElementInfoController.this.inputLock) {
 				if (monitor.isCanceled()
 						|| (ElementInfoController.this.input == null && ElementInfoController.this.newInput == null)) {
@@ -120,7 +121,7 @@
 			@Override
 			public void elementChanged(final ElementChangedEvent event) {
 				SourceUnit input;
-				ImIdentityList<IModelElementInputListener> listeners;
+				ImIdentityList<ModelElementInputListener> listeners;
 				synchronized (ElementInfoController.this.inputLock) {
 					if (ElementInfoController.this.newInput != null && ElementInfoController.this.newInput.equals(event.delta.getModelElement())) {
 						if (ElementInfoController.this.newInputJob.getState() != Job.WAITING) {
@@ -170,28 +171,30 @@
 		this.newInputJob.schedule(NEWINPUT_DELAY);
 	}
 	
-	private ImIdentityList<IModelElementInputListener> checkNewListeners() {
-		final ImIdentityList<IModelElementInputListener> listeners= this.newListenerList.clearToList();
-		for (final IModelElementInputListener listener : listeners) {
+	private ImIdentityList<ModelElementInputListener> checkNewListeners() {
+		final ImIdentityList<ModelElementInputListener> listeners= this.newListenerList.clearToList();
+		for (final ModelElementInputListener listener : listeners) {
 			this.listenerList.add(listener);
 		}
 		return listeners;
 	}
 	
-	private void notifyChanged(final ImIdentityList<IModelElementInputListener> listeners, final SourceUnit input) {
-		for (final IModelElementInputListener listener : listeners) {
+	private void notifyChanged(final ImIdentityList<ModelElementInputListener> listeners,
+			final @Nullable SourceUnit input) {
+		for (final ModelElementInputListener listener : listeners) {
 			listener.elementChanged(input);
 		}
 	}
 	
-	private void notifyInitial(final ImIdentityList<IModelElementInputListener> listeners, final SourceUnit input, 
+	private void notifyInitial(final ImIdentityList<ModelElementInputListener> listeners,
+			final SourceUnit input, 
 			final IProgressMonitor monitor) {
 		if (listeners.isEmpty() || input != this.input) {
 			return;
 		}
 		try {
 			input.connect(monitor);
-			for (final IModelElementInputListener listener : listeners) {
+			for (final ModelElementInputListener listener : listeners) {
 				if (input != this.input) {
 					return;
 				}
@@ -203,14 +206,15 @@
 		}
 	}
 	
-	private void notifyUpdated(final ImIdentityList<IModelElementInputListener> listeners, final SourceUnit input, final LtkModelElementDelta delta, 
+	private void notifyUpdated(final ImIdentityList<ModelElementInputListener> listeners,
+			final SourceUnit input, final LtkModelElementDelta delta,
 			final IProgressMonitor monitor) {
 		if (input != this.input) {
 			return;
 		}
 		try {
 			input.connect(monitor);
-			for (final IModelElementInputListener listener : listeners) {
+			for (final ModelElementInputListener listener : listeners) {
 				if (input != this.input) {
 					return;
 				}
@@ -228,7 +232,7 @@
 	}
 	
 	@Override
-	public void addListener(final IModelElementInputListener listener) {
+	public void addListener(final ModelElementInputListener listener) {
 		synchronized (this.inputLock) {
 			SourceUnit input= this.newInput;
 			if (input == null) {
@@ -249,7 +253,7 @@
 	}
 	
 	@Override
-	public void removeListener(final IModelElementInputListener listener) {
+	public void removeListener(final ModelElementInputListener listener) {
 		this.newListenerList.remove(listener);
 		this.listenerList.remove(listener);
 	}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/LTKInputData.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/LTKInputData.java
index b26a5bf..b1d4f30 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/LTKInputData.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/LTKInputData.java
@@ -20,6 +20,9 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.ui.part.ShowInContext;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ltk.ast.core.util.AstSelection;
 import org.eclipse.statet.ltk.model.core.LtkModelUtils;
 import org.eclipse.statet.ltk.model.core.ModelManager;
@@ -34,20 +37,22 @@
  * 
  * E.g. used for {@link ISelectionWithElementInfoListener} or {@link ShowInContext}
  */
+@NonNullByDefault
 public class LTKInputData implements ISelection {
 	
 	
-	protected SourceUnit inputElement;
-	protected SourceUnitModelInfo inputInfo;
+	protected final SourceUnit inputElement;
+	protected @Nullable SourceUnitModelInfo inputInfo;
 	
-	protected ISelectionProvider selectionProvider;
+	protected final @Nullable ISelectionProvider selectionProvider;
 	protected ISelection selection;
-	protected AstSelection astSelection;
-	protected SourceStructElement modelSelection;
+	protected @Nullable AstSelection astSelection;
+	protected @Nullable SourceStructElement<?, ?> modelSelection;
 	
 	
 	public LTKInputData(final SourceUnit inputElement, final ISelection selection) {
 		this.inputElement= inputElement;
+		this.selectionProvider= null;
 		this.selection= selection;
 	}
 	
@@ -70,15 +75,17 @@
 		return false;
 	}
 	
-	public LtkModelElement getInputElement() {
+	public LtkModelElement<?> getInputElement() {
 		return this.inputElement;
 	}
 	
-	public SourceUnitModelInfo getInputInfo() {
-		if (this.inputInfo == null) {
-			this.inputInfo= this.inputElement.getModelInfo(null, ModelManager.NONE, new NullProgressMonitor());
+	public @Nullable SourceUnitModelInfo getInputInfo() {
+		SourceUnitModelInfo inputInfo= this.inputInfo;
+		if (inputInfo == null) {
+			inputInfo= this.inputElement.getModelInfo(null, ModelManager.NONE, new NullProgressMonitor());
+			this.inputInfo= inputInfo;
 		}
-		return this.inputInfo;
+		return inputInfo;
 	}
 	
 	
@@ -91,26 +98,33 @@
 		return this.selection;
 	}
 	
-	public AstSelection getAstSelection() {
-		if (this.astSelection == null) {
-			if (this.selection instanceof ITextSelection && getInputInfo() != null) {
-				final ITextSelection textSelection= (ITextSelection) this.selection;
-				this.astSelection= AstSelection.search(getInputInfo().getAst().getRoot(),
+	public @Nullable AstSelection getAstSelection() {
+		AstSelection astSelection= this.astSelection;
+		if (astSelection == null) {
+			final SourceUnitModelInfo modelInfo;
+			if (this.selection instanceof ITextSelection && (modelInfo= getInputInfo()) != null) {
+				final ITextSelection textSelection= (ITextSelection)this.selection;
+				astSelection= AstSelection.search(modelInfo.getAst().getRoot(),
 						textSelection.getOffset(), textSelection.getOffset()+textSelection.getLength(),
 						AstSelection.MODE_COVERING_SAME_LAST );
+				this.astSelection= astSelection;
 			}
 		}
-		return this.astSelection;
+		return astSelection;
 	}
 	
-	public SourceStructElement getModelSelection() {
-		if (this.modelSelection == null) {
-			if (this.selection instanceof ITextSelection && getInputInfo() != null) {
-				final ITextSelection textSelection= (ITextSelection) this.selection;
-				this.modelSelection= LtkModelUtils.getCoveringSourceElement(getInputInfo().getSourceElement(), textSelection.getOffset(), textSelection.getOffset()+textSelection.getLength());
+	public @Nullable SourceStructElement<?, ?> getModelSelection() {
+		SourceStructElement<?, ?> modelSelection= this.modelSelection;
+		if (modelSelection == null) {
+			final SourceUnitModelInfo modelInfo;
+			if (this.selection instanceof ITextSelection && (modelInfo= getInputInfo()) != null) {
+				final ITextSelection textSelection= (ITextSelection)this.selection;
+				modelSelection= LtkModelUtils.getCoveringSourceElement(modelInfo.getSourceElement(),
+						textSelection.getOffset(), textSelection.getOffset() + textSelection.getLength() );
+				this.modelSelection= modelSelection;
 			}
 		}
-		return this.modelSelection;
+		return modelSelection;
 	}
 	
 	
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputListener.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputListener.java
similarity index 76%
rename from ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputListener.java
rename to ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputListener.java
index 73e173b..1ffe190 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputListener.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputListener.java
@@ -14,6 +14,8 @@
 
 package org.eclipse.statet.ltk.ui;
 
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
 import org.eclipse.statet.ltk.model.core.element.LtkModelElementDelta;
 
@@ -21,9 +23,9 @@
 /**
  * Interface to listen to changes of object input of the type {@link LtkModelElement}.
  * 
- * @see IModelElementInputProvider
+ * @see ModelElementInputProvider
  */
-public interface IModelElementInputListener {
+public interface ModelElementInputListener<TModelElement extends LtkModelElement<?>> {
 	
 	
 	/**
@@ -32,16 +34,16 @@
 	 * Directly called while changing the input.
 	 * For longer tasks, wait for {@link #elementInitialInfo(LtkModelElement)}.
 	 */
-	public void elementChanged(LtkModelElement element);
+	void elementChanged(final @Nullable TModelElement element);
 	
 	/**
 	 * First detail info for the element.
 	 */
-	public void elementInitialInfo(LtkModelElement element);
+	void elementInitialInfo(final @Nullable TModelElement element);
 	
 	/**
 	 * Detail info changed.
 	 */
-	public void elementUpdatedInfo(LtkModelElement element, LtkModelElementDelta delta);
+	void elementUpdatedInfo(final TModelElement element, final LtkModelElementDelta delta);
 	
 }
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputProvider.java
similarity index 68%
rename from ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputProvider.java
rename to ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputProvider.java
index 810cdba..1eff92f 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/IModelElementInputProvider.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/ModelElementInputProvider.java
@@ -14,18 +14,22 @@
 
 package org.eclipse.statet.ltk.ui;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 
 
 /**
  * Object having an {@link SourceUnit} as input.
  */
-public interface IModelElementInputProvider {
+@NonNullByDefault
+public interface ModelElementInputProvider<TModelElement> {
 	
 	
-	public abstract SourceUnit getInput();
+	@Nullable TModelElement getInput();
 	
-	public abstract void addListener(IModelElementInputListener listener);
-	public abstract void removeListener(IModelElementInputListener listener);
+	void addListener(final ModelElementInputListener<? super TModelElement> listener);
+	void removeListener(final ModelElementInputListener<? super TModelElement> listener);
 	
 }
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/PostSelectionWithElementInfoController.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/PostSelectionWithElementInfoController.java
index 5d107bd..299a676 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/PostSelectionWithElementInfoController.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/PostSelectionWithElementInfoController.java
@@ -37,7 +37,7 @@
 
 /**
  * Controller implementation combining {@link IPostSelectionProvider} and 
- * {@link IModelElementInputProvider} to provide support for
+ * {@link ModelElementInputProvider} to provide support for
  * {@link ISelectionWithElementInfoListener}.
  */
 public class PostSelectionWithElementInfoController {
@@ -210,12 +210,12 @@
 	}
 	
 	private final IPostSelectionProvider selectionProvider;
-	private final IModelElementInputProvider modelProvider;
+	private final ModelElementInputProvider modelProvider;
 	private final CopyOnWriteIdentityListSet<ISelectionWithElementInfoListener> listeners= new CopyOnWriteIdentityListSet<>();
 	private final CopyOnWriteIdentityListSet<ISelectionWithElementInfoListener> newListeners= new CopyOnWriteIdentityListSet<>();
 	private final Object inputLock= new Object();
 	
-	private final IModelElementInputListener elementChangeListener;
+	private final ModelElementInputListener elementChangeListener;
 	private final SelectionListener selectionListener;
 	private final SelectionListener postSelectionListener;
 	private PostSelectionCancelExtension cancelExtension;
@@ -230,13 +230,13 @@
 	private final SelectionTask updateJob= new SelectionTask();
 	
 	
-	public PostSelectionWithElementInfoController(final IModelElementInputProvider modelProvider,
+	public PostSelectionWithElementInfoController(final ModelElementInputProvider modelProvider,
 			final IPostSelectionProvider selectionProvider, final PostSelectionCancelExtension cancelExt) {
 		this.selectionProvider= selectionProvider;
 		
 		this.modelProvider= modelProvider;
 		
-		this.elementChangeListener= new IModelElementInputListener() {
+		this.elementChangeListener= new ModelElementInputListener() {
 			@Override
 			public void elementChanged(final LtkModelElement element) {
 				synchronized (PostSelectionWithElementInfoController.this.inputLock) {
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java
index 5abad95..ce1919b 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/OutlineContentProvider.java
@@ -19,80 +19,104 @@
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 
+import org.eclipse.statet.jcommons.lang.NonNull;
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ltk.core.SourceModelStamp;
 import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
 import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
 import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
 
 
+@NonNullByDefault
 public class OutlineContentProvider implements ITreeContentProvider {
 	
 	
-	public interface IOutlineContent {
+	private static final SourceStructElement[] NO_CHILDREN= new SourceStructElement[0];
+	
+	
+	public interface OutlineContent {
 		
-		SourceUnitModelInfo getModelInfo(Object inputElement);
+		@Nullable SourceUnitModelInfo getModelInfo(Object inputElement);
 		
-		LtkModelElementFilter getContentFilter();
+		@Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter();
 		
 	}
 	
 	
-	private final IOutlineContent content;
+	private final OutlineContent content;
 	
 	
-	public OutlineContentProvider(final IOutlineContent content) {
+	public OutlineContentProvider(final OutlineContent content) {
 		this.content= content;
 	}
 	
 	
-	protected final IOutlineContent getContent() {
+	protected final OutlineContent getContent() {
 		return this.content;
 	}
 	
-	public SourceModelStamp getStamp(final Object inputElement) {
+	public @Nullable SourceModelStamp getStamp(final Object inputElement) {
 		final SourceUnitModelInfo modelInfo= getContent().getModelInfo(inputElement);
 		return (modelInfo != null) ? modelInfo.getStamp() : null;
 	}
 	
 	@Override
-	public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
-	}
-	
-	@Override
-	public Object[] getElements(final Object inputElement) {
-		final SourceUnitModelInfo modelInfo= getContent().getModelInfo(inputElement);
-		if (modelInfo != null) {
-			final List<? extends SourceStructElement> children= modelInfo.getSourceElement().getSourceChildren(getContent().getContentFilter());
-			return children.toArray(new SourceStructElement[children.size()]);
-		}
-		return new SourceStructElement[0];
+	public void inputChanged(final Viewer viewer, final @Nullable Object oldInput, final @Nullable Object newInput) {
 	}
 	
 	@Override
 	public void dispose() {
 	}
 	
+	
+	protected SourceStructElement[] getElements(final @Nullable SourceUnitModelInfo modelInfo) {
+		if (modelInfo != null) {
+			final List<? extends SourceStructElement> children= modelInfo.getSourceElement()
+					.getSourceChildren(getContent().getContentFilter());
+			return children.toArray(new @NonNull SourceStructElement[children.size()]);
+		}
+		return NO_CHILDREN;
+	}
+	
+	protected @Nullable SourceStructElement getParent(final SourceStructElement<?, ?> element) {
+		return element.getSourceParent();
+	}
+	
+	protected boolean hasChildren(final @Nullable SourceStructElement<?, ?> element) {
+		return (element != null
+				&& element.hasSourceChildren(getContent().getContentFilter()) );
+	}
+	
+	protected SourceStructElement[] getChildren(final @Nullable SourceStructElement<?, ?> element) {
+		if (element != null) {
+			final List<? extends SourceStructElement> children= element
+					.getSourceChildren(getContent().getContentFilter());
+			return children.toArray(new @NonNull SourceStructElement[children.size()]);
+		}
+		return NO_CHILDREN;
+	}
+	
+	
 	@Override
-	public Object getParent(final Object element) {
-		final SourceStructElement o= (SourceStructElement) element;
-		return o.getSourceParent();
+	public Object[] getElements(final Object inputElement) {
+		return getElements(getContent().getModelInfo(inputElement));
+	}
+	
+	@Override
+	public @Nullable Object getParent(final Object element) {
+		return getParent((SourceStructElement<?, ?>)element);
 	}
 	
 	@Override
 	public boolean hasChildren(final Object element) {
-		final SourceStructElement o= (SourceStructElement) element;
-		return o.hasSourceChildren(getContent().getContentFilter());
+		return hasChildren((SourceStructElement<?, ?>)element);
 	}
 	
 	@Override
-	public Object[] getChildren(final Object parentElement) {
-		// Check required for E bug #438919
-		if (parentElement instanceof SourceStructElement) {
-			final SourceStructElement o= (SourceStructElement) parentElement;
-			final List<? extends SourceStructElement> children= o.getSourceChildren(getContent().getContentFilter());
-			return children.toArray(new SourceStructElement[children.size()]);
-		}
-		return new SourceStructElement[0];
+	public Object[] getChildren(final Object element) {
+		return getChildren((SourceStructElement<?, ?>)element);
 	}
 	
 }
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
index bd2f62e..2ae1f03 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/QuickOutlineInformationControl.java
@@ -21,6 +21,9 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Shell;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
 import org.eclipse.statet.ecommons.ui.dialogs.QuickTreeInformationControl;
 
@@ -28,6 +31,7 @@
 import org.eclipse.statet.ltk.model.core.element.LtkModelElement;
 import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
 import org.eclipse.statet.ltk.model.core.element.SourceElement;
+import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
 import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
 import org.eclipse.statet.ltk.ui.LTKUI;
@@ -37,25 +41,26 @@
 /**
  * Show outline in light-weight control.
  */
+@NonNullByDefault
 public abstract class QuickOutlineInformationControl extends QuickTreeInformationControl {
 	
 	
 	protected static final String INHERITED_COLOR_NAME= "org.eclipse.jdt.ui.ColoredLabels.inherited"; //$NON-NLS-1$
 	
 	
-	protected class OutlineContent implements OutlineContentProvider.IOutlineContent {
+	protected class QuickOutlineContent implements OutlineContentProvider.OutlineContent {
 		
 		
-		public OutlineContent() {
+		public QuickOutlineContent() {
 		}
 		
 		
 		@Override
-		public SourceUnitModelInfo getModelInfo(final Object input) {
+		public @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
 			return QuickOutlineInformationControl.this.getModelInfo(input);
 		}
 		@Override
-		public LtkModelElementFilter getContentFilter() {
+		public @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
 			return QuickOutlineInformationControl.this.getContentFilter();
 		}
 		
@@ -113,7 +118,7 @@
 	@Override
 	protected String getElementName(final IAdaptable element) {
 		if (element instanceof LtkModelElement && !this.requireFullName) {
-			return ((LtkModelElement) element).getElementName().getSegmentName();
+			return ((LtkModelElement<?>)element).getElementName().getSegmentName();
 		}
 		return super.getElementName(element);
 	}
@@ -126,29 +131,29 @@
 	}
 	
 	protected OutlineContentProvider createContentProvider() {
-		return new OutlineContentProvider(new OutlineContent());
+		return new OutlineContentProvider(new QuickOutlineContent());
 	}
 	
-	protected SourceUnitModelInfo getModelInfo(final Object input) {
+	protected @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
 		if (input instanceof SourceUnit) {
 			return ((SourceUnit) input).getModelInfo(getModelTypeId(), 0, null);
 		}
 		return null;
 	}
 	
-	protected LtkModelElementFilter getContentFilter() {
+	protected @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
 		return null;
 	}
 	
 	
-	protected int getInitialIterationPage(final SourceElement element) {
+	protected int getInitialIterationPage(final SourceElement<?> element) {
 		return 0;
 	}
 	
 	@Override
 	public void setInput(final Object information) {
 		if (information instanceof SourceElement) {
-			final SourceElement element= (SourceElement) information;
+			final SourceElement<?> element= (SourceElement<?>)information;
 			final SourceUnit su= element.getSourceUnit();
 			if (su != null) {
 				inputChanged(getInitialIterationPage(element), su, element);
@@ -162,7 +167,7 @@
 	@Override
 	protected void openElement(final Object element) throws CoreException {
 		if (element instanceof SourceElement) {
-			this.opener.open((SourceElement) element, true);
+			this.opener.open((SourceElement<?>)element, true);
 		}
 	}
 	
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
index 14a4c86..90da759 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1.java
@@ -106,10 +106,10 @@
 import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
 import org.eclipse.statet.ltk.ui.ElementInfoController;
-import org.eclipse.statet.ltk.ui.IModelElementInputProvider;
 import org.eclipse.statet.ltk.ui.ISelectionWithElementInfoListener;
 import org.eclipse.statet.ltk.ui.LTKInputData;
 import org.eclipse.statet.ltk.ui.LTKUI;
+import org.eclipse.statet.ltk.ui.ModelElementInputProvider;
 import org.eclipse.statet.ltk.ui.PostSelectionCancelExtension;
 import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController;
 import org.eclipse.statet.ltk.ui.PostSelectionWithElementInfoController.IgnoreActivation;
@@ -520,7 +520,7 @@
 		return SourceEditor1.this.isEditorInputModifiable();
 	}
 	
-	public IModelElementInputProvider getModelInputProvider() {
+	public ModelElementInputProvider getModelInputProvider() {
 		return this.modelProvider;
 	}
 	
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
index a0a344f..d8120d4 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor1OutlinePage.java
@@ -14,6 +14,8 @@
 
 package org.eclipse.statet.ltk.ui.sourceediting;
 
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
 import static org.eclipse.statet.ecommons.ui.actions.UIActions.ADDITIONS_GROUP_ID;
 
 import org.eclipse.core.runtime.IAdaptable;
@@ -44,10 +46,14 @@
 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
 import org.eclipse.statet.ecommons.ui.SharedUIResources;
 import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
 import org.eclipse.statet.ecommons.ui.util.UIAccess;
-import org.eclipse.statet.ecommons.ui.workbench.AbstractEditorOutlinePage;
+import org.eclipse.statet.ecommons.ui.workbench.BasicEditorOutlinePage;
+import org.eclipse.statet.ecommons.ui.workbench.ContextHandlers;
 
 import org.eclipse.statet.internal.ltk.ui.EditingMessages;
 import org.eclipse.statet.ltk.ast.core.AstInfo;
@@ -58,33 +64,35 @@
 import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
 import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
-import org.eclipse.statet.ltk.ui.IModelElementInputListener;
 import org.eclipse.statet.ltk.ui.ISelectionWithElementInfoListener;
 import org.eclipse.statet.ltk.ui.LTKInputData;
+import org.eclipse.statet.ltk.ui.ModelElementInputListener;
 
 
 /**
  * Abstract content outline page for a {@link SourceEditor1} with model info.
  */
-public abstract class SourceEditor1OutlinePage extends AbstractEditorOutlinePage
+@NonNullByDefault
+public abstract class SourceEditor1OutlinePage extends BasicEditorOutlinePage
 		implements IContentOutlinePage, IAdaptable, ISourceEditorAssociated,
-			IShowInSource, IShowInTargetList, IShowInTarget,
-			IPostSelectionProvider, IModelElementInputListener {
+				IShowInSource, IShowInTargetList, IShowInTarget,
+				IPostSelectionProvider, ModelElementInputListener<LtkModelElement<?>> {
 	
 	
-	protected class OutlineContent implements OutlineContentProvider.IOutlineContent {
+	protected class PageOutlineContent implements OutlineContentProvider.OutlineContent {
 		
 		
-		public OutlineContent() {
+		public PageOutlineContent() {
 		}
 		
 		
 		@Override
-		public SourceUnitModelInfo getModelInfo(final Object input) {
+		public @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
 			return SourceEditor1OutlinePage.this.getModelInfo(input);
 		}
+		
 		@Override
-		public LtkModelElementFilter getContentFilter() {
+		public @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
 			return SourceEditor1OutlinePage.this.getContentFilter();
 		}
 		
@@ -94,14 +102,14 @@
 		
 		
 		public AstContentProvider() {
-			super(new OutlineContent());
+			super(new PageOutlineContent());
 		}
 		
 		
 		@Override
-		public SourceModelStamp getStamp(final Object inputElement) {
+		public @Nullable SourceModelStamp getStamp(final Object inputElement) {
 			if (inputElement instanceof SourceUnit) {
-				final AstInfo ast= ((SourceUnit) inputElement).getAstInfo(SourceEditor1OutlinePage.this.mainType, false, null);
+				final AstInfo ast= ((SourceUnit)inputElement).getAstInfo(SourceEditor1OutlinePage.this.mainType, false, null);
 				if (ast != null) {
 					return ast.getStamp();
 				}
@@ -112,7 +120,7 @@
 		@Override
 		public Object[] getElements(final Object inputElement) {
 			if (inputElement instanceof SourceUnit) {
-				final AstInfo ast= ((SourceUnit) inputElement).getAstInfo(SourceEditor1OutlinePage.this.mainType, false, null); 
+				final AstInfo ast= ((SourceUnit)inputElement).getAstInfo(SourceEditor1OutlinePage.this.mainType, false, null); 
 				if (ast != null) {
 					SourceEditor1OutlinePage.this.currentModelStamp= ast.getStamp();
 					return new Object[] { ast.getRoot() };
@@ -219,23 +227,22 @@
 	private final String mainType;
 	private OutlineContentProvider contentProvider;
 	
-	private SourceModelStamp currentModelStamp;
+	private @Nullable SourceModelStamp currentModelStamp;
 	
-	private LtkModelElement inputUnit;
+	private @Nullable LtkModelElement<?> inputUnit;
 	
 	private SyncWithEditorAction syncWithEditorAction;
 	
 	
 	public SourceEditor1OutlinePage(final SourceEditor1 editor, final String mainType, final String contextMenuId) {
 		super(contextMenuId);
-		if (editor == null) {
-			throw new NullPointerException();
-		}
-		if (mainType == null) {
-			throw new NullPointerException();
-		}
-		this.editor= editor;
-		this.mainType= mainType;
+		this.editor= nonNullAssert(editor);
+		this.mainType= nonNullAssert(mainType);
+	}
+	
+	
+	public SourceEditor1 getEditor() {
+		return this.editor;
 	}
 	
 	
@@ -250,10 +257,16 @@
 		return (current != null && current.equals(stamp));
 	}
 	
-	protected LtkModelElementFilter getContentFilter() {
+	protected @Nullable LtkModelElementFilter<? super SourceStructElement<?, ?>> getContentFilter() {
 		return null;
 	}
 	
+	
+	@Override
+	protected @Nullable TreeViewer getViewer() {
+		return (TreeViewer)super.getViewer();
+	}
+	
 	@Override
 	public void createControl(final Composite parent) {
 		super.createControl(parent);
@@ -263,7 +276,7 @@
 	}
 	
 	protected OutlineContentProvider createContentProvider() {
-		return new OutlineContentProvider(new OutlineContent());
+		return new OutlineContentProvider(new PageOutlineContent());
 	}
 	
 	@Override
@@ -274,7 +287,8 @@
 	
 	
 	@Override
-	protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection handlers) {
+	protected void initActions(final IServiceLocator serviceLocator,
+			final ContextHandlers handlers) {
 		super.initActions(serviceLocator, handlers);
 		
 		this.syncWithEditorAction= new SyncWithEditorAction();
@@ -309,22 +323,22 @@
 	
 	
 	@Override
-	public void elementChanged(final LtkModelElement element) {
+	public void elementChanged(final @Nullable LtkModelElement<?> element) {
 		this.inputUnit= element;
 		this.currentModelStamp= null;
 		final TreeViewer viewer= getViewer();
-		if (UIAccess.isOkToUse(viewer)) {
+		if (viewer != null && UIAccess.isOkToUse(viewer.getControl())) {
 			viewer.setInput(this.inputUnit);
 		}
 	}
 	
 	@Override
-	public void elementInitialInfo(final LtkModelElement element) {
+	public void elementInitialInfo(final @Nullable LtkModelElement<?> element) {
 		elementUpdatedInfo(element, null);
 	}
 	
 	@Override
-	public void elementUpdatedInfo(final LtkModelElement element, final LtkModelElementDelta delta) {
+	public void elementUpdatedInfo(final @Nullable LtkModelElement<?> element, final @Nullable LtkModelElementDelta delta) {
 		if (element != this.inputUnit || (element == null && this.inputUnit == null)) {
 			return;
 		}
@@ -335,7 +349,7 @@
 				final TreeViewer viewer= getViewer();
 				
 				if (element != SourceEditor1OutlinePage.this.inputUnit 
-						|| !UIAccess.isOkToUse(viewer)
+						|| viewer == null || !UIAccess.isOkToUse(viewer.getControl())
 						|| isUpToDate(SourceEditor1OutlinePage.this.contentProvider.getStamp(element)) ) {
 					return;
 				}
@@ -350,9 +364,9 @@
 		});
 	}
 	
-	protected SourceUnitModelInfo getModelInfo(final Object input) {
+	protected @Nullable SourceUnitModelInfo getModelInfo(final Object input) {
 		if (input instanceof SourceUnit) {
-			return ((SourceUnit) input).getModelInfo(this.mainType, 0, null);
+			return ((SourceUnit)input).getModelInfo(this.mainType, 0, null);
 		}
 		return null;
 	}
@@ -372,14 +386,14 @@
 		this.editor.setSelection(selection, this.syncWithEditorAction);
 	}
 	
-	protected void select(SourceStructElement element) {
+	protected void select(@Nullable SourceStructElement<?, ?> element) {
 		final TreeViewer viewer= getViewer();
-		if (UIAccess.isOkToUse(viewer)) {
+		if (viewer != null && UIAccess.isOkToUse(viewer.getControl())) {
 			beginIgnoreSelection();
 			try {
-				final LtkModelElementFilter filter= getContentFilter();
+				final LtkModelElementFilter<? super SourceStructElement<?, ?>> filter= getContentFilter();
 				Object selectedElement= null;
-				final IStructuredSelection currentSelection= ((IStructuredSelection) viewer.getSelection());
+				final IStructuredSelection currentSelection= ((IStructuredSelection)viewer.getSelection());
 				if (currentSelection.size() == 1) {
 					selectedElement= currentSelection.getFirstElement();
 				}
@@ -395,9 +409,9 @@
 							return;
 						}
 					}
-					final LtkModelElement parent= element.getSourceParent();
+					final LtkModelElement<?> parent= element.getSourceParent();
 					if (parent instanceof SourceStructElement) {
-						element= (SourceStructElement) parent;
+						element= (SourceStructElement<?, ?>)parent;
 						continue;
 					}
 					else {
@@ -427,7 +441,7 @@
 	
 	@Override
 	public boolean show(final ShowInContext context) {
-		final LtkModelElement inputUnit= this.inputUnit;
+		final LtkModelElement<?> inputUnit= this.inputUnit;
 		final ISelection selection= context.getSelection();
 		if (selection instanceof LTKInputData) {
 			final LTKInputData data= (LTKInputData) selection;
@@ -448,15 +462,15 @@
 	
 	@Override
 	@SuppressWarnings("unchecked")
-	public <T> T getAdapter(final Class<T> adapterType) {
+	public <T> @Nullable T getAdapter(final Class<T> adapterType) {
 		if (adapterType == ISourceEditorAssociated.class) {
-			return (T) this;
+			return (T)this;
 		}
 		if (adapterType == IEncodingSupport.class) {
-			return this.editor.getAdapter((Class<T>) IEncodingSupport.class);
+			return (T)this.editor.getAdapter(IEncodingSupport.class);
 		}
 		if (adapterType == IContentType.class) {
-			return (T) this.editor.getContentType();
+			return (T)this.editor.getContentType();
 		}
 		return null;
 	}
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor2OutlinePage.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor2OutlinePage.java
index 013a2c2..153b872 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor2OutlinePage.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/SourceEditor2OutlinePage.java
@@ -22,14 +22,15 @@
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.TextSelection;
 import org.eclipse.ui.IWorkbenchCommandConstants;
-import org.eclipse.ui.handlers.IHandlerService;
 import org.eclipse.ui.menus.CommandContributionItem;
 import org.eclipse.ui.menus.CommandContributionItemParameter;
 import org.eclipse.ui.part.IPageSite;
 import org.eclipse.ui.services.IServiceLocator;
 
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+
 import org.eclipse.statet.ecommons.ui.SharedUIResources;
-import org.eclipse.statet.ecommons.ui.actions.HandlerCollection;
+import org.eclipse.statet.ecommons.ui.workbench.ContextHandlers;
 
 import org.eclipse.statet.internal.ltk.ui.EditingMessages;
 import org.eclipse.statet.ltk.model.core.element.SourceStructElement;
@@ -44,6 +45,7 @@
 import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;
 
 
+@NonNullByDefault
 public abstract class SourceEditor2OutlinePage extends SourceEditor1OutlinePage {
 	
 	
@@ -91,32 +93,27 @@
 	}
 	
 	@Override
-	protected void initActions(final IServiceLocator serviceLocator, final HandlerCollection handlers) {
+	protected void initActions(final IServiceLocator serviceLocator,
+			final ContextHandlers handlers) {
 		super.initActions(serviceLocator, handlers);
 		
-		final IHandlerService handlerService= serviceLocator.getService(IHandlerService.class);
 		{	final AbstractElementsHandler handler= new CutElementsHandler(this.refactoring);
-			handlers.add(IWorkbenchCommandConstants.EDIT_CUT, handler);
+			handlers.addActivate(IWorkbenchCommandConstants.EDIT_CUT, handler);
 			registerHandlerToUpdate(handler);
-			handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_CUT, handler);
 		}
 		{	final AbstractElementsHandler handler= new CopyElementsHandler(this.refactoring);
-			handlers.add(IWorkbenchCommandConstants.EDIT_COPY, handler);
+			handlers.addActivate(IWorkbenchCommandConstants.EDIT_COPY, handler);
 			registerHandlerToUpdate(handler);
-			handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_COPY, handler);
 		}
 		{	final AbstractElementsHandler handler= new CopyNamesHandler(this.refactoring);
-			handlers.add(ISourceEditorCommandIds.COPY_ELEMENT_NAME, handler);
+			handlers.addActivate(ISourceEditorCommandIds.COPY_ELEMENT_NAME, handler);
 			registerHandlerToUpdate(handler);
-			handlerService.activateHandler(ISourceEditorCommandIds.COPY_ELEMENT_NAME, handler);
 		}
 		{	final AbstractElementsHandler handler= new PasteElementsHandler(getSourceEditor(), this.refactoring);
-			handlers.add(IWorkbenchCommandConstants.EDIT_PASTE, handler);
-			handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_PASTE, handler);
+			handlers.addActivate(IWorkbenchCommandConstants.EDIT_PASTE, handler);
 		}
 		{	final AbstractElementsHandler handler= new DeleteElementsHandler(this.refactoring);
-			handlers.add(IWorkbenchCommandConstants.EDIT_DELETE, handler);
-			handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_DELETE, handler);
+			handlers.addActivate(IWorkbenchCommandConstants.EDIT_DELETE, handler);
 		}
 	}
 	
diff --git a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/folding/FoldingEditorAddon.java b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/folding/FoldingEditorAddon.java
index 5fa9e4d..5662e89 100644
--- a/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/folding/FoldingEditorAddon.java
+++ b/ltk/org.eclipse.statet.ltk.ui/src/org/eclipse/statet/ltk/ui/sourceediting/folding/FoldingEditorAddon.java
@@ -52,13 +52,13 @@
 import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 import org.eclipse.statet.ltk.model.core.element.SourceUnitModelInfo;
 import org.eclipse.statet.ltk.model.core.element.WorkspaceSourceUnit;
-import org.eclipse.statet.ltk.ui.IModelElementInputListener;
+import org.eclipse.statet.ltk.ui.ModelElementInputListener;
 import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
 import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorAddon;
 import org.eclipse.statet.ltk.ui.sourceediting.SourceEditor1;
 
 
-public class FoldingEditorAddon implements ISourceEditorAddon, IModelElementInputListener, ChangeListener {
+public class FoldingEditorAddon implements ISourceEditorAddon, ModelElementInputListener, ChangeListener {
 	
 	
 	public static final class FoldingStructureComputationContext {