/*******************************************************************************
 * Copyright (c) 2000, 2008 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.wst.jsdt.internal.corext.refactoring.code;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.RangeMarker;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.wst.jsdt.core.Flags;
import org.eclipse.wst.jsdt.core.IField;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.ISourceRange;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.wst.jsdt.core.dom.ArrayCreation;
import org.eclipse.wst.jsdt.core.dom.ArrayInitializer;
import org.eclipse.wst.jsdt.core.dom.ArrayType;
import org.eclipse.wst.jsdt.core.dom.Assignment;
import org.eclipse.wst.jsdt.core.dom.BodyDeclaration;
import org.eclipse.wst.jsdt.core.dom.Expression;
import org.eclipse.wst.jsdt.core.dom.FieldAccess;
import org.eclipse.wst.jsdt.core.dom.FieldDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.IBinding;
import org.eclipse.wst.jsdt.core.dom.IFunctionBinding;
import org.eclipse.wst.jsdt.core.dom.ITypeBinding;
import org.eclipse.wst.jsdt.core.dom.IVariableBinding;
import org.eclipse.wst.jsdt.core.dom.ImportDeclaration;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.Modifier;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.ParenthesizedExpression;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.SuperMethodInvocation;
import org.eclipse.wst.jsdt.core.dom.Type;
import org.eclipse.wst.jsdt.core.dom.TypeDeclarationStatement;
import org.eclipse.wst.jsdt.core.dom.VariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.VariableDeclarationFragment;
import org.eclipse.wst.jsdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.wst.jsdt.core.dom.rewrite.ListRewrite;
import org.eclipse.wst.jsdt.core.refactoring.IJavaScriptRefactorings;
import org.eclipse.wst.jsdt.core.refactoring.descriptors.JavaScriptRefactoringDescriptor;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants;
import org.eclipse.wst.jsdt.core.search.SearchMatch;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
import org.eclipse.wst.jsdt.internal.corext.Corext;
import org.eclipse.wst.jsdt.internal.corext.codemanipulation.ImportReferencesCollector;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes;
import org.eclipse.wst.jsdt.internal.corext.dom.HierarchicalASTVisitor;
import org.eclipse.wst.jsdt.internal.corext.dom.NodeFinder;
import org.eclipse.wst.jsdt.internal.corext.dom.fragments.ASTFragmentFactory;
import org.eclipse.wst.jsdt.internal.corext.dom.fragments.IExpressionFragment;
import org.eclipse.wst.jsdt.internal.corext.refactoring.Checks;
import org.eclipse.wst.jsdt.internal.corext.refactoring.IRefactoringSearchRequestor;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptor;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringScopeFactory;
import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringSearchEngine2;
import org.eclipse.wst.jsdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.wst.jsdt.internal.corext.refactoring.base.RefactoringStatusCodes;
import org.eclipse.wst.jsdt.internal.corext.refactoring.changes.CompilationUnitChange;
import org.eclipse.wst.jsdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.wst.jsdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
import org.eclipse.wst.jsdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.TightSourceRangeComputer;
import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.corext.util.Strings;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels;

public class InlineConstantRefactoring extends ScriptableRefactoring {

	private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
	private static final String ATTRIBUTE_REMOVE= "remove";	 //$NON-NLS-1$

	private static class InlineTargetCompilationUnit {

		private static class InitializerTraversal extends HierarchicalASTVisitor {
		
			private static boolean areInSameType(ASTNode one, ASTNode other) {
				ASTNode onesContainer= getContainingTypeDeclaration(one);
				ASTNode othersContainer= getContainingTypeDeclaration(other);
		
				if (onesContainer == null || othersContainer == null)
					return false;
		
				ITypeBinding onesContainerBinding= getTypeBindingForTypeDeclaration(onesContainer);
				ITypeBinding othersContainerBinding= getTypeBindingForTypeDeclaration(othersContainer);
		
				Assert.isNotNull(onesContainerBinding);
				Assert.isNotNull(othersContainerBinding);
		
				String onesKey= onesContainerBinding.getKey();
				String othersKey= othersContainerBinding.getKey();
		
				if (onesKey == null || othersKey == null)
					return false;
		
				return onesKey.equals(othersKey);
			}
		
			private static boolean isStaticAccess(SimpleName memberName) {
				IBinding binding= memberName.resolveBinding();
				Assert.isTrue(binding instanceof IVariableBinding || binding instanceof IFunctionBinding || binding instanceof ITypeBinding);
		
				if (binding instanceof ITypeBinding)
					return true;
		
				if (binding instanceof IVariableBinding)
					return ((IVariableBinding) binding).isField();
		
				int modifiers= binding.getModifiers();
				return Modifier.isStatic(modifiers);
			}
		
			private static ASTNode getContainingTypeDeclaration(ASTNode node) {
				while (node != null && !(node instanceof AbstractTypeDeclaration) && !(node instanceof AnonymousClassDeclaration)) {
					node= node.getParent();
				}
				return node;
			}
		
			private static ITypeBinding getTypeBindingForTypeDeclaration(ASTNode declaration) {
				if (declaration instanceof AnonymousClassDeclaration)
					return ((AnonymousClassDeclaration) declaration).resolveBinding();
		
				if (declaration instanceof AbstractTypeDeclaration)
					return ((AbstractTypeDeclaration) declaration).resolveBinding();
		
				Assert.isTrue(false);
				return null;
			}
		
			private final Expression fInitializer;
			private ASTRewrite fInitializerRewrite;
			private final HashSet fStaticImportsInInitializer2;
		
			// cache:
			private Set fNamesDeclaredLocallyAtNewLocation;
		
			private final Expression fNewLocation;
			private final HashSet fStaticImportsInReference;
			private final CompilationUnitRewrite fNewLocationCuRewrite;
		
			public InitializerTraversal(Expression initializer, HashSet staticImportsInInitializer, Expression newLocation, HashSet staticImportsInReference, CompilationUnitRewrite newLocationCuRewrite) {
				fInitializer= initializer;
				fInitializerRewrite= ASTRewrite.create(initializer.getAST());
				fStaticImportsInInitializer2= staticImportsInInitializer;
				
				fNewLocation= newLocation;
				fStaticImportsInReference= staticImportsInReference;
				fNewLocationCuRewrite= newLocationCuRewrite;
		
				perform(initializer);
			}
		
			/**
			 * @param scope not a TypeDeclaration
			 * @return Set containing Strings representing simple names
			 */
			private Set getLocallyDeclaredNames(BodyDeclaration scope) {
				Assert.isTrue(!(scope instanceof AbstractTypeDeclaration));
		
				final Set result= new HashSet();
		
				if (scope instanceof FieldDeclaration)
					return result;
		
				scope.accept(new HierarchicalASTVisitor() {
		
					public boolean visit(AbstractTypeDeclaration node) {
						Assert.isTrue(node.getParent() instanceof TypeDeclarationStatement);
		
						result.add(node.getName().getIdentifier());
						return false;
					}
		
					public boolean visit(AnonymousClassDeclaration anonDecl) {
						return false;
					}
		
					public boolean visit(VariableDeclaration varDecl) {
						result.add(varDecl.getName().getIdentifier());
						return false;
					}
				});
				return result;
			}
		
			public ASTRewrite getInitializerRewrite() {
				return fInitializerRewrite;
			}
		
			private void perform(Expression initializer) {
				initializer.accept(this);
				if (initializer instanceof FunctionInvocation || initializer instanceof SuperMethodInvocation) {
					addExplicitTypeArgumentsIfNecessary(initializer);
				}
			}
			
			private void addExplicitTypeArgumentsIfNecessary(Expression invocation) {
				if (Invocations.isResolvedTypeInferredFromExpectedType(invocation)) {
					ASTNode referenceContext= fNewLocation.getParent();
					if (! (referenceContext instanceof VariableDeclarationFragment
							|| referenceContext instanceof SingleVariableDeclaration
							|| referenceContext instanceof Assignment)) {
						IFunctionBinding methodBinding= Invocations.resolveBinding(invocation);
						ITypeBinding[] typeArguments= methodBinding.getTypeArguments();
						ListRewrite typeArgsRewrite= fInitializerRewrite.getListRewrite(invocation, Invocations.getTypeArgumentsProperty(invocation));
						for (int i= 0; i < typeArguments.length; i++) {
							Type typeArgument= fNewLocationCuRewrite.getImportRewrite().addImport(typeArguments[i], fNewLocationCuRewrite.getAST());
							fNewLocationCuRewrite.getImportRemover().registerAddedImports(typeArgument);
							typeArgsRewrite.insertLast(typeArgument, null);
						}
					}
				}
			}
			
			public boolean visit(FieldAccess fieldAccess) {
				fieldAccess.getExpression().accept(this);
				return false;
			}
		
			public boolean visit(FunctionInvocation invocation) {
				if (invocation.getExpression() == null)
					qualifyUnqualifiedMemberNameIfNecessary(invocation.getName());
				else
					invocation.getExpression().accept(this);
		
				for (Iterator it= invocation.arguments().iterator(); it.hasNext();)
					((Expression) it.next()).accept(this);
		
				return false;
			}
		
			public boolean visit(Name name) {
				SimpleName leftmost= getLeftmost(name);
		
				IBinding leftmostBinding= leftmost.resolveBinding();
				if (leftmostBinding instanceof IVariableBinding || leftmostBinding instanceof IFunctionBinding || leftmostBinding instanceof ITypeBinding) {
					if (shouldUnqualify(leftmost))
						unqualifyMemberName(leftmost);
					else
						qualifyUnqualifiedMemberNameIfNecessary(leftmost);
				}
		
				if (leftmostBinding instanceof ITypeBinding) {
					String addedImport= fNewLocationCuRewrite.getImportRewrite().addImport((ITypeBinding) leftmostBinding);
					fNewLocationCuRewrite.getImportRemover().registerAddedImport(addedImport);
				}
				
				return false;
			}
			
			private void qualifyUnqualifiedMemberNameIfNecessary(SimpleName memberName) {
				if (shouldQualify(memberName))
					qualifyMemberName(memberName);
			}
		
			private boolean shouldUnqualify(SimpleName memberName) {
				if (areInSameType(memberName, fNewLocation))
					return ! mayBeShadowedByLocalDeclaration(memberName);
				
				return false;
			}
		
			private void unqualifyMemberName(SimpleName memberName) {
				if (doesParentQualify(memberName))
					fInitializerRewrite.replace(memberName.getParent(), memberName, null);
			}

			private boolean shouldQualify(SimpleName memberName) {
				if (! areInSameType(fInitializer, fNewLocation))
					return true;
		
				return mayBeShadowedByLocalDeclaration(memberName);
			}
			
			private boolean mayBeShadowedByLocalDeclaration(SimpleName memberName) {
				return getNamesDeclaredLocallyAtNewLocation().contains(memberName.getIdentifier());
			}
		
			private Set getNamesDeclaredLocallyAtNewLocation() {
				if (fNamesDeclaredLocallyAtNewLocation != null)
					return fNamesDeclaredLocallyAtNewLocation;
		
				BodyDeclaration enclosingBodyDecl= (BodyDeclaration) ASTNodes.getParent(fNewLocation, BodyDeclaration.class);
				Assert.isTrue(!(enclosingBodyDecl instanceof AbstractTypeDeclaration));
		
				return fNamesDeclaredLocallyAtNewLocation= getLocallyDeclaredNames(enclosingBodyDecl);
			}
		
			private void qualifyMemberName(SimpleName memberName) {
				if (isStaticAccess(memberName)) {
					IBinding memberBinding= memberName.resolveBinding();
					
					if (memberBinding instanceof IVariableBinding || memberBinding instanceof IFunctionBinding) {
						if (fStaticImportsInReference.contains(fNewLocation)) { // use static import if reference location used static import
							importStatically(memberName, memberBinding);
							return;
						} else if (fStaticImportsInInitializer2.contains(memberName)) { // use static import if already imported statically in initializer
							importStatically(memberName, memberBinding);
							return;
						}
					}
					qualifyToTopLevelClass(memberName); //otherwise: qualify and import non-static
				}
			}
		
			private void importStatically(SimpleName toImport, IBinding binding) {
				String newName= fNewLocationCuRewrite.getImportRewrite().addStaticImport(binding);
				fNewLocationCuRewrite.getImportRemover().registerAddedStaticImport(binding);
				
				Name newReference= ASTNodeFactory.newName(fInitializerRewrite.getAST(), newName);
				fInitializerRewrite.replace(toImport, newReference, null);
			}
			
			private void qualifyToTopLevelClass(SimpleName toQualify) {
				ITypeBinding declaringClass= getDeclaringClassBinding(toQualify);
				if (declaringClass == null)
					return;
				
				Type newQualification= fNewLocationCuRewrite.getImportRewrite().addImport(declaringClass, fInitializerRewrite.getAST());
				fNewLocationCuRewrite.getImportRemover().registerAddedImports(newQualification);
				
				SimpleName newToQualify= (SimpleName) fInitializerRewrite.createMoveTarget(toQualify);
				Type newType= fInitializerRewrite.getAST().newQualifiedType(newQualification, newToQualify);
				fInitializerRewrite.replace(toQualify, newType, null);
			}
			
			private static ITypeBinding getDeclaringClassBinding(SimpleName memberName) {
		
				IBinding binding= memberName.resolveBinding();
				if (binding instanceof IFunctionBinding)
					return ((IFunctionBinding) binding).getDeclaringClass();
		
				if (binding instanceof IVariableBinding)
					return ((IVariableBinding) binding).getDeclaringClass();
		
				if (binding instanceof ITypeBinding)
					return ((ITypeBinding) binding).getDeclaringClass();
		
				Assert.isTrue(false);
				return null;
		
			}
		
		}
		
		private final Expression fInitializer;
		private final IJavaScriptUnit fInitializerUnit;
		private final VariableDeclarationFragment fOriginalDeclaration; 
		
		/** The references in this compilation unit, represented as AST Nodes in the parsed representation of the compilation unit */
		private final Expression[] fReferences;
		private final VariableDeclarationFragment fDeclarationToRemove;
		private final CompilationUnitRewrite fCuRewrite;
		private final TightSourceRangeComputer fSourceRangeComputer;
		private final HashSet fStaticImportsInInitializer;
		private final boolean fIs15;
		
		private InlineTargetCompilationUnit(CompilationUnitRewrite cuRewrite, Name[] references, InlineConstantRefactoring refactoring, HashSet staticImportsInInitializer) throws JavaScriptModelException {
			fInitializer= refactoring.getInitializer();
			fInitializerUnit= refactoring.getDeclaringCompilationUnit();
			
			fCuRewrite= cuRewrite;
			fSourceRangeComputer= new TightSourceRangeComputer();
			fCuRewrite.getASTRewrite().setTargetSourceRangeComputer(fSourceRangeComputer);
			if (refactoring.getRemoveDeclaration() && refactoring.getReplaceAllReferences() && cuRewrite.getCu().equals(fInitializerUnit))
				fDeclarationToRemove= refactoring.getDeclaration();
			else
				fDeclarationToRemove= null;
			
			fOriginalDeclaration= refactoring.getDeclaration();
			
			fReferences= new Expression[references.length];
			for (int i= 0; i < references.length; i++)
				fReferences[i]= getQualifiedReference(references[i]);
			
			fIs15= JavaModelUtil.is50OrHigher(cuRewrite.getCu().getJavaScriptProject());
			fStaticImportsInInitializer= fIs15 ? staticImportsInInitializer : new HashSet(0);
		}

		private static Expression getQualifiedReference(Name fieldName) {
			if (doesParentQualify(fieldName))
				return (Expression) fieldName.getParent();

			return fieldName;
		}

		private static boolean doesParentQualify(Name fieldName) {
			ASTNode parent= fieldName.getParent();
			Assert.isNotNull(parent);

			if (parent instanceof FieldAccess && ((FieldAccess) parent).getName() == fieldName)
				return true;

			if (parent instanceof QualifiedName && ((QualifiedName) parent).getName() == fieldName)
				return true;

			if (parent instanceof FunctionInvocation && ((FunctionInvocation) parent).getName() == fieldName)
				return true;

			return false;
		}

		public CompilationUnitChange getChange() throws CoreException {
			for (int i= 0; i < fReferences.length; i++)
				inlineReference(fReferences[i]);
			
			removeConstantDeclarationIfNecessary();
			
			return fCuRewrite.createChange();
		}

		private void inlineReference(Expression reference) throws CoreException {
			ASTNode importDecl= ASTNodes.getParent(reference, ImportDeclaration.class);
			if (importDecl != null)
				return; // don't inline into static imports

			String modifiedInitializer= prepareInitializerForLocation(reference);
			if (modifiedInitializer == null)
				return;

			TextEditGroup msg= fCuRewrite.createGroupDescription(RefactoringCoreMessages.InlineConstantRefactoring_Inline); 
			Expression newReference= (Expression) fCuRewrite.getASTRewrite().createStringPlaceholder(modifiedInitializer, reference.getNodeType());

			if (fInitializer instanceof ArrayInitializer) {
				ArrayCreation arrayCreation= fCuRewrite.getAST().newArrayCreation();
				ArrayType arrayType= (ArrayType) ASTNodeFactory.newType(fCuRewrite.getAST(), fOriginalDeclaration);
				arrayCreation.setType(arrayType);

				ArrayInitializer newArrayInitializer= (ArrayInitializer) fCuRewrite.getASTRewrite().createStringPlaceholder(modifiedInitializer,
						ASTNode.ARRAY_INITIALIZER);
				arrayCreation.setInitializer(newArrayInitializer);
				newReference= arrayCreation;

				ITypeBinding typeToAddToImport= ASTNodes.getType(fOriginalDeclaration).resolveBinding();
				fCuRewrite.getImportRewrite().addImport(typeToAddToImport);
				fCuRewrite.getImportRemover().registerAddedImport(typeToAddToImport.getName());
			}

			if (shouldParenthesizeSubstitute(fInitializer, reference)) {
				ParenthesizedExpression parenthesized= fCuRewrite.getAST().newParenthesizedExpression();
				parenthesized.setExpression(newReference);
				newReference= parenthesized;
			}
			fCuRewrite.getASTRewrite().replace(reference, newReference, msg);
			fSourceRangeComputer.addTightSourceNode(reference);
			fCuRewrite.getImportRemover().registerRemovedNode(reference);
		}

		private String prepareInitializerForLocation(Expression location) throws CoreException {
			HashSet staticImportsInReference= new HashSet();
			final IJavaScriptProject project= fCuRewrite.getCu().getJavaScriptProject();
			if (fIs15)
				location.accept(new ImportReferencesCollector(project, null, new ArrayList(), staticImportsInReference));
			InitializerTraversal traversal= new InitializerTraversal(fInitializer, fStaticImportsInInitializer, location, staticImportsInReference, fCuRewrite);
			ASTRewrite initializerRewrite= traversal.getInitializerRewrite();
			IDocument document= new Document(fInitializerUnit.getBuffer().getContents()); // could reuse document when generating and applying undo edits
			
			final RangeMarker marker= new RangeMarker(fInitializer.getStartPosition(), fInitializer.getLength());
			TextEdit[] rewriteEdits= initializerRewrite.rewriteAST(document, fInitializerUnit.getJavaScriptProject().getOptions(true)).removeChildren();
			marker.addChildren(rewriteEdits);
			try {
				marker.apply(document, TextEdit.UPDATE_REGIONS);
				String rewrittenInitializer= document.get(marker.getOffset(), marker.getLength());
				IRegion region= document.getLineInformation(document.getLineOfOffset(marker.getOffset()));
				int oldIndent= Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project);
				return Strings.changeIndent(rewrittenInitializer, oldIndent, project, "", TextUtilities.getDefaultLineDelimiter(document)); //$NON-NLS-1$
			} catch (MalformedTreeException e) {
				JavaScriptPlugin.log(e);
			} catch (BadLocationException e) {
				JavaScriptPlugin.log(e);
			}
			return fInitializerUnit.getBuffer().getText(fInitializer.getStartPosition(), fInitializer.getLength());
		}

		private static boolean shouldParenthesizeSubstitute(Expression substitute, Expression location) {
			if (substitute instanceof Assignment) // for esthetic reasons
				return true;
			else
				return ASTNodes.substituteMustBeParenthesized(substitute, location);
		}
		
		private void removeConstantDeclarationIfNecessary() throws CoreException {
			if (fDeclarationToRemove == null)
				return;
			
			FieldDeclaration parentDeclaration= (FieldDeclaration) fDeclarationToRemove.getParent();
			ASTNode toRemove;
			if (parentDeclaration.fragments().size() == 1)
				toRemove= parentDeclaration;
			else
				toRemove= fDeclarationToRemove;

			TextEditGroup msg= fCuRewrite.createGroupDescription(RefactoringCoreMessages.InlineConstantRefactoring_remove_declaration); 
			fCuRewrite.getASTRewrite().remove(toRemove, msg);
			fCuRewrite.getImportRemover().registerRemovedNode(toRemove);
		}
	}

	// ---- End InlineTargetCompilationUnit ----------------------------------------------------------------------------------------------

	private static SimpleName getLeftmost(Name name) {
		if (name instanceof SimpleName)
			return (SimpleName) name;

		return getLeftmost(((QualifiedName) name).getQualifier());
	}

	private int fSelectionStart;
	private int fSelectionLength;
	
	private IJavaScriptUnit fSelectionCu;
	private CompilationUnitRewrite fSelectionCuRewrite;
	private Name fSelectedConstantName;
	
	private IField fField;
	private CompilationUnitRewrite fDeclarationCuRewrite;
	private VariableDeclarationFragment fDeclaration;
	private boolean fDeclarationSelected;
	private boolean fDeclarationSelectedChecked= false;
	private boolean fInitializerAllStaticFinal;
	private boolean fInitializerChecked= false;

	private boolean fRemoveDeclaration= false;
	private boolean fReplaceAllReferences= true;

	private CompilationUnitChange[] fChanges;
	
	/**
	 * Creates a new inline constant refactoring.
	 * <p>
	 * This constructor is only used by <code>DelegateCreator</code>.
	 * </p>
	 * 
	 * @param field the field to inline
	 */
	public InlineConstantRefactoring(IField field) {
		Assert.isNotNull(field);
		Assert.isTrue(!field.isBinary());
		fField= field;
	}

	/**
	 * Creates a new inline constant refactoring.
	 * @param unit the compilation unit, or <code>null</code> if invoked by scripting
	 * @param node the compilation unit node, or <code>null</code> if invoked by scripting
	 * @param selectionStart
	 * @param selectionLength
	 */
	public InlineConstantRefactoring(IJavaScriptUnit unit, JavaScriptUnit node, int selectionStart, int selectionLength) {
		Assert.isTrue(selectionStart >= 0);
		Assert.isTrue(selectionLength >= 0);
		fSelectionCu= unit;
		fSelectionStart= selectionStart;
		fSelectionLength= selectionLength;
		if (unit != null)
			initialize(unit, node);
	}

	private void initialize(IJavaScriptUnit cu, JavaScriptUnit node) {
		fSelectionCuRewrite= new CompilationUnitRewrite(cu, node);
		fSelectedConstantName= findConstantNameNode();
	}

	private Name findConstantNameNode() {
		ASTNode node= NodeFinder.perform(fSelectionCuRewrite.getRoot(), fSelectionStart, fSelectionLength);
		if (node == null)
			return null;
		if (node instanceof FieldAccess)
			node= ((FieldAccess) node).getName();
		if (!(node instanceof Name))
			return null;
		Name name= (Name) node;
		IBinding binding= name.resolveBinding();
		if (!(binding instanceof IVariableBinding))
			return null;
		IVariableBinding variableBinding= (IVariableBinding) binding;
		if (!variableBinding.isField() || variableBinding.isEnumConstant())
			return null;
		int modifiers= binding.getModifiers();
		if (! (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)))
			return null;

		return name;
	}

	public RefactoringStatus checkStaticFinalConstantNameSelected() {
		if (fSelectedConstantName == null)
			return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_static_final_field, null, Corext.getPluginId(), RefactoringStatusCodes.NOT_STATIC_FINAL_SELECTED, null); 

		return new RefactoringStatus();
	}

	public String getName() {
		return RefactoringCoreMessages.InlineConstantRefactoring_name; 
	}

	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
		try {
			pm.beginTask("", 3); //$NON-NLS-1$

			if (!fSelectionCu.isStructureKnown())
				return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_syntax_errors, null, Corext.getPluginId(), RefactoringStatusCodes.SYNTAX_ERRORS, null); 

			RefactoringStatus result= checkStaticFinalConstantNameSelected();
			if (result.hasFatalError())
				return result;
			
			result.merge(findField());
			if (result.hasFatalError())
				return result;
			pm.worked(1);

			result.merge(findDeclaration());
			if (result.hasFatalError())
				return result;
			pm.worked(1);

			result.merge(checkInitializer());
			if (result.hasFatalError())
				return result;
			pm.worked(1);

			return result;
			
		} finally {
			pm.done();
		}
	}

	private RefactoringStatus findField() throws JavaScriptModelException {
		fField= (IField) ((IVariableBinding) fSelectedConstantName.resolveBinding()).getJavaElement();
		if (fField != null && ! fField.exists())
			return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_local_anonymous_unsupported, null, Corext.getPluginId(), RefactoringStatusCodes.LOCAL_AND_ANONYMOUS_NOT_SUPPORTED, null); 
		
		return null;
	}
	private RefactoringStatus findDeclaration() throws JavaScriptModelException {
		fDeclarationSelectedChecked= true;
		fDeclarationSelected= false;
		ASTNode parent= fSelectedConstantName.getParent();
		if (parent instanceof VariableDeclarationFragment) {
			VariableDeclarationFragment parentDeclaration= (VariableDeclarationFragment) parent;
			if (parentDeclaration.getName() == fSelectedConstantName) {
				fDeclarationSelected= true;
				fDeclarationCuRewrite= fSelectionCuRewrite;
				fDeclaration= (VariableDeclarationFragment) fSelectedConstantName.getParent();
				return null;
			}
		}
		
		VariableDeclarationFragment declaration= (VariableDeclarationFragment) fSelectionCuRewrite.getRoot().findDeclaringNode(fSelectedConstantName.resolveBinding());
		if (declaration != null) {
			fDeclarationCuRewrite= fSelectionCuRewrite;
			fDeclaration= declaration;
			return null;
		}

		if (fField.getJavaScriptUnit() == null)
			return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_binary_file, null, Corext.getPluginId(), RefactoringStatusCodes.DECLARED_IN_CLASSFILE, null); 
		
		fDeclarationCuRewrite= new CompilationUnitRewrite(fField.getJavaScriptUnit());
		fDeclaration= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(fField, fDeclarationCuRewrite.getRoot());
		return null;
	}

	private RefactoringStatus checkInitializer() {
		Expression initializer= getInitializer();
		if (initializer == null)
			return RefactoringStatus.createStatus(RefactoringStatus.FATAL, RefactoringCoreMessages.InlineConstantRefactoring_blank_finals, null, Corext.getPluginId(), RefactoringStatusCodes.CANNOT_INLINE_BLANK_FINAL, null); 

		fInitializerAllStaticFinal= ConstantChecks.isStaticFinalConstant((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(initializer));
		fInitializerChecked= true;
		return new RefactoringStatus();
	}

	private VariableDeclarationFragment getDeclaration() throws JavaScriptModelException {
		return fDeclaration;
	}

	private Expression getInitializer() {
		return fDeclaration.getInitializer();
	}
	
	private IJavaScriptUnit getDeclaringCompilationUnit() throws JavaScriptModelException {
		return fField.getJavaScriptUnit();
	}

	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
		RefactoringStatus result= new RefactoringStatus();
		pm.beginTask("", 3); //$NON-NLS-1$
		
		try {
			List/*<CompilationUnitChange>*/changes= new ArrayList();
			HashSet staticImportsInInitializer= new HashSet();
			ImportReferencesCollector importReferencesCollector= new ImportReferencesCollector(fField.getJavaScriptProject(), null, new ArrayList(), staticImportsInInitializer);
			getInitializer().accept(importReferencesCollector);
			
			if (getReplaceAllReferences()) {
				SearchResultGroup[] searchResultGroups= findReferences(pm, result);
				for (int i= 0; i < searchResultGroups.length; i++) {
					if (pm.isCanceled())
						throw new OperationCanceledException();
					SearchResultGroup group= searchResultGroups[i];
					IJavaScriptUnit cu= group.getCompilationUnit();

					CompilationUnitRewrite cuRewrite= getCuRewrite(cu);
					Name[] references= extractReferenceNodes(group.getSearchResults(), cuRewrite.getRoot());
					InlineTargetCompilationUnit targetCompilationUnit= new InlineTargetCompilationUnit(
							cuRewrite, references, this, staticImportsInInitializer);
					changes.add(targetCompilationUnit.getChange());
				}

			} else {
				Assert.isTrue(! isDeclarationSelected());
				InlineTargetCompilationUnit targetForOnlySelectedReference= new InlineTargetCompilationUnit(
						fSelectionCuRewrite, new Name[] { fSelectedConstantName }, this, staticImportsInInitializer);
				changes.add(targetForOnlySelectedReference.getChange());
			}

			if (result.hasFatalError())
				return result;

			if (getRemoveDeclaration() && getReplaceAllReferences()) {
				boolean declarationRemoved= false;
				for (Iterator iter= changes.iterator(); iter.hasNext();) {
					CompilationUnitChange change= (CompilationUnitChange) iter.next();
					if (change.getCompilationUnit().equals(fDeclarationCuRewrite.getCu())) {
						declarationRemoved= true;
						break;
					}
				}
				if (! declarationRemoved) {
					InlineTargetCompilationUnit targetForDeclaration= new InlineTargetCompilationUnit(fDeclarationCuRewrite, new Name[0], this, staticImportsInInitializer);
					CompilationUnitChange change= targetForDeclaration.getChange();
					if (change != null)
						changes.add(change);
				}
			}

			IJavaScriptUnit[] cus= new IJavaScriptUnit[changes.size()];
			for (int i= 0; i < changes.size(); i++) {
				CompilationUnitChange change= (CompilationUnitChange) changes.get(i);
				cus[i]= change.getCompilationUnit();
			}
			result.merge(Checks.validateModifiesFiles(ResourceUtil.getFiles(cus), getValidationContext()));

			pm.worked(1);

			fChanges= (CompilationUnitChange[]) changes.toArray(new CompilationUnitChange[changes.size()]);

			return result;
			
		} finally {
			fSelectionCuRewrite= null;
			fSelectedConstantName= null;
			fDeclarationCuRewrite= null;
			fDeclaration= null;
			pm.done();
		}
	}

	private Name[] extractReferenceNodes(SearchMatch[] searchResults, JavaScriptUnit cuNode) {
		Name[] references= new Name[searchResults.length];
		for (int i= 0; i < searchResults.length; i++)
			references[i]= (Name) NodeFinder.perform(cuNode, searchResults[i].getOffset(), searchResults[i].getLength());
		return references;
	}

	private CompilationUnitRewrite getCuRewrite(IJavaScriptUnit cu) {
		CompilationUnitRewrite cuRewrite;
		if (cu.equals(fSelectionCu)) {
			cuRewrite= fSelectionCuRewrite;
		} else if (cu.equals(fField.getJavaScriptUnit())) {
			cuRewrite= fDeclarationCuRewrite;
		} else {
			cuRewrite= new CompilationUnitRewrite(cu);
		}
		return cuRewrite;
	}

	private SearchResultGroup[] findReferences(IProgressMonitor pm, RefactoringStatus status) throws JavaScriptModelException {
		final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fField, IJavaScriptSearchConstants.REFERENCES));
		engine.setFiltering(true, true);
		engine.setScope(RefactoringScopeFactory.create(fField));
		engine.setStatus(status);
		engine.setRequestor(new IRefactoringSearchRequestor() {
			public SearchMatch acceptSearchMatch(SearchMatch match) {
				return match.isInsideDocComment() ? null : match;
			}
		});
		engine.searchPattern(new SubProgressMonitor(pm, 1));
		return (SearchResultGroup[]) engine.getResults();
	}

	public Change createChange(IProgressMonitor pm) throws CoreException {
		try {
			pm.beginTask(RefactoringCoreMessages.InlineConstantRefactoring_preview, 2);
			final Map arguments= new HashMap();
			String project= null;
			IJavaScriptProject javaProject= fSelectionCu.getJavaScriptProject();
			if (javaProject != null)
				project= javaProject.getElementName();
			int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | JavaScriptRefactoringDescriptor.JAR_REFACTORING | JavaScriptRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
			try {
				if (!Flags.isPrivate(fField.getFlags()))
					flags|= RefactoringDescriptor.MULTI_CHANGE;
			} catch (JavaScriptModelException exception) {
				JavaScriptPlugin.log(exception);
			}
			final String description= Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_descriptor_description_short, fField.getElementName());
			final String header= Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_descriptor_description, new String[] { JavaScriptElementLabels.getElementLabel(fField, JavaScriptElementLabels.ALL_FULLY_QUALIFIED), JavaScriptElementLabels.getElementLabel(fField.getParent(), JavaScriptElementLabels.ALL_FULLY_QUALIFIED)});
			final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
			comment.addSetting(Messages.format(RefactoringCoreMessages.InlineConstantRefactoring_original_pattern, JavaScriptElementLabels.getElementLabel(fField, JavaScriptElementLabels.ALL_FULLY_QUALIFIED)));
			if (fRemoveDeclaration)
				comment.addSetting(RefactoringCoreMessages.InlineConstantRefactoring_remove_declaration);
			if (fReplaceAllReferences)
				comment.addSetting(RefactoringCoreMessages.InlineConstantRefactoring_replace_references);
			final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaScriptRefactorings.INLINE_CONSTANT, project, description, comment.asString(), arguments, flags);
			arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fSelectionCu));
			arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
			arguments.put(ATTRIBUTE_REMOVE, Boolean.valueOf(fRemoveDeclaration).toString());
			arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceAllReferences).toString());
			return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.InlineConstantRefactoring_inline, fChanges);
		} finally {
			pm.done();
			fChanges= null;
		}
	}

	private void checkInvariant() {
		if (isDeclarationSelected())
			Assert.isTrue(fReplaceAllReferences);
	}

	public boolean getRemoveDeclaration() {
		return fRemoveDeclaration;
	}

	public boolean getReplaceAllReferences() {
		checkInvariant();
		return fReplaceAllReferences;
	}

	public boolean isDeclarationSelected() {
		Assert.isTrue(fDeclarationSelectedChecked);
		return fDeclarationSelected;
	}

	public boolean isInitializerAllStaticFinal() {
		Assert.isTrue(fInitializerChecked);
		return fInitializerAllStaticFinal;
	}

	public void setRemoveDeclaration(boolean removeDeclaration) {
		fRemoveDeclaration= removeDeclaration;
	}

	public void setReplaceAllReferences(boolean replaceAllReferences) {
		fReplaceAllReferences= replaceAllReferences;
		checkInvariant();
	}

	public RefactoringStatus initialize(final RefactoringArguments arguments) {
		if (arguments instanceof JavaRefactoringArguments) {
			final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
			final String selection= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_SELECTION);
			if (selection != null) {
				int offset= -1;
				int length= -1;
				final StringTokenizer tokenizer= new StringTokenizer(selection);
				if (tokenizer.hasMoreTokens())
					offset= Integer.valueOf(tokenizer.nextToken()).intValue();
				if (tokenizer.hasMoreTokens())
					length= Integer.valueOf(tokenizer.nextToken()).intValue();
				if (offset >= 0 && length >= 0) {
					fSelectionStart= offset;
					fSelectionLength= length;
				} else
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, JDTRefactoringDescriptor.ATTRIBUTE_SELECTION}));
			}
			final String handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT);
			if (handle != null) {
				final IJavaScriptElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
				if (element == null || !element.exists())
					return createInputFatalStatus(element, IJavaScriptRefactorings.INLINE_CONSTANT);
				else {
					if (element instanceof IJavaScriptUnit) {
						fSelectionCu= (IJavaScriptUnit) element;
						if (selection == null)
							return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_SELECTION));
					} else if (element instanceof IField) {
						final IField field= (IField) element;
						try {
							final ISourceRange range= field.getNameRange();
							if (range != null) {
								fSelectionStart= range.getOffset();
								fSelectionLength= range.getLength();
							} else
								return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, IJavaScriptRefactorings.INLINE_CONSTANT));
						} catch (JavaScriptModelException exception) {
							return createInputFatalStatus(element, IJavaScriptRefactorings.INLINE_CONSTANT);
						}
						fSelectionCu= field.getJavaScriptUnit();
					} else
						return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { handle, JDTRefactoringDescriptor.ATTRIBUTE_INPUT}));
					final ASTParser parser= ASTParser.newParser(AST.JLS3);
					parser.setResolveBindings(true);
					parser.setSource(fSelectionCu);
					final JavaScriptUnit unit= (JavaScriptUnit) parser.createAST(null);
					initialize(fSelectionCu, unit);
					if (checkStaticFinalConstantNameSelected().hasFatalError())
						return createInputFatalStatus(element, IJavaScriptRefactorings.INLINE_CONSTANT);
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT));
			final String replace= extended.getAttribute(ATTRIBUTE_REPLACE);
			if (replace != null) {
				fReplaceAllReferences= Boolean.valueOf(replace).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
			final String remove= extended.getAttribute(ATTRIBUTE_REMOVE);
			if (remove != null)
				fRemoveDeclaration= Boolean.valueOf(remove).booleanValue();
			else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REMOVE));
		} else
			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
		return new RefactoringStatus();
	}
}
