/*******************************************************************************
 * Copyright (c) 2000, 2011 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;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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.ltk.core.refactoring.RefactoringStatus;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
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.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameMatch;

import org.eclipse.jdt.internal.corext.dom.ASTFlattener;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.TypeNameMatchCollector;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;

public class TypeContextChecker {
	private static class MethodTypesChecker {

		private static final String METHOD_NAME= "__$$__"; //$NON-NLS-1$

		private final IMethod fMethod;
		private final StubTypeContext fStubTypeContext;
		private final List<ParameterInfo> fParameterInfos;
		private final ReturnTypeInfo fReturnTypeInfo;

		public MethodTypesChecker(IMethod method, StubTypeContext stubTypeContext, List<ParameterInfo> parameterInfos, ReturnTypeInfo returnTypeInfo) {
			fMethod= method;
			fStubTypeContext= stubTypeContext;
			fParameterInfos= parameterInfos;
			fReturnTypeInfo= returnTypeInfo;
		}

		public RefactoringStatus[] checkAndResolveMethodTypes() throws CoreException {
			RefactoringStatus[] results= new MethodTypesSyntaxChecker(fMethod, fParameterInfos, fReturnTypeInfo).checkSyntax();
			for (int i= 0; i < results.length; i++)
				if (results[i] != null && results[i].hasFatalError())
					return results;

			int parameterCount= fParameterInfos.size();
			String[] types= new String[parameterCount + 1];
			for (int i= 0; i < parameterCount; i++)
				types[i]= ParameterInfo.stripEllipsis((fParameterInfos.get(i)).getNewTypeName());
			types[parameterCount]= fReturnTypeInfo.getNewTypeName();
			RefactoringStatus[] semanticsResults= new RefactoringStatus[parameterCount + 1];
			ITypeBinding[] typeBindings= resolveBindings(types, semanticsResults, true);

			boolean needsSecondPass= false;
			for (int i= 0; i < types.length; i++)
				if (typeBindings[i] == null || ! semanticsResults[i].isOK())
					needsSecondPass= true;

			RefactoringStatus[] semanticsResults2= new RefactoringStatus[parameterCount + 1];
			if (needsSecondPass)
				typeBindings= resolveBindings(types, semanticsResults2, false);

			for (int i= 0; i < fParameterInfos.size(); i++) {
				ParameterInfo parameterInfo= fParameterInfos.get(i);
				if (!parameterInfo.isResolve())
					continue;
				if (parameterInfo.getOldTypeBinding() != null && ! parameterInfo.isTypeNameChanged()) {
					parameterInfo.setNewTypeBinding(parameterInfo.getOldTypeBinding());
				} else {
					parameterInfo.setNewTypeBinding(typeBindings[i]);
					if (typeBindings[i] == null || (needsSecondPass && ! semanticsResults2[i].isOK())) {
						if (results[i] == null)
							results[i]= semanticsResults2[i];
						else
							results[i].merge(semanticsResults2[i]);
					}
				}
			}
			fReturnTypeInfo.setNewTypeBinding(typeBindings[fParameterInfos.size()]);
			if (typeBindings[parameterCount] == null || (needsSecondPass && ! semanticsResults2[parameterCount].isOK())) {
				if (results[parameterCount] == null)
					results[parameterCount]= semanticsResults2[parameterCount];
				else
					results[parameterCount].merge(semanticsResults2[parameterCount]);
			}

			return results;
		}

		private ITypeBinding[] resolveBindings(String[] types, RefactoringStatus[] results, boolean firstPass) throws CoreException {
			//TODO: split types into parameterTypes and returnType
			int parameterCount= types.length - 1;
			ITypeBinding[] typeBindings= new ITypeBinding[types.length];

			StringBuffer cuString= new StringBuffer();
			cuString.append(fStubTypeContext.getBeforeString());
			int offsetBeforeMethodName= appendMethodDeclaration(cuString, types, parameterCount);
			cuString.append(fStubTypeContext.getAfterString());

			// need a working copy to tell the parser where to resolve (package visible) types
			ICompilationUnit wc= fMethod.getCompilationUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				CompilationUnit compilationUnit= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(wc, true);
				ASTNode method= NodeFinder.perform(compilationUnit, offsetBeforeMethodName, METHOD_NAME.length()).getParent();
				Type[] typeNodes= new Type[types.length];
				if (method instanceof MethodDeclaration) {
					MethodDeclaration methodDeclaration= (MethodDeclaration) method;
					typeNodes[parameterCount]= methodDeclaration.getReturnType2();
					List<SingleVariableDeclaration> parameters= methodDeclaration.parameters();
					for (int i= 0; i < parameterCount; i++)
						typeNodes[i]= parameters.get(i).getType();

				} else if (method instanceof AnnotationTypeMemberDeclaration) {
					typeNodes[0]= ((AnnotationTypeMemberDeclaration) method).getType();
				}

				for (int i= 0; i < types.length; i++) {
					Type type= typeNodes[i];
					if (type == null) {
						String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_couldNotResolveType, BasicElementLabels.getJavaElementName(types[i]));
						results[i]= RefactoringStatus.createErrorStatus(msg);
						continue;
					}
					results[i]= new RefactoringStatus();
					IProblem[] problems= ASTNodes.getProblems(type, ASTNodes.NODE_ONLY, ASTNodes.PROBLEMS);
					if (problems.length > 0) {
						for (int p= 0; p < problems.length; p++)
							if (isError(problems[p], type))
								results[i].addError(problems[p].getMessage());
					}
					ITypeBinding binding= handleBug84585(type.resolveBinding());
					if (firstPass && (binding == null || binding.isRecovered())) {
						types[i]= qualifyTypes(type, results[i]);
					}
					typeBindings[i]= binding;
				}
				return typeBindings;
			} finally {
				wc.discardWorkingCopy();
			}
		}

		/**
		 * Decides if a problem matters.
		 * @param problem the problem
		 * @param type the current type
		 * @return return if a problem matters.
		 */
		private boolean isError(IProblem problem, Type type) {
			return true;
		}

		private int appendMethodDeclaration(StringBuffer cuString, String[] types, int parameterCount) throws JavaModelException {
			if (Flags.isStatic(fMethod.getFlags()))
				cuString.append("static "); //$NON-NLS-1$

			ITypeParameter[] methodTypeParameters= fMethod.getTypeParameters();
			if (methodTypeParameters.length != 0) {
				cuString.append('<');
				for (int i= 0; i < methodTypeParameters.length; i++) {
					ITypeParameter typeParameter= methodTypeParameters[i];
					if (i > 0)
						cuString.append(',');
					cuString.append(typeParameter.getElementName());
				}
				cuString.append("> "); //$NON-NLS-1$
			}

			cuString.append(types[parameterCount]).append(' ');
			int offsetBeforeMethodName= cuString.length();
			cuString.append(METHOD_NAME).append('(');
			for (int i= 0; i < parameterCount; i++) {
				if (i > 0)
					cuString.append(',');
				cuString.append(types[i]).append(" p").append(i); //$NON-NLS-1$
			}
			cuString.append(");"); //$NON-NLS-1$

			return offsetBeforeMethodName;
		}

		private String qualifyTypes(Type type, final RefactoringStatus result) throws CoreException {
			class NestedException extends RuntimeException {
				private static final long serialVersionUID= 1L;
				NestedException(CoreException e) {
					super(e);
				}
			}
			ASTFlattener flattener= new ASTFlattener() {
				@Override
				public boolean visit(SimpleName node) {
					appendResolved(node.getIdentifier());
					return false;
				}
				@Override
				public boolean visit(QualifiedName node) {
					appendResolved(node.getFullyQualifiedName());
					return false;
				}
				@Override
				public boolean visit(QualifiedType node) {
					appendResolved(ASTNodes.asString(node));
					return false;
				}
				private void appendResolved(String typeName) {
					String resolvedType;
					try {
						resolvedType= resolveType(typeName, result, fMethod.getDeclaringType(), null);
					} catch (CoreException e) {
						throw new NestedException(e);
					}
					this.fBuffer.append(resolvedType);
				}
			};
			try {
				type.accept(flattener);
			} catch (NestedException e) {
				throw ((CoreException) e.getCause());
			}
			return flattener.getResult();
		}

		private static String resolveType(String elementTypeName, RefactoringStatus status, IType declaringType, IProgressMonitor pm) throws CoreException {
			String[][] fqns= declaringType.resolveType(elementTypeName);
			if (fqns != null) {
				if (fqns.length == 1) {
					return JavaModelUtil.concatenateName(fqns[0][0], fqns[0][1]);
				} else if (fqns.length > 1){
					String[] keys= { BasicElementLabels.getJavaElementName(elementTypeName), String.valueOf(fqns.length)};
					String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_ambiguous, keys);
					status.addError(msg);
					return elementTypeName;
				}
			}

			List<TypeNameMatch> typeRefsFound= findTypeInfos(elementTypeName, declaringType, pm);
			if (typeRefsFound.size() == 0){
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_not_unique, BasicElementLabels.getJavaElementName(elementTypeName));
				status.addError(msg);
				return elementTypeName;
			} else if (typeRefsFound.size() == 1){
				TypeNameMatch typeInfo= typeRefsFound.get(0);
				return typeInfo.getFullyQualifiedName();
			} else {
				Assert.isTrue(typeRefsFound.size() > 1);
				String[] keys= {BasicElementLabels.getJavaElementName(elementTypeName), String.valueOf(typeRefsFound.size())};
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_ambiguous, keys);
				status.addError(msg);
				return elementTypeName;
			}
		}

		private static List<TypeNameMatch> findTypeInfos(String typeName, IType contextType, IProgressMonitor pm) throws JavaModelException {
			IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaProject[]{contextType.getJavaProject()}, true);
			IPackageFragment currPackage= contextType.getPackageFragment();
			ArrayList<TypeNameMatch> collectedInfos= new ArrayList<TypeNameMatch>();
			TypeNameMatchCollector requestor= new TypeNameMatchCollector(collectedInfos);
			int matchMode= SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
			new SearchEngine().searchAllTypeNames(null, matchMode, typeName.toCharArray(), matchMode, IJavaSearchConstants.TYPE, scope, requestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, pm);

			List<TypeNameMatch> result= new ArrayList<TypeNameMatch>();
			for (Iterator<TypeNameMatch> iter= collectedInfos.iterator(); iter.hasNext();) {
				TypeNameMatch curr= iter.next();
				IType type= curr.getType();
				if (type != null) {
					boolean visible=true;
					try {
						visible= JavaModelUtil.isVisible(type, currPackage);
					} catch (JavaModelException e) {
						//Assume visibile if not available
					}
					if (visible) {
						result.add(curr);
					}
				}
			}
			return result;
		}

	}

	private static class MethodTypesSyntaxChecker {

		private final IMethod fMethod;
		private final List<ParameterInfo> fParameterInfos;
		private final ReturnTypeInfo fReturnTypeInfo;

		public MethodTypesSyntaxChecker(IMethod method, List<ParameterInfo> parameterInfos, ReturnTypeInfo returnTypeInfo) {
			fMethod= method;
			fParameterInfos= parameterInfos;
			fReturnTypeInfo= returnTypeInfo;
		}

		public RefactoringStatus[] checkSyntax() {
			int parameterCount= fParameterInfos.size();
			RefactoringStatus[] results= new RefactoringStatus[parameterCount + 1];
			results[parameterCount]= checkReturnTypeSyntax();
			for (int i= 0; i < parameterCount; i++) {
				ParameterInfo info= fParameterInfos.get(i);
				if (!info.isDeleted())
					results[i]= checkParameterTypeSyntax(info);
			}
			return results;
		}

		private RefactoringStatus checkParameterTypeSyntax(ParameterInfo info) {
			if (!info.isAdded() && !info.isTypeNameChanged() && !info.isDeleted())
				return null;
			return TypeContextChecker.checkParameterTypeSyntax(info.getNewTypeName(), fMethod.getJavaProject());
		}

		private RefactoringStatus checkReturnTypeSyntax() {
			String newTypeName= fReturnTypeInfo.getNewTypeName();
			if ("".equals(newTypeName.trim())) { //$NON-NLS-1$
				String msg= RefactoringCoreMessages.TypeContextChecker_return_type_not_empty;
				return RefactoringStatus.createFatalErrorStatus(msg);
			}
			List<String> problemsCollector= new ArrayList<String>(0);
			Type parsedType= parseType(newTypeName, fMethod.getJavaProject(), problemsCollector);
			if (parsedType == null) {
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_return_type, BasicElementLabels.getJavaElementName(newTypeName));
				return RefactoringStatus.createFatalErrorStatus(msg);
			}
			if (problemsCollector.size() == 0)
				return null;

			RefactoringStatus result= new RefactoringStatus();
			for (Iterator<String> iter= problemsCollector.iterator(); iter.hasNext();) {
				String[] keys= new String[]{ BasicElementLabels.getJavaElementName(newTypeName), BasicElementLabels.getJavaElementName(iter.next())};
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_return_type_syntax, keys);
				result.addError(msg);
			}
			return result;
		}

		private static boolean isVoidArrayType(Type type){
			if (! type.isArrayType())
				return false;

			ArrayType arrayType= (ArrayType)type;
			if (! arrayType.getComponentType().isPrimitiveType())
				return false;
			PrimitiveType primitiveType= (PrimitiveType)arrayType.getComponentType();
			return (primitiveType.getPrimitiveTypeCode() == PrimitiveType.VOID);
		}

	}

	private static Type parseType(String typeString, IJavaProject javaProject, List<String> problemsCollector) {
		if ("".equals(typeString.trim())) //speed up for a common case //$NON-NLS-1$
			return null;
		if (! typeString.trim().equals(typeString))
			return null;

		StringBuffer cuBuff= new StringBuffer();
		cuBuff.append("interface A{"); //$NON-NLS-1$
		int offset= cuBuff.length();
		cuBuff.append(typeString).append(" m();}"); //$NON-NLS-1$

		ASTParser p= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
		p.setSource(cuBuff.toString().toCharArray());
		p.setProject(javaProject);
		CompilationUnit cu= (CompilationUnit) p.createAST(null);
		Selection selection= Selection.createFromStartLength(offset, typeString.length());
		SelectionAnalyzer analyzer= new SelectionAnalyzer(selection, false);
		cu.accept(analyzer);
		ASTNode selected= analyzer.getFirstSelectedNode();
		if (!(selected instanceof Type))
			return null;
		Type type= (Type)selected;
		if (MethodTypesSyntaxChecker.isVoidArrayType(type))
			return null;
		IProblem[] problems= ASTNodes.getProblems(type, ASTNodes.NODE_ONLY, ASTNodes.PROBLEMS);
		if (problems.length > 0) {
			for (int i= 0; i < problems.length; i++)
				problemsCollector.add(problems[i].getMessage());
		}

		String typeNodeRange= cuBuff.substring(type.getStartPosition(), ASTNodes.getExclusiveEnd(type));
		if (typeString.equals(typeNodeRange))
			return type;
		else
			return null;
	}

	private static ITypeBinding handleBug84585(ITypeBinding typeBinding) {
		if (typeBinding == null)
			return null;
		else if (typeBinding.isGenericType() && ! typeBinding.isRawType() && ! typeBinding.isParameterizedType())
			return null; //see bug 84585
		else
			return typeBinding;
	}

	public static RefactoringStatus[] checkAndResolveMethodTypes(IMethod method, StubTypeContext stubTypeContext, List<ParameterInfo> parameterInfos, ReturnTypeInfo returnTypeInfo) throws CoreException {
		MethodTypesChecker checker= new MethodTypesChecker(method, stubTypeContext, parameterInfos, returnTypeInfo);
		return checker.checkAndResolveMethodTypes();
	}

	public static RefactoringStatus[] checkMethodTypesSyntax(IMethod method, List<ParameterInfo> parameterInfos, ReturnTypeInfo returnTypeInfo) {
		MethodTypesSyntaxChecker checker= new MethodTypesSyntaxChecker(method, parameterInfos, returnTypeInfo);
		return checker.checkSyntax();
	}

	public static RefactoringStatus checkParameterTypeSyntax(String type, IJavaProject project) {
		String newTypeName= ParameterInfo.stripEllipsis(type.trim()).trim();
		String typeLabel= BasicElementLabels.getJavaElementName(type);

		if ("".equals(newTypeName.trim())){ //$NON-NLS-1$
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_parameter_type, typeLabel);
			return RefactoringStatus.createFatalErrorStatus(msg);
		}

		if (ParameterInfo.isVarargs(type) && ! JavaModelUtil.is50OrHigher(project)) {
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_no_vararg_below_50, typeLabel);
			return RefactoringStatus.createFatalErrorStatus(msg);
		}

		List<String> problemsCollector= new ArrayList<String>(0);
		Type parsedType= parseType(newTypeName, project, problemsCollector);
		boolean valid= parsedType != null;
		if (valid && parsedType instanceof PrimitiveType)
			valid= ! PrimitiveType.VOID.equals(((PrimitiveType) parsedType).getPrimitiveTypeCode());
		if (! valid) {
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_type_name, BasicElementLabels.getJavaElementName(newTypeName));
			return RefactoringStatus.createFatalErrorStatus(msg);
		}
		if (problemsCollector.size() == 0)
			return null;

		RefactoringStatus result= new RefactoringStatus();
		for (Iterator<String> iter= problemsCollector.iterator(); iter.hasNext();) {
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_type_syntax,
					new String[]{BasicElementLabels.getJavaElementName(newTypeName), BasicElementLabels.getJavaElementName(iter.next())});
			result.addError(msg);
		}
		return result;
	}

	public static StubTypeContext createStubTypeContext(ICompilationUnit cu, CompilationUnit root, int focalPosition) throws CoreException {
		StringBuffer bufBefore= new StringBuffer();
		StringBuffer bufAfter= new StringBuffer();

		int introEnd= 0;
		PackageDeclaration pack= root.getPackage();
		if (pack != null)
			introEnd= pack.getStartPosition() + pack.getLength();
		List<ImportDeclaration> imports= root.imports();
		if (imports.size() > 0) {
			ImportDeclaration lastImport= imports.get(imports.size() - 1);
			introEnd= lastImport.getStartPosition() + lastImport.getLength();
		}
		bufBefore.append(cu.getBuffer().getText(0, introEnd));

		fillWithTypeStubs(bufBefore, bufAfter, focalPosition, root.types());
		bufBefore.append(' ');
		bufAfter.insert(0, ' ');
		return new StubTypeContext(cu, bufBefore.toString(), bufAfter.toString());
	}

	private static void fillWithTypeStubs(final StringBuffer bufBefore, final StringBuffer bufAfter, final int focalPosition, List<? extends BodyDeclaration> types) {
		StringBuffer buf;
		for (Iterator<? extends BodyDeclaration> iter= types.iterator(); iter.hasNext();) {
			BodyDeclaration bodyDeclaration= iter.next();
			if (! (bodyDeclaration instanceof AbstractTypeDeclaration)) {
				//account for local classes:
				if (! (bodyDeclaration instanceof MethodDeclaration))
					continue;
				int bodyStart= bodyDeclaration.getStartPosition();
				int bodyEnd= bodyDeclaration.getStartPosition() + bodyDeclaration.getLength();
				if (! (bodyStart < focalPosition && focalPosition < bodyEnd))
					continue;
				MethodDeclaration methodDeclaration= (MethodDeclaration) bodyDeclaration;
				buf= bufBefore;
				appendModifiers(buf, methodDeclaration.modifiers());
				appendTypeParameters(buf, methodDeclaration.typeParameters());
				buf.append(" void "); //$NON-NLS-1$
				buf.append(methodDeclaration.getName().getIdentifier());
				buf.append("(){\n"); //$NON-NLS-1$
				Block body= methodDeclaration.getBody();
				body.accept(new HierarchicalASTVisitor() {
					@Override
					public boolean visit(AbstractTypeDeclaration node) {
						fillWithTypeStubs(bufBefore, bufAfter, focalPosition, Collections.singletonList(node));
						return false;
					}
					@Override
					public boolean visit(ClassInstanceCreation node) {
						AnonymousClassDeclaration anonDecl= node.getAnonymousClassDeclaration();
						if (anonDecl == null)
							return false;
						int anonStart= anonDecl.getStartPosition();
						int anonEnd= anonDecl.getStartPosition() + anonDecl.getLength();
						if (! (anonStart < focalPosition && focalPosition < anonEnd))
							return false;
						bufBefore.append(" new "); //$NON-NLS-1$
						bufBefore.append(node.getType().toString());
						bufBefore.append("(){\n"); //$NON-NLS-1$
						fillWithTypeStubs(bufBefore, bufAfter, focalPosition, anonDecl.bodyDeclarations());
						bufAfter.append("};\n"); //$NON-NLS-1$
						return false;
					}
				});
				buf= bufAfter;
				buf.append("}\n"); //$NON-NLS-1$
				continue;
			}

			AbstractTypeDeclaration decl= (AbstractTypeDeclaration) bodyDeclaration;
			buf= decl.getStartPosition() < focalPosition ? bufBefore : bufAfter;
			appendModifiers(buf, decl.modifiers());

			if (decl instanceof TypeDeclaration) {
				TypeDeclaration type= (TypeDeclaration) decl;
				buf.append(type.isInterface() ? "interface " : "class "); //$NON-NLS-1$//$NON-NLS-2$
				buf.append(type.getName().getIdentifier());
				appendTypeParameters(buf, type.typeParameters());
				if (type.getSuperclassType() != null) {
					buf.append(" extends "); //$NON-NLS-1$
					buf.append(ASTNodes.asString(type.getSuperclassType()));
				}
				List<Type> superInterfaces= type.superInterfaceTypes();
				appendSuperInterfaces(buf, superInterfaces);

			} else if (decl instanceof AnnotationTypeDeclaration) {
				AnnotationTypeDeclaration annotation= (AnnotationTypeDeclaration) decl;
				buf.append("@interface "); //$NON-NLS-1$
				buf.append(annotation.getName().getIdentifier());

			} else if (decl instanceof EnumDeclaration) {
				EnumDeclaration enumDecl= (EnumDeclaration) decl;
				buf.append("enum "); //$NON-NLS-1$
				buf.append(enumDecl.getName().getIdentifier());
				List<Type> superInterfaces= enumDecl.superInterfaceTypes();
				appendSuperInterfaces(buf, superInterfaces);
			}

			buf.append("{\n"); //$NON-NLS-1$
			if (decl instanceof EnumDeclaration)
				buf.append(";\n"); //$NON-NLS-1$
			fillWithTypeStubs(bufBefore, bufAfter, focalPosition, decl.bodyDeclarations());
			buf= decl.getStartPosition() + decl.getLength() < focalPosition ? bufBefore : bufAfter;
			buf.append("}\n"); //$NON-NLS-1$
		}
	}

	private static void appendTypeParameters(StringBuffer buf, List<TypeParameter> typeParameters) {
		int typeParametersCount= typeParameters.size();
		if (typeParametersCount > 0) {
			buf.append('<');
			for (int i= 0; i < typeParametersCount; i++) {
				TypeParameter typeParameter= typeParameters.get(i);
				buf.append(ASTNodes.asString(typeParameter));
				if (i < typeParametersCount - 1)
					buf.append(',');
			}
			buf.append('>');
		}
	}

	private static void appendModifiers(StringBuffer buf, List<IExtendedModifier> modifiers) {
		for (Iterator<IExtendedModifier> iterator= modifiers.iterator(); iterator.hasNext();) {
			IExtendedModifier extendedModifier= iterator.next();
			if (extendedModifier.isModifier()) {
				Modifier modifier= (Modifier) extendedModifier;
				buf.append(modifier.getKeyword().toString()).append(' ');
			}
		}
	}

	private static void appendSuperInterfaces(StringBuffer buf, List<Type> superInterfaces) {
		int superInterfaceCount= superInterfaces.size();
		if (superInterfaceCount > 0) {
			buf.append(" implements "); //$NON-NLS-1$
			for (int i= 0; i < superInterfaceCount; i++) {
				Type superInterface= superInterfaces.get(i);
				buf.append(ASTNodes.asString(superInterface));
				if (i < superInterfaceCount - 1)
					buf.append(',');
			}
		}
	}

	public static StubTypeContext createSuperInterfaceStubTypeContext(String typeName, IType enclosingType, IPackageFragment packageFragment) {
		return createSupertypeStubTypeContext(typeName, true, enclosingType, packageFragment);
	}

	public static StubTypeContext createSuperClassStubTypeContext(String typeName, IType enclosingType, IPackageFragment packageFragment) {
		return createSupertypeStubTypeContext(typeName, false, enclosingType, packageFragment);
	}

	private static StubTypeContext createSupertypeStubTypeContext(String typeName, boolean isInterface, IType enclosingType, IPackageFragment packageFragment) {
		StubTypeContext stubTypeContext;
		String prolog= "class " + typeName + (isInterface ? " implements " : " extends "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		String epilog= " {} "; //$NON-NLS-1$
		if (enclosingType != null) {
			try {
				ICompilationUnit cu= enclosingType.getCompilationUnit();
				ISourceRange typeSourceRange= enclosingType.getSourceRange();
				int focalPosition= typeSourceRange.getOffset() + typeSourceRange.getLength() - 1; // before closing brace

				ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
				parser.setSource(cu);
				parser.setFocalPosition(focalPosition);
				CompilationUnit compilationUnit= (CompilationUnit) parser.createAST(null);

				stubTypeContext= createStubTypeContext(cu, compilationUnit, focalPosition);
				stubTypeContext= new StubTypeContext(stubTypeContext.getCuHandle(),
						stubTypeContext.getBeforeString() + prolog,
						epilog + stubTypeContext.getAfterString());
			} catch (CoreException e) {
				JavaPlugin.log(e);
				stubTypeContext= new StubTypeContext(null, null, null);
			}

		} else if (packageFragment != null) {
			ICompilationUnit cu= packageFragment.getCompilationUnit(JavaTypeCompletionProcessor.DUMMY_CU_NAME);
			stubTypeContext= new StubTypeContext(cu, "package " + packageFragment.getElementName() + ";" + prolog, epilog);  //$NON-NLS-1$//$NON-NLS-2$

		} else {
			stubTypeContext= new StubTypeContext(null, null, null);
		}
		return stubTypeContext;
	}

	public static Type parseSuperClass(String superClass) {
		return parseSuperType(superClass, false);
	}

	public static Type parseSuperInterface(String superInterface) {
		return parseSuperType(superInterface, true);
	}

	private static Type parseSuperType(String superType, boolean isInterface) {
		if (! superType.trim().equals(superType)) {
			return null;
		}

		StringBuffer cuBuff= new StringBuffer();
		if (isInterface)
			cuBuff.append("class __X__ implements "); //$NON-NLS-1$
		else
			cuBuff.append("class __X__ extends "); //$NON-NLS-1$
		int offset= cuBuff.length();
		cuBuff.append(superType).append(" {}"); //$NON-NLS-1$

		ASTParser p= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
		p.setSource(cuBuff.toString().toCharArray());
		Map<String, String> options= new HashMap<String, String>();
		JavaModelUtil.setComplianceOptions(options, JavaModelUtil.VERSION_LATEST);
		p.setCompilerOptions(options);
		CompilationUnit cu= (CompilationUnit) p.createAST(null);
		ASTNode selected= NodeFinder.perform(cu, offset, superType.length());
		if (selected instanceof Name)
			selected= selected.getParent();
		if (selected.getStartPosition() != offset
				|| selected.getLength() != superType.length()
				|| ! (selected instanceof Type)
				|| selected instanceof PrimitiveType) {
			return null;
		}
		Type type= (Type) selected;

		String typeNodeRange= cuBuff.substring(type.getStartPosition(), ASTNodes.getExclusiveEnd(type));
		if (! superType.equals(typeNodeRange)){
			return null;
		}
		return type;
	}

	public static ITypeBinding resolveSuperClass(String superclass, IType typeHandle, StubTypeContext superClassContext) {
		StringBuffer cuString= new StringBuffer();
		cuString.append(superClassContext.getBeforeString());
		cuString.append(superclass);
		cuString.append(superClassContext.getAfterString());

		try {
			ICompilationUnit wc= typeHandle.getCompilationUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				CompilationUnit compilationUnit= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(wc, true);
				ASTNode type= NodeFinder.perform(compilationUnit, superClassContext.getBeforeString().length(), superclass.length());
				if (type instanceof Type) {
					return handleBug84585(((Type) type).resolveBinding());
				} else if (type instanceof Name) {
					ASTNode parent= type.getParent();
					if (parent instanceof Type)
						return handleBug84585(((Type) parent).resolveBinding());
				}
				throw new IllegalStateException();
			} finally {
				wc.discardWorkingCopy();
			}
		} catch (JavaModelException e) {
			return null;
		}
	}

	public static ITypeBinding[] resolveSuperInterfaces(String[] interfaces, IType typeHandle, StubTypeContext superInterfaceContext) {
		ITypeBinding[] result= new ITypeBinding[interfaces.length];

		int[] interfaceOffsets= new int[interfaces.length];
		StringBuffer cuString= new StringBuffer();
		cuString.append(superInterfaceContext.getBeforeString());
		int last= interfaces.length - 1;
		for (int i= 0; i <= last; i++) {
			interfaceOffsets[i]= cuString.length();
			cuString.append(interfaces[i]);
			if (i != last)
				cuString.append(", "); //$NON-NLS-1$
		}
		cuString.append(superInterfaceContext.getAfterString());

		try {
			ICompilationUnit wc= typeHandle.getCompilationUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				CompilationUnit compilationUnit= new RefactoringASTParser(ASTProvider.SHARED_AST_LEVEL).parse(wc, true);
				for (int i= 0; i <= last; i++) {
					ASTNode type= NodeFinder.perform(compilationUnit, interfaceOffsets[i], interfaces[i].length());
					if (type instanceof Type) {
						result[i]= handleBug84585(((Type) type).resolveBinding());
					} else if (type instanceof Name) {
						ASTNode parent= type.getParent();
						if (parent instanceof Type) {
							result[i]= handleBug84585(((Type) parent).resolveBinding());
						} else {
							throw new IllegalStateException();
						}
					} else {
						throw new IllegalStateException();
					}
				}
			} finally {
				wc.discardWorkingCopy();
			}
		} catch (JavaModelException e) {
			// won't happen
		}
		return result;
	}
}
