/*******************************************************************************
 * Copyright (c) 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.refactoring.structure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditCopier;

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

import org.eclipse.core.resources.IFile;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.GroupCategory;
import org.eclipse.ltk.core.refactoring.GroupCategorySet;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.TextEditBasedChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTRequestor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
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.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.formatter.CodeFormatter;

import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptor;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorComment;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.changes.CompilationUnitChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.CreateCompilationUnitChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.jdt.internal.corext.refactoring.changes.MultiStateCompilationUnitChange;
import org.eclipse.jdt.internal.corext.refactoring.code.ScriptableRefactoring;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.TextEditBasedChangeManager;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.CodeGeneration;
import org.eclipse.jdt.ui.JavaElementLabels;

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

/**
 * Refactoring processor for the extract supertype refactoring.
 * 
 * @since 3.2
 */
public final class ExtractSupertypeProcessor extends PullUpRefactoringProcessor {

	/** The extract attribute */
	private static final String ATTRIBUTE_EXTRACT= "extract"; //$NON-NLS-1$

	/** The types attribute */
	private static final String ATTRIBUTE_TYPES= "types"; //$NON-NLS-1$

	/** The id of the refactoring */
	private static final String ID_EXTRACT_SUPERTYPE= "org.eclipse.jdt.ui.extract.superclass"; //$NON-NLS-1$

	/** The extract supertype group category set */
	private static final GroupCategorySet SET_EXTRACT_SUPERTYPE= new GroupCategorySet(new GroupCategory("org.eclipse.jdt.internal.corext.extractSupertype", //$NON-NLS-1$
			RefactoringCoreMessages.ExtractSupertypeProcessor_category_name, RefactoringCoreMessages.ExtractSupertypeProcessor_category_description));

	/**
	 * The changes of the working copy layer (element type:
	 * &lt;ICompilationUnit, TextEditBasedChange&gt;)
	 * <p>
	 * The compilation units are all primary working copies or normal
	 * compilation units.
	 * </p>
	 */
	private final Map fLayerChanges= new HashMap();

	/** The possible extract supertype candidates, or the empty array */
	private IType[] fPossibleCandidates= {};

	/** The source of the supertype */
	private String fSuperSource;

	/** The name of the extracted type */
	private String fTypeName= ""; //$NON-NLS-1$

	/** The types where to extract the supertype */
	private IType[] fTypesToExtract= {};

	/**
	 * Creates a new extract supertype refactoring processor.
	 * 
	 * @param members
	 *            the members to extract, or <code>null</code> if invoked by
	 *            scripting
	 * @param settings
	 *            the code generation settings, or <code>null</code> if
	 *            invoked by scripting
	 */
	public ExtractSupertypeProcessor(final IMember[] members, final CodeGenerationSettings settings) {
		super(members, settings, true);
		if (members != null) {
			final IType declaring= getDeclaringType();
			if (declaring != null)
				fTypesToExtract= new IType[] { declaring};
		}
	}

	/**
	 * {@inheritDoc}
	 */
	protected final RefactoringStatus checkDeclaringSuperTypes(final IProgressMonitor monitor) throws JavaModelException {
		return new RefactoringStatus();
	}
	
	protected CompilationUnitRewrite getCompilationUnitRewrite(final Map rewrites, final ICompilationUnit unit) {
		Assert.isNotNull(rewrites);
		Assert.isNotNull(unit);
		CompilationUnitRewrite rewrite= (CompilationUnitRewrite) rewrites.get(unit);
		if (rewrite == null) {
			rewrite= new CompilationUnitRewrite(fOwner, unit);
			rewrite.rememberContent();
			rewrites.put(unit, rewrite);
		}
		return rewrite;
	}

	/**
	 * Checks whether the compilation unit to be extracted is valid.
	 * 
	 * @return a status describing the outcome of the
	 */
	public RefactoringStatus checkExtractedCompilationUnit() {
		final RefactoringStatus status= new RefactoringStatus();
		final ICompilationUnit cu= getDeclaringType().getCompilationUnit();
		if (fTypeName == null || "".equals(fTypeName)) //$NON-NLS-1$
			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.Checks_Choose_name);
		status.merge(Checks.checkTypeName(fTypeName));
		if (status.hasFatalError())
			return status;
		status.merge(Checks.checkCompilationUnitName(JavaModelUtil.getRenamedCUName(cu, fTypeName)));
		if (status.hasFatalError())
			return status;
		status.merge(Checks.checkCompilationUnitNewName(cu, fTypeName));
		return status;
	}

	/**
	 * {@inheritDoc}
	 */
	public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException {
		final RefactoringStatus status= new RefactoringStatus();
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_checking);
			status.merge(checkExtractedCompilationUnit());
			if (status.hasFatalError())
				return status;
			return super.checkFinalConditions(new SubProgressMonitor(monitor, 1), context);
		} finally {
			monitor.done();
		}
	}

	/**
	 * Computes the destination type based on the new name.
	 * 
	 * @return the destination type
	 */
	public IType computeExtractedType(final String name) {
		if (name != null && !name.equals("")) {//$NON-NLS-1$
			final IType declaring= getDeclaringType();
			try {
				final ICompilationUnit[] units= declaring.getPackageFragment().getCompilationUnits(fOwner);
				final String newName= JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), name);
				ICompilationUnit result= null;
				for (int index= 0; index < units.length; index++) {
					if (units[index].getElementName().equals(newName))
						result= units[index];
				}
				if (result != null) {
					final IType type= result.getType(name);
					setDestinationType(type);
					return type;
				}
			} catch (JavaModelException exception) {
				JavaPlugin.log(exception);
			}
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		try {
			final Map arguments= new HashMap();
			String project= null;
			final IType declaring= getDeclaringType();
			final IJavaProject javaProject= declaring.getJavaProject();
			if (javaProject != null)
				project= javaProject.getElementName();
			int flags= JavaRefactoringDescriptor.JAR_IMPORTABLE | JavaRefactoringDescriptor.JAR_REFACTORABLE | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
			try {
				if (declaring.isLocal() || declaring.isAnonymous())
					flags|= JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
			} catch (JavaModelException exception) {
				JavaPlugin.log(exception);
			}
			final String description= Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_descriptor_description_short, fTypeName);
			final String header= Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_descriptor_description, new String[] { JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED), JavaElementLabels.getElementLabel(fCachedDeclaringType, JavaElementLabels.ALL_FULLY_QUALIFIED)});
			final JavaRefactoringDescriptorComment comment= new JavaRefactoringDescriptorComment(this, header);
			final IType[] types= getTypesToExtract();
			String[] settings= new String[types.length];
			for (int index= 0; index < settings.length; index++)
				settings[index]= JavaElementLabels.getElementLabel(types[index], JavaElementLabels.ALL_FULLY_QUALIFIED);
			comment.addSetting(JavaRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractSupertypeProcessor_subtypes_pattern, settings));
			comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractSupertypeProcessor_refactored_element_pattern, JavaElementLabels.getElementLabel(fDestinationType, JavaElementLabels.ALL_FULLY_QUALIFIED)));
			settings= new String[fMembersToMove.length];
			for (int index= 0; index < settings.length; index++)
				settings[index]= JavaElementLabels.getElementLabel(fMembersToMove[index], JavaElementLabels.ALL_FULLY_QUALIFIED);
			comment.addSetting(JavaRefactoringDescriptorComment.createCompositeSetting(RefactoringCoreMessages.ExtractInterfaceProcessor_extracted_members_pattern, settings));
			addSuperTypeSettings(comment, true);
			final JavaRefactoringDescriptor descriptor= new JavaRefactoringDescriptor(ID_EXTRACT_SUPERTYPE, project, description, comment.asString(), arguments, flags);
			arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_NAME, fTypeName);
			arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(getDeclaringType()));
			arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplace).toString());
			arguments.put(ATTRIBUTE_INSTANCEOF, Boolean.valueOf(fInstanceOf).toString());
			arguments.put(ATTRIBUTE_STUBS, Boolean.valueOf(fCreateMethodStubs).toString());
			arguments.put(ATTRIBUTE_EXTRACT, new Integer(fMembersToMove.length).toString());
			for (int offset= 0; offset < fMembersToMove.length; offset++)
				arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + 1), descriptor.elementToHandle(fMembersToMove[offset]));
			arguments.put(ATTRIBUTE_DELETE, new Integer(fDeletedMethods.length).toString());
			for (int offset= 0; offset < fDeletedMethods.length; offset++)
				arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + 1), descriptor.elementToHandle(fDeletedMethods[offset]));
			arguments.put(ATTRIBUTE_ABSTRACT, new Integer(fAbstractMethods.length).toString());
			for (int offset= 0; offset < fAbstractMethods.length; offset++)
				arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + fDeletedMethods.length + 1), descriptor.elementToHandle(fAbstractMethods[offset]));
			arguments.put(ATTRIBUTE_TYPES, new Integer(fTypesToExtract.length).toString());
			for (int offset= 0; offset < fTypesToExtract.length; offset++)
				arguments.put(JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (offset + fMembersToMove.length + fDeletedMethods.length + fAbstractMethods.length + 1), descriptor.elementToHandle(fTypesToExtract[offset]));
			final DynamicValidationRefactoringChange change= new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.ExtractSupertypeProcessor_extract_supertype, fChangeManager.getAllChanges());
			final IFile file= ResourceUtil.getFile(declaring.getCompilationUnit());
			if (fSuperSource != null && fSuperSource.length() > 0)
				change.add(new CreateCompilationUnitChange(declaring.getPackageFragment().getCompilationUnit(JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), fTypeName)), fSuperSource, file.getCharset(false)));
			return change;
		} finally {
			monitor.done();
			clearCaches();
		}
	}

	/**
	 * Creates the new extracted supertype.
	 * 
	 * @param superType
	 *            the super type, or <code>null</code> if no super type (ie.
	 *            <code>java.lang.Object</code>) is available
	 * @param monitor
	 *            the progress monitor
	 * @return a status describing the outcome of the operation
	 * @throws CoreException
	 *             if an error occurs
	 */
	protected final RefactoringStatus createExtractedSuperType(final IType superType, final IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(monitor);
		fSuperSource= null;
		final RefactoringStatus status= new RefactoringStatus();
		try {
			monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 20);
			final IType declaring= getDeclaringType();
			final CompilationUnitRewrite declaringRewrite= new CompilationUnitRewrite(fOwner, declaring.getCompilationUnit());
			final AbstractTypeDeclaration declaringDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(declaring, declaringRewrite.getRoot());
			if (declaringDeclaration != null) {
				final String name= JavaModelUtil.getRenamedCUName(declaring.getCompilationUnit(), fTypeName);
				final ICompilationUnit original= declaring.getPackageFragment().getCompilationUnit(name);
				final ICompilationUnit copy= getSharedWorkingCopy(original.getPrimary(), new SubProgressMonitor(monitor, 10));
				fSuperSource= createSuperTypeSource(copy, superType, declaringDeclaration, status, new SubProgressMonitor(monitor, 10));
				if (fSuperSource != null) {
					copy.getBuffer().setContents(fSuperSource);
					JavaModelUtil.reconcile(copy);
				}
			}
		} finally {
			monitor.done();
		}
		return status;
	}

	/**
	 * Creates a working copy for the modified subtype.
	 * 
	 * @param unit
	 *            the compilation unit
	 * @param root
	 *            the compilation unit node
	 * @param subDeclaration
	 *            the declaration of the subtype to modify
	 * @param extractedType
	 *            the extracted super type
	 * @param extractedBinding
	 *            the binding of the extracted super type
	 * @param status
	 *            the refactoring status
	 */
	protected final void createModifiedSubType(final ICompilationUnit unit, final CompilationUnit root, final IType extractedType, final ITypeBinding extractedBinding, final AbstractTypeDeclaration subDeclaration, final RefactoringStatus status) {
		Assert.isNotNull(unit);
		Assert.isNotNull(subDeclaration);
		Assert.isNotNull(extractedType);
		try {
			final CompilationUnitRewrite rewrite= new CompilationUnitRewrite(fOwner, unit, root);
			createTypeSignature(rewrite, subDeclaration, extractedType, extractedBinding, new NullProgressMonitor());
			final Document document= new Document(unit.getBuffer().getContents());
			final CompilationUnitChange change= rewrite.createChange();
			if (change != null) {
				fLayerChanges.put(unit.getPrimary(), change);
				final TextEdit edit= change.getEdit();
				if (edit != null) {
					final TextEditCopier copier= new TextEditCopier(edit);
					final TextEdit copy= copier.perform();
					copy.apply(document, TextEdit.NONE);
				}
			}
			final ICompilationUnit copy= getSharedWorkingCopy(unit, new NullProgressMonitor());
			copy.getBuffer().setContents(document.get());
			JavaModelUtil.reconcile(copy);
		} catch (CoreException exception) {
			JavaPlugin.log(exception);
			status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
		} catch (MalformedTreeException exception) {
			JavaPlugin.log(exception);
			status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
		} catch (BadLocationException exception) {
			JavaPlugin.log(exception);
			status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
		}
	}

	/**
	 * Creates the necessary constructors for the extracted supertype.
	 * 
	 * @param targetRewrite
	 *            the target compilation unit rewrite
	 * @param superType
	 *            the super type, or <code>null</code> if no super type (ie.
	 *            <code>java.lang.Object</code>) is available
	 * @param targetDeclaration
	 *            the type declaration of the target type
	 * @param status
	 *            the refactoring status
	 */
	protected final void createNecessaryConstructors(final CompilationUnitRewrite targetRewrite, final IType superType, final AbstractTypeDeclaration targetDeclaration, final RefactoringStatus status) {
		Assert.isNotNull(targetRewrite);
		Assert.isNotNull(targetDeclaration);
		if (superType != null) {
			final ITypeBinding binding= targetDeclaration.resolveBinding();
			if (binding != null && binding.isClass()) {
				final IMethodBinding[] bindings= StubUtility2.getVisibleConstructors(binding, true, true);
				int deprecationCount= 0;
				for (int i= 0; i < bindings.length; i++) {
					if (bindings[i].isDeprecated())
						deprecationCount++;
				}
				final ListRewrite rewrite= targetRewrite.getASTRewrite().getListRewrite(targetDeclaration, TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
				if (rewrite != null) {
					boolean createDeprecated= deprecationCount == bindings.length;
					for (int i= 0; i < bindings.length; i++) {
						IMethodBinding curr= bindings[i];
						if (!curr.isDeprecated() || createDeprecated) {
							MethodDeclaration stub;
							try {
								stub= StubUtility2.createConstructorStub(targetRewrite.getCu(), targetRewrite.getASTRewrite(), targetRewrite.getImportRewrite(), curr, binding.getName(), Modifier.PUBLIC, false, false, fSettings);
								if (stub != null)
									rewrite.insertLast(stub, null);
							} catch (CoreException exception) {
								JavaPlugin.log(exception);
								status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
							}
						}
					}
				}
			}
		}
	}

	/**
	 * Creates the source for the new compilation unit containing the supertype.
	 * 
	 * @param extractedWorkingCopy
	 *            the working copy of the new extracted supertype
	 * @param superType
	 *            the super type, or <code>null</code> if no super type (ie.
	 *            <code>java.lang.Object</code>) is available
	 * @param declaringDeclaration
	 *            the declaration of the declaring type
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to display progress
	 * @return the source of the new compilation unit, or <code>null</code>
	 * @throws CoreException
	 *             if an error occurs
	 */
	protected final String createSuperTypeSource(final ICompilationUnit extractedWorkingCopy, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(extractedWorkingCopy);
		Assert.isNotNull(declaringDeclaration);
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		String source= null;
		try {
			monitor.beginTask("", 2); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
			final IType declaring= getDeclaringType();
			final String delimiter= StubUtility.getLineDelimiterUsed(extractedWorkingCopy.getJavaProject());
			String typeComment= null;
			String fileComment= null;
			if (fSettings.createComments) {
				final ITypeParameter[] parameters= declaring.getTypeParameters();
				final String[] names= new String[parameters.length];
				for (int index= 0; index < parameters.length; index++)
					names[index]= parameters[index].getElementName();
				typeComment= CodeGeneration.getTypeComment(extractedWorkingCopy, fTypeName, names, delimiter);
				fileComment= CodeGeneration.getFileComment(extractedWorkingCopy, delimiter);
			}
			final StringBuffer buffer= new StringBuffer(64);
			createTypeDeclaration(extractedWorkingCopy, superType, declaringDeclaration, typeComment, buffer, status, new SubProgressMonitor(monitor, 1));
			final String imports= createTypeImports(extractedWorkingCopy, monitor);
			source= createTypeTemplate(extractedWorkingCopy, imports, fileComment, "", buffer.toString()); //$NON-NLS-1$
			if (source == null) {
				if (!declaring.getPackageFragment().isDefaultPackage()) {
					if (imports.length() > 0)
						buffer.insert(0, imports);
					buffer.insert(0, "package " + declaring.getPackageFragment().getElementName() + ";"); //$NON-NLS-1$//$NON-NLS-2$
				}
				source= buffer.toString();
			}
			final IDocument document= new Document(source);
			final TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, source, 0, delimiter, extractedWorkingCopy.getJavaProject().getOptions(true));
			if (edit != null) {
				try {
					edit.apply(document, TextEdit.UPDATE_REGIONS);
				} catch (MalformedTreeException exception) {
					JavaPlugin.log(exception);
					status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
				} catch (BadLocationException exception) {
					JavaPlugin.log(exception);
					status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
				}
				source= document.get();
			}
		} finally {
			monitor.done();
		}
		return source;
	}

	/**
	 * Creates the declaration of the new supertype, excluding any comments or
	 * package declaration.
	 * 
	 * @param extractedWorkingCopy
	 *            the working copy of the new extracted supertype
	 * @param superType
	 *            the super type, or <code>null</code> if no super type (ie.
	 *            <code>java.lang.Object</code>) is available
	 * @param declaringDeclaration
	 *            the declaration of the declaring type
	 * @param comment
	 *            the comment of the new type declaration
	 * @param buffer
	 *            the string buffer containing the declaration
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to use
	 * @throws CoreException
	 *             if an error occurs
	 */
	protected final void createTypeDeclaration(final ICompilationUnit extractedWorkingCopy, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final String comment, final StringBuffer buffer, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(extractedWorkingCopy);
		Assert.isNotNull(declaringDeclaration);
		Assert.isNotNull(buffer);
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
			final IJavaProject project= extractedWorkingCopy.getJavaProject();
			final String delimiter= StubUtility.getLineDelimiterUsed(project);
			if (comment != null && !"".equals(comment)) { //$NON-NLS-1$
				buffer.append(comment);
				buffer.append(delimiter);
			}
			buffer.append(JdtFlags.VISIBILITY_STRING_PUBLIC);
			if (superType != null && Flags.isAbstract(superType.getFlags())) {
				buffer.append(' ');
				buffer.append("abstract "); //$NON-NLS-1$
			}
			buffer.append(' ');
			buffer.append("class "); //$NON-NLS-1$
			buffer.append(fTypeName);
			if (superType != null && !"java.lang.Object".equals(superType.getFullyQualifiedName())) { //$NON-NLS-1$
				buffer.append(' ');
				if (superType.isInterface())
					buffer.append("implements "); //$NON-NLS-1$
				else
					buffer.append("extends "); //$NON-NLS-1$
				buffer.append(superType.getElementName());
			}
			buffer.append(" {"); //$NON-NLS-1$
			buffer.append(delimiter);
			buffer.append(delimiter);
			buffer.append('}');
			final String string= buffer.toString();
			extractedWorkingCopy.getBuffer().setContents(string);
			final IDocument document= new Document(string);
			final CompilationUnitRewrite targetRewrite= new CompilationUnitRewrite(fOwner, extractedWorkingCopy);
			final AbstractTypeDeclaration targetDeclaration= (AbstractTypeDeclaration) targetRewrite.getRoot().types().get(0);
			createTypeParameters(targetRewrite, superType, declaringDeclaration, targetDeclaration);
			createTypeSignature(targetRewrite, superType, declaringDeclaration, targetDeclaration);
			createNecessaryConstructors(targetRewrite, superType, targetDeclaration, status);
			final TextEdit edit= targetRewrite.createChange().getEdit();
			try {
				edit.apply(document, TextEdit.UPDATE_REGIONS);
			} catch (MalformedTreeException exception) {
				JavaPlugin.log(exception);
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
			} catch (BadLocationException exception) {
				JavaPlugin.log(exception);
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
			}
			buffer.setLength(0);
			buffer.append(document.get());
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the type parameters of the new supertype.
	 * 
	 * @param targetRewrite
	 *            the target compilation unit rewrite
	 * @param subType
	 *            the subtype
	 * @param sourceDeclaration
	 *            the type declaration of the source type
	 * @param targetDeclaration
	 *            the type declaration of the target type
	 */
	protected final void createTypeParameters(final CompilationUnitRewrite targetRewrite, final IType subType, final AbstractTypeDeclaration sourceDeclaration, final AbstractTypeDeclaration targetDeclaration) {
		Assert.isNotNull(targetRewrite);
		Assert.isNotNull(sourceDeclaration);
		Assert.isNotNull(targetDeclaration);
		if (sourceDeclaration instanceof TypeDeclaration) {
			TypeParameter parameter= null;
			final ListRewrite rewrite= targetRewrite.getASTRewrite().getListRewrite(targetDeclaration, TypeDeclaration.TYPE_PARAMETERS_PROPERTY);
			for (final Iterator iterator= ((TypeDeclaration) sourceDeclaration).typeParameters().iterator(); iterator.hasNext();) {
				parameter= (TypeParameter) iterator.next();
				final ASTNode node= ASTNode.copySubtree(targetRewrite.getAST(), parameter);
				rewrite.insertLast(node, null);
			}
		}
	}

	/**
	 * Creates a new type signature of a subtype.
	 * 
	 * @param subRewrite
	 *            the compilation unit rewrite of a subtype
	 * @param declaration
	 *            the type declaration of a subtype
	 * @param extractedType
	 *            the extracted super type
	 * @param extractedBinding
	 *            the binding of the extracted super type
	 * @param monitor
	 *            the progress monitor to use
	 * @throws JavaModelException
	 *             if the type parameters cannot be retrieved
	 */
	protected final void createTypeSignature(final CompilationUnitRewrite subRewrite, final AbstractTypeDeclaration declaration, final IType extractedType, final ITypeBinding extractedBinding, final IProgressMonitor monitor) throws JavaModelException {
		Assert.isNotNull(subRewrite);
		Assert.isNotNull(declaration);
		Assert.isNotNull(extractedType);
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 10);
			final AST ast= subRewrite.getAST();
			Type type= null;
			if (extractedBinding != null) {
				type= subRewrite.getImportRewrite().addImport(extractedBinding, ast);
			} else {
				subRewrite.getImportRewrite().addImport(extractedType.getFullyQualifiedName('.'));
				type= ast.newSimpleType(ast.newSimpleName(extractedType.getElementName()));
			}
			subRewrite.getImportRemover().registerAddedImport(extractedType.getFullyQualifiedName('.'));
			if (type != null) {
				final ITypeParameter[] parameters= extractedType.getTypeParameters();
				if (parameters.length > 0) {
					final ParameterizedType parameterized= ast.newParameterizedType(type);
					for (int index= 0; index < parameters.length; index++)
						parameterized.typeArguments().add(ast.newSimpleType(ast.newSimpleName(parameters[index].getElementName())));
					type= parameterized;
				}
			}
			final ASTRewrite rewriter= subRewrite.getASTRewrite();
			if (type != null && declaration instanceof TypeDeclaration) {
				final TypeDeclaration extended= (TypeDeclaration) declaration;
				final Type superClass= extended.getSuperclassType();
				if (superClass != null)
					rewriter.replace(superClass, type, subRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractSupertypeProcessor_add_supertype, SET_EXTRACT_SUPERTYPE));
				else
					rewriter.set(extended, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, type, subRewrite.createCategorizedGroupDescription(RefactoringCoreMessages.ExtractSupertypeProcessor_add_supertype, SET_EXTRACT_SUPERTYPE));
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the type signature of the extracted supertype.
	 * 
	 * @param targetRewrite
	 *            the target compilation unit rewrite
	 * @param superType
	 *            the super type, or <code>null</code> if no super type (ie.
	 *            <code>java.lang.Object</code>) is available
	 * @param declaringDeclaration
	 *            the declaration of the declaring type
	 * @param targetDeclaration
	 *            the type declaration of the target type
	 */
	protected final void createTypeSignature(final CompilationUnitRewrite targetRewrite, final IType superType, final AbstractTypeDeclaration declaringDeclaration, final AbstractTypeDeclaration targetDeclaration) {
		Assert.isNotNull(targetRewrite);
		Assert.isNotNull(declaringDeclaration);
		Assert.isNotNull(targetDeclaration);
		if (declaringDeclaration instanceof TypeDeclaration) {
			final TypeDeclaration declaration= (TypeDeclaration) declaringDeclaration;
			final Type superclassType= declaration.getSuperclassType();
			if (superclassType != null) {
				Type type= null;
				final ITypeBinding binding= superclassType.resolveBinding();
				if (binding != null) {
					type= targetRewrite.getImportRewrite().addImport(binding, targetRewrite.getAST());
					targetRewrite.getImportRemover().registerAddedImports(type);
				}
				if (type != null && targetDeclaration instanceof TypeDeclaration) {
					final TypeDeclaration extended= (TypeDeclaration) targetDeclaration;
					final Type targetSuperType= extended.getSuperclassType();
					if (targetSuperType != null) {
						targetRewrite.getASTRewrite().replace(targetSuperType, type, null);
					} else {
						targetRewrite.getASTRewrite().set(extended, TypeDeclaration.SUPERCLASS_TYPE_PROPERTY, type, null);
					}
				}
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public final RefactoringStatus createWorkingCopyLayer(final IProgressMonitor monitor) {
		Assert.isNotNull(monitor);
		final RefactoringStatus status= new RefactoringStatus();
		try {
			monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing, 70);
			status.merge(super.createWorkingCopyLayer(new SubProgressMonitor(monitor, 10)));
			final IType declaring= getDeclaringType();
			status.merge(createExtractedSuperType(getDeclaringSuperTypeHierarchy(new SubProgressMonitor(monitor, 10)).getSuperclass(declaring), new SubProgressMonitor(monitor, 10)));
			if (status.hasFatalError())
				return status;
			final IType extractedType= computeExtractedType(fTypeName);
			setDestinationType(extractedType);
			final List subTypes= new ArrayList(Arrays.asList(fTypesToExtract));
			if (!subTypes.contains(declaring))
				subTypes.add(declaring);
			final Map unitToTypes= new HashMap(subTypes.size());
			final Set units= new HashSet(subTypes.size());
			for (int index= 0; index < subTypes.size(); index++) {
				final IType type= (IType) subTypes.get(index);
				final ICompilationUnit unit= type.getCompilationUnit();
				units.add(unit);
				Collection collection= (Collection) unitToTypes.get(unit);
				if (collection == null) {
					collection= new ArrayList(2);
					unitToTypes.put(unit, collection);
				}
				collection.add(type);
			}
			final Map projectToUnits= new HashMap();
			Collection collection= null;
			IJavaProject project= null;
			ICompilationUnit current= null;
			for (final Iterator iterator= units.iterator(); iterator.hasNext();) {
				current= (ICompilationUnit) iterator.next();
				project= current.getJavaProject();
				collection= (Collection) projectToUnits.get(project);
				if (collection == null) {
					collection= new ArrayList();
					projectToUnits.put(project, collection);
				}
				collection.add(current);
			}
			final ITypeBinding[] extractBindings= { null};
			final ASTParser extractParser= ASTParser.newParser(AST.JLS3);
			extractParser.setWorkingCopyOwner(fOwner);
			extractParser.setResolveBindings(true);
			extractParser.setProject(project);
			extractParser.setSource(extractedType.getCompilationUnit());
			final CompilationUnit extractUnit= (CompilationUnit) extractParser.createAST(new SubProgressMonitor(monitor, 10));
			if (extractUnit != null) {
				final AbstractTypeDeclaration extractDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(extractedType, extractUnit);
				if (extractDeclaration != null)
					extractBindings[0]= extractDeclaration.resolveBinding();
			}
			final ASTParser parser= ASTParser.newParser(AST.JLS3);
			final IProgressMonitor subMonitor= new SubProgressMonitor(monitor, 30);
			try {
				final Set keySet= projectToUnits.keySet();
				subMonitor.beginTask("", keySet.size()); //$NON-NLS-1$
				subMonitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
				for (final Iterator iterator= keySet.iterator(); iterator.hasNext();) {
					project= (IJavaProject) iterator.next();
					collection= (Collection) projectToUnits.get(project);
					parser.setWorkingCopyOwner(fOwner);
					parser.setResolveBindings(true);
					parser.setProject(project);
					parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
					final IProgressMonitor subsubMonitor= new SubProgressMonitor(subMonitor, 1);
					try {
						subsubMonitor.beginTask("", collection.size()); //$NON-NLS-1$
						subsubMonitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_preparing);
						parser.createASTs((ICompilationUnit[]) collection.toArray(new ICompilationUnit[collection.size()]), new String[0], new ASTRequestor() {

							public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
								try {
									final Collection types= (Collection) unitToTypes.get(unit);
									if (types != null) {
										for (final Iterator innerIterator= types.iterator(); innerIterator.hasNext();) {
											final IType currentType= (IType) innerIterator.next();
											final AbstractTypeDeclaration currentDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(currentType, node);
											if (currentDeclaration != null)
												createModifiedSubType(unit, node, extractedType, extractBindings[0], currentDeclaration, status);
										}
									}
								} catch (CoreException exception) {
									JavaPlugin.log(exception);
									status.merge(RefactoringStatus.createFatalErrorStatus(exception.getLocalizedMessage()));
								} finally {
									subsubMonitor.worked(1);
								}
							}

							public final void acceptBinding(final String key, final IBinding binding) {
								// Do nothing
							}
						}, subsubMonitor);
					} finally {
						subsubMonitor.done();
					}
				}
			} finally {
				subMonitor.done();
			}
		} catch (CoreException exception) {
			JavaPlugin.log(exception);
			status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception_on_layer));
		} finally {
			monitor.done();
		}
		return status;
	}

	/**
	 * {@inheritDoc}
	 */
	public IType[] getCandidateTypes(final RefactoringStatus status, final IProgressMonitor monitor) {
		Assert.isNotNull(monitor);
		if (fPossibleCandidates == null || fPossibleCandidates.length == 0) {
			final IType declaring= getDeclaringType();
			if (declaring != null) {
				try {
					monitor.beginTask(RefactoringCoreMessages.ExtractSupertypeProcessor_computing_possible_types, 10);
					final IType superType= getDeclaringSuperTypeHierarchy(new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).getSuperclass(declaring);
					if (superType != null) {
						fPossibleCandidates= superType.newTypeHierarchy(fOwner, new SubProgressMonitor(monitor, 9, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).getSubtypes(superType);
						final LinkedList list= new LinkedList(Arrays.asList(fPossibleCandidates));
						final Set names= new HashSet();
						for (final Iterator iterator= list.iterator(); iterator.hasNext();) {
							final IType type= (IType) iterator.next();
							if (type.isReadOnly() || type.isBinary() || type.isAnonymous() || !type.isClass() || names.contains(type.getFullyQualifiedName()))
								iterator.remove();
							else
								names.add(type.getFullyQualifiedName());
						}
						fPossibleCandidates= (IType[]) list.toArray(new IType[list.size()]);
					}
				} catch (JavaModelException exception) {
					JavaPlugin.log(exception);
				} finally {
					monitor.done();
				}
			}
		}
		return fPossibleCandidates;
	}

	/**
	 * {@inheritDoc}
	 */
	public Object[] getElements() {
		return new Object[] { getDeclaringType()};
	}

	/**
	 * Returns the extracted type.
	 * 
	 * @return the extracted type, or <code>null</code>
	 */
	public IType getExtractedType() {
		return getDestinationType();
	}

	/**
	 * Returns the type name.
	 * 
	 * @return the type name
	 */
	public String getTypeName() {
		return fTypeName;
	}

	/**
	 * Returns the types to extract. The declaring type may or may not be
	 * contained in the result.
	 * 
	 * @return the types to extract
	 */
	public IType[] getTypesToExtract() {
		return fTypesToExtract;
	}

	/**
	 * {@inheritDoc}
	 */
	public RefactoringStatus initialize(final RefactoringArguments arguments) {
		if (arguments instanceof JavaRefactoringArguments) {
			final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
			final String name= extended.getAttribute(JavaRefactoringDescriptor.ATTRIBUTE_NAME);
			if (name != null && !"".equals(name)) //$NON-NLS-1$
				fTypeName= name;
			else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptor.ATTRIBUTE_NAME));
			String handle= extended.getAttribute(JavaRefactoringDescriptor.ATTRIBUTE_INPUT);
			if (handle != null) {
				final IJavaElement element= JavaRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
				if (element == null || element.getElementType() != IJavaElement.TYPE)
					return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE);
				IType type= null;
				final ICompilationUnit unit= ((IType) element).getCompilationUnit();
				if (unit != null && unit.exists()) {
					try {
						final ICompilationUnit copy= getSharedWorkingCopy(unit, new NullProgressMonitor());
						final IJavaElement[] elements= copy.findElements(element);
						if (elements != null && elements.length == 1 && elements[0] instanceof IType && elements[0].exists())
							type= (IType) elements[0];
					} catch (JavaModelException exception) {
						// TODO: log exception
					}
				}
				if (type != null)
					fCachedDeclaringType= type;
				else
					return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE);
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JavaRefactoringDescriptor.ATTRIBUTE_INPUT));
			final String stubs= extended.getAttribute(ATTRIBUTE_STUBS);
			if (stubs != null) {
				fCreateMethodStubs= Boolean.valueOf(stubs).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_STUBS));
			final String instance= extended.getAttribute(ATTRIBUTE_INSTANCEOF);
			if (instance != null) {
				fInstanceOf= Boolean.valueOf(instance).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INSTANCEOF));
			final String replace= extended.getAttribute(ATTRIBUTE_REPLACE);
			if (replace != null) {
				fReplace= Boolean.valueOf(replace).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));
			int extractCount= 0;
			int abstractCount= 0;
			int deleteCount= 0;
			int typeCount= 0;
			String value= extended.getAttribute(ATTRIBUTE_ABSTRACT);
			if (value != null && !"".equals(value)) {//$NON-NLS-1$
				try {
					abstractCount= Integer.parseInt(value);
				} catch (NumberFormatException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_ABSTRACT));
			value= extended.getAttribute(ATTRIBUTE_DELETE);
			if (value != null && !"".equals(value)) {//$NON-NLS-1$
				try {
					deleteCount= Integer.parseInt(value);
				} catch (NumberFormatException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DELETE));
			value= extended.getAttribute(ATTRIBUTE_EXTRACT);
			if (value != null && !"".equals(value)) {//$NON-NLS-1$
				try {
					extractCount= Integer.parseInt(value);
				} catch (NumberFormatException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_EXTRACT));
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_EXTRACT));
			value= extended.getAttribute(ATTRIBUTE_TYPES);
			if (value != null && !"".equals(value)) {//$NON-NLS-1$
				try {
					typeCount= Integer.parseInt(value);
				} catch (NumberFormatException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TYPES));
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TYPES));
			final RefactoringStatus status= new RefactoringStatus();
			List elements= new ArrayList();
			for (int index= 0; index < extractCount; index++) {
				final String attribute= JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (index + 1);
				handle= extended.getAttribute(attribute);
				if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
					final IJavaElement element= JavaRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
					if (element == null || !element.exists())
						status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE));
					else
						elements.add(element);
				} else
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
			}
			fMembersToMove= (IMember[]) elements.toArray(new IMember[elements.size()]);
			elements= new ArrayList();
			for (int index= 0; index < deleteCount; index++) {
				final String attribute= JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + index + 1);
				handle= extended.getAttribute(attribute);
				if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
					final IJavaElement element= JavaRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
					if (element == null || !element.exists())
						status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE));
					else
						elements.add(element);
				} else
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
			}
			fDeletedMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
			elements= new ArrayList();
			for (int index= 0; index < abstractCount; index++) {
				final String attribute= JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + abstractCount + index + 1);
				handle= extended.getAttribute(attribute);
				if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
					final IJavaElement element= JavaRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
					if (element == null || !element.exists())
						status.merge(ScriptableRefactoring.createInputWarningStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE));
					else
						elements.add(element);
				} else
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
			}
			fAbstractMethods= (IMethod[]) elements.toArray(new IMethod[elements.size()]);
			elements= new ArrayList();
			for (int index= 0; index < typeCount; index++) {
				final String attribute= JavaRefactoringDescriptor.ATTRIBUTE_ELEMENT + (extractCount + abstractCount + deleteCount + index + 1);
				handle= extended.getAttribute(attribute);
				if (handle != null && !"".equals(handle)) { //$NON-NLS-1$
					final IJavaElement element= JavaRefactoringDescriptor.handleToElement(fOwner, extended.getProject(), handle, false);
					if (element == null || !element.exists())
						status.merge(ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), ID_EXTRACT_SUPERTYPE));
					else
						elements.add(element);
				} else
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, attribute));
			}
			fTypesToExtract= (IType[]) elements.toArray(new IType[elements.size()]);
			IJavaProject project= null;
			if (fMembersToMove.length > 0)
				project= fMembersToMove[0].getJavaProject();
			fSettings= JavaPreferencesSettings.getCodeGenerationSettings(project);
			if (!status.isOK())
				return status;
		} else
			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
		return new RefactoringStatus();
	}

	/**
	 * {@inheritDoc}
	 */
	protected void registerChanges(final TextEditBasedChangeManager manager) throws CoreException {
		try {
			final ICompilationUnit extractedUnit= getExtractedType().getCompilationUnit().getPrimary();
			ICompilationUnit unit= null;
			CompilationUnitRewrite rewrite= null;
			for (final Iterator iterator= fCompilationUnitRewrites.keySet().iterator(); iterator.hasNext();) {
				unit= (ICompilationUnit) iterator.next();
				if (!unit.getPrimary().equals(extractedUnit)) {
					rewrite= (CompilationUnitRewrite) fCompilationUnitRewrites.get(unit);
					if (rewrite != null) {
						final CompilationUnitChange layerChange= (CompilationUnitChange) fLayerChanges.get(unit.getPrimary());
						final CompilationUnitChange rewriteChange= rewrite.createChange();
						if (rewriteChange != null && layerChange != null) {
							final MultiStateCompilationUnitChange change= new MultiStateCompilationUnitChange(rewriteChange.getName(), unit);
							change.addChange(layerChange);
							change.addChange(rewriteChange);
							fLayerChanges.remove(unit.getPrimary());
							manager.manage(unit, change);
						} else if (layerChange != null) {
							manager.manage(unit, layerChange);
							fLayerChanges.remove(unit.getPrimary());
						} else if (rewriteChange != null) {
							manager.manage(unit, rewriteChange);
						}
					}
				}
			}
			for (Iterator iterator= fLayerChanges.entrySet().iterator(); iterator.hasNext();) {
				final Map.Entry entry= (Map.Entry) iterator.next();
				manager.manage((ICompilationUnit) entry.getKey(), (TextEditBasedChange) entry.getValue());
			}
			ICompilationUnit[] units= manager.getAllCompilationUnits();
			for (int index= 0; index < units.length; index++) {
				if (units[index].getPath().equals(extractedUnit.getPath()))
					manager.remove(units[index]);
			}
		} finally {
			fLayerChanges.clear();
		}
	}

	/**
	 * Resets the changes necessary for the working copy layer.
	 */
	public void resetChanges() {
		fLayerChanges.clear();
	}

	/**
	 * {@inheritDoc}
	 */
	protected void rewriteTypeOccurrences(final TextEditBasedChangeManager manager, final CompilationUnitRewrite sourceRewrite, final ICompilationUnit copy, final Set replacements, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		try {
			monitor.beginTask("", 20); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.ExtractSupertypeProcessor_checking);
			try {
				final IType declaring= getDeclaringType();
				final ICompilationUnit destinationUnit= getDestinationType().getCompilationUnit();
				final IJavaProject project= declaring.getJavaProject();
				final ASTParser parser= ASTParser.newParser(AST.JLS3);
				parser.setWorkingCopyOwner(fOwner);
				parser.setResolveBindings(true);
				parser.setProject(project);
				parser.setCompilerOptions(RefactoringASTParser.getCompilerOptions(project));
				parser.createASTs(new ICompilationUnit[] { copy}, new String[0], new ASTRequestor() {

					public final void acceptAST(final ICompilationUnit unit, final CompilationUnit node) {
						try {
							final IType subType= (IType) JavaModelUtil.findInCompilationUnit(unit, declaring);
							final AbstractTypeDeclaration subDeclaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(subType, node);
							if (subDeclaration != null) {
								final ITypeBinding subBinding= subDeclaration.resolveBinding();
								if (subBinding != null) {
									String name= null;
									ITypeBinding superBinding= null;
									final ITypeBinding[] superBindings= Bindings.getAllSuperTypes(subBinding);
									for (int index= 0; index < superBindings.length; index++) {
										name= superBindings[index].getName();
										if (name.startsWith(fDestinationType.getElementName()))
											superBinding= superBindings[index];
									}
									if (superBinding != null) {
										solveSuperTypeConstraints(unit, node, subType, subBinding, superBinding, new SubProgressMonitor(monitor, 14), status);
										if (!status.hasFatalError())
											rewriteTypeOccurrences(manager, this, sourceRewrite, unit, node, replacements, status, new SubProgressMonitor(monitor, 3));
										if (manager.containsChangesIn(destinationUnit)) {
											final TextEditBasedChange change= manager.get(destinationUnit);
											if (change instanceof TextChange) {
												final TextEdit edit= ((TextChange) change).getEdit();
												if (edit != null) {
													final IDocument document= new Document(destinationUnit.getBuffer().getContents());
													try {
														edit.apply(document, TextEdit.UPDATE_REGIONS);
													} catch (MalformedTreeException exception) {
														JavaPlugin.log(exception);
														status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception));
													} catch (BadLocationException exception) {
														JavaPlugin.log(exception);
														status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception));
													}
													fSuperSource= document.get();
													manager.remove(destinationUnit);
												}
											}
										}
									}
								}
							}
						} catch (JavaModelException exception) {
							JavaPlugin.log(exception);
							status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractSupertypeProcessor_unexpected_exception));
						}
					}

					public final void acceptBinding(final String key, final IBinding binding) {
						// Do nothing
					}
				}, new SubProgressMonitor(monitor, 1));
			} finally {

			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Sets the type name.
	 * 
	 * @param name
	 *            the type name
	 */
	public void setTypeName(final String name) {
		Assert.isNotNull(name);
		fTypeName= name;
	}

	/**
	 * Sets the types to extract. Must be a subset of
	 * <code>getPossibleCandidates()</code>. If the declaring type is not
	 * contained, it will automatically be added.
	 * 
	 * @param types
	 *            the types to extract
	 */
	public void setTypesToExtract(final IType[] types) {
		Assert.isNotNull(types);
		fTypesToExtract= types;
	}
}