Fix for Bug 355297 - Make infra structure around AbstractMarkable API
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/IMarkableJavaElement.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/IMarkableJavaElement.java
new file mode 100644
index 0000000..95e9ff9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/IMarkableJavaElement.java
@@ -0,0 +1,84 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2011 GK Software AG
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.core.ext;
+
+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.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Generalization over elements to which a marker can be attached:
+ * <ul>
+ * <li>resources representing source files
+ * <li>java elements representing binary class files
+ * </ul>
+ *
+ * @since 2.1.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMarkableJavaElement {
+
+	/** Name of this markable for use in the UI. */
+	String getName();
+
+	/** Remove all markers of the given IDs from this markable. */
+	void removeMarkers(String[] markerIds) throws CoreException;
+
+	/**
+	 * Answer the java element underlying this markable.
+	 * For binaries this is the IClassFile, otherwise an ICompilationUnit.
+	 */
+	IJavaElement getJavaElement();
+
+	/**
+	 * Answer the resource underlying this markable.
+	 * @see IJavaElement#getResource()
+	 */
+	IResource getResource();
+	
+	/** Create a real marker with the given ID. */
+	IMarker createMarker(String id) throws CoreException;
+	
+    /** Does this represent a real JavaElement (including existing ancestors)? */
+	boolean exists();
+	
+	/** Is underlying element binary / a classfile? */
+	boolean isBinary();
+
+	/** 
+	 * Get all types that contribute members to the current markable.
+	 * Contribution happens through containment (members) and inheritance. 
+	 */
+	Set<IType> getAllTypes(IJavaProject[] projects, IProgressMonitor monitor) throws CoreException;
+	
+	/**
+	 * Get all projects that could be relevant for searching.
+	 */
+	IJavaProject[] getProjects() throws JavaModelException;
+
+	/**
+	 * Is the given element contained in this markable?
+	 */
+	boolean containsElement(IJavaElement element);
+
+}
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/MarkableFactory.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/MarkableFactory.java
new file mode 100644
index 0000000..26dfa43
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/core/ext/MarkableFactory.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2011 GK Software AG
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * 	  Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.core.ext;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.objectteams.otdt.internal.core.ext.JavaElementMarkable;
+import org.eclipse.objectteams.otdt.internal.core.ext.ResourceMarkable;
+
+/**
+ * Factory for {@link IMarkableJavaElement elements} to which a marker can be attached.
+ * 
+ * @since 2.1.0
+ * @noextend This class is not intended to be extended by clients.
+ */
+public class MarkableFactory {
+
+	private MarkableFactory() {} // don't instantiate
+	
+	public static IMarkableJavaElement createMarkable(IResource resource) {
+		return new ResourceMarkable(resource);
+	}
+	
+	public static IMarkableJavaElement createMarkable(IJavaElement javaElement) {
+		IClassFile classFile = (IClassFile) javaElement.getAncestor(IJavaElement.CLASS_FILE);
+		if (classFile != null)
+			return new JavaElementMarkable(classFile);
+		else
+			return new ResourceMarkable(javaElement.getResource());
+	}
+}
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/AbstractMarkable.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/AbstractMarkable.java
new file mode 100644
index 0000000..4b81991
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/AbstractMarkable.java
@@ -0,0 +1,195 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008 Technical University Berlin, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * $Id: AbstractMarkable.java 23435 2010-02-04 00:14:38Z stephan $
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.core.ext;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import org.eclipse.objectteams.otdt.core.compiler.OTNameUtils;
+import org.eclipse.objectteams.otdt.core.ext.IMarkableJavaElement;
+
+
+/**
+ * Partial implementation of {@link IMarkableJavaElement}, as a shared base
+ * for concrete subclasses.
+ *
+ * @author stephan
+ * @since 1.2.5
+ */
+public abstract class AbstractMarkable implements IMarkableJavaElement {
+
+	final static String PDE_PLUGIN_NATURE_ID = "org.eclipse.pde.PluginNature"; //$NON-NLS-1$ // avoid importing org.eclipse.pde.core
+	
+	/**
+	 * Fetch the member and super types of type and add them to the given sets.
+	 * Works recursively.
+	 * 
+	 * @param members  all members, direct and indirect, including inherited members.
+	 * @param supers   all super types of this and its members.
+	 * @param type     focus type
+	 * @param currentProject the project of the current Markable, use this first when searching types.
+	 * @param projects       where to search for super types which are given by their name
+	 * @param monitor
+	 * @throws JavaModelException
+	 */
+	void addSuperAndMemberTypes(Set<IType> members, Set<IType> supers, IType type, IJavaProject currentProject, IJavaProject[] projects, IProgressMonitor monitor) 
+			throws JavaModelException 
+	{
+		if (!type.exists())
+			return; // mh?
+		
+		IType superType = null;
+		String superclassName = type.getSuperclassName();
+		String packageName = null;
+		String typeName = null;
+		if (superclassName != null) {
+			superclassName = superclassName.replace('$', '.');
+			if (superclassName.indexOf('.') != -1) {
+				// qualified, find the type directly:
+				superType = currentProject.findType(superclassName);
+			} else {
+				// resolve it now:
+				String[][] resolvedSuperName = type.resolveType(superclassName);
+				if (resolvedSuperName != null && resolvedSuperName.length == 1) {
+					packageName = resolvedSuperName[0][0];
+					typeName    = resolvedSuperName[0][1];
+					if (!(packageName.equals("java.lang") && typeName.equals("Object"))) //$NON-NLS-1$ //$NON-NLS-2$
+					{
+						superType = currentProject.findType(packageName, typeName, (IProgressMonitor)null);
+						
+						if (superType == null) 
+							for (IJavaProject prj : projects)
+								if ((superType = prj.findType(packageName, typeName, (IProgressMonitor)null)) != null)
+									break;
+					}
+				}
+			}
+		}
+
+		if (superType != null && !superType.isAnonymous()) {
+			supers.add(superType);
+			if (!members.contains(superType)) // avoid super-member-loop
+				addSuperAndMemberTypes(members, supers, superType, currentProject, projects, monitor);					
+		}
+
+		for (IType member : type.getTypes()) {
+			if (member.isInterface()) continue; // not currently bindable
+			if (   Flags.isRole(member.getFlags())
+				&& OTNameUtils.isTopConfined(member.getElementName())) continue; // confineds are not bound base
+			members.add(member);
+			if (!supers.contains(member)) // avoid super-member-loop
+				addSuperAndMemberTypes(members, supers, member, currentProject, projects, monitor);
+		}
+	}
+	/**
+	 * Get all direct and indirect subtypes of all types in 'types'.
+	 * @param types
+	 * @param monitor
+	 * @return
+	 * @throws JavaModelException
+	 */
+	Set<IType> getSubTypes(Set<IType> types, IProgressMonitor monitor) throws JavaModelException {
+		monitor.beginTask(OTCoreExtMessages.AbstractMarkable_baseClassHierarchy_progress, types.size());
+
+		IJavaSearchScope workspaceScope = SearchEngine.createWorkspaceScope();
+		Set<IType> subTypes = new HashSet<IType>(13);
+		for (IType type: types) {
+			TypeHierarchy hier = new TypeHierarchy(type, null, workspaceScope, true);
+			hier.refresh(monitor);
+			for(IType subType : hier.getSubtypes(type))
+				subTypes.add(subType);
+			monitor.worked(1);
+		}
+		monitor.done();
+		return subTypes;
+	}
+
+	/** Fetch projects from a resource or all workspace projects if resource === null */
+	IJavaProject[] getProjects(IResource resource) {
+		IJavaProject[] projects = null;
+        if (resource != null) {
+        	IProject project = resource.getProject();
+        	projects = getProjectsToSearch(project);
+        } else {
+        	IWorkspace ws = ResourcesPlugin.getWorkspace();
+        	ArrayList<IJavaProject> projectList = new ArrayList<IJavaProject>(); 
+        	for (IProject prj : ws.getRoot().getProjects())
+        		if (isOTProject(prj) && prj.isOpen()) // FIXME(SH): better project filtering
+        			projectList.add(JavaCore.create(prj));
+        	projects = projectList.toArray(new IJavaProject[projectList.size()]);
+        }
+		return projects;
+	}
+
+    private IJavaProject[] getProjectsToSearch(IProject baseProject)
+    {
+        Set<IJavaProject> result = new HashSet<IJavaProject>();
+        calculateProjectsToSearch(baseProject, result);
+        return result.toArray(new IJavaProject[result.size()]);
+    }
+        
+    private boolean isOTProject(IProject project)
+    {
+        try
+        {
+            return project.hasNature(JavaCore.OTJ_NATURE_ID);
+        }
+        catch (CoreException ex)
+        {
+	        return false;
+        }
+    }
+    
+    private boolean isPluginProject(IProject project)
+    {
+        try
+        {
+			return project.hasNature(PDE_PLUGIN_NATURE_ID);
+        }
+        catch (CoreException ex)
+        {
+	        return false;
+        }
+    }
+    
+    private void calculateProjectsToSearch(IProject currentProject, Set<IJavaProject> allProjectsFound)
+    {
+        if (isOTProject(currentProject))
+            allProjectsFound.add(JavaCore.create(currentProject));
+        
+//        if (isPluginProject(currentProject))
+//        	return; // don't search indirect dependencies of plug-in projects because aspectBindings must be declared directly 
+        
+        for(IProject referencingProject : currentProject.getReferencingProjects())
+        	calculateProjectsToSearch(referencingProject, allProjectsFound);
+    }
+}
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/JavaElementMarkable.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/JavaElementMarkable.java
new file mode 100644
index 0000000..6d09cf9
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/JavaElementMarkable.java
@@ -0,0 +1,140 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008 Technical University Berlin, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * $Id: JavaElementMarkable.java 23435 2010-02-04 00:14:38Z stephan $
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.core.ext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Implement markable protocol for IClassFile elements.
+ * 
+ * @author stephan
+ * @since 1.2.5
+ */
+public class JavaElementMarkable extends AbstractMarkable {
+	IClassFile fJavaElement;
+
+	/**
+	 * @param javaElement should actually be an IClassFile (otherwise use ResourceMarkable on the IFile (source file))
+	 */
+	public JavaElementMarkable(IClassFile javaElement) {
+		this.fJavaElement = javaElement;
+	}
+
+	public String getName() {
+		return this.fJavaElement.getElementName();
+	}
+	
+	public Set<IType> getAllTypes(IJavaProject[] projects, IProgressMonitor monitor) throws JavaModelException {
+		Set<IType> result = new HashSet<IType>(13);
+		
+		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 SubProgressMonitor(monitor, 5, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)));
+
+		monitor.done();
+		return result;
+	}
+
+	public void removeMarkers(String[] markerIds) throws CoreException {
+		if (this.fJavaElement.exists())
+		{
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+			for (IMarker marker : getAllMarkers(root, markerIds))
+				if (JavaCore.isReferencedBy(this.fJavaElement, marker))
+					marker.delete();
+    	}
+	}
+
+	private IMarker[] getAllMarkers(IResource resource, String[] markerIds) throws CoreException {
+		IMarker[][] markers = new IMarker[markerIds.length][];
+		int total = 0;
+		for (int i = 0; i < markerIds.length; i++) {
+			markers[i] = resource.findMarkers(markerIds[i], true, IResource.DEPTH_INFINITE);
+			total += markers[i].length;
+		}
+		IMarker[] result = new IMarker[total];
+		int offset = 0;
+		for (int i = 0; i < markerIds.length; i++) {
+			System.arraycopy(markers[i], 0, result, offset, markers[i].length);
+			offset += markers[i].length;
+		}
+		return result;
+	}
+
+	public IClassFile getJavaElement() {
+		return this.fJavaElement;
+	}
+	
+	public IResource getResource() {
+		return this.fJavaElement.getResource();
+	}
+	
+	public boolean containsElement(IJavaElement element) {
+		IJavaElement current = element;
+		while (current != null) {
+			if (current == this.fJavaElement)
+				return true;
+			current = current.getParent();
+		}
+		return false;
+	}
+
+	public boolean exists() {
+		return this.fJavaElement.exists();
+	}
+	
+	public boolean isBinary() {
+		return true;
+	}
+
+	public IJavaProject[] getProjects() throws JavaModelException {
+		// FIXME(SH): might want to lookup the project from a library??
+		return getProjects(this.fJavaElement.getCorrespondingResource());
+	}
+
+	public IMarker createMarker(String id) throws CoreException {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IMarker marker = root.createMarker(id);
+		((JavaCore)JavaCore.getPlugin()).configureJavaElementMarker(marker, this.fJavaElement);
+		return marker;
+	}
+
+}
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.java
index 84cce6f..94045da 100644
--- a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.java
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.java
@@ -28,6 +28,9 @@
 	public static String OTREContainer__Description;
 
 	public static String OTREContainer_otre_not_found;
+
+	public static String AbstractMarkable_baseClassHierarchy_progress;
+
 	static {
 		// initialize resource bundle
 		NLS.initializeMessages(BUNDLE_NAME, OTCoreExtMessages.class);
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.properties b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.properties
index 6a81b37..1295fb2 100644
--- a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.properties
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/OTCoreExtMessages.properties
@@ -1,2 +1,3 @@
 OTREContainer__Description=Object Teams Runtime Environment
 OTREContainer_otre_not_found=Cannot setup Object Teams ClassPath -- maybe otre.jar not found?
+AbstractMarkable_baseClassHierarchy_progress=base class hierarchy
diff --git a/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/ResourceMarkable.java b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/ResourceMarkable.java
new file mode 100644
index 0000000..a587e0a
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otdt/src/org/eclipse/objectteams/otdt/internal/core/ext/ResourceMarkable.java
@@ -0,0 +1,110 @@
+/**********************************************************************
+ * This file is part of "Object Teams Development Tooling"-Software
+ * 
+ * Copyright 2008 Technical University Berlin, Germany.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * $Id: ResourceMarkable.java 23435 2010-02-04 00:14:38Z stephan $
+ * 
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ * 
+ * Contributors:
+ * Technical University Berlin - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.objectteams.otdt.internal.core.ext;
+
+import java.util.HashSet;
+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.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Implement the markable protocol for resources.
+ * 
+ * @author stephan
+ * @since 1.2.5
+ */
+public class ResourceMarkable extends AbstractMarkable {
+	IResource  fResource;
+
+	public ResourceMarkable(IResource resource) {
+		this.fResource = resource;
+	}
+
+	public String getName() {
+		return this.fResource.getName();
+	}
+
+	public Set<IType> getAllTypes(IJavaProject[] projects, IProgressMonitor monitor) throws CoreException {
+		Set<IType> result = new HashSet<IType>(13);
+		IJavaElement element = JavaCore.create(this.fResource);
+		if (element instanceof ICompilationUnit) 
+		{			
+			Set<IType> members = new HashSet<IType>(5);
+			Set<IType> supers = new HashSet<IType>(5);
+			for (IType type : ((ICompilationUnit) element).getTypes()) {
+				members.add(type);	
+				addSuperAndMemberTypes(members, supers, type, JavaCore.create(this.fResource.getProject()), projects, monitor);
+			}
+			result.addAll(members);
+			result.addAll(supers);
+			monitor.worked(5);
+				
+			result.addAll(getSubTypes(members, new SubProgressMonitor(monitor, 5, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)));
+		}
+		return result;
+	}
+	public IJavaProject[] getProjects() throws JavaModelException {
+		return getProjects(this.fResource);
+	}
+
+	public void removeMarkers(String[] markerIds) throws CoreException {
+		if (this.fResource.exists())
+			for (String id : markerIds)
+				this.fResource.deleteMarkers(id, true, IResource.DEPTH_INFINITE);
+	}
+
+	public IJavaElement getJavaElement() {
+		return JavaCore.create(this.fResource);
+	}
+	
+	public IResource getResource() {
+		return this.fResource;
+	}
+
+	public boolean containsElement(IJavaElement element) {
+		return this.fResource.equals(element.getResource());
+	}
+	
+	public boolean exists() {
+		if (!this.fResource.exists()) return false;
+		IJavaElement javaElement = getJavaElement();
+		do {
+			if (!javaElement.exists())
+				return false;
+			javaElement = javaElement.getParent();
+		} while (javaElement.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		return true;
+	}
+
+	public boolean isBinary() {
+		return false;
+	}
+
+	public IMarker createMarker(String id) throws CoreException {
+		return this.fResource.createMarker(id);		
+	}
+}