/*******************************************************************************
 * 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.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.text.edits.TextEditGroup;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;

import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.text.java.IProblemLocation;

import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation;

/**
 * A fix which fixes code style issues.
 */
public class CodeStyleFix extends AbstractFix {
	
	private final static class CodeStyleVisitor extends GenericVisitor {
		
		private final List/*<IFixRewriteOperation>*/ fResult;
		private final ImportRewrite fImportRewrite;
		private final boolean fFindUnqualifiedAccesses;
		private final boolean fFindUnqualifiedStaticAccesses;
		private final boolean fFindUnqualifiedMethodAccesses;
		private final boolean fFindUnqualifiedStaticMethodAccesses;
		
		public CodeStyleVisitor(CompilationUnit compilationUnit, 
				boolean findUnqualifiedAccesses, 
				boolean findUnqualifiedStaticAccesses,
				boolean findUnqualifiedMethodAccesses,
				boolean findUnqualifiedStaticMethodAccesses,
				List resultingCollection) throws CoreException {
			
			fFindUnqualifiedAccesses= findUnqualifiedAccesses;
			fFindUnqualifiedStaticAccesses= findUnqualifiedStaticAccesses;
			fFindUnqualifiedMethodAccesses= findUnqualifiedMethodAccesses;
			fFindUnqualifiedStaticMethodAccesses= findUnqualifiedStaticMethodAccesses;
			fImportRewrite= StubUtility.createImportRewrite(compilationUnit, true);
			fResult= resultingCollection;
		}
		
		/**
		 * {@inheritDoc}
		 */
		public boolean visit(TypeDeclaration node) {
			if (!fFindUnqualifiedStaticAccesses && !fFindUnqualifiedStaticMethodAccesses && node.isInterface())
				return false;
			
			return super.visit(node);
		}

		public boolean visit(QualifiedName node) {
			if (fFindUnqualifiedAccesses || fFindUnqualifiedStaticAccesses) {
				ASTNode simpleName= node;
				while (simpleName instanceof QualifiedName) {
					simpleName= ((QualifiedName) simpleName).getQualifier();
				}
				if (simpleName instanceof SimpleName) {
					handleSimpleName((SimpleName)simpleName);
				}
			}
			return false;
		}

		public boolean visit(SimpleName node) {
			if (fFindUnqualifiedAccesses || fFindUnqualifiedStaticAccesses) {
				handleSimpleName(node);
			}
			return false;
		}
		
		/**
		 * {@inheritDoc}
		 */
		public boolean visit(MethodInvocation node) {
			if (!fFindUnqualifiedMethodAccesses && !fFindUnqualifiedStaticMethodAccesses)
				return true;
			
			if (node.getExpression() != null)
				return true;
			
			IBinding binding= node.getName().resolveBinding();
			if (!(binding instanceof IMethodBinding))
				return true;
			
			handleMethod(node.getName(), (IMethodBinding)binding);
			return true;
		}

		private void handleSimpleName(SimpleName node) {
			ASTNode firstExpression= node.getParent();
			if (firstExpression instanceof FieldAccess) {
				while (firstExpression instanceof FieldAccess) {
					firstExpression= ((FieldAccess)firstExpression).getExpression();
				}
				if (!(firstExpression instanceof SimpleName))
					return;
				
				node= (SimpleName)firstExpression;
			} else if (firstExpression instanceof SuperFieldAccess)
				return;
			
			StructuralPropertyDescriptor parentDescription= node.getLocationInParent();
			if (parentDescription == VariableDeclarationFragment.NAME_PROPERTY || parentDescription == SwitchCase.EXPRESSION_PROPERTY)
				return;
			
			IBinding binding= node.resolveBinding();
			if (!(binding instanceof IVariableBinding))
				return;
			
			handleVariable(node, (IVariableBinding) binding);
		}

		private void handleVariable(SimpleName node, IVariableBinding varbinding) {
			if (!varbinding.isField())
				return;
			
			if (varbinding.isEnumConstant())
				return;

			ITypeBinding declaringClass= varbinding.getDeclaringClass();
			if (Modifier.isStatic(varbinding.getModifiers())) {
				if (fFindUnqualifiedStaticAccesses) {
					Initializer initializer= (Initializer) ASTNodes.getParent(node, Initializer.class);
					//Do not qualify assignments to static final fields in static initializers (would result in compile error)
					StructuralPropertyDescriptor parentDescription= node.getLocationInParent();
					if (initializer != null && Modifier.isStatic(initializer.getModifiers())
							&& Modifier.isFinal(varbinding.getModifiers()) && parentDescription == Assignment.LEFT_HAND_SIDE_PROPERTY)
						return;
						
					//Do not qualify static fields if defined inside an anonymous class
					if (declaringClass.isAnonymous())
						return;

					fResult.add(new AddStaticQualifierOperation(declaringClass, node));
				}
			} else if (fFindUnqualifiedAccesses){
				String qualifier= getNonStaticQualifier(declaringClass, fImportRewrite, node);
				if (qualifier == null)
					return;

				fResult.add(new AddThisQualifierOperation(qualifier, node));
			}
		}		

		private void handleMethod(SimpleName node, IMethodBinding binding) {
			ITypeBinding declaringClass= binding.getDeclaringClass();
			if (Modifier.isStatic(binding.getModifiers())) {
				if (fFindUnqualifiedStaticMethodAccesses) {
					//Do not qualify static fields if defined inside an anonymous class
					if (declaringClass.isAnonymous())
						return;

					fResult.add(new AddStaticQualifierOperation(declaringClass, node));
				}
			} else {
				if (fFindUnqualifiedMethodAccesses) {
					String qualifier= getNonStaticQualifier(declaringClass, fImportRewrite, node);
					if (qualifier == null)
						return;

					fResult.add(new AddThisQualifierOperation(qualifier, node));
				}
			}
		}
	}
	
	private static class ThisQualifierVisitor extends GenericVisitor {
		
		private final CompilationUnit fCompilationUnit;
		private final List fOperations;
		private final boolean fRemoveFieldQualifiers;
		private final boolean fRemoveMethodQualifiers;
		
		public ThisQualifierVisitor(boolean removeFieldQualifiers,
									boolean removeMethodQualifiers,
									CompilationUnit compilationUnit,
									List result) {
			fRemoveFieldQualifiers= removeFieldQualifiers;
			fRemoveMethodQualifiers= removeMethodQualifiers;
			fCompilationUnit= compilationUnit;
			fOperations= result;
		}
		
		/**
		 * {@inheritDoc}
		 */
		public boolean visit(final FieldAccess node) {
			if (!fRemoveFieldQualifiers)
				return true;
			
			Expression expression= node.getExpression();
			if (!(expression instanceof ThisExpression))
				return true;
			
			final SimpleName name= node.getName();
			if (hasConflict(expression.getStartPosition(), name, ScopeAnalyzer.VARIABLES))
				return true;
			
			fOperations.add(new AbstractFixRewriteOperation() {
				public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException {
					ASTRewrite rewrite= cuRewrite.getASTRewrite();
					
					TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_removeThis_groupDescription);
					textEditGroups.add(group);
					
					rewrite.replace(node, rewrite.createCopyTarget(name), group);
				}
			});
			return super.visit(node);
		}
		
		/**
		 * {@inheritDoc}
		 */
		public boolean visit(final MethodInvocation node) {
			if (!fRemoveMethodQualifiers)
				return true;
			
			Expression expression= node.getExpression();
			if (!(expression instanceof ThisExpression)) 
				return true;
			
			if (((ThisExpression)expression).getQualifier() != null)
				return true;
			
			final SimpleName name= node.getName();
			if (hasConflict(expression.getStartPosition(), name, ScopeAnalyzer.METHODS))
				return true;
			
			fOperations.add(new AbstractFixRewriteOperation() {
				public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException {
					ASTRewrite rewrite= cuRewrite.getASTRewrite();
					
					TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_removeThis_groupDescription);
					textEditGroups.add(group);
					
					rewrite.remove(node.getExpression(), group);
				}
			});
			return super.visit(node);
		}
		
		private boolean hasConflict(int startPosition, SimpleName name, int flag) {
			ScopeAnalyzer analyzer= new ScopeAnalyzer(fCompilationUnit);
			IBinding[] declarationsInScope= analyzer.getDeclarationsInScope(startPosition, flag);
			for (int i= 0; i < declarationsInScope.length; i++) {
				IBinding decl= declarationsInScope[i];
				if (decl.getName().equals(name.getIdentifier()) && name.resolveBinding() != decl)
					return true;
			}
			return false;
		}
	}

	private final static class AddThisQualifierOperation extends AbstractFixRewriteOperation {

		private final String fQualifier;
		private final SimpleName fName;

		public AddThisQualifierOperation(String qualifier, SimpleName name) {
			fQualifier= qualifier;
			fName= name;
		}
		
		public String getDescription() {
			return Messages.format(FixMessages.CodeStyleFix_QualifyWithThis_description, new Object[] {fName.getIdentifier(), fQualifier});
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.corext.fix.AbstractFix.IFixRewriteOperation#rewriteAST(org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite, java.util.List)
		 */
		public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException {
			ASTRewrite rewrite= cuRewrite.getASTRewrite();
			TextEditGroup group;
			if (fName.resolveBinding() instanceof IMethodBinding) {
				group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyMethodWithThis_description);
			} else {
				group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyFieldWithThis_description);
			}
			textEditGroups.add(group);
			rewrite.replace(fName, rewrite.createStringPlaceholder(fQualifier  + '.' + fName.getIdentifier(), ASTNode.SIMPLE_NAME), group);
		}		
	}
	
	private final static class AddStaticQualifierOperation extends AbstractFixRewriteOperation {

		private final SimpleName fName;
		private final ITypeBinding fDeclaringClass;
		
		public AddStaticQualifierOperation(ITypeBinding declaringClass, SimpleName name) {
			super();
			fDeclaringClass= declaringClass;
			fName= name;
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.corext.fix.AbstractFix.IFixRewriteOperation#rewriteAST(org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite, java.util.List)
		 */
		public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException {
			ASTRewrite rewrite= cuRewrite.getASTRewrite();
			CompilationUnit compilationUnit= cuRewrite.getRoot();
			importType(fDeclaringClass, fName, cuRewrite.getImportRewrite(), compilationUnit);
			TextEditGroup group;
			if (fName.resolveBinding() instanceof IMethodBinding) {
				group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyMethodWithDeclClass_description);
			} else {
				group= createTextEditGroup(FixMessages.CodeStyleFix_QualifyFieldWithDeclClass_description);
			}
			textEditGroups.add(group);
			IJavaElement javaElement= fDeclaringClass.getJavaElement();
			if (javaElement instanceof IType) {
				Name qualifierName= compilationUnit.getAST().newName(((IType)javaElement).getElementName());
				SimpleName simpleName= (SimpleName)rewrite.createMoveTarget(fName);
				QualifiedName qualifiedName= compilationUnit.getAST().newQualifiedName(qualifierName, simpleName);
				rewrite.replace(fName, qualifiedName, group);
			}
		}
		
	}
	
	private final static class ToStaticAccessOperation extends AbstractFixRewriteOperation {

		private final ITypeBinding fDeclaringTypeBinding;
		private final Expression fQualifier;

		public ToStaticAccessOperation(ITypeBinding declaringTypeBinding, Expression qualifier) {
			super();
			fDeclaringTypeBinding= declaringTypeBinding;
			fQualifier= qualifier;
		}
		
		public String getAccessorName() {
			return fDeclaringTypeBinding.getName();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.jdt.internal.corext.fix.AbstractFix.IFixRewriteOperation#rewriteAST(org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite, java.util.List)
		 */
		public void rewriteAST(CompilationUnitRewrite cuRewrite, List textEditGroups) throws CoreException {
			Type type= importType(fDeclaringTypeBinding, fQualifier, cuRewrite.getImportRewrite(), cuRewrite.getRoot());
			TextEditGroup group= createTextEditGroup(FixMessages.CodeStyleFix_ChangeAccessUsingDeclaring_description);
			textEditGroups.add(group);
			cuRewrite.getASTRewrite().replace(fQualifier, type, group);
		}
	}
	
	public static CodeStyleFix[] createNonStaticAccessFixes(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException {
		if (!isNonStaticAccess(problem))
			return null;
		
		ToStaticAccessOperation operations[]= createNonStaticAccessResolveOperations(compilationUnit, problem);
		if (operations == null)
			return null;

		String label1= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStatic_description, operations[0].getAccessorName());
		CodeStyleFix fix1= new CodeStyleFix(label1, compilationUnit, new IFixRewriteOperation[] {operations[0]});

		if (operations.length > 1) {
			String label2= Messages.format(FixMessages.CodeStyleFix_ChangeAccessToStaticUsingInstanceType_description, operations[1].getAccessorName());
			CodeStyleFix fix2= new CodeStyleFix(label2, compilationUnit, new IFixRewriteOperation[] {operations[1]});
			return new CodeStyleFix[] {fix1, fix2};
		}
		return new CodeStyleFix[] {fix1};
	}
	
	public static CodeStyleFix createAddFieldQualifierFix(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException {
		if (IProblem.UnqualifiedFieldAccess != problem.getProblemId())
			return null;
		
		AddThisQualifierOperation operation= getUnqualifiedFieldAccessResolveOperation(compilationUnit, problem);
		if (operation == null)
			return null;

		String groupName= operation.getDescription();
		return new CodeStyleFix(groupName, compilationUnit, new IFixRewriteOperation[] {operation});
	}
	
	public static CodeStyleFix createIndirectAccessToStaticFix(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException {
		if (!isIndirectStaticAccess(problem))
			return null;
		
		ToStaticAccessOperation operations[]= createNonStaticAccessResolveOperations(compilationUnit, problem);
		if (operations == null)
			return null;

		String label= Messages.format(FixMessages.CodeStyleFix_ChangeStaticAccess_description, operations[0].getAccessorName());
		return new CodeStyleFix(label, compilationUnit, new IFixRewriteOperation[] {operations[0]});
	}
	
	public static CodeStyleFix createCleanUp(CompilationUnit compilationUnit, 
			boolean addThisQualifier,
			boolean changeNonStaticAccessToStatic, 
			boolean qualifyStaticFieldAccess,
			boolean changeIndirectStaticAccessToDirect,
			boolean qualifyMethodAccess,
			boolean qualifyStaticMethodAccess,
			boolean removeFieldQualifier,
			boolean removeMethodQualifier) throws CoreException {
		
		if (!addThisQualifier && !changeNonStaticAccessToStatic && !qualifyStaticFieldAccess && !changeIndirectStaticAccessToDirect && !qualifyMethodAccess && !qualifyStaticMethodAccess && !removeFieldQualifier && !removeMethodQualifier)
			return null;

		List/*<IFixRewriteOperation>*/ operations= new ArrayList(); 
		if (addThisQualifier || qualifyStaticFieldAccess || qualifyMethodAccess || qualifyStaticMethodAccess) {
			CodeStyleVisitor codeStyleVisitor= new CodeStyleVisitor(compilationUnit, addThisQualifier, qualifyStaticFieldAccess, qualifyMethodAccess, qualifyStaticMethodAccess, operations);
			compilationUnit.accept(codeStyleVisitor);
		}
		
		IProblem[] problems= compilationUnit.getProblems();
		IProblemLocation[] locations= new IProblemLocation[problems.length];
		for (int i= 0; i < problems.length; i++) {
	        locations[i]= new ProblemLocation(problems[i]);
        }
		addToStaticAccessOperations(compilationUnit, locations, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect, operations);
		
		if (removeFieldQualifier || removeMethodQualifier) {
			ThisQualifierVisitor visitor= new ThisQualifierVisitor(removeFieldQualifier, removeMethodQualifier, compilationUnit, operations);
			compilationUnit.accept(visitor);
		}

		if (operations.isEmpty())
			return null;
		
		IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]);
		return new CodeStyleFix("", compilationUnit, operationsArray); //$NON-NLS-1$
	}
	
	public static CodeStyleFix createCleanUp(CompilationUnit compilationUnit, IProblemLocation[] problems, 
			boolean addThisQualifier, 
			boolean changeNonStaticAccessToStatic,
			boolean changeIndirectStaticAccessToDirect) throws CoreException {
		
		if (!addThisQualifier && !changeNonStaticAccessToStatic && !changeIndirectStaticAccessToDirect)
			return null;
				
		List/*<IFixRewriteOperation>*/ operations= new ArrayList(); 
		if (addThisQualifier) {
			for (int i= 0; i < problems.length; i++) {
				IProblemLocation problem= problems[i];
				if (problem.getProblemId() == IProblem.UnqualifiedFieldAccess) {
					AddThisQualifierOperation operation= getUnqualifiedFieldAccessResolveOperation(compilationUnit, problem);
					if (operation != null)
						operations.add(operation);
				}
			}
		}

		addToStaticAccessOperations(compilationUnit, problems, changeNonStaticAccessToStatic, changeIndirectStaticAccessToDirect, operations);

		if (operations.isEmpty())
			return null;
		
		IFixRewriteOperation[] operationsArray= (IFixRewriteOperation[])operations.toArray(new IFixRewriteOperation[operations.size()]);
		return new CodeStyleFix("", compilationUnit, operationsArray); //$NON-NLS-1$
	}
	
	private static void addToStaticAccessOperations(CompilationUnit compilationUnit, IProblemLocation[] problems, boolean changeNonStaticAccessToStatic, boolean changeIndirectStaticAccessToDirect, List result) {
	    Hashtable nonStaticAccessOps= new Hashtable();
		if (changeNonStaticAccessToStatic || changeIndirectStaticAccessToDirect) {
			for (int i= 0; i < problems.length; i++) {
				IProblemLocation problem= problems[i];
				boolean isNonStaticAccess= changeNonStaticAccessToStatic && isNonStaticAccess(problem);
				boolean isIndirectStaticAccess= changeIndirectStaticAccessToDirect && isIndirectStaticAccess(problem);
				if (isNonStaticAccess || isIndirectStaticAccess) {
					ToStaticAccessOperation[] nonStaticAccessInformation= createNonStaticAccessResolveOperations(compilationUnit, problem);
					if (nonStaticAccessInformation != null) {
						ToStaticAccessOperation op= nonStaticAccessInformation[0];
						nonStaticAccessOps.put(op.fQualifier, op);
					}
				}
			}
		}
		for (Iterator iter= nonStaticAccessOps.values().iterator(); iter.hasNext();) {
			ToStaticAccessOperation op= (ToStaticAccessOperation)iter.next();
			if (!nonStaticAccessOps.containsKey(op.fQualifier.getParent()))
				result.add(op);
		}
	}

	private static boolean isIndirectStaticAccess(IProblemLocation problem) {
		return (problem.getProblemId() == IProblem.IndirectAccessToStaticField
				|| problem.getProblemId() == IProblem.IndirectAccessToStaticMethod);
	}
	
	private static boolean isNonStaticAccess(IProblemLocation problem) {
		return (problem.getProblemId() == IProblem.NonStaticAccessToStaticField
				|| problem.getProblemId() == IProblem.NonStaticAccessToStaticMethod);
	}
	
	private static ToStaticAccessOperation[] createNonStaticAccessResolveOperations(CompilationUnit astRoot, IProblemLocation problem) {
		ASTNode selectedNode= problem.getCoveringNode(astRoot);
		if (selectedNode == null) {
			return null;
		}

		Expression qualifier= null;
		IBinding accessBinding= null;

        if (selectedNode instanceof QualifiedName) {
        	QualifiedName name= (QualifiedName) selectedNode;
        	qualifier= name.getQualifier();
        	accessBinding= name.resolveBinding();
        } else if (selectedNode instanceof SimpleName) {
        	ASTNode parent= selectedNode.getParent();
        	if (parent instanceof FieldAccess) {
        		FieldAccess fieldAccess= (FieldAccess) parent;
        		qualifier= fieldAccess.getExpression();
        		accessBinding= fieldAccess.getName().resolveBinding();
        	} else if (parent instanceof QualifiedName) {
        		QualifiedName qualifiedName= (QualifiedName) parent;
        		qualifier= qualifiedName.getQualifier();
        		accessBinding= qualifiedName.getName().resolveBinding();
        	}
        } else if (selectedNode instanceof MethodInvocation) {
        	MethodInvocation methodInvocation= (MethodInvocation) selectedNode;
        	qualifier= methodInvocation.getExpression();
        	accessBinding= methodInvocation.getName().resolveBinding();
        } else if (selectedNode instanceof FieldAccess) {
			FieldAccess fieldAccess= (FieldAccess) selectedNode;
			qualifier= fieldAccess.getExpression();
			accessBinding= fieldAccess.getName().resolveBinding();
		}
        
		if (accessBinding != null && qualifier != null) {
			ToStaticAccessOperation declaring= null;
			ITypeBinding declaringTypeBinding= getDeclaringTypeBinding(accessBinding);
			if (declaringTypeBinding != null) {
				declaringTypeBinding= declaringTypeBinding.getTypeDeclaration(); // use generic to avoid any type arguments
				
				declaring= new ToStaticAccessOperation(declaringTypeBinding, qualifier);
			}
			ToStaticAccessOperation instance= null;
			ITypeBinding instanceTypeBinding= Bindings.normalizeTypeBinding(qualifier.resolveTypeBinding());
			if (instanceTypeBinding != null) {
				instanceTypeBinding= instanceTypeBinding.getTypeDeclaration();  // use generic to avoid any type arguments
				if (instanceTypeBinding.getTypeDeclaration() != declaringTypeBinding) {
					instance= new ToStaticAccessOperation(instanceTypeBinding, qualifier);
				}
			}
			if (declaring != null && instance != null) {
				return new ToStaticAccessOperation[] {declaring, instance};
			} else {
				return new ToStaticAccessOperation[] {declaring};
			}
		}
		return null;
	}
	
	private static ITypeBinding getDeclaringTypeBinding(IBinding accessBinding) {
		if (accessBinding instanceof IMethodBinding) {
			return ((IMethodBinding) accessBinding).getDeclaringClass();
		} else if (accessBinding instanceof IVariableBinding) {
			return ((IVariableBinding) accessBinding).getDeclaringClass();
		}
		return null;
	}
		
	private static AddThisQualifierOperation getUnqualifiedFieldAccessResolveOperation(CompilationUnit compilationUnit, IProblemLocation problem) throws CoreException {
		SimpleName name= getName(compilationUnit, problem);
		if (name == null)
			return null;
		
		IBinding binding= name.resolveBinding();
		if (binding == null || binding.getKind() != IBinding.VARIABLE)
			return null;
		
		ImportRewrite imports= StubUtility.createImportRewrite(compilationUnit, true);
		
		String replacement= getQualifier((IVariableBinding)binding, imports, name);
		if (replacement == null)
			return null;
		
		return new AddThisQualifierOperation(replacement, name);
	}
	
	private static String getQualifier(IVariableBinding binding, ImportRewrite imports, SimpleName name) {
		ITypeBinding declaringClass= binding.getDeclaringClass();
		if (Modifier.isStatic(binding.getModifiers())) {
			IJavaElement javaElement= declaringClass.getJavaElement();
			if (javaElement instanceof IType) {
				return ((IType)javaElement).getElementName();
			}
		} else {
			return getNonStaticQualifier(declaringClass, imports, name);
		}

		return null;
	}

	private static String getNonStaticQualifier(ITypeBinding declaringClass, ImportRewrite imports, SimpleName name) {
		ITypeBinding parentType= Bindings.getBindingOfParentType(name);
		ITypeBinding currType= parentType;
		while (currType != null && !Bindings.isSuperType(declaringClass, currType)) {
			currType= currType.getDeclaringClass();
		}
		if (currType == null) {
			declaringClass= declaringClass.getTypeDeclaration();
			currType= parentType;
			while (currType != null && !Bindings.isSuperType(declaringClass, currType)) {
				currType= currType.getDeclaringClass();
			}
		}
		if (currType != parentType) {
			if (currType == null)
				return null;
			
			if (currType.isAnonymous())
				//If we access a field of a super class of an anonymous class
				//then we can only qualify with 'this' but not with outer.this
				//see bug 115277
				return null;
			
			String outer= imports.addImport(currType);
			return outer + ".this"; //$NON-NLS-1$
		} else {
			return "this"; //$NON-NLS-1$
		}
	}
	
	private static SimpleName getName(CompilationUnit compilationUnit, IProblemLocation problem) {
		ASTNode selectedNode= problem.getCoveringNode(compilationUnit);
		
		while (selectedNode instanceof QualifiedName) {
			selectedNode= ((QualifiedName) selectedNode).getQualifier();
		}
		if (!(selectedNode instanceof SimpleName)) {
			return null;
		}
		return (SimpleName) selectedNode;
	}

	private CodeStyleFix(String name, CompilationUnit compilationUnit, IFixRewriteOperation[] fixRewriteOperations) {
		super(name, compilationUnit, fixRewriteOperations);
	}
}
