/*******************************************************************************
 * Copyright (c) 2014, 2015 Google, Inc and others.
 * 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
 *
 * Contributors:
 * 	   Sergey Prigogin (Google) - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.rename;

import java.io.File;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
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.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexInclude;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.refactoring.CTextFileChange;
import org.eclipse.cdt.utils.PathUtil;

import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
import org.eclipse.cdt.internal.core.model.SourceRoot;
import org.eclipse.cdt.internal.core.util.TextUtil;
import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo;
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.cdt.internal.corext.codemanipulation.StyledInclude;

import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeCreationContext;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeUtil;

/**
 * Updates include statements and include guards in response to file or folder move or rename.
 */
public class HeaderFileReferenceAdjuster {
	private static final int PARSE_MODE = ITranslationUnit.AST_SKIP_ALL_HEADERS
			| ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT
			| ITranslationUnit.AST_SKIP_FUNCTION_BODIES
			| ITranslationUnit.AST_PARSE_INACTIVE_CODE;

	private final Map<IFile, IFile> movedFiles;
	private final Map<String, IPath> movedFilesByLocation;
	private final Map<IContainer, IContainer> renamedContainers;
	private ASTManager astManager;
	private IIndex index;
	private int indexLockCount;

	/**
	 * @param movedFiles keys are files being moved or renamed, values are new, not yet existing,
	 *     files
	 * @param renamedContainers keys are folders and projects being renamed, values are new,
	 *     not yet existing folders and projects. 
	 * @param processor the refactoring processor
	 */
	public HeaderFileReferenceAdjuster(Map<IFile, IFile> movedFiles,
			Map<IContainer, IContainer> renamedContainers, RefactoringProcessor processor) {
		this.movedFiles = movedFiles;
		this.movedFilesByLocation = new HashMap<>();
		for (Entry<IFile, IFile> entry : movedFiles.entrySet()) {
			//Construct map using normalised file paths
			this.movedFilesByLocation.put(entry.getKey().getLocation().toString(),
					entry.getValue().getLocation());
		}
		this.renamedContainers = renamedContainers;
		this.astManager = getASTManager(processor);
	}

	public Change createChange(CheckConditionsContext context, IProgressMonitor pm)
			throws CoreException, OperationCanceledException {
		SubMonitor progress = SubMonitor.convert(pm, 10);
		CompositeChange change = null;
		Set<IFile> affectedFiles = new HashSet<>();
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

		lockIndex();

		ASTManager sharedASTManager = astManager;
		if (astManager == null)
			astManager = new ASTManager(null);

		try {
			for (Entry<IFile, IFile> entry : movedFiles.entrySet()) {
				IFile oldFile = entry.getKey();
				IFile newFile = entry.getValue();
				if (areIncludeGuardsAffected(oldFile, newFile))
					affectedFiles.add(oldFile);

				IIndexFileLocation indexFileLocation = IndexLocationFactory.getWorkspaceIFL(oldFile);
				IIndexFile[] indexFiles = index.getFiles(indexFileLocation);
				for (IIndexFile indexFile : indexFiles) {
					IIndexInclude[] includes = index.findIncludedBy(indexFile);
					for (IIndexInclude include : includes) {
						IIndexFileLocation includeLocation = include.getIncludedByLocation();
						String path = includeLocation.getFullPath();
						if (path != null) {
							IResource resource = workspaceRoot.findMember(path);
							if (resource.getType() == IResource.FILE) {
								IFile includer = (IFile) resource;
								affectedFiles.add(includer);
							}
						}
					}
				}
			}

			IWorkingCopyManager workingCopyManager = CUIPlugin.getDefault().getWorkingCopyManager();
			IWorkingCopy[] workingCopies = workingCopyManager.getSharedWorkingCopies();
			progress.worked(1);
			progress = SubMonitor.convert(progress.newChild(9), workingCopies.length + affectedFiles.size());

			List<Change> changes = new ArrayList<>();
			ValidateEditChecker checker= (ValidateEditChecker) context.getChecker(ValidateEditChecker.class);
			for (ITranslationUnit tu : workingCopies) {
				addFileChange(tu, changes, checker, progress.newChild(1));
			}

			CoreModel coreModel = CoreModel.getDefault();
			for (IFile file : affectedFiles) {
				ITranslationUnit tu = (ITranslationUnit) coreModel.create(file);
				if (tu != null) {
					if (workingCopyManager.findSharedWorkingCopy(tu) != null)
						continue;  // Shared working copies have already been processed.
					addFileChange(tu, changes, checker, progress.newChild(1));
				}
			}

			if (!changes.isEmpty()) {
				change = new CompositeChange("", changes.toArray(new Change[changes.size()])); //$NON-NLS-1$
				change.markAsSynthetic();
			}
		} finally {
			if (astManager != sharedASTManager) {
				astManager.dispose();
				astManager = null;
			}
			unlockIndex();
			pm.done();
		}
		return change;
	}

	private void addFileChange(ITranslationUnit tu, List<Change> changes, ValidateEditChecker checker,
			IProgressMonitor pm) throws CoreException {
		TextEditGroup editGroup = createEdit(tu, pm);
		if (editGroup != null) {
			CTextFileChange fileChange = new CTextFileChange(tu.getElementName(), tu);
			TextEdit[] edits = editGroup.getTextEdits();
			if (edits.length == 1) {
				fileChange.setEdit(edits[0]);
			} else {
				fileChange.setEdit(new MultiTextEdit());
				for (TextEdit edit : edits) {
					fileChange.addEdit(edit);
				}
			}
            fileChange.addTextEditGroup(editGroup);
			changes.add(fileChange);
			checker.addFile(fileChange.getFile());
		}
	}

	private TextEditGroup createEdit(ITranslationUnit tu, IProgressMonitor pm)
			throws CoreException, OperationCanceledException {
		checkCanceled(pm);

		SubMonitor progress = SubMonitor.convert(pm, 2);
		try {
			IASTTranslationUnit ast = astManager.getAST(index, tu.getFile(), PARSE_MODE, false);
	       	return createEdit(ast, tu, progress.newChild(1));
		} finally {
			pm.done();
		}
    }

	private TextEditGroup createEdit(IASTTranslationUnit ast, ITranslationUnit tu, IProgressMonitor pm)
			throws CoreException, OperationCanceledException {
		IncludeCreationContext context = new IncludeCreationContext(tu, index);
		// Adjust the translation unit location in the inclusion context.
		IFile movedFile = movedFiles.get(tu.getFile());
		if (movedFile != null)
			context.setTranslationUnitLocation(movedFile.getLocation());

		String contents = context.getSourceContents();

		MultiTextEdit rootEdit = createIncludeGuardEdit(ast, tu, contents);
		int numIncludeGuardEdits = rootEdit == null ? 0 : rootEdit.getChildrenSize();

		Map<IASTPreprocessorIncludeStatement, IPath> affectedIncludes = new IdentityHashMap<>();
		IASTPreprocessorIncludeStatement[] existingIncludes = ast.getIncludeDirectives();
		for (IASTPreprocessorIncludeStatement include : existingIncludes) {
			if (include.isPartOfTranslationUnitFile()) {
				String location;
				if (include.isActive()) {
					location = include.getPath();
					if (location.isEmpty())
						continue;	// Unresolved include.
					if (File.separatorChar == '\\') {
						// Normalize path separators on Windows.
						location = new Path(location).toString();
					}
				} else {
					String name = new String(include.getName().getSimpleID());
					IncludeInfo includeInfo = new IncludeInfo(name, include.isSystemInclude());
					IPath path = context.resolveInclude(includeInfo);
					if (path == null)
						continue;
					location = path.toString();
				}
				IPath newLocation = movedFilesByLocation.get(location);
				if (newLocation != null) {
					affectedIncludes.put(include, newLocation);
				}
			}
		}
		if (!affectedIncludes.isEmpty()) {
			NodeCommentMap commentedNodeMap = ASTCommenter.getCommentedNodeMap(ast);
			IRegion includeRegion =
					IncludeUtil.getSafeIncludeReplacementRegion(contents, ast, commentedNodeMap);
	
			IncludePreferences preferences = context.getPreferences();
	
			if (rootEdit == null)
				rootEdit = new MultiTextEdit();
	
			context.addHeadersIncludedPreviously(existingIncludes);
	
			if (preferences.allowReordering) {
				List<StyledInclude> modifiedIncludes = new ArrayList<>();
				// Put the changed includes into modifiedIncludes.
				for (Entry<IASTPreprocessorIncludeStatement, IPath> entry : affectedIncludes.entrySet()) {
					IASTPreprocessorIncludeStatement existingInclude = entry.getKey();
					if (IncludeUtil.isContainedInRegion(existingInclude, includeRegion)) {
						IPath header = entry.getValue();
						IncludeGroupStyle style = context.getIncludeStyle(header);
						IncludeInfo includeInfo = context.createIncludeInfo(header, style);
						StyledInclude include = new StyledInclude(header, includeInfo, style, existingInclude);
						modifiedIncludes.add(include);
					}
				}
	
				Collections.sort(modifiedIncludes, preferences);
	
				// Populate a list of the existing unchanged includes in the include insertion region.
				List<StyledInclude> mergedIncludes =
						IncludeUtil.getIncludesInRegion(existingIncludes, includeRegion, context);
				Deque<DeleteEdit> deletes = new ArrayDeque<>();
				// Create text deletes for old locations of the includes that will be changed.
				int deleteOffset = -1;
				boolean emptyLineEncountered = false;
				int j = 0;
				for (int i = 0; i < mergedIncludes.size(); i++) {
					StyledInclude include = mergedIncludes.get(i);
					IASTPreprocessorIncludeStatement existingInclude = include.getExistingInclude();
					int offset = ASTNodes.offset(existingInclude);
					boolean previousLineBlank = TextUtil.isPreviousLineBlank(contents, offset);
					if (affectedIncludes.containsKey(existingInclude)) {
						if (deleteOffset < 0) {
							deleteOffset = offset;
						} else if (!emptyLineEncountered && previousLineBlank) {
							// Preserve the first encountered blank line.
							deletes.add(new DeleteEdit(deleteOffset, offset - deleteOffset));
							deleteOffset = -1;
						}
						emptyLineEncountered |= previousLineBlank;
					} else {
						if (deleteOffset >= 0) {
							if (!emptyLineEncountered && previousLineBlank) {
								offset = TextUtil.getPreviousLineStart(contents, offset);
							}
							deletes.add(new DeleteEdit(deleteOffset, offset - deleteOffset));
							deleteOffset = -1;
						}
						emptyLineEncountered = false;
						if (j < i)
							mergedIncludes.set(j, include);
						j++;
					}
				}
				while (j < mergedIncludes.size()) {
					mergedIncludes.remove(mergedIncludes.size() - 1);
				}
				if (deleteOffset >= 0)
					deletes.add(new DeleteEdit(deleteOffset, includeRegion.getOffset() + includeRegion.getLength() - deleteOffset));
	
				// Since the order of existing include statements may not match the include order
				// preferences, we find positions for the new include statements by pushing them up
				// from the bottom of the include insertion region.
				for (StyledInclude include : modifiedIncludes) {
					if (IncludeUtil.isContainedInRegion(include.getExistingInclude(), includeRegion)) {
						int i = mergedIncludes.size();
						while (--i >= 0 && preferences.compare(include, mergedIncludes.get(i)) < 0) {}
						mergedIncludes.add(i + 1, include);
					}
				}
	
				int offset = includeRegion.getOffset();
				StringBuilder text = new StringBuilder();
				StyledInclude previousInclude = null;
				for (StyledInclude include : mergedIncludes) {
					IASTPreprocessorIncludeStatement existingInclude = include.getExistingInclude();
					if (affectedIncludes.containsKey(existingInclude)) {
						if (previousInclude != null) {
							IASTNode previousNode = previousInclude.getExistingInclude();
							if (!affectedIncludes.containsKey(previousNode)) {
								offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode);
								flushEditBuffer(offset, text, deletes, rootEdit);
								if (contents.charAt(offset - 1) != '\n')
									text.append(context.getLineDelimiter());
							}
							if (isBlankLineNeededBetween(previousInclude, include, preferences)) {
								if (TextUtil.isLineBlank(contents, offset)) {
									int oldOffset = offset;
									offset = TextUtil.skipToNextLine(contents, offset);
									if (offset == oldOffset || contents.charAt(offset - 1) != '\n')
										text.append(context.getLineDelimiter());
								} else {
									text.append(context.getLineDelimiter());
								}
							}
						}
						text.append(include.getIncludeInfo().composeIncludeStatement());
						List<IASTComment> comments = commentedNodeMap.getTrailingCommentsForNode(existingInclude);
						for (IASTComment comment : comments) {
							text.append(ASTNodes.getPrecedingWhitespaceInLine(contents, comment));
							text.append(comment.getRawSignature());
						}
						text.append(context.getLineDelimiter());
					} else {
						if (previousInclude != null && affectedIncludes.containsKey(previousInclude.getExistingInclude()) &&
								isBlankLineNeededBetween(previousInclude, include, preferences) &&
								TextUtil.findBlankLine(contents, skipDeletedRegion(offset, deletes), ASTNodes.offset(existingInclude)) < 0) {
							text.append(context.getLineDelimiter());
						}
						flushEditBuffer(offset, text, deletes, rootEdit);
					}
					previousInclude = include;
				}
				if (includeRegion.getLength() == 0 && !TextUtil.isLineBlank(contents, includeRegion.getOffset())) {
					text.append(context.getLineDelimiter());
				}
				offset = includeRegion.getOffset() + includeRegion.getLength();
				flushEditBuffer(offset, text, deletes, rootEdit);
			}
	
			for (IASTPreprocessorIncludeStatement existingInclude : existingIncludes) {
				IPath header = affectedIncludes.get(existingInclude);
				if (header != null &&
						(!preferences.allowReordering || !IncludeUtil.isContainedInRegion(existingInclude, includeRegion))) {
					IncludeGroupStyle style = context.getIncludeStyle(header);
					IncludeInfo includeInfo = context.createIncludeInfo(header, style);
					IASTName name = existingInclude.getName();
					int offset = ASTNodes.offset(name) - 1;
					int length = ASTNodes.endOffset(name) + 1 - offset;
					rootEdit.addChild(new ReplaceEdit(offset, length, includeInfo.toString()));
				}
			}
		}

		if (rootEdit == null)
			return null;

		int numEdits = rootEdit.getChildrenSize();
		String message =
				numEdits == numIncludeGuardEdits ?
						RenameMessages.HeaderReferenceAdjuster_update_include_guards :
				numIncludeGuardEdits == 0 ?
						RenameMessages.HeaderReferenceAdjuster_update_includes :
						RenameMessages.HeaderReferenceAdjuster_update_include_guards_and_includes;
        TextEditGroup editGroup= new TextEditGroup(message, rootEdit);

		return editGroup;
	}

	private static boolean isBlankLineNeededBetween(StyledInclude include1, StyledInclude include2,
			IncludePreferences preferences) {
		return include2.getStyle().isBlankLineNeededAfter(include1.getStyle(), preferences.includeStyles);
	}

	private MultiTextEdit createIncludeGuardEdit(IASTTranslationUnit ast, ITranslationUnit tu, String contents) {
		IResource resource = tu.getResource();
		IFile newFile = movedFiles.get(resource);
		if (newFile == null)
			return null;
		boolean guardsAffected = areIncludeGuardsAffected((IFile) resource, newFile);
		if (!guardsAffected)
			return null;
		List<IRegion> includeGuardPositions = new ArrayList<>();
		String oldGuard = IncludeUtil.findIncludeGuard(contents, ast, includeGuardPositions);
		if (oldGuard == null)
			return null;
		if (!oldGuard.equals(StubUtility.generateIncludeGuardSymbol(resource, tu.getCProject())))
			return null;
		String guard = generateNewIncludeGuardSymbol(resource, newFile, tu.getCProject());
		if (guard == null || guard.equals(oldGuard))
			return null;
		MultiTextEdit rootEdit = new MultiTextEdit();
		for (IRegion region : includeGuardPositions) {
			rootEdit.addChild(new ReplaceEdit(region.getOffset(), region.getLength(), guard));
		}
		return rootEdit;
	}

	private String generateNewIncludeGuardSymbol(IResource resource, IFile newFile, ICProject cProject) {
		switch (getIncludeGuardScheme(cProject.getProject())) {
		case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
			IProject newProject = newFile.getProject();
			if (newProject.exists()) {
				// Move within the same or to a different existing project.
				cProject = CoreModel.getDefault().create(newProject);
				if (cProject == null)
					break;
			}
			ISourceRoot[] roots;
			try {
				roots = cProject.getAllSourceRoots();
			} catch (CModelException e) {
				break;
			}
			IContainer base = null;
			for (ISourceRoot root : roots) {
				root = getModifiedSourceRoot(cProject, root);
				if (root.isOnSourceEntry(newFile)) {
					base = root.getResource();
					break;
				}
			}

			if (base == null)
				break;
			IPath path = PathUtil.makeRelativePath(newFile.getFullPath(), base.getFullPath());
			if (path == null)
				break;
			return StubUtility.generateIncludeGuardSymbolFromFilePath(path.toString());

		case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME:
			return StubUtility.generateIncludeGuardSymbolFromFilePath(newFile.getName());

		default:
			break;
		}
		return null;
	}

	protected ISourceRoot getModifiedSourceRoot(ICProject cProject, ISourceRoot root) {
		IContainer container = root.getResource();
		ICSourceEntry sourceEntry = ((SourceRoot) root).getSourceEntry();
		for (Entry<IContainer, IContainer> entry : renamedContainers.entrySet()) {
			IPath oldFolderPath = entry.getKey().getFullPath();
			IPath newFolderPath = entry.getValue().getFullPath();
			sourceEntry = RenameCSourceFolderChange.renameSourceEntry(sourceEntry, oldFolderPath, newFolderPath);
		}
		IContainer newContainer = getModifiedContainer(container);
		return new SourceRoot(cProject, newContainer, sourceEntry);
	}

	private IContainer getModifiedContainer(IContainer container) {
		IPath relativePath = Path.EMPTY;
		for (IContainer ancestor = container; ancestor.getType() != IResource.ROOT; ancestor = ancestor.getParent()) {
			IContainer newContainer = renamedContainers.get(ancestor);
			if (newContainer != null) {
				if (relativePath.isEmpty()) {
					return newContainer;
				}
				return newContainer.getFolder(relativePath);
			}
			relativePath = new Path(ancestor.getName()).append(relativePath);
		}
		return container;
	}

	private void flushEditBuffer(int offset, StringBuilder text, Deque<DeleteEdit> deletes, MultiTextEdit edit) {
		consumeDeletesUpTo(offset, deletes, edit);
		if (text.length() != 0) {
			edit.addChild(new InsertEdit(offset, text.toString()));
			text.delete(0, text.length());
		}
	}

	private void consumeDeletesUpTo(int offset, Deque<DeleteEdit> deletes, MultiTextEdit rootEdit) {
		while (!deletes.isEmpty()) {
			DeleteEdit edit = deletes.peek();
			if (edit.getOffset() > offset)
				break;
			deletes.remove();
			rootEdit.addChild(edit);
		}
	}

	private int skipDeletedRegion(int offset, Deque<DeleteEdit> deletes) {
		for (DeleteEdit edit : deletes) {
			if (edit.getOffset() > offset)
				break;
			offset = edit.getExclusiveEnd();
		}
		return offset;
	}

	private void lockIndex() throws CoreException, OperationCanceledException {
		if (indexLockCount == 0) {
			if (index == null) {
				ICProject[] projects= CoreModel.getDefault().getCModel().getCProjects();
				index = CCorePlugin.getIndexManager().getIndex(projects,
						IIndexManager.ADD_EXTENSION_FRAGMENTS_EDITOR);
			}
			try {
				index.acquireReadLock();
			} catch (InterruptedException e) {
				throw new OperationCanceledException();
			}
		}
		indexLockCount++;
	}

	private void unlockIndex() {
		if (--indexLockCount <= 0) {
			if (index != null) {
				index.releaseReadLock();
			}
			index = null;
		}
	}

	private static ASTManager getASTManager(RefactoringProcessor processor) {
		if (processor instanceof CRenameProcessor) {
			return ((CRenameProcessor) processor).getAstManager();
		}
		return null;
	}

	private static void checkCanceled(IProgressMonitor pm) throws OperationCanceledException {
		if (pm != null && pm.isCanceled())
			throw new OperationCanceledException();
	}

	private static boolean areIncludeGuardsAffected(IFile oldfile, IFile newFile) {
		IProject project = oldfile.getProject();
		String filename = oldfile.getLocation().lastSegment();
		if (!CoreModel.isValidHeaderUnitName(project, filename))
			return false;
		switch (getIncludeGuardScheme(project)) {
		case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_PATH:
			return true;

		case PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME:
			return !filename.equals(newFile.getName());

		default:
			return false;
		}
	}

	private static int getIncludeGuardScheme(IProject project) {
		IPreferencesService preferences = Platform.getPreferencesService();
		IScopeContext[] scopes = PreferenceConstants.getPreferenceScopes(project);
		int scheme = preferences.getInt(CUIPlugin.PLUGIN_ID,
				PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME,
				PreferenceConstants.CODE_TEMPLATES_INCLUDE_GUARD_SCHEME_FILE_NAME, scopes);
		return scheme;
	}
}
