Bug 477409 - Replace SubProgressMonitor with SubMonitor in
eclipse.platform.resources

Also converted non-Javadoc comments to Javadoc ones and did some other
minor cleanup.

Change-Id: Iddd5b615f0407a99aab37d3392a50e067b048dcf
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java
index ff3fad0..4f064bc 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Resource.java
@@ -54,7 +54,7 @@
 
 	@Override
 	public void accept(final IResourceProxyVisitor visitor, final int depth, final int memberFlags) throws CoreException {
-		// it is invalid to call accept on a phantom when INCLUDE_PHANTOMS is not specified
+		// It is invalid to call accept on a phantom when INCLUDE_PHANTOMS is not specified.
 		final boolean includePhantoms = (memberFlags & IContainer.INCLUDE_PHANTOMS) != 0;
 		if ((memberFlags & IContainer.DO_NOT_CHECK_EXISTENCE) == 0)
 			checkAccessible(getFlags(getResourceInfo(includePhantoms, false)));
@@ -83,7 +83,7 @@
 					}
 					return visitor.visit(proxy) && shouldContinue;
 				} catch (CoreException e) {
-					//throw an exception to bail out of the traversal
+					// Throw an exception to bail out of the traversal.
 					throw new WrappedRuntimeException(e);
 				} finally {
 					proxy.reset();
@@ -112,7 +112,7 @@
 
 	@Override
 	public void accept(final IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
-		//use the fast visitor if visiting to infinite depth
+		// Use the fast visitor if visiting to infinite depth.
 		if (depth == IResource.DEPTH_INFINITE) {
 			accept(new IResourceProxyVisitor() {
 				@Override
@@ -122,28 +122,28 @@
 			}, memberFlags);
 			return;
 		}
-		// it is invalid to call accept on a phantom when INCLUDE_PHANTOMS is not specified
+		// It is invalid to call accept on a phantom when INCLUDE_PHANTOMS is not specified.
 		final boolean includePhantoms = (memberFlags & IContainer.INCLUDE_PHANTOMS) != 0;
 		ResourceInfo info = getResourceInfo(includePhantoms, false);
 		int flags = getFlags(info);
 		if ((memberFlags & IContainer.DO_NOT_CHECK_EXISTENCE) == 0)
 			checkAccessible(flags);
 
-		//check that this resource matches the member flags
+		// Check that this resource matches the member flags
 		if (!isMember(flags, memberFlags))
 			return;
-		// visit this resource
+		// Visit this resource.
 		if (!visitor.visit(this) || depth == DEPTH_ZERO)
 			return;
-		// get the info again because it might have been changed by the visitor
+		// Get the info again because it might have been changed by the visitor.
 		info = getResourceInfo(includePhantoms, false);
 		if (info == null)
 			return;
-		// thread safety: (cache the type to avoid changes -- we might not be inside an operation)
+		// Thread safety: (cache the type to avoid changes -- we might not be inside an operation).
 		int type = info.getType();
 		if (type == FILE)
 			return;
-		// if we had a gender change we need to fix up the resource before asking for its members
+		// If we had a gender change we need to fix up the resource before asking for its members.
 		IContainer resource = getType() != type ? (IContainer) workspace.newResource(getFullPath(), type) : (IContainer) this;
 		IResource[] members = resource.members(memberFlags);
 		for (int i = 0; i < members.length; i++)
@@ -153,8 +153,8 @@
 	protected void assertCopyRequirements(IPath destination, int destinationType, int updateFlags) throws CoreException {
 		IStatus status = checkCopyRequirements(destination, destinationType, updateFlags);
 		if (!status.isOK()) {
-			// this assert is ok because the error cases generated by the
-			// check method above indicate assertion conditions.
+			// This assert is ok because the error cases generated by the check method above
+			// indicate assertion conditions.
 			Assert.isTrue(false, status.getChildren()[0].getMessage());
 		}
 	}
@@ -169,17 +169,17 @@
 		if ((updateFlags & IResource.REPLACE) == 0)
 			checkDoesNotExist(getFlags(getResourceInfo(false, false)), true);
 		IStatus locationStatus = workspace.validateLinkLocationURI(this, localLocation);
-		//we only tolerate an undefined path variable in the allow missing local case
+		// We only tolerate an undefined path variable in the allow missing local case.
 		final boolean variableUndefined = locationStatus.getCode() == IResourceStatus.VARIABLE_NOT_DEFINED_WARNING;
 		if (locationStatus.getSeverity() == IStatus.ERROR || (variableUndefined && !allowMissingLocal))
 			throw new ResourceException(locationStatus);
-		//check that the parent exists and is open
+		// Check that the parent exists and is open.
 		Container parent = (Container) getParent();
 		parent.checkAccessible(getFlags(parent.getResourceInfo(false, false)));
-		//if the variable is undefined we can't do any further checks
+		// If the variable is undefined we can't do any further checks.
 		if (variableUndefined)
 			return null;
-		//check if the file exists
+		// Check if the file exists.
 		URI resolved = getPathVariableManager().resolveURI(localLocation);
 		IFileStore store = EFS.getStore(resolved);
 		IFileInfo fileInfo = store.fetchInfo();
@@ -188,7 +188,7 @@
 			String msg = NLS.bind(Messages.links_localDoesNotExist, store.toString());
 			throw new ResourceException(IResourceStatus.NOT_FOUND_LOCAL, getFullPath(), msg, null);
 		}
-		//resource type and file system type must match
+		// Resource type and file system type must match.
 		if (localExists && ((getType() == IResource.FOLDER) != fileInfo.isDirectory())) {
 			String msg = NLS.bind(Messages.links_wrongLocalType, getFullPath());
 			throw new ResourceException(IResourceStatus.WRONG_TYPE_LOCAL, getFullPath(), msg, null);
@@ -199,8 +199,8 @@
 	protected void assertMoveRequirements(IPath destination, int destinationType, int updateFlags) throws CoreException {
 		IStatus status = checkMoveRequirements(destination, destinationType, updateFlags);
 		if (!status.isOK()) {
-			// this assert is ok because the error cases generated by the
-			// check method above indicate assertion conditions.
+			// This assert is ok because the error cases generated by the check method
+			// above indicate assertion conditions.
 			Assert.isTrue(false, status.getChildren()[0].getMessage());
 		}
 	}
@@ -252,13 +252,13 @@
 		Resource dest = workspace.newResource(destination, destinationType);
 		dest.checkDoesNotExist();
 
-		// ensure we aren't trying to copy a file to a project
+		// Ensure we aren't trying to copy a file to a project.
 		if (getType() == IResource.FILE && destinationType == IResource.PROJECT) {
 			message = Messages.resources_fileToProj;
 			throw new ResourceException(IResourceStatus.INVALID_VALUE, getFullPath(), message, null);
 		}
 
-		// we can't copy into a closed project
+		// We can't copy into a closed project.
 		if (destinationType != IResource.PROJECT) {
 			Project project = (Project) dest.getProject();
 			info = project.getResourceInfo(false, false);
@@ -270,8 +270,8 @@
 			}
 		}
 		if (isUnderLink() || dest.isUnderLink()) {
-			//make sure location is not null.  This can occur with linked resources relative to
-			//undefined path variables
+			// Make sure location is not null.  This can occur with linked resources relative to
+			// undefined path variables
 			URI sourceLocation = getLocationURI();
 			if (sourceLocation == null) {
 				message = NLS.bind(Messages.localstore_locationUndefined, getFullPath());
@@ -282,8 +282,8 @@
 				message = NLS.bind(Messages.localstore_locationUndefined, dest.getFullPath());
 				throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, dest.getFullPath(), message, null);
 			}
-			//make sure location of source is not a prefix of the location of the destination
-			//this can occur if the source and/or destination is a linked resource
+			// Make sure location of source is not a prefix of the location of the destination
+			// this can occur if the source and/or destination is a linked resource
 			if (getStore().isParentOf(dest.getStore())) {
 				message = NLS.bind(Messages.resources_copyDestNotSub, getFullPath());
 				throw new ResourceException(IResourceStatus.INVALID_VALUE, getFullPath(), message, null);
@@ -308,14 +308,14 @@
 	 * @exception CoreException if this resource exists
 	 */
 	public void checkDoesNotExist(int flags, boolean checkType) throws CoreException {
-		//if this exact resource exists we are done
+		// If this exact resource exists we are done.
 		if (exists(flags, checkType)) {
 			String message = NLS.bind(Messages.resources_mustNotExist, getFullPath());
 			throw new ResourceException(checkType ? IResourceStatus.RESOURCE_EXISTS : IResourceStatus.PATH_OCCUPIED, getFullPath(), message, null);
 		}
 		if (Workspace.caseSensitive)
 			return;
-		//now look for a matching case variant in the tree
+		// Now look for a matching case variant in the tree.
 		IResource variant = findExistingResourceVariant(getFullPath());
 		if (variant == null)
 			return;
@@ -384,18 +384,18 @@
 
 		Resource dest = workspace.newResource(destination, destinationType);
 
-		// check if we are only changing case
+		// Check if we are only changing case.
 		IResource variant = Workspace.caseSensitive ? null : findExistingResourceVariant(destination);
 		if (variant == null || !this.equals(variant))
 			dest.checkDoesNotExist();
 
-		// ensure we aren't trying to move a file to a project
+		// Ensure we aren't trying to move a file to a project.
 		if (getType() == IResource.FILE && dest.getType() == IResource.PROJECT) {
 			message = Messages.resources_fileToProj;
 			throw new ResourceException(new ResourceStatus(IResourceStatus.INVALID_VALUE, getFullPath(), message));
 		}
 
-		// we can't move into a closed project
+		// We can't move into a closed project.
 		if (destinationType != IResource.PROJECT) {
 			Project project = (Project) dest.getProject();
 			info = project.getResourceInfo(false, false);
@@ -407,8 +407,8 @@
 			}
 		}
 		if (isUnderLink() || dest.isUnderLink()) {
-			//make sure location is not null.  This can occur with linked resources relative to
-			//undefined path variables
+			// Make sure location is not null.  This can occur with linked resources relative to
+			// undefined path variables.
 			URI sourceLocation = getLocationURI();
 			if (sourceLocation == null) {
 				message = NLS.bind(Messages.localstore_locationUndefined, getFullPath());
@@ -419,8 +419,8 @@
 				message = NLS.bind(Messages.localstore_locationUndefined, dest.getFullPath());
 				throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, dest.getFullPath(), message, null);
 			}
-			//make sure location of source is not a prefix of the location of the destination
-			//this can occur if the source and/or destination is a linked resource
+			// Make sure location of source is not a prefix of the location of the destination
+			// this can occur if the source and/or destination is a linked resource.
 			if (getStore().isParentOf(dest.getStore())) {
 				message = NLS.bind(Messages.resources_moveDestNotSub, getFullPath());
 				throw new ResourceException(IResourceStatus.INVALID_VALUE, getFullPath(), message, null);
@@ -442,11 +442,9 @@
 	}
 
 	/**
-	 * Checks that the destination is a suitable one given that it could be a
-	 * group.
+	 * Checks that the destination is a suitable one given that it could be a group.
 	 *
-	 * @exception CoreException
-	 *                if the path points to a group
+	 * @exception CoreException if the path points to a group
 	 */
 	public void checkValidGroupContainer(IPath destination, boolean isLink, boolean isGroup) throws CoreException {
 		if (!isLink && !isGroup) {
@@ -458,11 +456,9 @@
 	}
 
 	/**
-	 * Checks that the destination is a suitable one given that it could be a
-	 * group.
+	 * Checks that the destination is a suitable one given that it could be a group.
 	 *
-	 * @exception CoreException
-	 *                if the path points to a group
+	 * @exception CoreException if the path points to a group
 	 */
 	public void checkValidGroupContainer(Container destination, boolean isLink, boolean isGroup) throws CoreException {
 		if (!isLink && !isGroup) {
@@ -491,7 +487,7 @@
 	public boolean contains(ISchedulingRule rule) {
 		if (this == rule)
 			return true;
-		//must allow notifications to nest in all resource rules
+		// Must allow notifications to nest in all resource rules.
 		if (rule.getClass().equals(WorkManager.NotifyRule.class))
 			return true;
 		if (rule instanceof MultiRule) {
@@ -521,7 +517,7 @@
 		info.set(M_PHANTOM);
 		getLocalManager().updateLocalSync(info, I_NULL_SYNC_INFO);
 		info.clearModificationStamp();
-		// should already be done by the #deleteResource call but left in
+		// Should already be done by the #deleteResource call but left in
 		// just to be safe and for code clarity.
 		info.setMarkers(null);
 	}
@@ -534,30 +530,24 @@
 
 	@Override
 	public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
+		String message = NLS.bind(Messages.resources_copying, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
+		destination = makePathAbsolute(destination);
+		checkValidPath(destination, getType(), false);
+		Resource destResource = workspace.newResource(destination, getType());
+		final ISchedulingRule rule = workspace.getRuleFactory().copyRule(this, destResource);
 		try {
-			monitor = Policy.monitorFor(monitor);
-			String message = NLS.bind(Messages.resources_copying, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			Policy.checkCanceled(monitor);
-			destination = makePathAbsolute(destination);
-			checkValidPath(destination, getType(), false);
-			Resource destResource = workspace.newResource(destination, getType());
-			final ISchedulingRule rule = workspace.getRuleFactory().copyRule(this, destResource);
-			try {
-				workspace.prepareOperation(rule, monitor);
-				// The following assert method throws CoreExceptions as stated in the IResource.copy API
-				// and assert for programming errors. See checkCopyRequirements for more information.
-				assertCopyRequirements(destination, getType(), updateFlags);
-				workspace.beginOperation(true);
-				getLocalManager().copy(this, destResource, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork));
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
-			}
+			workspace.prepareOperation(rule, progress.split(1));
+			// The following assert method throws CoreExceptions as stated in the IResource.copy API
+			// and assert for programming errors. See checkCopyRequirements for more information.
+			assertCopyRequirements(destination, getType(), updateFlags);
+			workspace.beginOperation(true);
+			getLocalManager().copy(this, destResource, updateFlags, progress.split(98));
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
@@ -567,50 +557,44 @@
 		copy(destDesc, updateFlags, monitor);
 	}
 
-	/* (non-Javadoc)
+	/**
 	 * Used when a folder is to be copied to a project.
 	 * @see IResource#copy(IProjectDescription, int, IProgressMonitor)
 	 */
 	@Override
 	public void copy(IProjectDescription destDesc, int updateFlags, IProgressMonitor monitor) throws CoreException {
 		Assert.isNotNull(destDesc);
-		monitor = Policy.monitorFor(monitor);
+		String message = NLS.bind(Messages.resources_copying, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
 		try {
-			String message = NLS.bind(Messages.resources_copying, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			try {
-				workspace.prepareOperation(workspace.getRoot(), monitor);
-				// The following assert method throws CoreExceptions as stated in the IResource.copy API
-				// and assert for programming errors. See checkCopyRequirements for more information.
-				IPath destPath = new Path(destDesc.getName()).makeAbsolute();
-				assertCopyRequirements(destPath, getType(), updateFlags);
-				Project destProject = (Project) workspace.getRoot().getProject(destPath.lastSegment());
-				workspace.beginOperation(true);
+			workspace.prepareOperation(workspace.getRoot(), progress.split(1));
+			// The following assert method throws CoreExceptions as stated in the IResource.copy API
+			// and assert for programming errors. See checkCopyRequirements for more information.
+			IPath destPath = new Path(destDesc.getName()).makeAbsolute();
+			assertCopyRequirements(destPath, getType(), updateFlags);
+			Project destProject = (Project) workspace.getRoot().getProject(destPath.lastSegment());
+			workspace.beginOperation(true);
 
-				// create and open the new project
-				destProject.create(destDesc, Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));
-				destProject.open(Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));
+			// Create and open the new project.
+			destProject.create(destDesc, progress.split(5));
+			destProject.open(progress.split(5));
 
-				// copy the children
-				// FIXME: fix the progress monitor here...create a sub monitor and do a worked(1) after each child instead
-				IResource[] children = ((IContainer) this).members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
-				for (int i = 0; i < children.length; i++) {
-					Resource child = (Resource) children[i];
-					child.copy(destPath.append(child.getName()), updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 60 / 100 / children.length));
-				}
-
-				// copy over the properties
-				getPropertyManager().copy(this, destProject, DEPTH_ZERO);
-				monitor.worked(Policy.opWork * 15 / 100);
-
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(workspace.getRoot(), true, Policy.subMonitorFor(monitor, Policy.endOpWork));
+			// Copy the children.
+			IResource[] children = ((IContainer) this).members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
+			SubMonitor loopProgress = SubMonitor.convert(progress.split(70), children.length);
+			for (int i = 0; i < children.length; i++) {
+				Resource child = (Resource) children[i];
+				child.copy(destPath.append(child.getName()), updateFlags, loopProgress.split(1));
 			}
+
+			// Copy over the properties.
+			getPropertyManager().copy(this, destProject, DEPTH_ZERO);
+			progress.step(18);
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(workspace.getRoot(), true, progress.split(1));
 		}
 	}
 
@@ -623,22 +607,21 @@
 		return workspace.countResources(path, depth, phantom);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.resources.IFolder#createLink(IPath, int, IProgressMonitor)
-	 * @see org.eclipse.core.resources.IFile#createLink(IPath, int, IProgressMonitor)
+	/**
+	 * @see IFolder#createLink(IPath, int, IProgressMonitor)
+	 * @see IFile#createLink(IPath, int, IProgressMonitor)
 	 */
 	public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException {
 		Assert.isNotNull(localLocation);
 		createLink(URIUtil.toURI(localLocation), updateFlags, monitor);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.resources.IFolder#createLink(URI, int, IProgressMonitor)
-	 * @see org.eclipse.core.resources.IFile#createLink(URI, int, IProgressMonitor)
+	/**
+	 * @see IFolder#createLink(URI, int, IProgressMonitor)
+	 * @see IFile#createLink(URI, int, IProgressMonitor)
 	 */
 	public void createLink(URI localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException {
 		Assert.isNotNull(localLocation);
-		monitor = Policy.monitorFor(monitor);
 		IResource existing = null;
 		if ((updateFlags & REPLACE) != 0) {
 			existing = workspace.getRoot().findMember(getFullPath());
@@ -647,63 +630,60 @@
 				return;
 			}
 		}
-		try {
-			String message = NLS.bind(Messages.links_creating, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			Policy.checkCanceled(monitor);
-			checkValidPath(path, FOLDER, true);
-			final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
-			try {
-				workspace.prepareOperation(rule, monitor);
-				IFileInfo fileInfo = assertLinkRequirements(localLocation, updateFlags);
-				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_CREATE, this));
-				workspace.beginOperation(true);
-				//replace existing resource, if applicable
-				if ((updateFlags & REPLACE) != 0) {
-					if (existing != null)
-						workspace.deleteResource(existing);
-				}
-				ResourceInfo info = workspace.createResource(this, false);
-				if ((updateFlags & IResource.HIDDEN) != 0)
-					info.set(M_HIDDEN);
-				info.set(M_LINK);
-				LinkDescription linkDescription = new LinkDescription(this, localLocation);
-				if (linkDescription.isGroup())
-					info.set(M_VIRTUAL);
-				getLocalManager().link(this, localLocation, fileInfo);
-				monitor.worked(Policy.opWork * 5 / 100);
-				//save the location in the project description
-				Project project = (Project) getProject();
-				boolean changed = project.internalGetDescription().setLinkLocation(getProjectRelativePath(), linkDescription);
-				if (changed)
-					try {
-						project.writeDescription(IResource.NONE);
-					} catch (CoreException e) {
-						// a problem happened updating the description, so delete the resource from the workspace
-						workspace.deleteResource(this);
-						throw e; // rethrow
-					}
-				monitor.worked(Policy.opWork * 5 / 100);
 
-				//refresh to discover any new resources below this linked location
-				if (getType() != IResource.FILE) {
-					//refresh either in background or foreground
-					if ((updateFlags & IResource.BACKGROUND_REFRESH) != 0) {
-						workspace.refreshManager.refresh(this);
-						monitor.worked(Policy.opWork * 90 / 100);
-					} else {
-						refreshLocal(DEPTH_INFINITE, Policy.subMonitorFor(monitor, Policy.opWork * 90 / 100));
-					}
-				} else
-					monitor.worked(Policy.opWork * 90 / 100);
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
+		String message = NLS.bind(Messages.links_creating, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
+		checkValidPath(path, FOLDER, true);
+		final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
+		try {
+			workspace.prepareOperation(rule, progress.split(1));
+			IFileInfo fileInfo = assertLinkRequirements(localLocation, updateFlags);
+			workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_CREATE, this));
+			workspace.beginOperation(true);
+			// Replace existing resource, if applicable.
+			if ((updateFlags & REPLACE) != 0 && existing != null) {
+				workspace.deleteResource(existing);
 			}
+			ResourceInfo info = workspace.createResource(this, false);
+			if ((updateFlags & IResource.HIDDEN) != 0)
+				info.set(M_HIDDEN);
+			info.set(M_LINK);
+			LinkDescription linkDescription = new LinkDescription(this, localLocation);
+			if (linkDescription.isGroup())
+				info.set(M_VIRTUAL);
+			getLocalManager().link(this, localLocation, fileInfo);
+			progress.step(5);
+			// Save the location in the project description.
+			Project project = (Project) getProject();
+			boolean changed = project.internalGetDescription().setLinkLocation(getProjectRelativePath(), linkDescription);
+			if (changed) {
+				try {
+					project.writeDescription(IResource.NONE);
+				} catch (CoreException e) {
+					// A problem happened updating the description, so delete the resource from the workspace.
+					workspace.deleteResource(this);
+					throw e; // Rethrow.
+				}
+			}
+			progress.step(4);
+
+			// Refresh to discover any new resources below this linked location.
+			if (getType() != IResource.FILE) {
+				// Refresh either in background or foreground.
+				if ((updateFlags & IResource.BACKGROUND_REFRESH) != 0) {
+					workspace.refreshManager.refresh(this);
+					progress.step(90);
+				} else {
+					refreshLocal(DEPTH_INFINITE, progress.split(90));
+				}
+			} else {
+				progress.step(90);
+			}
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
@@ -734,7 +714,7 @@
 		return result;
 	}
 
-	/* (non-Javadoc)
+	/**
 	 * @see IProject#delete(boolean, boolean, IProgressMonitor)
 	 * @see IWorkspaceRoot#delete(boolean, boolean, IProgressMonitor)
 	 * N.B. This is not an IResource method!
@@ -752,65 +732,60 @@
 
 	@Override
 	public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		String message = NLS.bind(Messages.resources_deleting, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, 100).checkCanceled();
+		progress.subTask(message);
+		final ISchedulingRule rule = workspace.getRuleFactory().deleteRule(this);
 		try {
-			String message = NLS.bind(Messages.resources_deleting, getFullPath());
-			monitor.beginTask("", Policy.totalWork * 1000); //$NON-NLS-1$
-			monitor.subTask(message);
-			final ISchedulingRule rule = workspace.getRuleFactory().deleteRule(this);
+			workspace.prepareOperation(rule, progress.split(1));
+			// If there is no resource then there is nothing to delete so just return.
+			if (!exists())
+				return;
+			workspace.beginOperation(true);
+			broadcastPreDeleteEvent();
+
+			// When a project is being deleted, flush the build order in case there is a problem.
+			if (this.getType() == IResource.PROJECT)
+				workspace.flushBuildOrder();
+
+			final IFileStore originalStore = getStore();
+			boolean wasLinked = isLinked();
+			message = Messages.resources_deleteProblem;
+			MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_DELETE_LOCAL, message, null);
+			WorkManager workManager = workspace.getWorkManager();
+			ResourceTree tree = new ResourceTree(workspace.getFileSystemManager(), workManager.getLock(), status, updateFlags);
+			int depth = 0;
 			try {
-				workspace.prepareOperation(rule, monitor);
-				// if there is no resource then there is nothing to delete so just return
-				if (!exists())
-					return;
-				workspace.beginOperation(true);
-				broadcastPreDeleteEvent();
-
-				// when a project is being deleted, flush the build order in case there is a problem
-				if (this.getType() == IResource.PROJECT)
-					workspace.flushBuildOrder();
-
-				final IFileStore originalStore = getStore();
-				boolean wasLinked = isLinked();
-				message = Messages.resources_deleteProblem;
-				MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_DELETE_LOCAL, message, null);
-				WorkManager workManager = workspace.getWorkManager();
-				ResourceTree tree = new ResourceTree(workspace.getFileSystemManager(), workManager.getLock(), status, updateFlags);
-				int depth = 0;
-				try {
-					depth = workManager.beginUnprotected();
-					unprotectedDelete(tree, updateFlags, monitor);
-				} finally {
-					workManager.endUnprotected(depth);
-				}
-				if (getType() == ROOT) {
-					// need to clear out the root info
-					workspace.getMarkerManager().removeMarkers(this, IResource.DEPTH_ZERO);
-					getPropertyManager().deleteProperties(this, IResource.DEPTH_ZERO);
-					getResourceInfo(false, false).clearSessionProperties();
-				}
-				// Invalidate the tree for further use by clients.
-				tree.makeInvalid();
-				if (!tree.getStatus().isOK())
-					throw new ResourceException(tree.getStatus());
-				//update any aliases of this resource
-				//note that deletion of a linked resource cannot affect other resources
-				if (!wasLinked)
-					workspace.getAliasManager().updateAliases(this, originalStore, IResource.DEPTH_INFINITE, monitor);
-				if (getType() == PROJECT) {
-					// make sure the rule factory is cleared on project deletion
-					((Rules) workspace.getRuleFactory()).setRuleFactory((IProject) this, null);
-					// make sure project deletion is remembered
-					workspace.getSaveManager().requestSnapshot();
-				}
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
+				depth = workManager.beginUnprotected();
+				unprotectedDelete(tree, updateFlags, progress.split(50));
 			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork * 1000));
+				workManager.endUnprotected(depth);
 			}
+			if (getType() == ROOT) {
+				// Need to clear out the root info.
+				workspace.getMarkerManager().removeMarkers(this, IResource.DEPTH_ZERO);
+				getPropertyManager().deleteProperties(this, IResource.DEPTH_ZERO);
+				getResourceInfo(false, false).clearSessionProperties();
+			}
+			// Invalidate the tree for further use by clients.
+			tree.makeInvalid();
+			if (!tree.getStatus().isOK())
+				throw new ResourceException(tree.getStatus());
+			// Update any aliases of this resource.
+			// Note that deletion of a linked resource cannot affect other resources.
+			if (!wasLinked)
+				workspace.getAliasManager().updateAliases(this, originalStore, IResource.DEPTH_INFINITE, progress.split(48));
+			if (getType() == PROJECT) {
+				// Make sure the rule factory is cleared on project deletion.
+				((Rules) workspace.getRuleFactory()).setRuleFactory((IProject) this, null);
+				// Make sure project deletion is remembered.
+				workspace.getSaveManager().requestSnapshot();
+			}
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
@@ -835,20 +810,21 @@
 	 * added, otherwise they are thrown.  If major exceptions occur, they are always thrown.
 	 */
 	public void deleteResource(boolean convertToPhantom, MultiStatus status) throws CoreException {
-		// remove markers on this resource and its descendents
+		// Remove markers on this resource and its descendants.
 		if (exists())
 			getMarkerManager().removeMarkers(this, IResource.DEPTH_INFINITE);
-		// if this is a linked resource or contains linked resources , remove their entries from the project description
+		// If this is a linked resource or contains linked resources,
+		// remove their entries from the project description.
 		List<Resource> links = findLinks();
-		//pre-delete notification to internal infrastructure
+		// Pre-delete notification to internal infrastructure
 		if (links != null)
 			for (Iterator<Resource> it = links.iterator(); it.hasNext();)
 				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_DELETE, it.next()));
 
-		// check if we deleted a preferences file
+		// Check if we deleted a preferences file.
 		ProjectPreferences.deleted(this);
 
-		//remove all deleted linked resources from the project description
+		// Remove all deleted linked resources from the project description.
 		if (getType() != IResource.PROJECT && links != null) {
 			Project project = (Project) getProject();
 			ProjectDescription description = project.internalGetDescription();
@@ -861,24 +837,25 @@
 					try {
 						project.writeDescription(IResource.FORCE);
 					} catch (CoreException e) {
-						// a problem happened updating the description, update the description in memory
+						// A problem happened updating the description, update the description in memory.
 						project.updateDescription();
-						throw e; // rethrow
+						throw e; // Rethrow.
 					}
 				}
 			}
 		}
 
-		/* if we are synchronizing, do not delete the resource. Convert it
-		 into a phantom. Actual deletion will happen when we refresh or push. */
-		if (convertToPhantom && getType() != PROJECT && synchronizing(getResourceInfo(true, false)))
+		// If we are synchronizing, do not delete the resource. Convert it
+		// into a phantom. Actual deletion will happen when we refresh or push.
+		if (convertToPhantom && getType() != PROJECT && synchronizing(getResourceInfo(true, false))) {
 			convertToPhantom();
-		else
+		} else {
 			workspace.deleteResource(this);
+		}
 
 		List<Resource> filters = findFilters();
 		if ((filters != null) && (filters.size() > 0)) {
-			// delete resource filters
+			// Delete resource filters.
 			Project project = (Project) getProject();
 			ProjectDescription description = project.internalGetDescription();
 			if (description != null) {
@@ -894,18 +871,18 @@
 		try {
 			getPropertyManager().deleteResource(this);
 		} catch (CoreException e) {
-			if (status != null)
+			if (status != null) {
 				status.add(e.getStatus());
-			else
+			} else {
 				err = e;
+			}
 		}
 		if (err != null)
 			throw err;
 	}
 
-	/*
-	 * Returns a list of all linked resources at or below this resource, or null if there
-	 * are no links.
+	/**
+	 * Returns a list of all linked resources at or below this resource, or null if there are no links.
 	 */
 	private List<Resource> findLinks() {
 		Project project = (Project) getProject();
@@ -927,9 +904,8 @@
 		return links;
 	}
 
-	/*
-	 * Returns a list of all filtered resources at or below this resource, or null if there
-	 * are no links.
+	/**
+	 * Returns a list of all filtered resources at or below this resource, or null if there are no links.
 	 */
 	private List<Resource> findFilters() {
 		Project project = (Project) getProject();
@@ -980,11 +956,11 @@
 	public IResource findExistingResourceVariant(IPath target) {
 		if (!workspace.tree.includesIgnoreCase(target))
 			return null;
-		//ignore phantoms
+		// Ignore phantoms.
 		ResourceInfo info = (ResourceInfo) workspace.tree.getElementDataIgnoreCase(target);
 		if (info != null && info.isSet(M_PHANTOM))
 			return null;
-		//resort to slow lookup to find exact case variant
+		// Resort to slow lookup to find exact case variant.
 		IPath result = Path.ROOT;
 		int segmentCount = target.segmentCount();
 		for (int i = 0; i < segmentCount; i++) {
@@ -1007,8 +983,7 @@
 		ResourceInfo info = getResourceInfo(false, false);
 		checkAccessible(getFlags(info));
 		// It might happen that from this point the resource is not accessible anymore.
-		// But markers have the #exists method that callers can use to check if it is
-		// still valid.
+		// But markers have the #exists method that callers can use to check if it is still valid.
 		return workspace.getMarkerManager().findMarkers(this, type, includeSubtypes, depth);
 	}
 
@@ -1017,8 +992,7 @@
 		ResourceInfo info = getResourceInfo(false, false);
 		checkAccessible(getFlags(info));
 		// It might happen that from this point the resource is not accessible anymore.
-		// But markers have the #exists method that callers can use to check if it is
-		// still valid.
+		// But markers have the #exists method that callers can use to check if it is still valid.
 		return workspace.getMarkerManager().findMaxProblemSeverity(this, type, includeSubtypes, depth);
 	}
 
@@ -1037,7 +1011,7 @@
 
 	protected void fixupAfterMoveSource() throws CoreException {
 		ResourceInfo info = getResourceInfo(true, true);
-		//if a linked resource is moved, we need to remove the location info from the .project
+		// If a linked resource is moved, we need to remove the location info from the ".project" file.
 		if (isLinked() || isVirtual()) {
 			Project project = (Project) getProject();
 			if (project.internalGetDescription().setLinkLocation(getProjectRelativePath(), null))
@@ -1046,7 +1020,7 @@
 
 		List<Resource> filters = findFilters();
 		if ((filters != null) && (filters.size() > 0)) {
-			// delete resource filters
+			// Delete resource filters.
 			Project project = (Project) getProject();
 			ProjectDescription description = project.internalGetDescription();
 			for (Iterator<Resource> it = filters.iterator(); it.hasNext();)
@@ -1054,7 +1028,7 @@
 			project.writeDescription(IResource.NONE);
 		}
 
-		// check if we deleted a preferences file
+		// Check if we deleted a preferences file.
 		ProjectPreferences.deleted(this);
 
 		if (!synchronizing(info)) {
@@ -1138,7 +1112,7 @@
 	@Override
 	public IContainer getParent() {
 		int segments = path.segmentCount();
-		//zero and one segments handled by subclasses
+		// Zero and one segments handled by subclasses.
 		if (segments < 2)
 			Assert.isLegal(false, path.toString());
 		if (segments == 2)
@@ -1242,7 +1216,7 @@
 
 	@Override
 	public int hashCode() {
-		// the container may be null if the identified resource
+		// The container may be null if the identified resource
 		// does not exist so don't bother with it in the hash
 		return getFullPath().hashCode();
 	}
@@ -1253,7 +1227,7 @@
 	 */
 	protected void internalSetLocal(boolean flag, int depth) throws CoreException {
 		ResourceInfo info = getResourceInfo(true, true);
-		//only make the change if it's not already in desired state
+		// Only make the change if it's not already in desired state.
 		if (info.isSet(M_LOCAL_EXISTS) != flag) {
 			if (flag && !isPhantom(getFlags(info))) {
 				info.set(M_LOCAL_EXISTS);
@@ -1281,7 +1255,7 @@
 	public boolean isConflicting(ISchedulingRule rule) {
 		if (this == rule)
 			return true;
-		//must not schedule at same time as notification
+		// Must not schedule at same time as notification.
 		if (rule.getClass().equals(WorkManager.NotifyRule.class))
 			return true;
 		if (rule instanceof MultiRule) {
@@ -1312,7 +1286,7 @@
 		int flags = getFlags(info);
 		if (flags != NULL_FLAG && ResourceInfo.isSet(flags, ICoreConstants.M_DERIVED))
 			return true;
-		// check ancestors if the appropriate option is set
+		// Check ancestors if the appropriate option is set.
 		if ((options & CHECK_ANCESTORS) != 0)
 			return getParent().isDerived(options);
 		return false;
@@ -1331,7 +1305,7 @@
 		int flags = getFlags(info);
 		if (flags != NULL_FLAG && ResourceInfo.isSet(flags, ICoreConstants.M_HIDDEN))
 			return true;
-		// check ancestors if the appropriate option is set
+		// Check ancestors if the appropriate option is set.
 		if ((options & CHECK_ANCESTORS) != 0)
 			return getParent().isHidden(options);
 		return false;
@@ -1361,7 +1335,7 @@
 			}
 			return false;
 		}
-		//the no ancestor checking case
+		// The no ancestor checking case.
 		ResourceInfo info = getResourceInfo(false, false);
 		return info != null && info.isSet(M_LINK);
 	}
@@ -1372,8 +1346,8 @@
 		return info != null && info.isSet(M_VIRTUAL);
 	}
 
-	/*
-	 * @return whether the current resource has a parent that is virtual.
+	/**
+	 * Checks whether the current resource has a parent that is virtual.
 	 */
 	public boolean isUnderVirtual() {
 		IContainer parent = getParent();
@@ -1394,7 +1368,7 @@
 
 	/**
 	 * Note the depth parameter is intentionally ignored because
-	 * this method is over-ridden by Container.isLocal().
+	 * this method is over-ridden by {@link Container#isLocal(int)}.
 	 * @deprecated
 	 */
 	@Deprecated
@@ -1420,7 +1394,7 @@
 			excludeMask |= M_TEAM_PRIVATE_MEMBER;
 		if ((memberFlags & IContainer.EXCLUDE_DERIVED) != 0)
 			excludeMask |= M_DERIVED;
-		//the resource is a matching member if it matches none of the exclude flags
+		// The resource is a matching member if it matches none of the exclude flags.
 		return flags != NULL_FLAG && (flags & excludeMask) == 0;
 	}
 
@@ -1438,7 +1412,7 @@
 	@Override
 	public boolean isReadOnly() {
 		final ResourceAttributes attributes = getResourceAttributes();
-		return attributes == null ? false : attributes.isReadOnly();
+		return attributes != null && attributes.isReadOnly();
 	}
 
 	@Override
@@ -1459,7 +1433,7 @@
 		int flags = getFlags(info);
 		if (flags != NULL_FLAG && ResourceInfo.isSet(flags, ICoreConstants.M_TEAM_PRIVATE_MEMBER))
 			return true;
-		// check ancestors if the appropriate option is set
+		// Check ancestors if the appropriate option is set.
 		if ((options & CHECK_ANCESTORS) != 0)
 			return getParent().isTeamPrivateMember(options);
 		return false;
@@ -1475,7 +1449,7 @@
 			return false;
 		if (depth == 2)
 			return isLinked();
-		//check if parent at depth two is a link
+		// Check if parent at depth two is a link.
 		IPath linkParent = path.removeLastSegments(depth - 2);
 		return workspace.getResourceInfo(linkParent, false, false).isSet(ICoreConstants.M_LINK);
 	}
@@ -1486,7 +1460,7 @@
 		return getParent().getFullPath().append(target);
 	}
 
-	/* (non-Javadoc)
+	/**
 	 * @see IFile#move(IPath, boolean, boolean, IProgressMonitor)
 	 * @see IFolder#move(IPath, boolean, boolean, IProgressMonitor)
 	 */
@@ -1503,55 +1477,49 @@
 
 	@Override
 	public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		String message = NLS.bind(Messages.resources_moving, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
+		destination = makePathAbsolute(destination);
+		checkValidPath(destination, getType(), false);
+		Resource destResource = workspace.newResource(destination, getType());
+		final ISchedulingRule rule = workspace.getRuleFactory().moveRule(this, destResource);
 		try {
-			String message = NLS.bind(Messages.resources_moving, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			Policy.checkCanceled(monitor);
-			destination = makePathAbsolute(destination);
-			checkValidPath(destination, getType(), false);
-			Resource destResource = workspace.newResource(destination, getType());
-			final ISchedulingRule rule = workspace.getRuleFactory().moveRule(this, destResource);
+			workspace.prepareOperation(rule, progress.split(1));
+			// The following assert method throws CoreExceptions as stated in the IResource.move API
+			// and assert for programming errors. See checkMoveRequirements for more information.
+			assertMoveRequirements(destination, getType(), updateFlags);
+			workspace.beginOperation(true);
+			broadcastPreMoveEvent(destResource, updateFlags);
+			IFileStore originalStore = getStore();
+			message = Messages.resources_moveProblem;
+			MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, null);
+			WorkManager workManager = workspace.getWorkManager();
+			ResourceTree tree = new ResourceTree(workspace.getFileSystemManager(), workManager.getLock(), status, updateFlags);
+			boolean success = false;
+			int depth = 0;
 			try {
-				workspace.prepareOperation(rule, monitor);
-				// The following assert method throws CoreExceptions as stated in the IResource.move API
-				// and assert for programming errors. See checkMoveRequirements for more information.
-				assertMoveRequirements(destination, getType(), updateFlags);
-				workspace.beginOperation(true);
-				broadcastPreMoveEvent(destResource, updateFlags);
-				IFileStore originalStore = getStore();
-				message = Messages.resources_moveProblem;
-				MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, null);
-				WorkManager workManager = workspace.getWorkManager();
-				ResourceTree tree = new ResourceTree(workspace.getFileSystemManager(), workManager.getLock(), status, updateFlags);
-				boolean success = false;
-				int depth = 0;
-				try {
-					depth = workManager.beginUnprotected();
-					success = unprotectedMove(tree, destResource, updateFlags, monitor);
-				} finally {
-					workManager.endUnprotected(depth);
-				}
-				// Invalidate the tree for further use by clients.
-				tree.makeInvalid();
-				//update any aliases of this resource and the destination
-				if (success) {
-					workspace.getAliasManager().updateAliases(this, originalStore, IResource.DEPTH_INFINITE, monitor);
-					workspace.getAliasManager().updateAliases(destResource, destResource.getStore(), IResource.DEPTH_INFINITE, monitor);
-				}
-				if (!tree.getStatus().isOK())
-					throw new ResourceException(tree.getStatus());
-				// if this is a project, make sure the move operation is remembered
-				if (getType() == PROJECT)
-					workspace.getSaveManager().requestSnapshot();
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
+				depth = workManager.beginUnprotected();
+				success = unprotectedMove(tree, destResource, updateFlags, progress.split(50));
 			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
+				workManager.endUnprotected(depth);
 			}
+			// Invalidate the tree for further use by clients.
+			tree.makeInvalid();
+			// Update any aliases of this resource and the destination.
+			if (success) {
+				workspace.getAliasManager().updateAliases(this, originalStore, IResource.DEPTH_INFINITE, progress.split(24));
+				workspace.getAliasManager().updateAliases(destResource, destResource.getStore(), IResource.DEPTH_INFINITE, progress.split(24));
+			}
+			if (!tree.getStatus().isOK())
+				throw new ResourceException(tree.getStatus());
+			// If this is a project, make sure the move operation is remembered.
+			if (getType() == PROJECT)
+				workspace.getSaveManager().requestSnapshot();
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
@@ -1574,32 +1542,27 @@
 
 	@Override
 	public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		boolean isRoot = getType() == ROOT;
+		String message = isRoot ? Messages.resources_refreshingRoot : NLS.bind(Messages.resources_refreshing, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, 100).checkCanceled();
+		progress.subTask(message);
+		boolean build = false;
+		final ISchedulingRule rule = workspace.getRuleFactory().refreshRule(this);
 		try {
-			boolean isRoot = getType() == ROOT;
-			String message = isRoot ? Messages.resources_refreshingRoot : NLS.bind(Messages.resources_refreshing, getFullPath());
-			monitor.beginTask("", Policy.totalWork); //$NON-NLS-1$
-			monitor.subTask(message);
-			boolean build = false;
-			final ISchedulingRule rule = workspace.getRuleFactory().refreshRule(this);
-			try {
-				workspace.prepareOperation(rule, monitor);
-				if (!isRoot && !getProject().isAccessible())
-					return;
-				if (!exists() && isFiltered())
-					return;
-				workspace.beginOperation(true);
-				if (getType() == IResource.PROJECT || getType() == IResource.ROOT)
-					workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_REFRESH, this));
-				build = getLocalManager().refresh(this, depth, true, Policy.subMonitorFor(monitor, Policy.opWork));
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(rule, build, Policy.subMonitorFor(monitor, Policy.endOpWork));
-			}
+			workspace.prepareOperation(rule, progress.split(1));
+			if (!isRoot && !getProject().isAccessible())
+				return;
+			if (!exists() && isFiltered())
+				return;
+			workspace.beginOperation(true);
+			if (getType() == IResource.PROJECT || getType() == IResource.ROOT)
+				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_REFRESH, this));
+			build = getLocalManager().refresh(this, depth, true, progress.split(98));
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, build, progress.split(1));
 		}
 	}
 
@@ -1617,8 +1580,8 @@
 	public void revertModificationStamp(long value) throws CoreException {
 		if (value < 0)
 			throw new IllegalArgumentException("Illegal value: " + value); //$NON-NLS-1$
-		// fetch the info but don't bother making it mutable even though we are going
-		// to modify it. It really doesn't matter as the change we are doing does not show up in deltas.
+		// Fetch the info but don't bother making it mutable even though we are going to modify it.
+		// It really doesn't matter as the change we are making does not show up in deltas.
 		ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO);
 		info.setModificationStamp(value);
 	}
@@ -1626,13 +1589,13 @@
 	@Deprecated
 	@Override
 	public void setDerived(boolean isDerived) throws CoreException {
-		// fetch the info but don't bother making it mutable even though we are going
+		// Fetch the info but don't bother making it mutable even though we are going
 		// to modify it.  We don't know whether or not the tree is open and it really doesn't
-		// matter as the change we are doing does not show up in deltas.
+		// matter as the change we are making does not show up in deltas.
 		ResourceInfo info = getResourceInfo(false, false);
 		int flags = getFlags(info);
 		checkAccessible(flags);
-		// ignore attempts to set derived flag on anything except files and folders
+		// Ignore attempts to set derived flag on anything except files and folders
 		if (info.getType() == FILE || info.getType() == FOLDER) {
 			if (isDerived) {
 				info.set(ICoreConstants.M_DERIVED);
@@ -1644,42 +1607,37 @@
 
 	@Override
 	public void setDerived(boolean isDerived, IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		String message = NLS.bind(Messages.resources_settingDerivedFlag, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
+		final ISchedulingRule rule = workspace.getRuleFactory().derivedRule(this);
 		try {
-			String message = NLS.bind(Messages.resources_settingDerivedFlag, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			final ISchedulingRule rule = workspace.getRuleFactory().derivedRule(this);
-			try {
-				workspace.prepareOperation(rule, monitor);
-				ResourceInfo info = getResourceInfo(false, false);
-				checkAccessible(getFlags(info));
-				// ignore attempts to set derived flag on anything except files and folders
-				if (info.getType() != FILE && info.getType() != FOLDER)
-					return;
-				workspace.beginOperation(true);
-				info = getResourceInfo(false, true);
-				if (isDerived)
-					info.set(ICoreConstants.M_DERIVED);
-				else {
-					info.clear(ICoreConstants.M_DERIVED);
-				}
-				monitor.worked(Policy.opWork);
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
+			workspace.prepareOperation(rule, progress.split(1));
+			ResourceInfo info = getResourceInfo(false, false);
+			checkAccessible(getFlags(info));
+			// Ignore attempts to set derived flag on anything except files and folders.
+			if (info.getType() != FILE && info.getType() != FOLDER)
+				return;
+			workspace.beginOperation(true);
+			info = getResourceInfo(false, true);
+			if (isDerived) {
+				info.set(ICoreConstants.M_DERIVED);
+			} else {
+				info.clear(ICoreConstants.M_DERIVED);
 			}
+			progress.step(98);
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
 	@Override
 	public void setHidden(boolean isHidden) throws CoreException {
-		// fetch the info but don't bother making it mutable even though we are going
+		// Fetch the info but don't bother making it mutable even though we are going
 		// to modify it.  We don't know whether or not the tree is open and it really doesn't
-		// matter as the change we are doing does not show up in deltas.
+		// matter as the change we are making does not show up in deltas.
 		ResourceInfo info = getResourceInfo(false, false);
 		int flags = getFlags(info);
 		checkAccessible(flags);
@@ -1693,20 +1651,15 @@
 	@Deprecated
 	@Override
 	public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		String message = Messages.resources_setLocal;
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
 		try {
-			String message = Messages.resources_setLocal;
-			monitor.beginTask(message, Policy.totalWork);
-			try {
-				workspace.prepareOperation(null, monitor);
-				workspace.beginOperation(true);
-				internalSetLocal(flag, depth);
-				monitor.worked(Policy.opWork);
-			} finally {
-				workspace.endOperation(null, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
-			}
+			workspace.prepareOperation(null, progress.split(1));
+			workspace.beginOperation(true);
+			internalSetLocal(flag, depth);
+			progress.step(98);
 		} finally {
-			monitor.done();
+			workspace.endOperation(null, true, progress.split(1));
 		}
 	}
 
@@ -1714,8 +1667,8 @@
 	public long setLocalTimeStamp(long value) throws CoreException {
 		if (value < 0)
 			throw new IllegalArgumentException("Illegal value: " + value); //$NON-NLS-1$
-		// fetch the info but don't bother making it mutable even though we are going
-		// to modify it. It really doesn't matter as the change we are doing does not show up in deltas.
+		// Fetch the info but don't bother making it mutable even though we are going to modify it.
+		// It really doesn't matter as the change we are making does not show up in deltas.
 		ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO);
 		return getLocalManager().setLocalTimeStamp(this, info, value);
 	}
@@ -1736,7 +1689,7 @@
 		try {
 			setResourceAttributes(attributes);
 		} catch (CoreException e) {
-			//failure is not an option
+			// Failure is not an option.
 		}
 	}
 
@@ -1748,18 +1701,18 @@
 
 	@Override
 	public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
-		// fetch the info but don't bother making it mutable even though we are going
-		// to modify it.  We don't know whether or not the tree is open and it really doesn't
-		// matter as the change we are doing does not show up in deltas.
+		// Fetch the info but don't bother making it mutable even though we are going to modify it.
+		// We don't know whether or not the tree is open and it really doesn't matter as the change
+		// we are making does not show up in deltas.
 		ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO);
 		info.setSessionProperty(key, value);
 	}
 
 	@Override
 	public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
-		// fetch the info but don't bother making it mutable even though we are going
+		// Fetch the info but don't bother making it mutable even though we are going
 		// to modify it.  We don't know whether or not the tree is open and it really doesn't
-		// matter as the change we are doing does not show up in deltas.
+		// matter as the change we are making does not show up in deltas.
 		ResourceInfo info = getResourceInfo(false, false);
 		int flags = getFlags(info);
 		checkAccessible(flags);
@@ -1788,31 +1741,26 @@
 
 	@Override
 	public void touch(IProgressMonitor monitor) throws CoreException {
-		monitor = Policy.monitorFor(monitor);
+		String message = NLS.bind(Messages.resources_touch, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
+		final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
 		try {
-			String message = NLS.bind(Messages.resources_touch, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-			final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
-			try {
-				workspace.prepareOperation(rule, monitor);
-				ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO);
+			workspace.prepareOperation(rule, progress.split(1));
+			ResourceInfo info = checkAccessibleAndLocal(DEPTH_ZERO);
 
-				workspace.beginOperation(true);
-				// fake a change by incrementing the content ID
-				info = getResourceInfo(false, true);
-				info.incrementContentId();
-				// forget content-related caching flags
-				info.clear(M_CONTENT_CACHE);
-				workspace.updateModificationStamp(info);
-				monitor.worked(Policy.opWork);
-			} catch (OperationCanceledException e) {
-				workspace.getWorkManager().operationCanceled();
-				throw e;
-			} finally {
-				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
-			}
+			workspace.beginOperation(true);
+			// Fake a change by incrementing the content ID.
+			info = getResourceInfo(false, true);
+			info.incrementContentId();
+			// Forget content-related caching flags.
+			info.clear(M_CONTENT_CACHE);
+			workspace.updateModificationStamp(info);
+			progress.step(98);
+		} catch (OperationCanceledException e) {
+			workspace.getWorkManager().operationCanceled();
+			throw e;
 		} finally {
-			monitor.done();
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
@@ -1822,27 +1770,29 @@
 	 */
 	private void unprotectedDelete(ResourceTree tree, int updateFlags, IProgressMonitor monitor) {
 		IMoveDeleteHook hook = workspace.getMoveDeleteHook();
+		SubMonitor progress = SubMonitor.convert(monitor, 2).checkCanceled();
 		switch (getType()) {
 			case IResource.FILE :
-				if (!hook.deleteFile(tree, (IFile) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000 / 2)))
-					tree.standardDeleteFile((IFile) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000));
+				if (!hook.deleteFile(tree, (IFile) this, updateFlags, progress.split(1)))
+					tree.standardDeleteFile((IFile) this, updateFlags, progress.split(1));
 				break;
 			case IResource.FOLDER :
-				if (!hook.deleteFolder(tree, (IFolder) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000 / 2)))
-					tree.standardDeleteFolder((IFolder) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000));
+				if (!hook.deleteFolder(tree, (IFolder) this, updateFlags, progress.split(1)))
+					tree.standardDeleteFolder((IFolder) this, updateFlags, progress.split(1));
 				break;
 			case IResource.PROJECT :
-				if (!hook.deleteProject(tree, (IProject) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000 / 2)))
-					tree.standardDeleteProject((IProject) this, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000));
+				if (!hook.deleteProject(tree, (IProject) this, updateFlags, progress.split(1)))
+					tree.standardDeleteProject((IProject) this, updateFlags, progress.split(1));
 				break;
 			case IResource.ROOT :
-				// when the root is deleted, all its children including hidden projects
-				// have to be deleted
+				// When the root is deleted, all its children including hidden projects have to be deleted.
 				IProject[] projects = ((IWorkspaceRoot) this).getProjects(IContainer.INCLUDE_HIDDEN);
-				for (int i = 0; i < projects.length; i++) {
-					if (!hook.deleteProject(tree, projects[i], updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000 / projects.length / 2)))
-						tree.standardDeleteProject(projects[i], updateFlags, Policy.subMonitorFor(monitor, Policy.opWork * 1000 / projects.length));
+				progress.setWorkRemaining(projects.length * 2);
+				for (IProject project : projects) {
+					if (!hook.deleteProject(tree, project, updateFlags, progress.split(1)))
+						tree.standardDeleteProject(project, updateFlags, progress.split(1));
 				}
+				break;
 		}
 	}
 
@@ -1853,24 +1803,25 @@
 	 */
 	private boolean unprotectedMove(ResourceTree tree, final IResource destination, int updateFlags, IProgressMonitor monitor) throws CoreException, ResourceException {
 		IMoveDeleteHook hook = workspace.getMoveDeleteHook();
+		SubMonitor progress = SubMonitor.convert(monitor, 2).checkCanceled();
 		switch (getType()) {
 			case IResource.FILE :
-				if (!hook.moveFile(tree, (IFile) this, (IFile) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2)))
-					tree.standardMoveFile((IFile) this, (IFile) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork));
+				if (!hook.moveFile(tree, (IFile) this, (IFile) destination, updateFlags, progress.split(1)))
+					tree.standardMoveFile((IFile) this, (IFile) destination, updateFlags, progress.split(1));
 				break;
 			case IResource.FOLDER :
-				if (!hook.moveFolder(tree, (IFolder) this, (IFolder) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2)))
-					tree.standardMoveFolder((IFolder) this, (IFolder) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork));
+				if (!hook.moveFolder(tree, (IFolder) this, (IFolder) destination, updateFlags, progress.split(1)))
+					tree.standardMoveFolder((IFolder) this, (IFolder) destination, updateFlags, progress.split(1));
 				break;
 			case IResource.PROJECT :
 				IProject project = (IProject) this;
-				// if there is no change in name, there is nothing to do so return.
+				// If there is no change in name, there is nothing to do so return.
 				if (getName().equals(destination.getName()))
 					return false;
 				IProjectDescription description = project.getDescription();
 				description.setName(destination.getName());
-				if (!hook.moveProject(tree, project, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2)))
-					tree.standardMoveProject(project, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork));
+				if (!hook.moveProject(tree, project, description, updateFlags, progress.split(1)))
+					tree.standardMoveProject(project, description, updateFlags, progress.split(1));
 				break;
 			case IResource.ROOT :
 				String msg = Messages.resources_moveRoot;
@@ -1885,10 +1836,12 @@
 				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, this));
 				break;
 			case IResource.ROOT :
-				// all root children including hidden projects will be deleted so notify
+				// All root children including hidden projects will be deleted so notify.
 				IResource[] projects = ((Container) this).getChildren(IContainer.INCLUDE_HIDDEN);
-				for (int i = 0; i < projects.length; i++)
+				for (int i = 0; i < projects.length; i++) {
 					workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_DELETE, projects[i]));
+				}
+				break;
 		}
 	}
 
@@ -1906,7 +1859,7 @@
 				break;
 			case IResource.PROJECT :
 				if (!getName().equals(destination.getName())) {
-					// if there is a change in name, we are deleting the source project so notify.
+					// If there is a change in name, we are deleting the source project so notify.
 					workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_MOVE, this, destination, updateFlags));
 				}
 				break;
@@ -1920,7 +1873,7 @@
 		return new ProjectPathVariableManager(this);
 	}
 
-	/* (non-Javadoc)
+	/**
 	 *  Calculates whether the current resource is filtered out from the resource tree
 	 *  by resource filters.  This can happen because resource filters apply to the resource,
 	 *  or because resource filters apply to one of its parent.  For example, if "/foo/bar"
@@ -1928,7 +1881,7 @@
 	 *  return true as well, even though there's no resource filters that apply to "file.txt" per se.
 	 *
 	 * @return true is the resource is filtered out from the resource tree
-	 * @see IResource#isFiltered()
+	 * @see IContainer#createFilter(int, FileInfoMatcherDescription, int, IProgressMonitor)
 	 */
 	public boolean isFiltered() {
 		try {
@@ -2024,10 +1977,9 @@
 		return list;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 *
-	 * @see IResource#setLinkLocation(IPath)
+	/**
+	 * @see IFolder#createLink(URI, int, IProgressMonitor)
+	 * @see IFile#createLink(URI, int, IProgressMonitor)
 	 */
 	public void setLinkLocation(URI location, int updateFlags, IProgressMonitor monitor) throws CoreException {
 		if (!isLinked()) {
@@ -2035,12 +1987,11 @@
 			throw new ResourceException(IResourceStatus.INVALID_VALUE, getFullPath(), message, null);
 		}
 
+		String message = NLS.bind(Messages.links_setLocation, getFullPath());
+		SubMonitor progress = SubMonitor.convert(monitor, message, 100).checkCanceled();
 		final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
 		try {
-			String message = NLS.bind(Messages.links_setLocation, getFullPath());
-			monitor.beginTask(message, Policy.totalWork);
-
-			workspace.prepareOperation(rule, monitor);
+			workspace.prepareOperation(rule, progress.split(1));
 			workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_LINK_CHANGE, this));
 			workspace.beginOperation(true);
 
@@ -2053,32 +2004,33 @@
 			project.internalGetDescription().setLinkLocation(getProjectRelativePath(), linkDescription);
 			project.writeDescription(updateFlags);
 
-			// refresh either in background or foreground
+			// Refresh either in background or foreground.
 			if ((updateFlags & IResource.BACKGROUND_REFRESH) != 0) {
 				workspace.refreshManager.refresh(this);
-				monitor.worked(Policy.opWork * 90 / 100);
+				progress.step(99);
 			} else {
-				refreshLocal(DEPTH_INFINITE, Policy.subMonitorFor(monitor, Policy.opWork * 90 / 100));
+				refreshLocal(DEPTH_INFINITE, progress.split(98));
 			}
 		} finally {
-			workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
+			workspace.endOperation(rule, true, progress.split(1));
 		}
 	}
 
-	/*
-	 * (non-Javadoc)
-	 *
-	 * @see IResource#setLinkLocation(URI)
+	/**
+	 * @see IFolder#createLink(IPath, int, IProgressMonitor)
+	 * @see IFile#createLink(IPath, int, IProgressMonitor)
 	 */
 	public void setLinkLocation(IPath location, int updateFlags, IProgressMonitor monitor) throws CoreException {
 		if (location.isAbsolute()) {
 			setLinkLocation(URIUtil.toURI(location.toPortableString()), updateFlags, monitor);
 		} else {
+			URI uri;
 			try {
-				setLinkLocation(new URI(null, null, location.toPortableString(), null), updateFlags, monitor);
+				uri = new URI(null, null, location.toPortableString(), null);
 			} catch (URISyntaxException e) {
-				setLinkLocation(URIUtil.toURI(location.toPortableString()), updateFlags, monitor);
+				uri = URIUtil.toURI(location.toPortableString());
 			}
+			setLinkLocation(uri, updateFlags, monitor);
 		}
 	}
 }