/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.fix;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.MoveSourceEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.text.edits.TextEditVisitor;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.IFile;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.NullChange;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringTickProvider;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.TextEditBasedChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;

import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTRequestor;
import org.eclipse.jdt.core.dom.CompilationUnit;

import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationStateChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaElementLabels;

import org.eclipse.jdt.internal.ui.fix.ICleanUp;
import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;

public class CleanUpRefactoring extends Refactoring {

	private static final int BATCH_SIZE= 40;

	private class FixCalculationException extends RuntimeException {

		private static final long serialVersionUID= 3807273310144726165L;
		
		private final CoreException fException;

		public FixCalculationException(CoreException exception) {
			fException= exception;
		}

		public CoreException getException() {
			return fException;
		}
		
	}
	
	private class ParseListElement {

		private final ICompilationUnit fUnit;
		private List fCleanUpsToGo;
		private ICleanUp[] fCleanUpsArray;

		public ParseListElement(ICompilationUnit unit) {
			fUnit= unit;
			fCleanUpsToGo= new ArrayList();
			fCleanUpsArray= new ICleanUp[0];
		}
		
		public ParseListElement(ICompilationUnit unit, ICleanUp[] cleanUps) {
			fUnit= unit;
			fCleanUpsArray= cleanUps;
			fCleanUpsToGo= null;
		}

		public void addCleanUp(ICleanUp multiFix) {
			if (fCleanUpsToGo == null) {
				fCleanUpsToGo= Arrays.asList(fCleanUpsArray);
			}
			fCleanUpsToGo.add(multiFix);
			fCleanUpsArray= null;
		}

		public ICompilationUnit getCompilationUnit() {
			return fUnit;
		}

		public ICleanUp[] getCleanUps() {
			if (fCleanUpsArray == null) {
				fCleanUpsArray= (ICleanUp[])fCleanUpsToGo.toArray(new ICleanUp[fCleanUpsToGo.size()]);
			}
			return fCleanUpsArray;
		}
	}
	
	private class IndexCounter {
		
		private int fIndex;
		private final int fSize;
		
		public IndexCounter(int index, int size) {
			fIndex= index;
			fSize= size;
		}
		
		public void inc() {
			fIndex++;
		}
		
		public int value() {
			return fIndex;
		}
		
		public int size() {
			return fSize;
		}
	}
	
	private final class CleanUpRefactoringProgressMonitor extends SubProgressMonitor {
		private int worked= 0;

		private CleanUpRefactoringProgressMonitor(IProgressMonitor monitor, int ticks) {
			super(monitor, ticks);
		}

		/**
		 * {@inheritDoc}
		 */
		public void worked(int work) {
			worked+=work;
		}

		public void flush() {
			super.worked(worked);
			reset();
		}

		public void reset() {
			worked= 0;
		}
		
		public void done() {
		}
	}
	
	private final class SolutionGenerator extends ASTRequestor {

		private final CleanUpRefactoringProgressMonitor fMonitor;
		private final List fResult;
		private final Hashtable fSolutions;
		private final Iterator fToParseIter;
		private ParseListElement fCurElement;
		private IndexCounter fIndex;

		private SolutionGenerator(List/*<ParseListElement>*/ toSolve, IndexCounter startIndex, Hashtable solutions, CleanUpRefactoringProgressMonitor monitor) {
			fMonitor= monitor;
			fResult= new ArrayList();
			fSolutions= solutions;
			fIndex= startIndex;
			
			fToParseIter= toSolve.iterator();
			fCurElement= (ParseListElement)fToParseIter.next();
			fMonitor.subTask(getSubTaskMessage(fCurElement.getCompilationUnit(), fIndex.value(), fIndex.size()));
		}

		public List getResult() {
			return fResult;
		}

		public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
			ParseListElement tuple= calculateSolution(fSolutions, ast, fCurElement.getCleanUps());
			if (fMonitor.isCanceled())
				throw new OperationCanceledException();
			if (tuple != null) {
				fResult.add(tuple);
				fMonitor.reset();
			} else {
				fIndex.inc();
				fMonitor.flush();
			}
			if (fToParseIter.hasNext()) {
				fCurElement= (ParseListElement)fToParseIter.next();
				fMonitor.subTask(getSubTaskMessage(fCurElement.getCompilationUnit(), fIndex.value(), fIndex.size()));
			}
		}
		
		private String getSubTaskMessage(ICompilationUnit cu, int index, int size) {
			String typeName= JavaCore.removeJavaLikeExtension(cu.getElementName());
			return Messages.format(FixMessages.CleanUpRefactoring_ProcessingCompilationUnit_message, new Object[] {typeName, new Integer(index), new Integer(size)});
		}
		
		private ParseListElement calculateSolution(Hashtable solutions, CompilationUnit ast, ICleanUp[] cleanUps) {
			TextChange solution= null;
			ParseListElement result= null;
			for (int i= 0; i < cleanUps.length; i++) {
				ICleanUp cleanUp= cleanUps[i];
				try {
					IFix fix= cleanUp.createFix(ast);
					if (fix != null) {
						TextChange current= fix.createChange();
						if (current instanceof TextFileChange && fLeaveFilesDirty)
							((TextFileChange)current).setSaveMode(TextFileChange.LEAVE_DIRTY);
						
						if (solution != null) {
							if (intersects(current.getEdit(),solution.getEdit())) {
								if (result == null) {
									result= new ParseListElement((ICompilationUnit)ast.getJavaElement().getPrimaryElement());
								}
								result.addCleanUp(cleanUp);
							} else {
								mergeTextChanges(current, solution);
								solution= current;
							}
						} else {
							solution= current;
						}
					}
				} catch (CoreException e) {
					throw new FixCalculationException(e);
				}
			}
			
			if (solution != null) {
				if (solutions.containsKey(ast.getJavaElement().getPrimaryElement())) {
					MultiStateCompilationUnitChange oldChange= (MultiStateCompilationUnitChange)solutions.get(ast.getJavaElement().getPrimaryElement());
					oldChange.addChange(solution);
				} else {
					solutions.put(ast.getJavaElement(), solution);
				}
			}
			
			return result;
		}
	}


	private static final RefactoringTickProvider CLEAN_UP_REFACTORING_TICK_PROVIDER= new RefactoringTickProvider(0, 1, 0, 0);
	
	private List/*<ICleanUp>*/ fCleanUps;
	private Hashtable/*<IJavaProject, List<ICompilationUnit>*/ fProjects;

	private Change fChange;

	private boolean fLeaveFilesDirty;
	
	public CleanUpRefactoring() {
		fCleanUps= new ArrayList();
		fProjects= new Hashtable();
	}
	
	public void addCompilationUnit(ICompilationUnit unit) {
		IJavaProject javaProject= unit.getJavaProject();
		if (!fProjects.containsKey(javaProject))
			fProjects.put(javaProject, new ArrayList());
		
		List cus= (List)fProjects.get(javaProject);
		cus.add(unit);
	}
	
	public void clearCompilationUnits() {
		fProjects.clear();
	}
	
	public boolean hasCompilationUnits() {
		return !fProjects.isEmpty();
	}
	
	public ICompilationUnit[] getCompilationUnits() {
		List cus= new ArrayList();
		for (Iterator iter= fProjects.values().iterator(); iter.hasNext();) {
			List pcus= (List)iter.next();
			cus.addAll(pcus);
		}
		return (ICompilationUnit[])cus.toArray(new ICompilationUnit[cus.size()]);
	}
	
	public void addCleanUp(ICleanUp fix) {
		fCleanUps.add(fix);
	}
	
	public void clearCleanUps() {
		fCleanUps.clear();
	}
	
	public boolean hasCleanUps() {
		return !fCleanUps.isEmpty();
	}
	
	public ICleanUp[] getCleanUps() {
		return (ICleanUp[])fCleanUps.toArray(new ICleanUp[fCleanUps.size()]);
	}
	
	public IJavaProject[] getProjects() {
		return (IJavaProject[])fProjects.keySet().toArray(new IJavaProject[fProjects.keySet().size()]);
	}
	
	public void setLeaveFilesDirty(boolean leaveFilesDirty) {
		fLeaveFilesDirty= leaveFilesDirty;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ltk.core.refactoring.Refactoring#getName()
	 */
	public String getName() {
		return FixMessages.CleanUpRefactoring_Refactoring_name;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ltk.core.refactoring.Refactoring#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		if (pm != null) {
			pm.beginTask("", 1); //$NON-NLS-1$
			pm.worked(1);
			pm.done();
		}
		return new RefactoringStatus();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ltk.core.refactoring.Refactoring#createChange(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		if (pm != null) {
			pm.beginTask("", 1); //$NON-NLS-1$
			pm.worked(1);
			pm.done();
		}
		return fChange;
	}


	/* (non-Javadoc)
	 * @see org.eclipse.ltk.core.refactoring.Refactoring#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		
		if (pm == null)
			pm= new NullProgressMonitor();
		
		if (fProjects.size() == 0 || fCleanUps.size() == 0) {
			pm.beginTask("", 1); //$NON-NLS-1$
			pm.worked(1);
			pm.done();
			fChange= new NullChange();

			return new RefactoringStatus();
		}
		
		int cuCount= 0;
		for (Iterator iter= fProjects.keySet().iterator(); iter.hasNext();) {
			IJavaProject project= (IJavaProject)iter.next();
			cuCount+= ((List)fProjects.get(project)).size();
		}
		
		pm.beginTask("", cuCount * 2 * fCleanUps.size() + 4 * fCleanUps.size()); //$NON-NLS-1$

		try {
			CompositeChange change= new DynamicValidationStateChange(getName());
			for (Iterator projectIter= fProjects.keySet().iterator(); projectIter.hasNext();) {
				IJavaProject project= (IJavaProject)projectIter.next();
				
				List compilationUnits= (List)fProjects.get(project);
				ICompilationUnit[] cus= (ICompilationUnit[])compilationUnits.toArray(new ICompilationUnit[compilationUnits.size()]);
				
				ICleanUp[] cleanUps= (ICleanUp[])fCleanUps.toArray(new ICleanUp[fCleanUps.size()]);
				
				cleanUpProject(project, cus, cleanUps, change, pm);
			}
			fChange= change;

			RefactoringStatus result= new RefactoringStatus();
			List files= new ArrayList();
			findFilesToBeModified(change, files);
			result.merge(Checks.validateModifiesFiles((IFile[])files.toArray(new IFile[files.size()]), getValidationContext()));
			if (result.hasFatalError())
				return result;
		} finally {
			pm.done();
		}
		
		return new RefactoringStatus();
	}

	private void findFilesToBeModified(CompositeChange change, List result) throws JavaModelException {
		Change[] children= change.getChildren();
		for (int i=0;i < children.length;i++) {
			Change child= children[i];
			if (child instanceof CompositeChange) {
				findFilesToBeModified((CompositeChange)child, result);
			} else if (child instanceof MultiStateCompilationUnitChange) {
				result.add(((MultiStateCompilationUnitChange)child).getCompilationUnit().getCorrespondingResource());
			} else if (child instanceof CompilationUnitChange) {
				result.add(((CompilationUnitChange)child).getCompilationUnit().getCorrespondingResource());
			}
		}
	}

	private void cleanUpProject(IJavaProject project, ICompilationUnit[] compilationUnits, ICleanUp[] cleanUps, CompositeChange result, IProgressMonitor monitor) throws CoreException {
		initCleanUps(project, compilationUnits, new SubProgressMonitor(monitor, 4 * cleanUps.length));
		
		List toGo= new ArrayList();
		for (int i= 0; i < compilationUnits.length; i++) {
			toGo.add(new ParseListElement(compilationUnits[i], cleanUps));
		}
		Hashtable resultingFixes= new Hashtable();
		Map cleanUpOptions= getCleanUpOptions();
		
		IndexCounter index= new IndexCounter(1, compilationUnits.length);
		int start= 0;
		int end= 0;
		while (end < toGo.size()) {
			end= Math.min(start + BATCH_SIZE, toGo.size());
			List toParse= toGo.subList(start, end);
			
			ASTParser parser= createParser(cleanUpOptions, project);
			List redoList= parse(toParse, parser, resultingFixes, index, new CleanUpRefactoringProgressMonitor(monitor, toParse.size() * 2 * cleanUps.length));
			toGo.addAll(redoList);
			
			start= end;
		}
		for (Iterator iter= resultingFixes.values().iterator(); iter.hasNext();) {
			Change element= (Change)iter.next();
			result.add(element);
		}

		endCleanUps();
	}

	private void initCleanUps(IJavaProject javaProject, ICompilationUnit[] compilationUnits, IProgressMonitor monitor) throws CoreException {
		ICleanUp[] cleanUps= getCleanUps();
		monitor.beginTask(Messages.format(FixMessages.CleanUpRefactoring_Initialize_message, javaProject.getElementName()), compilationUnits.length * cleanUps.length);
		try {
			for (int j= 0; j < cleanUps.length; j++) {
				cleanUps[j].beginCleanUp(javaProject, compilationUnits, new SubProgressMonitor(monitor, compilationUnits.length));
			}
		} finally {
			monitor.done();
		}
	}
	
	private void endCleanUps() throws CoreException {
		ICleanUp[] cleanUps= getCleanUps();
		for (int j= 0; j < cleanUps.length; j++) {
			cleanUps[j].endCleanUp();
		}
	}

	/**
	 * @return Options for all multi-fixes in <code>fMultiFixes</code>
	 */
	private Map getCleanUpOptions() {
		Map cleanUpOptions= new Hashtable();
		for (Iterator iter= fCleanUps.iterator(); iter.hasNext();) {
			ICleanUp cleanUp= (ICleanUp)iter.next();
			Map currentCleanUpOption= cleanUp.getRequiredOptions();
			if (currentCleanUpOption != null)
				cleanUpOptions.putAll(currentCleanUpOption);
		}
		return cleanUpOptions;
	}

	private List/*<ParseListElement>*/ parse(List/*<ParseListElement*/ toParse, ASTParser parser, final Hashtable solutions, final IndexCounter index, final CleanUpRefactoringProgressMonitor monitor) throws CoreException {

		final ICompilationUnit[] compilationUnits= new ICompilationUnit[toParse.size()];
		final List workingCopys= new ArrayList();
		try {
			int i= 0;
			for (Iterator iter= toParse.iterator(); iter.hasNext();) {
				ParseListElement element= (ParseListElement) iter.next();

				ICompilationUnit compilationUnit= element.getCompilationUnit();
				if (solutions.containsKey(compilationUnit)) {

					ICompilationUnit workingCopy= createWorkingCopy(solutions, compilationUnit);

					compilationUnits[i]= workingCopy;
					workingCopys.add(workingCopy);
				} else {
					compilationUnits[i]= compilationUnit;
				}
				i++;
			}

			SolutionGenerator solutionGenerator= new SolutionGenerator(toParse, index, solutions, monitor);
			try {
				parser.createASTs(compilationUnits, new String[0], solutionGenerator, monitor);
			} catch (FixCalculationException e) {
				throw e.getException();
			}
			return solutionGenerator.getResult();
		} finally { 
			if (!workingCopys.isEmpty()) {
				for (Iterator iter= workingCopys.iterator(); iter.hasNext();) {
					ICompilationUnit cu= (ICompilationUnit)iter.next();
					cu.discardWorkingCopy();
				}
			}
			monitor.done();
		}
	}

	private ICompilationUnit createWorkingCopy(final Hashtable solutions, ICompilationUnit compilationUnit) throws JavaModelException, CoreException {
		Change oldChange= (Change)solutions.get(compilationUnit);
		
		MultiStateCompilationUnitChange mscuc;
		if (!(oldChange instanceof MultiStateCompilationUnitChange)) {
			mscuc= new MultiStateCompilationUnitChange(getChangeName(compilationUnit), compilationUnit);
			mscuc.setKeepPreviewEdits(true);
			mscuc.addChange((TextChange)oldChange);
			solutions.remove(compilationUnit);
			solutions.put(compilationUnit, mscuc);
		} else {
			mscuc= (MultiStateCompilationUnitChange)oldChange;
		}

		ICompilationUnit workingCopy= compilationUnit.getWorkingCopy(new WorkingCopyOwner() {}, null, null);
		
		IBuffer buffer= workingCopy.getBuffer();
		buffer.setContents(mscuc.getPreviewContent(null));
		return workingCopy;
	}

	private String getChangeName(ICompilationUnit compilationUnit) {
		StringBuffer buf= new StringBuffer();
		JavaElementLabels.getCompilationUnitLabel(compilationUnit, JavaElementLabels.ALL_DEFAULT, buf);
		buf.append(JavaElementLabels.CONCAT_STRING);
		
		StringBuffer buf2= new StringBuffer();
		JavaElementLabels.getPackageFragmentLabel((IPackageFragment) compilationUnit.getParent(), JavaElementLabels.P_QUALIFIED, buf2);
		buf.append(buf2.toString().replace('.', '/'));
		
		return buf.toString();
	}

	private ASTParser createParser(Map cleanUpOptions, IJavaProject javaProject) {
		ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
		parser.setResolveBindings(true);
		parser.setProject(javaProject);
				
		Map options= RefactoringASTParser.getCompilerOptions(javaProject);
		options.putAll(cleanUpOptions);
		parser.setCompilerOptions(options);
		return parser;
	}

	private static boolean intersects(TextEdit edit1, TextEdit edit2) {
		if (edit1 instanceof MultiTextEdit && edit2 instanceof MultiTextEdit) {
			MultiTextEdit multiTextEdit1= (MultiTextEdit)edit1;
			TextEdit[] children1= multiTextEdit1.getChildren();
			
			MultiTextEdit multiTextEdit2= (MultiTextEdit)edit2;
			TextEdit[] children2= multiTextEdit2.getChildren();
			
			int i1= 0;
			int i2= 0;
			while (i1 < children1.length && i2 < children2.length) {
				while (children1[i1].getExclusiveEnd() < children2[i2].getOffset()) {
					i1++;
					if (i1 >= children1.length)
						return false;
				}
				while (children2[i2].getExclusiveEnd() < children1[i1].getOffset()) {
					i2++;
					if (i2 >= children2.length)
						return false;
				}
				if (intersects(children1[i1], children2[i2]))
					return true;
				
				if (children1[i1].getExclusiveEnd() < children2[i2].getExclusiveEnd()) {
					i1++;
				} else {
					i2++;
				}
			}
			
			return false;
			
		} else if (edit1 instanceof MultiTextEdit) {
			MultiTextEdit multiTextEdit1= (MultiTextEdit)edit1;
			TextEdit[] children= multiTextEdit1.getChildren();
			for (int i= 0; i < children.length; i++) {
				TextEdit child= children[i];
				if (intersects(child, edit2))
					return true;
			}
			return false;
			
		} else if (edit2 instanceof MultiTextEdit) {
			MultiTextEdit multiTextEdit2= (MultiTextEdit)edit2;
			TextEdit[] children= multiTextEdit2.getChildren();
			for (int i= 0; i < children.length; i++) {
				TextEdit child= children[i];
				if (intersects(child, edit1))
					return true;
			}
			return false;
			
		} else {
			int start1= edit1.getOffset();
			int end1= start1 + edit1.getLength();
			int start2= edit2.getOffset();
			int end2= start2 + edit2.getLength();
			
			if (start1 > end2)
				return false;
			
			if (start2 > end1)
				return false;
			
			return true;
		}
	}

	private static void mergeTextChanges(TextChange target, TextChange source) {
		final List edits= new ArrayList();
		source.getEdit().accept(new TextEditVisitor() {
			public boolean visitNode(TextEdit edit) {
				if (edit instanceof MoveSourceEdit)
					return false;
				
				if (edit instanceof MultiTextEdit)
					return true;
					
				edits.add(edit);
				return super.visitNode(edit);
			}
			
		});
		if (edits.isEmpty())
			return;
		
		final List removedEdits= new ArrayList();
		target.getEdit().accept(new TextEditVisitor() {
			public boolean visit(DeleteEdit deleteEdit) {
				int start= deleteEdit.getOffset();
				int end= start + deleteEdit.getLength();
				
				List toRemove= new ArrayList();
				for (Iterator iter= edits.iterator(); iter.hasNext();) {
					TextEdit edit= (TextEdit)iter.next();
					int offset= edit.getOffset();
					if (offset >= start && offset <= end) {
						toRemove.add(edit);
					}
				}
				
				if (!toRemove.isEmpty()) {
					edits.removeAll(toRemove);
					removedEdits.addAll(toRemove);
				}
				
				return super.visit(deleteEdit);
			}
		});
		for (Iterator iter= edits.iterator(); iter.hasNext();) {
			TextEdit edit= (TextEdit)iter.next();
			edit.getParent().removeChild(edit);
			TextChangeCompatibility.insert(target.getEdit(), edit);
		}
		TextEditBasedChangeGroup[] changeGroups= source.getChangeGroups();
		for (int i= 0; i < changeGroups.length; i++) {
			TextEditGroup textEditGroup= changeGroups[i].getTextEditGroup();
			TextEditGroup newGroup= new TextEditGroup(textEditGroup.getName());
			TextEdit[] textEdits= textEditGroup.getTextEdits();
			for (int j= 0; j < textEdits.length; j++) {
				if (!removedEdits.contains(textEdits[j]))
					newGroup.addTextEdit(textEdits[j]);
			}
			target.addTextEditGroup(newGroup);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ltk.core.refactoring.Refactoring#getRefactoringTickProvider()
	 */
	protected RefactoringTickProvider doGetRefactoringTickProvider() {
		return CLEAN_UP_REFACTORING_TICK_PROVIDER;
	}
}
