/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.jsdt.internal.corext.refactoring;

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.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.wst.jsdt.core.Flags;
import org.eclipse.wst.jsdt.core.IFunction;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IPackageFragment;
import org.eclipse.wst.jsdt.core.ISourceRange;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.ITypeParameter;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
import org.eclipse.wst.jsdt.core.compiler.IProblem;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.wst.jsdt.core.dom.ArrayType;
import org.eclipse.wst.jsdt.core.dom.Block;
import org.eclipse.wst.jsdt.core.dom.BodyDeclaration;
import org.eclipse.wst.jsdt.core.dom.ClassInstanceCreation;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.IExtendedModifier;
import org.eclipse.wst.jsdt.core.dom.ITypeBinding;
import org.eclipse.wst.jsdt.core.dom.ImportDeclaration;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.Modifier;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.PackageDeclaration;
import org.eclipse.wst.jsdt.core.dom.PrimitiveType;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.QualifiedType;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.Type;
import org.eclipse.wst.jsdt.core.dom.TypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.TypeParameter;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchScope;
import org.eclipse.wst.jsdt.core.search.SearchEngine;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
import org.eclipse.wst.jsdt.core.search.TypeNameMatch;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTFlattener;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes;
import org.eclipse.wst.jsdt.internal.corext.dom.HierarchicalASTVisitor;
import org.eclipse.wst.jsdt.internal.corext.dom.NodeFinder;
import org.eclipse.wst.jsdt.internal.corext.dom.Selection;
import org.eclipse.wst.jsdt.internal.corext.dom.SelectionAnalyzer;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.RefactoringASTParser;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.RefactoringFileBuffers;
import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.corext.util.TypeNameMatchCollector;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor;

public class TypeContextChecker {

	public interface IProblemVerifier {

		boolean isError(IProblem problem, ASTNode node);

	}

	private static class MethodTypesChecker {

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

		private final IFunction fMethod;
		private final StubTypeContext fStubTypeContext;
		private final List/*<ParameterInfo>*/ fParameterInfos;
		private final ReturnTypeInfo fReturnTypeInfo;

		private final IProblemVerifier fProblemVerifier;

		public MethodTypesChecker(IFunction method, StubTypeContext stubTypeContext, List/*<ParameterInfo>*/ parameterInfos, ReturnTypeInfo returnTypeInfo, IProblemVerifier problemVerifier) {
			fMethod= method;
			fStubTypeContext= stubTypeContext;
			fParameterInfos= parameterInfos;
			fReturnTypeInfo= returnTypeInfo;
			fProblemVerifier= problemVerifier;
		}
		
		public RefactoringStatus[] checkAndResolveMethodTypes() throws CoreException {
			
			/* ECMA3 no variable or return types */
			if(!JavaScriptCore.IS_ECMASCRIPT4) return new RefactoringStatus[0];
			
			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(((ParameterInfo) 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= (ParameterInfo) fParameterInfos.get(i);
				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
			IJavaScriptUnit wc= fMethod.getJavaScriptUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				JavaScriptUnit compilationUnit= new RefactoringASTParser(AST.JLS3).parse(wc, true);
				ASTNode method= NodeFinder.perform(compilationUnit, offsetBeforeMethodName, METHOD_NAME.length()).getParent();
				Type[] typeNodes= new Type[types.length];
				if (method instanceof FunctionDeclaration) {
					FunctionDeclaration methodDeclaration= (FunctionDeclaration) method;
					typeNodes[parameterCount]= methodDeclaration.getReturnType2();
					List/*<SingleVariableDeclaration>*/ parameters= methodDeclaration.parameters();
					for (int i= 0; i < parameterCount; i++)
						typeNodes[i]= ((SingleVariableDeclaration) parameters.get(i)).getType();

				}

				for (int i= 0; i < types.length; i++) {
					Type type= typeNodes[i];
					if (type == null) {
						String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_couldNotResolveType, 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());
					}
					typeBindings[i]= type.resolveBinding();
					typeBindings[i]= handleBug84585(typeBindings[i]);
					if (firstPass && typeBindings[i] == null)
						types[i]= qualifyTypes(type, results[i]);
				}
				return typeBindings;
			} finally {
				wc.discardWorkingCopy();
			}
		}

		private boolean isError(IProblem problem, Type type) {
			if (fProblemVerifier != null)
				return fProblemVerifier.isError(problem, type);
			return true;
		}

		private int appendMethodDeclaration(StringBuffer cuString, String[] types, int parameterCount) throws JavaScriptModelException {
			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() {
				public boolean visit(SimpleName node) {
					appendResolved(node.getIdentifier());
					return false;
				}
				public boolean visit(QualifiedName node) {
					appendResolved(node.getFullyQualifiedName());
					return false;
				}
				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= {elementTypeName, String.valueOf(fqns.length)};
					String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_ambiguous, keys); 
					status.addError(msg);
					return elementTypeName;
				}
			}
			
			List typeRefsFound= findTypeInfos(elementTypeName, declaringType, pm);
			if (typeRefsFound.size() == 0){
				String[] keys= {elementTypeName};
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_not_unique, keys); 
				status.addError(msg);
				return elementTypeName;
			} else if (typeRefsFound.size() == 1){
				TypeNameMatch typeInfo= (TypeNameMatch) typeRefsFound.get(0);
				return typeInfo.getFullyQualifiedName();
			} else {
				Assert.isTrue(typeRefsFound.size() > 1);
				String[] keys= {elementTypeName, String.valueOf(typeRefsFound.size())};
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_ambiguous, keys); 
				status.addError(msg);
				return elementTypeName;
			}
		}

		private static List findTypeInfos(String typeName, IType contextType, IProgressMonitor pm) throws JavaScriptModelException {
			IJavaScriptSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaScriptProject[]{contextType.getJavaScriptProject()}, true);
			IPackageFragment currPackage= contextType.getPackageFragment();
			ArrayList collectedInfos= new ArrayList();
			TypeNameMatchCollector requestor= new TypeNameMatchCollector(collectedInfos);
			int matchMode= SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
			new SearchEngine().searchAllTypeNames(null, matchMode, typeName.toCharArray(), matchMode, IJavaScriptSearchConstants.TYPE, scope, requestor, IJavaScriptSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, pm);
			
			List result= new ArrayList();
			for (Iterator iter= collectedInfos.iterator(); iter.hasNext();) {
				TypeNameMatch curr= (TypeNameMatch) iter.next();
				IType type= curr.getType();
				if (type != null) {
					boolean visible=true;
					try {
						visible= JavaModelUtil.isVisible(type, currPackage);
					} catch (JavaScriptModelException e) {
						//Assume visibile if not available
					}
					if (visible) {
						result.add(curr);
					}
				}
			}
			return result;
		}

	}
	
	private static class MethodTypesSyntaxChecker {
	
		private final IFunction fMethod;
		private final List/*<ParameterInfo>*/ fParameterInfos;
		private final ReturnTypeInfo fReturnTypeInfo;
	
		public MethodTypesSyntaxChecker(IFunction method, List/*<ParameterInfo>*/ parameterInfos, ReturnTypeInfo returnTypeInfo) {
			fMethod= method;
			fParameterInfos= parameterInfos;
			fReturnTypeInfo= returnTypeInfo;
		}
		
		public RefactoringStatus[] checkSyntax() {
			/* No checks for ECMA 3 */
			if(!JavaScriptCore.IS_ECMASCRIPT4) return new RefactoringStatus[0]; 
			int parameterCount= fParameterInfos.size();
			RefactoringStatus[] results= new RefactoringStatus[parameterCount + 1];
			results[parameterCount]= checkReturnTypeSyntax();
			for (int i= 0; i < parameterCount; i++) {
				ParameterInfo info= (ParameterInfo) fParameterInfos.get(i);
				results[i]= checkParameterTypeSyntax(info);
			}
			return results;
		}
		
		private RefactoringStatus checkParameterTypeSyntax(ParameterInfo info) {
			if (! info.isAdded() && ! info.isTypeNameChanged())
				return null;
			return TypeContextChecker.checkParameterTypeSyntax(info.getNewTypeName(), fMethod.getJavaScriptProject());
		}
		
		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 problemsCollector= new ArrayList(0);
			Type parsedType= parseType(newTypeName, fMethod.getJavaScriptProject(), problemsCollector);
			if (parsedType == null) {
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_return_type, new String[]{newTypeName}); 
				return RefactoringStatus.createFatalErrorStatus(msg);
			}
			if (problemsCollector.size() == 0)
				return null;
			
			RefactoringStatus result= new RefactoringStatus();
			for (Iterator iter= problemsCollector.iterator(); iter.hasNext();) {
				String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_return_type_syntax, new String[]{newTypeName, (String) iter.next()}); 
				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, IJavaScriptProject javaProject, List/*<IProblem>*/ 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(AST.JLS3);
		p.setSource(cuBuff.toString().toCharArray());
		p.setProject(javaProject);
		JavaScriptUnit cu= (JavaScriptUnit) 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(IFunction method, StubTypeContext stubTypeContext, List parameterInfos, ReturnTypeInfo returnTypeInfo, IProblemVerifier problemVerifier) throws CoreException {
		MethodTypesChecker checker= new MethodTypesChecker(method, stubTypeContext, parameterInfos, returnTypeInfo, problemVerifier);
		return checker.checkAndResolveMethodTypes();
	}

	public static RefactoringStatus[] checkMethodTypesSyntax(IFunction method, List parameterInfos, ReturnTypeInfo returnTypeInfo) {
		MethodTypesSyntaxChecker checker= new MethodTypesSyntaxChecker(method, parameterInfos, returnTypeInfo);
		return checker.checkSyntax();
	}
	
	public static RefactoringStatus checkParameterTypeSyntax(String type, IJavaScriptProject project) {
		String newTypeName= ParameterInfo.stripEllipsis(type.trim()).trim();
		
		if ("".equals(newTypeName.trim())){ //$NON-NLS-1$
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_parameter_type, new String[]{type}); 
			return RefactoringStatus.createFatalErrorStatus(msg);
		}
		
		if (ParameterInfo.isVarargs(type) && ! JavaModelUtil.is50OrHigher(project)) {
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_no_vararg_below_50, new String[]{type}); 
			return RefactoringStatus.createFatalErrorStatus(msg);
		}
		
		List problemsCollector= new ArrayList(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, new String[]{newTypeName}); 
			return RefactoringStatus.createFatalErrorStatus(msg);
		}
		if (problemsCollector.size() == 0)
			return null;
		
		RefactoringStatus result= new RefactoringStatus();
		for (Iterator iter= problemsCollector.iterator(); iter.hasNext();) {
			String msg= Messages.format(RefactoringCoreMessages.TypeContextChecker_invalid_type_syntax, new String[]{newTypeName, (String) iter.next()}); 
			result.addError(msg);
		}
		return result;
	}
	
	public static StubTypeContext createStubTypeContext(IJavaScriptUnit cu, JavaScriptUnit root, int focalPosition) throws CoreException {
		IDocument document= RefactoringFileBuffers.acquire(cu).getDocument();
		try {
			StringBuffer bufBefore= new StringBuffer();
			StringBuffer bufAfter= new StringBuffer();
			
			int introEnd= 0;
			PackageDeclaration pack= root.getPackage();
			if (pack != null)
				introEnd= pack.getStartPosition() + pack.getLength();
			List imports= root.imports();
			if (imports.size() > 0) {
				ImportDeclaration lastImport= (ImportDeclaration) imports.get(imports.size() - 1);
				introEnd= lastImport.getStartPosition() + lastImport.getLength();
			}
			try {
				bufBefore.append(document.get(0, introEnd));
			} catch (BadLocationException e) {
				throw new RuntimeException(e); // doesn't happen
			}
			
			fillWithTypeStubs(bufBefore, bufAfter, focalPosition, root.types());
			bufBefore.append(' ');
			bufAfter.insert(0, ' ');
			return new StubTypeContext(cu, bufBefore.toString(), bufAfter.toString());
			
		} finally {
			RefactoringFileBuffers.release(cu);
		}
	}

	private static void fillWithTypeStubs(final StringBuffer bufBefore, final StringBuffer bufAfter, final int focalPosition, List/*<? extends BodyDeclaration>*/ types) {
		StringBuffer buf;
		for (Iterator iter= types.iterator(); iter.hasNext();) {
			BodyDeclaration bodyDeclaration= (BodyDeclaration) iter.next();
			if (! (bodyDeclaration instanceof AbstractTypeDeclaration)) {
				//account for local classes:
				if (! (bodyDeclaration instanceof FunctionDeclaration))
					continue;
				int bodyStart= bodyDeclaration.getStartPosition();
				int bodyEnd= bodyDeclaration.getStartPosition() + bodyDeclaration.getLength();
				if (! (bodyStart < focalPosition && focalPosition < bodyEnd))
					continue;
				FunctionDeclaration methodDeclaration= (FunctionDeclaration) 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() {
					public boolean visit(AbstractTypeDeclaration node) {
						fillWithTypeStubs(bufBefore, bufAfter, focalPosition, Collections.singletonList(node));
						return false;
					}
					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.insert(0, "};\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 superInterfaces= type.superInterfaceTypes();
				appendSuperInterfaces(buf, superInterfaces);
				
			}
			
			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 typeParameters) {
		int typeParametersCount= typeParameters.size();
		if (typeParametersCount > 0) {
			buf.append('<');
			for (int i= 0; i < typeParametersCount; i++) {
				TypeParameter typeParameter= (TypeParameter) typeParameters.get(i);
				buf.append(ASTNodes.asString(typeParameter));
				if (i < typeParametersCount - 1)
					buf.append(',');
			}
		}
	}

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

	private static void appendSuperInterfaces(StringBuffer buf, List superInterfaces) {
		int superInterfaceCount= superInterfaces.size();
		if (superInterfaceCount > 0) {
			buf.append(" implements "); //$NON-NLS-1$
			for (int i= 0; i < superInterfaceCount; i++) {
				Type superInterface= (Type) 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 {
				IJavaScriptUnit cu= enclosingType.getJavaScriptUnit();
				ISourceRange typeSourceRange= enclosingType.getSourceRange();
				int focalPosition= typeSourceRange.getOffset() + typeSourceRange.getLength() - 1; // before closing brace
	
				ASTParser parser= ASTParser.newParser(AST.JLS3);
				parser.setSource(cu);
				parser.setFocalPosition(focalPosition);
				JavaScriptUnit compilationUnit= (JavaScriptUnit) parser.createAST(null);
	
				stubTypeContext= createStubTypeContext(cu, compilationUnit, focalPosition);
				stubTypeContext= new StubTypeContext(stubTypeContext.getCuHandle(),
						stubTypeContext.getBeforeString() + prolog,
						epilog + stubTypeContext.getAfterString());
			} catch (CoreException e) {
				JavaScriptPlugin.log(e);
				stubTypeContext= new StubTypeContext(null, null, null);
			}
			
		} else if (packageFragment != null) {
			IJavaScriptUnit cu= packageFragment.getJavaScriptUnit(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(AST.JLS3);
		p.setSource(cuBuff.toString().toCharArray());
		Map options= new HashMap();
		JavaModelUtil.set50CompilanceOptions(options);
		p.setCompilerOptions(options);
		JavaScriptUnit cu= (JavaScriptUnit) 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 {
			IJavaScriptUnit wc= typeHandle.getJavaScriptUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				JavaScriptUnit compilationUnit= new RefactoringASTParser(AST.JLS3).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 (JavaScriptModelException 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 {
			IJavaScriptUnit wc= typeHandle.getJavaScriptUnit().getWorkingCopy(new WorkingCopyOwner() {/*subclass*/}, new NullProgressMonitor());
			try {
				wc.getBuffer().setContents(cuString.toString());
				JavaScriptUnit compilationUnit= new RefactoringASTParser(AST.JLS3).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 (JavaScriptModelException e) {
			// won't happen
		}
		return result;
	}
}
