Additional fixes for  Bug 317352 -  [ui] callin marker creator fires too many jobs
(see comment 5)
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarker.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarker.java
index 43ea883..00193ec 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarker.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarker.java
@@ -25,6 +25,7 @@
 import java.util.Set;
 
 import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IMember;
@@ -108,6 +109,19 @@
 		_attribs.clear(); // clear attributes for reuse of this object
     }
 
+	/** get all playedBy and callin markers for the given resource. */
+	public static IMarker[] getAllBindingMarkers(IResource resource) throws CoreException {
+		IMarker[] markers1 = resource.findMarkers(PLAYEDBY_ID, true, IResource.DEPTH_INFINITE);
+		IMarker[] markers2 = resource.findMarkers(CALLIN_ID, true, IResource.DEPTH_INFINITE);
+		IMarker[] markers3 = resource.findMarkers(CALLOUT_ID, true, IResource.DEPTH_INFINITE);
+		int len1 = markers1.length, len2 = markers2.length, len3 = markers3.length;
+		IMarker[] result = new IMarker[len1+len2+len3];
+		System.arraycopy(markers1, 0, result, 0, len1);
+		System.arraycopy(markers2, 0, result, len1, len2);
+		System.arraycopy(markers3, 0, result, len1+len2, len3);
+		return result;
+	}
+
 	public static boolean isTypeMarker(IMarker marker) {
 		try {
 			return marker.getType().equals(PLAYEDBY_ID);
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
index 2300b77..a6ad884 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerCreator2.java
@@ -55,6 +55,7 @@
 import org.eclipse.jdt.core.search.SearchMatch;
 import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.core.search.SearchRequestor;
+import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
 import org.eclipse.jface.action.IStatusLineManager;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.text.BadLocationException;
@@ -99,7 +100,7 @@
 	protected CallinMarkerJob _currentJob;
 	private Map<IJavaElement,IType> m_cachedBaseForRole = new HashMap<IJavaElement,IType>();
     private Set<IResource> m_cachedMarkersForResources = new HashSet<IResource>();
-    private Set<IJavaElement> m_cachedMarkersForJavaElements = new HashSet<IJavaElement>();
+    private Set<IClassFile> m_cachedMarkersForJavaElements = new HashSet<IClassFile>();
     private boolean m_enabled = false;
     protected AnnotationHelper annotationHelper;
 
@@ -184,33 +185,45 @@
 		}
 	}
 	public void invalidateBase(IJavaElement baseClass) {
-		invalidateBaseCU(baseClass.getAncestor(IJavaElement.COMPILATION_UNIT));
+		
+		IClassFile baseClassFile = (IClassFile) baseClass.getAncestor(IJavaElement.CLASS_FILE);
+		if (baseClassFile != null)
+			invalidateBaseMarkable(new JavaElementMarkable(baseClassFile));
+		else
+			invalidateBaseMarkable(new ResourceMarkable(baseClass.getResource()));
 	}
 
 	/** API for {@link RoleBindingChangedListener}. */
-	public void invalidateBaseCU(IJavaElement cu) {
-		if (cu != null) {
-			this.m_cachedMarkersForJavaElements.remove(cu);
-			IResource resource = null;
-			try {
-				resource = cu.getCorrespondingResource();
-			} catch (JavaModelException e) {
-				// ignore, just check for null below
-			}
-			if (resource != null)
-				this.m_cachedMarkersForResources.remove(resource);
+	public void invalidateBaseMarkable(AbstractMarkable baseMarkable) {
+		IEditorPart editor = (IEditorPart) this.fActiveEditor;
+		if (baseMarkable instanceof JavaElementMarkable) {
+			IClassFile baseJavaElement = ((JavaElementMarkable)baseMarkable).getJavaElement();
+			this.m_cachedMarkersForJavaElements.remove(baseJavaElement);
 			if (this.fActiveEditor != null && this.fActiveEditor instanceof IEditorPart) {
-				IEditorPart editor = (IEditorPart) this.fActiveEditor;
+				if (editor.getEditorInput() instanceof IClassFileEditorInput) {
+					IClassFile editorClassFile = ((IClassFileEditorInput)editor.getEditorInput()).getClassFile();
+					if (editorClassFile != null && !isCreatingMarkersFor(editorClassFile) && editorClassFile.equals(baseJavaElement))
+						updateForBaseMarkable(baseMarkable, editor);					
+				}
+			}
+		} else {
+			IResource baseResource = baseMarkable.getResource();
+			this.m_cachedMarkersForResources.remove(baseResource);
+			if (this.fActiveEditor != null && this.fActiveEditor instanceof IEditorPart) {
 				if (editor.getEditorInput() instanceof IFileEditorInput) {
 					IResource editorResource = ((IFileEditorInput)editor.getEditorInput()).getFile();
-					if (editorResource != null && !isCreatingMarkersFor(editorResource) && editorResource.equals(cu.getResource())) {
-						IStatusLineManager statusLine = editor.getEditorSite().getActionBars().getStatusLineManager();
-						updateCallinMarkers(new ResourceMarkable(editorResource), statusLine);
-					}
+					if (editorResource != null && !isCreatingMarkersFor(editorResource) && editorResource.equals(baseResource))
+						updateForBaseMarkable(baseMarkable, editor);
 				}
 			}
 		}
 	}
+
+	private void updateForBaseMarkable(AbstractMarkable baseMarkable,
+			IEditorPart editor) {
+		IStatusLineManager statusLine = editor.getEditorSite().getActionBars().getStatusLineManager();
+		updateCallinMarkers(baseMarkable, statusLine);
+	}
 	
     /**
      * When the editor input changed find the markable target and update markers.
@@ -234,16 +247,18 @@
 		this.annotationHelper = new AnnotationHelper(targetEditor, editorInput);
 		
 		AbstractMarkable target= null;
-		if ((editorInput instanceof IFileEditorInput)) { // source file
+		if ((editorInput instanceof IFileEditorInput)) { 			// source file
 			IResource resource = ((IFileEditorInput)editorInput).getFile();
 			if (resource == null || isCached(resource) || isCreatingMarkersFor(resource))
 				return; // already has markers -- skip it
 			target = new ResourceMarkable(resource);
-		} else {										 // binary java element
-			IJavaElement element = getInputJavaElement((IEditorPart) editor);
+		} else if (editorInput instanceof IClassFileEditorInput) {	// binary java element
+			IClassFile element = ((IClassFileEditorInput) editorInput).getClassFile();
 			if (element == null || isCached(element) || isCreatingMarkersFor(element))
 				return; // already has markers -- skip it
 			target = new JavaElementMarkable(element);
+		} else {
+			return; // unexpected editor input
 		}
 		
 		if (target.exists())
@@ -427,7 +442,7 @@
     {
         return m_cachedMarkersForResources.contains(resource);
     }
-    private boolean isCached(IJavaElement element)
+    private boolean isCached(IClassFile element)
     {
     	return m_cachedMarkersForJavaElements.contains(element);
     }
@@ -436,7 +451,7 @@
     {
         m_cachedMarkersForResources.add(resource);
     }
-    private void setCached(final IJavaElement element)
+    private void setCached(final IClassFile element)
     {
     	m_cachedMarkersForJavaElements.add(element);
     }
@@ -445,7 +460,7 @@
     {
         m_cachedMarkersForResources.remove(resource);
     }
-    private void removeFromCache(final IJavaElement element)
+    private void removeFromCache(final IClassFile element)
     {
         m_cachedMarkersForJavaElements.remove(element);
     }
@@ -744,9 +759,9 @@
 									}
 						    	} else if (!baseElement.isBinary()) {
 							    	if (nameRange.getOffset() < 0)
-							    		throw new BadLocationException("Offset must be >= 0, is "+nameRange.getOffset());
+							    		throw new BadLocationException("Offset must be >= 0, is "+nameRange.getOffset()); //$NON-NLS-1$
 							    	if (nameRange.getLength() < 0)
-							    		throw new BadLocationException("Length must be >= 0, is "+nameRange.getLength());
+							    		throw new BadLocationException("Length must be >= 0, is "+nameRange.getLength()); //$NON-NLS-1$
 						    	}
                             }
                             catch (BadLocationException ex) {
@@ -788,7 +803,7 @@
                     	else
                     		removeFromCache(resource);
                     else {
-                    	IJavaElement element = job.getJavaElement();
+                    	IClassFile element = job.getJavaElement();
                     	if (status == IStatus.OK)
                     		setCached(element);
                     	else
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerJob.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerJob.java
index 7234cb8..cf29642 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerJob.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerJob.java
@@ -25,7 +25,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
 
 /**
@@ -34,7 +34,7 @@
 public abstract class CallinMarkerJob extends org.eclipse.core.runtime.jobs.Job
 {
     private final IResource _resource;
-    private final IJavaElement _javaElement;
+    private final IClassFile _javaElement;
     
     public CallinMarkerJob(final AbstractMarkable target)
     {
@@ -75,7 +75,7 @@
         return this._resource;
     }
     
-    public final IJavaElement getJavaElement() 
+    public final IClassFile getJavaElement() 
     {
         return this._javaElement;
     }
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerRemover.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerRemover.java
index 00ae68e..a875acd 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerRemover.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/CallinMarkerRemover.java
@@ -26,8 +26,10 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
 
@@ -93,17 +95,17 @@
     }
     
 
-    public static void removeCallinMarkers(IJavaElement element) throws CoreException
+    public static void removeCallinMarkers(IClassFile element) throws CoreException
     {
 		if (element.exists())
 		{
 			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			IMarker[] allMarkers = CallinMarker.getAllBindingMarkers(root);
 			
-			// FIXME(SH): implement!
-//			resource.deleteMarkers(CallinMarker.ID, 
-//			        			   true, 
-//								   IResource.DEPTH_INFINITE);
-		}
+			for (IMarker marker : allMarkers)
+				if (JavaCore.isReferencedBy(element, marker))
+					marker.delete();
+    	}
     }
     
 
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/JavaElementMarkable.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/JavaElementMarkable.java
index 2e6106a..179b31a 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/JavaElementMarkable.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/JavaElementMarkable.java
@@ -33,18 +33,18 @@
 import org.eclipse.jdt.core.JavaModelException;
 
 /**
- * Implement markable protocol for java elements.
+ * Implement markable protocol for IClassFile elements.
  * 
  * @author stephan
  * @since 1.2.5
  */
 public class JavaElementMarkable extends AbstractMarkable {
-	IJavaElement fJavaElement;
+	IClassFile fJavaElement;
 
 	/**
 	 * @param javaElement should actually be an IClassFile (otherwise use ResourceMarkable on the IFile (source file))
 	 */
-	public JavaElementMarkable(IJavaElement javaElement) {
+	public JavaElementMarkable(IClassFile javaElement) {
 		this.fJavaElement = javaElement;
 	}
 
@@ -54,20 +54,19 @@
 	
 	public Set<IType> getAllTypes(IJavaProject[] projects, IProgressMonitor monitor) throws JavaModelException {
 		Set<IType> result = new HashSet<IType>(13);
-		if (this.fJavaElement instanceof IClassFile) {
-			
-			IType type = ((IClassFile)this.fJavaElement).getType();
+		
+		IType type = this.fJavaElement.getType();
 
-			Set<IType> members = new HashSet<IType>(5);
-			Set<IType> supers = new HashSet<IType>(5);
-			members.add(type);
-			addSuperAndMemberTypes(members, supers, type, this.fJavaElement.getJavaProject(), projects, monitor);
-			result.addAll(members);
-			result.addAll(supers);
-			monitor.worked(5);
-			
-			result.addAll(getSubTypes(members, new MySubProgressMonitor(monitor, 5)));
-		}
+		Set<IType> members = new HashSet<IType>(5);
+		Set<IType> supers = new HashSet<IType>(5);
+		members.add(type);
+		addSuperAndMemberTypes(members, supers, type, this.fJavaElement.getJavaProject(), projects, monitor);
+		result.addAll(members);
+		result.addAll(supers);
+		monitor.worked(5);
+		
+		result.addAll(getSubTypes(members, new MySubProgressMonitor(monitor, 5)));
+
 		monitor.done();
 		return result;
 	}
@@ -76,7 +75,7 @@
 		CallinMarkerRemover.removeCallinMarkers(this.fJavaElement);		
 	}
 
-	public IJavaElement getJavaElement() {
+	public IClassFile getJavaElement() {
 		return this.fJavaElement;
 	}
 	
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/RoleBindingChangedListener.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/RoleBindingChangedListener.java
index 7f2f91d..6106a32 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/RoleBindingChangedListener.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/internal/ui/callinmarkers/RoleBindingChangedListener.java
@@ -66,7 +66,7 @@
 		Set<ICompilationUnit> invalidatedCUs = new HashSet<ICompilationUnit>();
         updateCallinMarkers(new IJavaElementDelta[] { event.getDelta() }, invalidatedCUs);
         for (ICompilationUnit cu : invalidatedCUs)
-			OTDTUIPlugin.getDefault().getCallinMarkerCreator().invalidateBaseCU(cu);
+			OTDTUIPlugin.getDefault().getCallinMarkerCreator().invalidateBaseMarkable(new ResourceMarkable(cu.getResource()));
 	}
 
 	private void updateCallinMarkers(IJavaElementDelta[] deltas, Set<ICompilationUnit> invalidatedCUs)
diff --git a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/ui/UpdateRulerAction.java b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/ui/UpdateRulerAction.java
index a2bc831..bec775b 100644
--- a/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/ui/UpdateRulerAction.java
+++ b/plugins/org.eclipse.objectteams.otdt.ui/src/org/eclipse/objectteams/otdt/ui/UpdateRulerAction.java
@@ -25,7 +25,6 @@
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
@@ -140,13 +139,13 @@
 			IFileEditorInput fileEditorInput = (IFileEditorInput)editorInput;
 			IFile            file            = fileEditorInput.getFile();			
 	
-			IMarker[] result = getAllBindingMarkers(file);
+			IMarker[] result = CallinMarker.getAllBindingMarkers(file);
 			return result;
 		} 
 		else if (editorInput instanceof IClassFileEditorInput) 
 		{			
 			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-			IMarker[] allMarkers = getAllBindingMarkers(root);
+			IMarker[] allMarkers = CallinMarker.getAllBindingMarkers(root);
 			
 			// now we have all CallinMarkers for all class files in the workspace, need to filter now: 
 			IClassFile classFile = ((IClassFileEditorInput) editorInput).getClassFile();
@@ -159,19 +158,6 @@
 		return null;
 	}
 
-	/** get all playedBy and callin markers for the given resource. */
-	private IMarker[] getAllBindingMarkers(IResource resource) throws CoreException {
-		IMarker[] markers1 = resource.findMarkers(CallinMarker.PLAYEDBY_ID, true, IResource.DEPTH_INFINITE);
-		IMarker[] markers2 = resource.findMarkers(CallinMarker.CALLIN_ID, true, IResource.DEPTH_INFINITE);
-		IMarker[] markers3 = resource.findMarkers(CallinMarker.CALLOUT_ID, true, IResource.DEPTH_INFINITE);
-		int len1 = markers1.length, len2 = markers2.length, len3 = markers3.length;
-		IMarker[] result = new IMarker[len1+len2+len3];
-		System.arraycopy(markers1, 0, result, 0, len1);
-		System.arraycopy(markers2, 0, result, len1, len2);
-		System.arraycopy(markers3, 0, result, len1+len2, len3);
-		return result;
-	}
-
 	/** Get the context menu of kind 'markerKind', creating it if ondemand. */
     private IMenuManager getObjectTeamsMenu(IMenuManager contextMenu, String markerKind)
     {