/*******************************************************************************
 * Copyright (c) 2007, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Nikolay Metchev <nikolaymetchev@gmail.com> - [extract class] Extract class refactoring on a field in an inner non-static class yields compilation error - https://bugs.eclipse.org/394547
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.structure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.text.edits.TextEditGroup;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.resource.ResourceChange;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.NamingConventions;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
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.FieldDeclaration;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SuperFieldAccess;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor;
import org.eclipse.jdt.core.refactoring.descriptors.ExtractClassDescriptor.Field;
import org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;

import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.codemanipulation.GetterSetterUtil;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.jdt.internal.corext.refactoring.structure.ParameterObjectFactory.CreationListener;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaStatusContext;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.internal.ui.JavaPlugin;

public class ExtractClassRefactoring extends Refactoring {

	public static class ExtractClassDescriptorVerification {
		private ExtractClassDescriptor fDescriptor;

		public ExtractClassDescriptorVerification(ExtractClassDescriptor descriptor) {
			fDescriptor= descriptor;
		}

		public RefactoringStatus validateClassName() {
			RefactoringStatus status= new RefactoringStatus();
			status.merge(Checks.checkTypeName(fDescriptor.getClassName(), fDescriptor.getType()));
			status.merge(checkClass());
			return status;
		}

		private RefactoringStatus checkClass() {
			RefactoringStatus status= new RefactoringStatus();
			IType type= fDescriptor.getType();
			if (!fDescriptor.isCreateTopLevel()) {
				if (type.getType(fDescriptor.getClassName()).exists()) {
					status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_errror_nested_name_clash, new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(type.getElementName()) }));
				}
			} else {
				status.merge(checkPackageClass());
			}
			return status;
		}

		private RefactoringStatus checkPackageClass() {
			RefactoringStatus status= new RefactoringStatus();
			IType type= fDescriptor.getType();
			IPackageFragmentRoot ancestor= (IPackageFragmentRoot) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
			IPackageFragment packageFragment= ancestor.getPackageFragment(fDescriptor.getPackage());
			if (packageFragment.getCompilationUnit(fDescriptor.getClassName() + JavaModelUtil.DEFAULT_CU_SUFFIX).exists())
				status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_toplevel_name_clash, new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(fDescriptor.getPackage()) }));
			return status;
		}

		public RefactoringStatus validateTopLevel() {
			return checkClass();
		}

		public RefactoringStatus validateParameterName() {
			RefactoringStatus status= new RefactoringStatus();
			String parameterName= fDescriptor.getFieldName();
			IType type= fDescriptor.getType();
			status.merge(Checks.checkFieldName(parameterName, type));
			validateFieldNames(status, parameterName, type);
			return status;
		}

		private void validateFieldNames(RefactoringStatus status, String parameterName, IType type) {
			if (type.getField(parameterName).exists()) {
				for (Field field : fDescriptor.getFields()) {
					if (parameterName.equals(field.getFieldName())){
						if (!field.isCreateField())
							status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_field_already_exists, BasicElementLabels.getJavaElementName(parameterName)));
					}
				}
			}
		}

		public RefactoringStatus validateFields() {
			RefactoringStatus status= new RefactoringStatus();
			Set<String> names= new HashSet<>();
			for (Field field : fDescriptor.getFields()) {
				if (field.isCreateField()) {
					if (names.contains(field.getNewFieldName())) {
						status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_duplicate_field_name, BasicElementLabels.getJavaElementName(field.getNewFieldName())));
					}
					names.add(field.getNewFieldName());
					status.merge(Checks.checkFieldName(field.getNewFieldName(), fDescriptor.getType()));
				}
			}
			if (names.isEmpty()) {
				status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_msg_one_field);
			}
			validateFieldNames(status, fDescriptor.getFieldName(), fDescriptor.getType());
			return status;
		}

		public RefactoringStatus validateAll() {
			RefactoringStatus status= new RefactoringStatus();
			status.merge(validateClassName()); //also validates toplevel
			status.merge(validateFields());
			status.merge(validateParameterName());
			return status;
		}
	}


	private final class FieldReferenceFinder extends ASTVisitor {
		public boolean fFieldRefFound= false;

		private FieldReferenceFinder() {
		}

		@Override
		public boolean visit(FieldAccess node) {
			IVariableBinding fieldBinding= node.resolveFieldBinding();
			return checkVariableBinding(fieldBinding);
		}

		@Override
		public boolean visit(SimpleName node) {
			IVariableBinding variableBinding= ASTNodes.getVariableBinding(node);
			return checkVariableBinding(variableBinding);
		}

		private boolean checkVariableBinding(IVariableBinding fieldBinding) {
			if (fieldBinding != null) {
				if (fieldBinding.isField()) {
					ITypeBinding declaringClass= fieldBinding.getDeclaringClass();
					if ((declaringClass != null) && declaringClass.getQualifiedName().equals(fDescriptor.getType().getFullyQualifiedName())) {
						FieldInfo fi= fVariables.get(fieldBinding.getName());
						if (fi != null && isCreateField(fi) && Bindings.equals(fieldBinding, fi.pi.getOldBinding())) {
							fFieldRefFound= true;
							return false;
						}
					}
				}
			}
			return true;
		}
	}

	private final class FieldInfo {
		ParameterInfo pi;
		VariableDeclarationFragment declaration;
		IField ifield;
		String name;
		Expression initializer;
		private Boolean hasFieldReferences= null;

		public boolean hasFieldReference() {
			if (hasFieldReferences == null) {
				if (initializer != null) {
					FieldReferenceFinder frf= new FieldReferenceFinder();
					initializer.accept(frf);
					hasFieldReferences= Boolean.valueOf(frf.fFieldRefFound);
				} else {
					hasFieldReferences= Boolean.FALSE;
				}
			}
			return hasFieldReferences.booleanValue();
		}

		private FieldInfo(ParameterInfo parameterInfo, IField ifield) {
			super();
			this.pi= parameterInfo;
			this.ifield= ifield;
			this.name= ifield.getElementName();
		}
	}

	private ExtractClassDescriptor fDescriptor;
	private Map<String, FieldInfo> fVariables;
	private CompilationUnitRewrite fBaseCURewrite;
	private TextChangeManager fChangeManager;
	private ParameterObjectFactory fParameterObjectFactory;
	private ExtractClassDescriptorVerification fVerification;

	public ExtractClassRefactoring(ExtractClassDescriptor descriptor) {
		fDescriptor= descriptor;
		IType type= fDescriptor.getType();
		if (fDescriptor.getPackage() == null) {
			fDescriptor.setPackage(type.getPackageFragment().getElementName());
		}
		if (fDescriptor.getClassName() == null) {
			fDescriptor.setClassName(type.getElementName() + "Data"); //$NON-NLS-1$
		}
		if (fDescriptor.getFieldName() == null) {
			fDescriptor.setFieldName(StubUtility.getVariableNameSuggestions(NamingConventions.VK_INSTANCE_FIELD, type.getJavaProject(), "data", 0, null, true)[0]); //$NON-NLS-1$
		}
		if (fDescriptor.getFields() == null) {
			try {
				fDescriptor.setFields(ExtractClassDescriptor.getFields(type));
			} catch (JavaModelException e) {
				JavaPlugin.log(e);
			}
		}
		fVerification= new ExtractClassDescriptorVerification(descriptor);
	}


	@Override
	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		RefactoringStatus result= new RefactoringStatus();
		pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_msg_check_initial_condition, 5);
		try {
			result.merge(fDescriptor.validateDescriptor());
			if (!result.isOK())
				return result;
			IType type= fDescriptor.getType();
			result.merge(Checks.checkAvailability(type));
			if (!result.isOK())
				return result;
			pm.worked(1);
			Field[] fields= ExtractClassDescriptor.getFields(fDescriptor.getType());
			pm.worked(1);
			if (pm.isCanceled())
				throw new OperationCanceledException();
			fVariables= new LinkedHashMap<>();
			if (fields.length == 0) {
				result.addFatalError(RefactoringCoreMessages.ExtractClassRefactoring_error_no_usable_fields, JavaStatusContext.create(type));
				return result;
			}
			for (int i= 0; i < fields.length; i++) {
				Field field= fields[i];
				String fieldName= field.getFieldName();
				IField declField= type.getField(fieldName);
				ParameterInfo info= new ParameterInfo(Signature.toString(declField.getTypeSignature()), fieldName, i);
				fVariables.put(fieldName, new FieldInfo(info, declField));
				if (pm.isCanceled())
					throw new OperationCanceledException();
			}
			pm.worked(3);
		} finally {
			pm.done();
		}
		return result;
	}

	@Override
	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		RefactoringStatus result= new RefactoringStatus();
		result.merge(fVerification.validateAll());
		try {
			pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_final_conditions, 95);
			for (FieldInfo fi : fVariables.values()) {
				boolean createField= isCreateField(fi);
				if (createField) {
					IField field= fi.ifield;
					int flags= field.getFlags();
					if (Flags.isStatic(flags)) {
						result.addFatalError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_field_is_static, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field));
						return result;
					}
					if (Flags.isTransient(flags)) {
						result.addWarning(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_transient, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field));
					}
					if (Flags.isVolatile(flags)) {
						result.addWarning(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_warning_field_is_volatile, BasicElementLabels.getJavaElementName(field.getElementName())), JavaStatusContext.create(field));
					}
				}
			}
			pm.worked(5);
			fChangeManager= new TextChangeManager();
			fParameterObjectFactory= initializeFactory();
			IType type= fDescriptor.getType();
			pm.worked(5);

			FieldDeclaration field= performFieldRewrite(type, fParameterObjectFactory, result);
			int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | JavaRefactoringDescriptor.JAR_MIGRATION | JavaRefactoringDescriptor.JAR_REFACTORING | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
			if (!Modifier.isPrivate(field.getModifiers()))
				flags|= RefactoringDescriptor.MULTI_CHANGE;
			fDescriptor.setFlags(flags);

			result.merge(updateReferences(type, fParameterObjectFactory, new SubProgressMonitor(pm, 65)));

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

	@Override
	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_create_change, 10);
		try {
			ICompilationUnit typeCU= fDescriptor.getType().getCompilationUnit();
			IPackageFragmentRoot packageRoot= (IPackageFragmentRoot) typeCU.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
			ArrayList<Change> changes= new ArrayList<>();

			changes.addAll(createParameterObject(fParameterObjectFactory, packageRoot));
			fChangeManager.manage(typeCU, fBaseCURewrite.createChange(true, pm));
			changes.addAll(Arrays.asList(fChangeManager.getAllChanges()));
			String project= fDescriptor.getType().getJavaProject().getElementName();
			fDescriptor.setProject(project);
			fDescriptor.setDescription(getName());
			fDescriptor.setComment(createComment());
			DynamicValidationRefactoringChange change= new DynamicValidationRefactoringChange(fDescriptor, RefactoringCoreMessages.ExtractClassRefactoring_change_name, changes
					.toArray(new Change[changes.size()]));
			return change;
		} finally {
			pm.done();
		}
	}

	private String createComment() {
		Object[] keys= new Object[] { BasicElementLabels.getJavaElementName(fDescriptor.getClassName()), BasicElementLabels.getJavaElementName(fDescriptor.getType().getElementName()) };
		String header= Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_change_comment_header, keys);
		JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(fDescriptor.getType().getJavaProject().getElementName(), this, header);
		comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_extracted_class, BasicElementLabels.getJavaElementName(fDescriptor.getClassName())));

		if (fDescriptor.isCreateTopLevel())
			comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_package, BasicElementLabels.getJavaElementName(fDescriptor.getPackage())));

		ArrayList<String> strings= new ArrayList<>();
		for (Field field : fDescriptor.getFields()) {
			if (field.isCreateField()) {
				strings.add(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_field_renamed, new Object[] { BasicElementLabels.getJavaElementName(field.getFieldName()), BasicElementLabels.getJavaElementName(field.getNewFieldName()) }));
			}
		}
		String fieldString= JDTRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractClassRefactoring_comment_move_field, strings.toArray(new String[strings
				.size()]));
		comment.addSetting(fieldString);

		if (fDescriptor.isCreateGetterSetter())
			comment.addSetting(RefactoringCoreMessages.ExtractClassRefactoring_comment_getters);

		comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_comment_fieldname, BasicElementLabels.getJavaElementName(fDescriptor.getFieldName())));
		return comment.asString();
	}

	private class FieldUpdate extends CreationListener {
		@Override
		public void fieldCreated(CompilationUnitRewrite cuRewrite, FieldDeclaration field, ParameterInfo pi) {
			FieldInfo fieldInfo= getFieldInfo(pi.getOldName());
			FieldDeclaration parent= (FieldDeclaration) fieldInfo.declaration.getParent();
			List<IExtendedModifier> modifiers= parent.modifiers();
			ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(field, FieldDeclaration.MODIFIERS2_PROPERTY);
			for (IExtendedModifier mod : modifiers) {
				//Temporarily disabled until initialization of final fields is handled correctly
//				if (mod.isModifier()) {
//					Modifier modifier= (Modifier) mod;
//					if (modifier.isFinal())
//						listRewrite.insertLast(moveNode(cuRewrite, modifier), null);
//				}
				if (mod.isAnnotation()) {
					listRewrite.insertFirst(moveNode(cuRewrite, (ASTNode) mod), null);
				}
			}
			if (fieldInfo.initializer != null && fieldInfo.hasFieldReference()) {
				List<VariableDeclarationFragment> fragments= field.fragments();
				for (VariableDeclarationFragment vdf : fragments) {
					vdf.setInitializer((Expression) moveNode(cuRewrite, fieldInfo.initializer));
				}
			}
			if (parent.getJavadoc() != null) {
				field.setJavadoc((Javadoc) moveNode(cuRewrite, parent.getJavadoc()));
			}
		}

		@Override
		public boolean isCreateSetter(ParameterInfo pi) {
			return true; //ignore that the original variable was final
		}

		@Override
		public boolean isUseInConstructor(ParameterInfo pi) {
			FieldInfo fi= getFieldInfo(pi.getOldName());
			return fi.initializer != null && !fi.hasFieldReference();
		}
	}

	private List<ResourceChange> createParameterObject(ParameterObjectFactory pof, IPackageFragmentRoot packageRoot) throws CoreException {
		FieldUpdate fieldUpdate= new FieldUpdate();
		if (fDescriptor.isCreateTopLevel())
			return pof.createTopLevelParameterObject(packageRoot, fieldUpdate);
		else {
			CompilationUnit root= fBaseCURewrite.getRoot();
			TypeDeclaration typeDecl= ASTNodeSearchUtil.getTypeDeclarationNode(fDescriptor.getType(), root);
			ASTRewrite rewrite= fBaseCURewrite.getASTRewrite();
			ListRewrite listRewrite= rewrite.getListRewrite(typeDecl, TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
			ContextSensitiveImportRewriteContext context= new ContextSensitiveImportRewriteContext(typeDecl, fBaseCURewrite.getImportRewrite());
			TypeDeclaration paramClass= pof.createClassDeclaration(typeDecl.getName().getFullyQualifiedName(), fBaseCURewrite, fieldUpdate, context);
			paramClass.modifiers().add(rewrite.getAST().newModifier(ModifierKeyword.PUBLIC_KEYWORD));
			if (shouldParamClassBeStatic(typeDecl)) {
				paramClass.modifiers().add(rewrite.getAST().newModifier(ModifierKeyword.STATIC_KEYWORD));
			}
			listRewrite.insertFirst(paramClass, fBaseCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_insert_parameter));
			return new ArrayList<>(); //Change will be generated later for fBaseCURewrite
		}

	}

	private boolean shouldParamClassBeStatic(TypeDeclaration enclosingTypeDecl) {
		if (enclosingTypeDecl.isPackageMemberTypeDeclaration()) {
			return true;
		}
		ITypeBinding binding= enclosingTypeDecl.resolveBinding();
		int modifiers= binding != null ? binding.getModifiers() : enclosingTypeDecl.getModifiers();
		return Modifier.isStatic(modifiers);
	}

	private ParameterObjectFactory initializeFactory() {
		ParameterObjectFactory pof= new ParameterObjectFactory();
		pof.setClassName(fDescriptor.getClassName());
		pof.setPackage(fDescriptor.getPackage());
		pof.setEnclosingType(fDescriptor.getType().getFullyQualifiedName('.'));
		pof.setCreateGetter(fDescriptor.isCreateGetterSetter());
		pof.setCreateSetter(fDescriptor.isCreateGetterSetter());
		List<ParameterInfo> variables= new ArrayList<>();
		for (FieldInfo info : fVariables.values()) {
			boolean createField= isCreateField(info);
			info.pi.setCreateField(createField);
			if (createField) {
				Field field= getField(info.name);
				info.pi.setNewName(field.getNewFieldName());
			}
			variables.add(info.pi);
		}
		pof.setVariables(variables);
		return pof;
	}

	private Field getField(String name) {
		for (Field field : fDescriptor.getFields()) {
			if (field.getFieldName().equals(name))
				return field;
		}
		return null;
	}


	private RefactoringStatus updateReferences(IType type, ParameterObjectFactory pof, IProgressMonitor pm) throws CoreException {
		RefactoringStatus status= new RefactoringStatus();
		pm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references, 100);
		try {
			pm.worked(10);
			if (pm.isCanceled())
				throw new OperationCanceledException();
			List<IField> validIFields= new ArrayList<>();
			for (FieldInfo info : fVariables.values()) {
				if (isCreateField(info))
					validIFields.add(info.ifield);
			}
			if (validIFields.isEmpty()) {
				status.addWarning(RefactoringCoreMessages.ExtractClassRefactoring_warning_no_fields_moved, JavaStatusContext.create(type));
				return status;
			}
			SearchPattern pattern= RefactoringSearchEngine.createOrPattern(validIFields.toArray(new IField[validIFields.size()]), IJavaSearchConstants.ALL_OCCURRENCES);
			SearchResultGroup[] results= RefactoringSearchEngine.search(pattern, RefactoringScopeFactory.create(type), pm, status);
			SubProgressMonitor spm= new SubProgressMonitor(pm, 90);
			spm.beginTask(RefactoringCoreMessages.ExtractClassRefactoring_progress_updating_references, results.length * 10);
			try {
				for (SearchResultGroup group : results) {
					ICompilationUnit unit= group.getCompilationUnit();

					CompilationUnitRewrite cuRewrite;
					if (unit.equals(fBaseCURewrite.getCu()))
						cuRewrite= fBaseCURewrite;
					else
						cuRewrite= new CompilationUnitRewrite(unit);
					spm.worked(1);

					status.merge(replaceReferences(pof, group, cuRewrite));
					if (cuRewrite != fBaseCURewrite) //Change for fBaseCURewrite will be generated later
						fChangeManager.manage(unit, cuRewrite.createChange(true, new SubProgressMonitor(spm, 9)));
					if (spm.isCanceled())
						throw new OperationCanceledException();
				}
			} finally {
				spm.done();
			}
		} finally {
			pm.done();
		}
		return status;
	}

	private RefactoringStatus replaceReferences(ParameterObjectFactory pof, SearchResultGroup group, CompilationUnitRewrite cuRewrite) {
		TextEditGroup writeGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_write);
		TextEditGroup readGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_read);
		ITypeRoot typeRoot= cuRewrite.getCu();
		IJavaProject javaProject= typeRoot.getJavaProject();
		AST ast= cuRewrite.getAST();

		RefactoringStatus status= new RefactoringStatus();
		String parameterName= fDescriptor.getFieldName();

		for (SearchMatch searchMatch : group.getSearchResults()) {
			ASTNode node= NodeFinder.perform(cuRewrite.getRoot(), searchMatch.getOffset(), searchMatch.getLength());
			ASTNode parent= node.getParent();
			boolean isDeclaration= parent instanceof VariableDeclaration && ((VariableDeclaration)parent).getInitializer() != node;
			if (!isDeclaration && node instanceof SimpleName) {
				ASTRewrite rewrite= cuRewrite.getASTRewrite();
				if (parent.getNodeType() == ASTNode.SWITCH_CASE)
					status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_switch, JavaStatusContext.create(typeRoot, node));

				SimpleName name= (SimpleName) node;
				ParameterInfo pi= getFieldInfo(name.getIdentifier()).pi;
				boolean writeAccess= ASTResolving.isWriteAccess(name);
				if (writeAccess && fDescriptor.isCreateGetterSetter()) {
					boolean useSuper= parent.getNodeType() == ASTNode.SUPER_FIELD_ACCESS;
					Expression qualifier= getQualifier(parent);
					ASTNode replaceNode= getReplacementNode(parent, useSuper, qualifier);
					Expression assignedValue= getAssignedValue(pof, parameterName, javaProject, status, rewrite, pi, useSuper, name.resolveTypeBinding(), qualifier, replaceNode, typeRoot);
					if (assignedValue == null) {
						status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_unable_to_convert_node, JavaStatusContext.create(typeRoot, replaceNode));
					} else {
						NullLiteral marker= qualifier == null ? null : ast.newNullLiteral();
						Expression access= pof.createFieldWriteAccess(pi, parameterName, ast, javaProject, assignedValue, useSuper, marker);
						replaceMarker(rewrite, qualifier, access, marker);
						rewrite.replace(replaceNode, access, writeGroup);
					}
				} else {
					Expression fieldReadAccess= pof.createFieldReadAccess(pi, parameterName, ast, javaProject, false, null); //qualifier is already there
					rewrite.replace(name, fieldReadAccess, readGroup);
				}
			}
		}
		return status;
	}

	private Expression getAssignedValue(ParameterObjectFactory pof, String parameterName, IJavaProject javaProject, RefactoringStatus status, ASTRewrite rewrite, ParameterInfo pi, boolean useSuper, ITypeBinding typeBinding, Expression qualifier, ASTNode replaceNode, ITypeRoot typeRoot) {
		AST ast= rewrite.getAST();
		boolean is50OrHigher= JavaModelUtil.is50OrHigher(javaProject);
		Expression assignedValue= handleSimpleNameAssignment(replaceNode, pof, parameterName, ast, javaProject, useSuper);
		if (assignedValue == null) {
			NullLiteral marker= qualifier == null ? null : ast.newNullLiteral();
			Expression fieldReadAccess= pof.createFieldReadAccess(pi, parameterName, ast, javaProject, useSuper, marker);
			assignedValue= GetterSetterUtil.getAssignedValue(replaceNode, rewrite, fieldReadAccess, typeBinding, is50OrHigher);
			boolean markerReplaced= replaceMarker(rewrite, qualifier, assignedValue, marker);
			if (markerReplaced) {
				switch (qualifier.getNodeType()) {
					case ASTNode.METHOD_INVOCATION:
					case ASTNode.CLASS_INSTANCE_CREATION:
					case ASTNode.SUPER_METHOD_INVOCATION:
					case ASTNode.PARENTHESIZED_EXPRESSION:
						status.addWarning(RefactoringCoreMessages.ExtractClassRefactoring_warning_semantic_change, JavaStatusContext.create(typeRoot, replaceNode));
						break;
				}
			}
		}
		return assignedValue;
	}

	private ASTNode getReplacementNode(ASTNode parent, boolean useSuper, Expression qualifier) {
		if (qualifier != null || useSuper) {
			return parent.getParent();
		} else {
			return parent;
		}
	}

	private Expression getQualifier(ASTNode parent) {
		switch (parent.getNodeType()) {
			case ASTNode.FIELD_ACCESS:
				return ((FieldAccess) parent).getExpression();
			case ASTNode.QUALIFIED_NAME:
				return ((QualifiedName)parent).getQualifier();
			case ASTNode.SUPER_FIELD_ACCESS:
				return ((SuperFieldAccess)parent).getQualifier();
			default:
				return null;
		}
	}

	/*
	 * Replaces the NullLiteral dummy with the copied qualifier
	 */
	private boolean replaceMarker(final ASTRewrite rewrite, final Expression qualifier, Expression assignedValue, final NullLiteral marker) {
		class MarkerReplacer extends ASTVisitor {

			private boolean fReplaced= false;

			@Override
			public boolean visit(NullLiteral node) {
				if (node == marker) {
					rewrite.replace(node, rewrite.createCopyTarget(qualifier), null);
					fReplaced= true;
					return false;
				}
				return true;
			}
		}
		if (assignedValue != null && qualifier != null) {
			MarkerReplacer visitor= new MarkerReplacer();
			assignedValue.accept(visitor);
			return visitor.fReplaced;
		}
		return false;
	}

	private Expression handleSimpleNameAssignment(ASTNode replaceNode, ParameterObjectFactory pof, String parameterName, AST ast, IJavaProject javaProject, boolean useSuper) {
		if (replaceNode instanceof Assignment) {
			Assignment assignment= (Assignment) replaceNode;
			Expression rightHandSide= assignment.getRightHandSide();
			if (rightHandSide.getNodeType() == ASTNode.SIMPLE_NAME) {
				SimpleName sn= (SimpleName) rightHandSide;
				IVariableBinding binding= ASTNodes.getVariableBinding(sn);
				if (binding != null && binding.isField()) {
					if (fDescriptor.getType().getFullyQualifiedName().equals(binding.getDeclaringClass().getQualifiedName())) {
						FieldInfo fieldInfo= getFieldInfo(binding.getName());
						if (fieldInfo != null && binding == fieldInfo.pi.getOldBinding()) {
							return pof.createFieldReadAccess(fieldInfo.pi, parameterName, ast, javaProject, useSuper, null);
						}
					}
				}
			}
		}
		return null;
	}

	private FieldInfo getFieldInfo(String identifier) {
		return fVariables.get(identifier);
	}

	private FieldDeclaration performFieldRewrite(IType type, ParameterObjectFactory pof, RefactoringStatus status) throws CoreException {
		fBaseCURewrite= new CompilationUnitRewrite(type.getCompilationUnit());
		SimpleName name= (SimpleName) NodeFinder.perform(fBaseCURewrite.getRoot(), type.getNameRange());
		TypeDeclaration typeNode= (TypeDeclaration) ASTNodes.getParent(name, ASTNode.TYPE_DECLARATION);
		ASTRewrite rewrite= fBaseCURewrite.getASTRewrite();
		int modifier= Modifier.PRIVATE;
		TextEditGroup removeFieldGroup= fBaseCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_remove_field);
		FieldDeclaration lastField= null;
		initializeDeclaration(typeNode);
		for (FieldInfo pi : fVariables.values()) {
			if (isCreateField(pi)) {
				VariableDeclarationFragment vdf= pi.declaration;
				FieldDeclaration parent= (FieldDeclaration) vdf.getParent();
				if (lastField == null)
					lastField= parent;
				else if (lastField.getStartPosition() < parent.getStartPosition())
					lastField= parent;

				ListRewrite listRewrite= rewrite.getListRewrite(parent, FieldDeclaration.FRAGMENTS_PROPERTY);
				removeNode(vdf, removeFieldGroup, fBaseCURewrite);
				if (listRewrite.getRewrittenList().size() == 0) {
					removeNode(parent, removeFieldGroup, fBaseCURewrite);
				}

				if (fDescriptor.isCreateTopLevel()) {
					IVariableBinding binding= vdf.resolveBinding();
					ITypeRoot typeRoot= fBaseCURewrite.getCu();
					if (binding == null || binding.getType() == null){
						status.addFatalError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_fatal_error_cannot_resolve_binding, BasicElementLabels.getJavaElementName(pi.name)), JavaStatusContext.create(typeRoot, vdf));
					} else {
						ITypeBinding typeBinding= binding.getType();
						if (Modifier.isPrivate(typeBinding.getModifiers())){
							status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_private_class, BasicElementLabels.getJavaElementName(typeBinding.getName())), JavaStatusContext.create(typeRoot, vdf));
						} else if (Modifier.isProtected(typeBinding.getModifiers())){
							ITypeBinding declaringClass= typeBinding.getDeclaringClass();
							if (declaringClass != null) {
								IPackageBinding package1= declaringClass.getPackage();
								if (package1 != null && !fDescriptor.getPackage().equals(package1.getName())){
									status.addError(Messages.format(RefactoringCoreMessages.ExtractClassRefactoring_error_referencing_protected_class, new String[] {BasicElementLabels.getJavaElementName(typeBinding.getName()), BasicElementLabels.getJavaElementName(fDescriptor.getPackage())}), JavaStatusContext.create(typeRoot, vdf));
								}
							}
						}
					}
				}
				Expression initializer= vdf.getInitializer();
				if (initializer != null)
					pi.initializer= initializer;
				int modifiers= parent.getModifiers();
				if (!MemberVisibilityAdjustor.hasLowerVisibility(modifiers, modifier)){
					modifier= modifiers;
				}
			}
		}
		FieldDeclaration fieldDeclaration= createParameterObjectField(pof, typeNode, modifier, removeFieldGroup);
		ListRewrite bodyDeclList= rewrite.getListRewrite(typeNode, TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
		if (lastField != null)
			bodyDeclList.insertAfter(fieldDeclaration, lastField, removeFieldGroup);
		else
			bodyDeclList.insertFirst(fieldDeclaration, removeFieldGroup);
		return fieldDeclaration;
	}

	private void initializeDeclaration(TypeDeclaration node) {
		for (FieldDeclaration fieldDeclaration : node.getFields()) {
			for (Object element : fieldDeclaration.fragments()) {
				VariableDeclarationFragment vdf=(VariableDeclarationFragment) element;
				FieldInfo fieldInfo= getFieldInfo(vdf.getName().getIdentifier());
				if (fieldInfo != null) {
					Assert.isNotNull(vdf);
					fieldInfo.declaration= vdf;
					fieldInfo.pi.setOldBinding(vdf.resolveBinding());
				}
			}
		}
	}

	private void removeNode(ASTNode parent, TextEditGroup removeFieldGroup, CompilationUnitRewrite baseCURewrite) {
		baseCURewrite.getASTRewrite().remove(parent, removeFieldGroup);
		baseCURewrite.getImportRemover().registerRemovedNode(parent);
	}

	private FieldDeclaration createParameterObjectField(ParameterObjectFactory pof, TypeDeclaration typeNode, int modifier, TextEditGroup removeFieldGroup) {
		AST ast= fBaseCURewrite.getAST();
		ClassInstanceCreation creation= ast.newClassInstanceCreation();
		creation.setType(pof.createType(fDescriptor.isCreateTopLevel(), fBaseCURewrite, typeNode.getStartPosition()));
		ListRewrite listRewrite= fBaseCURewrite.getASTRewrite().getListRewrite(creation, ClassInstanceCreation.ARGUMENTS_PROPERTY);
		for (FieldInfo fi : fVariables.values()) {
			if (isCreateField(fi)) {
				Expression expression= fi.initializer;
				if (expression != null && !fi.hasFieldReference()) {
					importNodeTypes(expression, fBaseCURewrite);
					ASTNode createMoveTarget= fBaseCURewrite.getASTRewrite().createMoveTarget(expression);
					if (expression instanceof ArrayInitializer) {
						ArrayInitializer ai= (ArrayInitializer) expression;
						ITypeBinding type= ai.resolveTypeBinding();
						Type addImport= fBaseCURewrite.getImportRewrite().addImport(type, ast);
						fBaseCURewrite.getImportRemover().registerAddedImports(addImport);
						ArrayCreation arrayCreation= ast.newArrayCreation();
						arrayCreation.setType((ArrayType) addImport);
						arrayCreation.setInitializer((ArrayInitializer) createMoveTarget);
						listRewrite.insertLast(arrayCreation, removeFieldGroup);
					} else {
						listRewrite.insertLast(createMoveTarget, removeFieldGroup);
					}
				}
			}
		}

		VariableDeclarationFragment fragment= ast.newVariableDeclarationFragment();
		fragment.setName(ast.newSimpleName(fDescriptor.getFieldName()));
		fragment.setInitializer(creation);

		ModifierKeyword acc= null;
		if (Modifier.isPublic(modifier)) {
			acc= ModifierKeyword.PUBLIC_KEYWORD;
		} else if (Modifier.isProtected(modifier)) {
			acc= ModifierKeyword.PROTECTED_KEYWORD;
		} else if (Modifier.isPrivate(modifier)) {
			acc= ModifierKeyword.PRIVATE_KEYWORD;
		}

		FieldDeclaration fieldDeclaration= ast.newFieldDeclaration(fragment);
		fieldDeclaration.setType(pof.createType(fDescriptor.isCreateTopLevel(), fBaseCURewrite, typeNode.getStartPosition()));
		if (acc != null)
			fieldDeclaration.modifiers().add(ast.newModifier(acc));
		return fieldDeclaration;
	}

	private void importNodeTypes(ASTNode node, final CompilationUnitRewrite cuRewrite) {
		ASTResolving.visitAllBindings(node, nodeBinding -> {
			ParameterObjectFactory.importBinding(nodeBinding, cuRewrite, null, TypeLocation.OTHER);
			return false;
		});
	}

	private boolean isCreateField(FieldInfo fi) {
		return getField(fi.name).isCreateField();
	}


	@Override
	public String getName() {
		return RefactoringCoreMessages.ExtractClassRefactoring_refactoring_name;
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter == ExtractClassDescriptorVerification.class) {
			return (T) fVerification;
		}
		return super.getAdapter(adapter);
	}
}
