reschedule the job if module is inconsistent - wait until reconciler thread does the task
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/viewsupport/SelectionListenerWithASTManager.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/viewsupport/SelectionListenerWithASTManager.java
index 031d025..dec3b5b 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/viewsupport/SelectionListenerWithASTManager.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/viewsupport/SelectionListenerWithASTManager.java
@@ -16,13 +16,13 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.ListenerList;
-import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.dltk.ast.parser.IModuleDeclaration;
 import org.eclipse.dltk.core.IModelElement;
 import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.ModelException;
 import org.eclipse.dltk.core.SourceParserUtil;
 import org.eclipse.dltk.internal.ui.DLTKUIMessages;
 import org.eclipse.dltk.internal.ui.editor.EditorUtility;
@@ -53,17 +53,17 @@
 	}
 
 	private final static class PartListenerGroup {
-		private ITextEditor fPart;
+		protected final ITextEditor fPart;
 		private ISelectionListener fPostSelectionListener;
 		private ISelectionChangedListener fSelectionListener;
 		private Job fCurrentJob;
-		private ListenerList fAstListeners;
+		protected final ListenerList fAstListeners;
 		/**
 		 * Lock to avoid having more than one calculateAndInform job in
 		 * parallel. Only jobs may synchronize on this as otherwise deadlocks
 		 * are possible.
 		 */
-		private final Object fJobLock = new Object();
+		protected final Object fJobLock = new Object();
 
 		public PartListenerGroup(ITextEditor editorPart) {
 			fPart = editorPart;
@@ -145,27 +145,58 @@
 			if (!(input instanceof ISourceModule)) {
 				return;
 			}
-			final ISourceModule typeRoot = (ISourceModule) input;
-
-			fCurrentJob = new Job(
-					DLTKUIMessages.SelectionListenerWithASTManager_job_title) {
-				public IStatus run(IProgressMonitor monitor) {
-					if (monitor == null) {
-						monitor = new NullProgressMonitor();
-					}
-					synchronized (fJobLock) {
-						return calculateASTandInform(typeRoot, selection,
-								monitor);
-					}
-				}
-			};
-			fCurrentJob.setPriority(Job.DECORATE);
-			fCurrentJob.setSystem(true);
+			fCurrentJob = new ASTJob(this, (ISourceModule) input, selection);
 			fCurrentJob.schedule();
 		}
 
-		protected final IStatus calculateASTandInform(ISourceModule input,
-				ITextSelection selection, IProgressMonitor monitor) {
+	}
+
+	protected static class ASTJob extends Job {
+
+		private final PartListenerGroup owner;
+		private final ISourceModule input;
+		private final ITextSelection selection;
+
+		public ASTJob(PartListenerGroup owner, ISourceModule module,
+				ITextSelection selection) {
+			super(DLTKUIMessages.SelectionListenerWithASTManager_job_title);
+			this.owner = owner;
+			this.input = module;
+			this.selection = selection;
+			setPriority(Job.DECORATE);
+			setSystem(true);
+		}
+
+		@Override
+		protected void canceling() {
+			synchronized (this) {
+				wasCancel = true;
+			}
+		}
+
+		private boolean wasCancel;
+
+		@Override
+		public IStatus run(IProgressMonitor monitor) {
+			try {
+				if (!input.isConsistent()) {
+					synchronized (this) {
+						if (!wasCancel) {
+							schedule(1000);
+						}
+					}
+					return Status.OK_STATUS;
+				}
+			} catch (ModelException e) {
+				// never happens, fall thru
+			}
+			synchronized (owner.fJobLock) {
+				// The monitor is never null
+				return calculateASTandInform(monitor);
+			}
+		}
+
+		protected final IStatus calculateASTandInform(IProgressMonitor monitor) {
 			if (monitor.isCanceled()) {
 				return Status.CANCEL_STATUS;
 			}
@@ -175,14 +206,11 @@
 						.parse(input, null);
 
 				if (astRoot != null && !monitor.isCanceled()) {
-					Object[] listeners;
-					synchronized (PartListenerGroup.this) {
-						listeners = fAstListeners.getListeners();
-					}
+					Object[] listeners = owner.fAstListeners.getListeners();
 					for (int i = 0; i < listeners.length; i++) {
 						((ISelectionListenerWithAST) listeners[i])
-								.selectionChanged(fPart, selection, input,
-										astRoot);
+								.selectionChanged(owner.fPart, selection,
+										input, astRoot);
 						if (monitor.isCanceled()) {
 							return Status.CANCEL_STATUS;
 						}