diff --git a/sb/src/main/java/com/oracle/javafx/scenebuilder/app/info/InfoPanelController.java b/sb/src/main/java/com/oracle/javafx/scenebuilder/app/info/InfoPanelController.java
index 04a74186ef148717e02fba66fb2b8cff8a12a911..82b07ecd06b11bc027498dff8081a2ef63eafe87 100644
--- a/sb/src/main/java/com/oracle/javafx/scenebuilder/app/info/InfoPanelController.java
+++ b/sb/src/main/java/com/oracle/javafx/scenebuilder/app/info/InfoPanelController.java
@@ -468,7 +468,7 @@ public class InfoPanelController extends AbstractFxmlPanelController {
     
     private final ChangeListener<Boolean> checkBoxListener = (ov, t, t1) -> toggleFxRoot();
 
-    private void resetSuggestedControllerClasses(URL location) {
+    public void resetSuggestedControllerClasses(URL location) {
         if (controllerClassEditor != null) {
             // The listener on fxmlLocationProperty is called before the file
             // denoted by the location is created on disk, hence the runLater.
diff --git a/sb4e.examples/src/no/tobask/sb4e/examples/Controller.java b/sb4e.examples/src/no/tobask/sb4e/examples/Controller.java
new file mode 100644
index 0000000000000000000000000000000000000000..86e27f97078be775f3788e3db30bbfcc4ed78f2d
--- /dev/null
+++ b/sb4e.examples/src/no/tobask/sb4e/examples/Controller.java
@@ -0,0 +1,11 @@
+package no.tobask.sb4e.examples;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+
+public class Controller {
+	
+	@FXML
+	Label lbl;
+
+}
diff --git a/sb4e/META-INF/MANIFEST.MF b/sb4e/META-INF/MANIFEST.MF
index ec04ff542000439967edffbca9a9bb5327647d7d..c8f2577c4b3b101a5ffec29eacc3d8218d607d93 100644
--- a/sb4e/META-INF/MANIFEST.MF
+++ b/sb4e/META-INF/MANIFEST.MF
@@ -24,6 +24,7 @@ Import-Package: com.oracle.javafx.scenebuilder.app.selectionbar,
  org.eclipse.e4.core.di.annotations;version="1.6.0",
  org.eclipse.e4.ui.di,
  org.eclipse.jdt.core,
+ org.eclipse.jdt.core.dom,
  org.eclipse.jdt.launching
 Bundle-ActivationPolicy: lazy
 Bundle-ClassPath: .
diff --git a/sb4e/src/no/tobask/sb4e/ControllerCandidateChecker.java b/sb4e/src/no/tobask/sb4e/ControllerCandidateChecker.java
new file mode 100644
index 0000000000000000000000000000000000000000..52892aa99e40787a434bb90ec7622113962f552c
--- /dev/null
+++ b/sb4e/src/no/tobask/sb4e/ControllerCandidateChecker.java
@@ -0,0 +1,54 @@
+package no.tobask.sb4e;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.IExtendedModifier;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+
+import javafx.fxml.FXML;
+
+public class ControllerCandidateChecker extends ASTVisitor {
+
+	private static final String FXML_ANNOTATION = FXML.class.getSimpleName();
+	private boolean hasEmptyConstructor;
+	private boolean hasFxmlAnnotatedMembers;
+	
+	private boolean hasConstructor;
+		
+	@Override
+	public boolean visit(FieldDeclaration node) {
+		return visitBodyDeclaration(node);
+	}
+	
+	@Override
+	public boolean visit(MethodDeclaration node) {
+		if (node.isConstructor()) {
+			hasConstructor = true;
+			hasEmptyConstructor = hasEmptyConstructor || node.parameters().size() == 0;
+		}
+		return visitBodyDeclaration(node);
+	}
+	
+	@SuppressWarnings("unchecked")
+	private boolean visitBodyDeclaration(BodyDeclaration node) {
+		List<IExtendedModifier> modifiers = node.modifiers();
+		for (IExtendedModifier modifier : modifiers) {
+			if (modifier.isAnnotation()) {
+				String annotationName = ((Annotation) modifier).getTypeName().toString();
+				if (annotationName != null && annotationName.equals(FXML_ANNOTATION)) {
+					hasFxmlAnnotatedMembers = true;
+				}
+			}
+		}
+		return false;
+	}
+	
+	public boolean visitedCandidate() {
+		return (hasEmptyConstructor || !hasConstructor) && hasFxmlAnnotatedMembers;
+	}
+	
+}
diff --git a/sb4e/src/no/tobask/sb4e/JavaProjectGlossary.java b/sb4e/src/no/tobask/sb4e/JavaProjectGlossary.java
index afabc3ef44c3bbb1f5fe8442160bcab52e1b2743..cab56772c7308cf8402f1b2483bcb4e472b141ae 100644
--- a/sb4e/src/no/tobask/sb4e/JavaProjectGlossary.java
+++ b/sb4e/src/no/tobask/sb4e/JavaProjectGlossary.java
@@ -3,14 +3,10 @@ package no.tobask.sb4e;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Stack;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
 import org.eclipse.jdt.core.ElementChangedEvent;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IElementChangedListener;
@@ -25,7 +21,10 @@ import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import com.oracle.javafx.scenebuilder.app.info.InfoPanelController;
 import com.oracle.javafx.scenebuilder.kit.glossary.Glossary;
 
 import javafx.beans.value.ObservableValue;
@@ -34,25 +33,35 @@ import javafx.fxml.FXML;
 
 public class JavaProjectGlossary extends Glossary implements IElementChangedListener {
 
+	private static final String FXML_ANNOTATION = FXML.class.getSimpleName();
+	
 	private String controllerClassName;
+	private URL fxmlLocation;
+	private InfoPanelController infoPanelController;
+
 	private Map<String, List<String>> fxIds;
 	private List<String> eventHandlers;
-	private static final String FXML_ANNOTATION = FXML.class.getSimpleName();
+	private List<ICompilationUnit> candidateControllers;
 
-	public JavaProjectGlossary(String controllerClassName) {
+	public JavaProjectGlossary(String controllerClassName, URL fxmlLocation,
+			InfoPanelController infoPanelController) {
 		this.controllerClassName = controllerClassName;
-		JavaCore.addElementChangedListener(this, ElementChangedEvent.POST_CHANGE);
+		this.fxmlLocation = fxmlLocation;
+		this.infoPanelController = infoPanelController;
+		JavaCore.addElementChangedListener(this);
 	}
 
 	@Override
 	public List<String> queryControllerClasses(URL fxmlLocation) {
-		IJavaProject project = JavaModelUtils.getJavaProjectFromUrl(fxmlLocation);
-		String packageName = JavaModelUtils.getPackageContainingFile(fxmlLocation).getElementName();
-		List<ICompilationUnit> candidates = new ArrayList<>();
-		for (IPackageFragment pkg : JavaModelUtils.getAllMatchingPackages(packageName, project)) {
-			candidates.addAll(getCandidateControllers(pkg, fxmlLocation));
+		if (candidateControllers == null) {
+			IJavaProject project = JavaModelUtils.getJavaProjectFromUrl(fxmlLocation);
+			String packageName = JavaModelUtils.getPackageContainingFile(fxmlLocation).getElementName();
+			candidateControllers = new ArrayList<>();
+			for (IPackageFragment pkg : JavaModelUtils.getAllMatchingPackages(packageName, project)) {
+				candidateControllers.addAll(getCandidateControllers(pkg));
+			}
 		}
-		return candidates.stream().map(c -> c.getElementName()).collect(Collectors.toList());
+		return candidateControllers.stream().map(c -> c.getElementName()).collect(Collectors.toList());
 	}
 
 	@Override
@@ -82,62 +91,83 @@ public class JavaProjectGlossary extends Glossary implements IElementChangedList
 
 	@Override
 	public void elementChanged(ElementChangedEvent event) {
-		if (controllerClassName != null) {
-			ICompilationUnit controllerClass = getControllerClass(event);
-			if (controllerClass != null) {
-				fxIds = getFxIds(controllerClass);
-				eventHandlers = getEventHandlers(controllerClass);
+		IJavaElementDelta delta = getClassChangedDelta(event.getDelta());
+		if (delta != null) {
+			ICompilationUnit affectedClass = (ICompilationUnit) delta.getElement();
+			if (fxmlLocation != null && inSameProject(affectedClass)) {
+				if (updateControllerCandidates(delta)) {
+					infoPanelController.resetSuggestedControllerClasses(fxmlLocation);
+				}
+				
+				if (controllerClassName != null && affectedClass.getElementName()
+						.equals(controllerClassName) && delta.getKind() != IJavaElementDelta.REMOVED) {
+					fxIds = getFxIds(affectedClass);
+					eventHandlers = getEventHandlers(affectedClass);
+				}
 			}
 		}
 	}
-
-	private Collection<ICompilationUnit> getCandidateControllers(IPackageFragment pkg,
-			URL fxmlLocation) {
-		try {
-			List<ICompilationUnit> allUnits = new ArrayList<>(Arrays.asList(pkg.
-					getCompilationUnits()));
-			Stream<ICompilationUnit> matches = allUnits.stream().filter(u
-					-> isCandidateControllerClass(u, fxmlLocation));
-			return matches.collect(Collectors.toList());
-		} catch (JavaModelException e) {
-			e.printStackTrace();
-			return new ArrayList<>();
+	
+	private boolean updateControllerCandidates(IJavaElementDelta delta) {
+		boolean updated = false;
+		ICompilationUnit compUnit = (ICompilationUnit) delta.getElement();
+		if (delta.getKind() == IJavaElementDelta.REMOVED) {
+			if (candidateControllers.contains(compUnit)) {
+				candidateControllers.remove(compUnit);
+				updated = true;
+			}
+		} else {
+			CompilationUnit ast = delta.getCompilationUnitAST();
+			CompilationUnit clazz = ast != null ? ast : getAst(compUnit);
+			ControllerCandidateChecker checker = new ControllerCandidateChecker();
+			clazz.accept(checker);
+			boolean isCandidateController = checker.visitedCandidate();
+			if (candidateControllers.contains(compUnit)) {
+				if (!isCandidateController) {
+					candidateControllers.remove(compUnit);
+					updated = true;
+				}
+			} else if (isCandidateController) {
+				candidateControllers.add(compUnit);
+				updated = true;
+			}
 		}
+		return updated;
+	}
+			
+	private CompilationUnit getAst(ICompilationUnit source) {
+		ASTParser parser = ASTParser.newParser(AST.JLS9);
+		parser.setSource(source);
+		return (CompilationUnit) parser.createAST(null);
 	}
 
-	private boolean isCandidateControllerClass(ICompilationUnit javaClass, URL fxmlLocation) {
-		IType type = javaClass.findPrimaryType();
-		return hasNoOrEmptyConstructor(type) && hasFxmlAnnotatedMembers(type);
+	private IJavaElementDelta getClassChangedDelta(IJavaElementDelta rootDelta) {
+		IJavaElementDelta delta = rootDelta;
+		IJavaElement element = delta.getElement();
+		while (delta.getAffectedChildren().length > 0 &&
+				!(element.getElementType() == IJavaElement.COMPILATION_UNIT)) {
+			delta = delta.getAffectedChildren()[0];
+			element = delta.getElement();
+		}
+		return element.getElementType() == IJavaElement.COMPILATION_UNIT ? delta : null;
 	}
 	
-	private boolean hasFxmlAnnotatedMembers(IType type) {
-		try {
-			List<IMethod> methods = new ArrayList<>(Arrays.asList(type.getMethods()));
-			List<IField> fields = new ArrayList<>(Arrays.asList(type.getFields()));
-			boolean anyMethodsAnnotated = methods.stream().anyMatch(m ->
-					m.getAnnotation(FXML_ANNOTATION).exists());
-			boolean anyFieldsAnnotated = fields.stream().anyMatch(f -> 
-					f.getAnnotation(FXML_ANNOTATION).exists());
-			return anyFieldsAnnotated || anyMethodsAnnotated;
-		} catch (JavaModelException e) {
-			e.printStackTrace();
-			return false;
-		}
+	private boolean inSameProject(ICompilationUnit clazz) {
+		return clazz.getJavaProject().equals(JavaModelUtils.getJavaProjectFromUrl(fxmlLocation));
 	}
-
-	private boolean hasNoOrEmptyConstructor(IType type) {
+		
+	private List<ICompilationUnit> getCandidateControllers(IPackageFragment pkg) {
+		ASTParser parser = ASTParser.newParser(AST.JLS9);
+		Requestor requestor = new Requestor();
 		try {
-			for (IMethod method : type.getMethods()) {
-				if (method.isConstructor()) {
-					return method.getParameters().length == 0;
-				}
-			}
+			parser.createASTs(pkg.getCompilationUnits(), null, requestor, null);
+			return requestor.getCandidates();
 		} catch (JavaModelException e) {
 			e.printStackTrace();
+			return new ArrayList<>();
 		}
-		return true;
 	}
-		
+			
 	private List<String> getEventHandlers(ICompilationUnit controller) {
 		List<String> eventHandlers = new ArrayList<>();
 		IType type = controller.findPrimaryType();
@@ -206,22 +236,4 @@ public class JavaProjectGlossary extends Glossary implements IElementChangedList
 		}
 	}
 
-	private ICompilationUnit getControllerClass(ElementChangedEvent event) {
-		IJavaElementDelta rootDelta = event.getDelta();
-		Stack<IJavaElementDelta> queue = new Stack<>();
-		queue.push(rootDelta);
-		while (!queue.isEmpty()) {
-			IJavaElementDelta delta = queue.pop();
-			IJavaElement element = delta.getElement();
-			if (element instanceof ICompilationUnit &&
-					((ICompilationUnit) element).getElementName().equals(controllerClassName)) {
-				return (ICompilationUnit) element;
-			}
-			for (IJavaElementDelta childDelta : delta.getAffectedChildren()) {
-				queue.push(childDelta);
-			}
-		}
-		return null;
-	}
-
 }
diff --git a/sb4e/src/no/tobask/sb4e/Requestor.java b/sb4e/src/no/tobask/sb4e/Requestor.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d3db506eaa2c74521911d113ccbe13e99f46192
--- /dev/null
+++ b/sb4e/src/no/tobask/sb4e/Requestor.java
@@ -0,0 +1,27 @@
+package no.tobask.sb4e;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.dom.ASTRequestor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+public class Requestor extends ASTRequestor {
+	
+	private List<ICompilationUnit> candidates = new ArrayList<>();
+	
+	@Override
+	public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
+		ControllerCandidateChecker checker = new ControllerCandidateChecker();
+		ast.accept(checker);
+		if (checker.visitedCandidate()) {
+			candidates.add(source);
+		}
+	}
+	
+	public List<ICompilationUnit> getCandidates() {
+		return new ArrayList<>(candidates);
+	}
+
+}
diff --git a/sb4e/src/no/tobask/sb4e/editors/FXMLEditor.java b/sb4e/src/no/tobask/sb4e/editors/FXMLEditor.java
index 8178bb0d9b6f5046c877e375b6b9e1f390105686..b5840e2b863dc61ceb3de2738d260f1110267482 100644
--- a/sb4e/src/no/tobask/sb4e/editors/FXMLEditor.java
+++ b/sb4e/src/no/tobask/sb4e/editors/FXMLEditor.java
@@ -155,7 +155,8 @@ public class FXMLEditor extends EditorPart {
 			e.printStackTrace();
 		}
 		String controllerName = editorController.getFxomDocument().getFxomRoot().getFxController();
-		editorController.setGlossary(new JavaProjectGlossary(controllerName));
+		editorController.setGlossary(new JavaProjectGlossary(controllerName, fxmlUrl,
+				editorWindowController.infoPanelController));
 		canvas.setScene(editorWindowController.getScene());
 		editorController.getSelection().revisionProperty().addListener(editorSelectionListener);