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

/**
 * This is the public entry point to resolve type hierarchies.
 *
 * When requesting additional types from the name environment, the resolver
 * accepts all forms (binary, source & compilation unit) for additional types.
 *
 * Side notes: Binary types already know their resolved supertypes so this
 * only makes sense for source types. Even though the compiler finds all binary
 * types to complete the hierarchy of a given source type, is there any reason
 * why the requestor should be informed that binary type X subclasses Y &
 * implements I & J?
 */

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IGenericType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.*;
import org.eclipse.jdt.internal.core.Member;
import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
import org.eclipse.jdt.internal.core.util.HandleFactory;

public class HierarchyResolver implements ITypeRequestor {
	
	/*
	 * A wrapper around the simple name of a type that is missing.
	 */
	public class MissingType implements IGenericType {
		public String simpleName;
		
		public MissingType(String simpleName) {
			this.simpleName = simpleName;
		}
	
		/**
		 * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
		 */
		public char[] getFileName() {
			return null;
		}
		
		/**
		 * @see IGenericType#getModifiers()
		 */
		public int getModifiers() {
			return 0;
		}
	
		/**
		 * @see IGenericType#isBinaryType()
		 */
		public boolean isBinaryType() {
			return false;
		}
	
		/**
		 * @see org.eclipse.jdt.internal.compiler.env.IGenericType#getKind()
		 */
		public int getKind() {
			return 0;
		}
		
		public String toString() {
			return "Missing type: " + this.simpleName; //$NON-NLS-1$
		}
	
	}
	private ReferenceBinding focusType;
	private boolean superTypesOnly;
	private boolean hasMissingSuperClass;
	LookupEnvironment lookupEnvironment;
	private CompilerOptions options;
	HierarchyBuilder requestor;
	private ReferenceBinding[] typeBindings;

	private int typeIndex;
	private IGenericType[] typeModels;
	
public HierarchyResolver(INameEnvironment nameEnvironment, Map settings, HierarchyBuilder requestor, IProblemFactory problemFactory) {
	// create a problem handler with the 'exit after all problems' handling policy
	this.options = new CompilerOptions(settings);
	IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
	ProblemReporter problemReporter = new ProblemReporter(policy, this.options, problemFactory);

	this.setEnvironment(
		new LookupEnvironment(this, this.options, problemReporter, nameEnvironment),
		requestor);
}
public HierarchyResolver(LookupEnvironment lookupEnvironment, HierarchyBuilder requestor) {
	this.setEnvironment(lookupEnvironment, requestor);
}

/**
 * Add an additional binary type
 * @param binaryType
 * @param packageBinding
 */
public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
	BinaryTypeBinding typeBinding = this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
	try {
		this.remember(binaryType, typeBinding);
	} catch (AbortCompilation e) {
		// ignore
	}
}

/**
 * Add an additional compilation unit.
 * @param sourceUnit
 */
public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
	//System.out.println("Cannot accept compilation units inside the HierarchyResolver.");
	this.lookupEnvironment.problemReporter.abortDueToInternalError(
		new StringBuffer(Util.bind("accept.cannot")) //$NON-NLS-1$
			.append(sourceUnit.getFileName())
			.toString());
}

/**
 * Add additional source types
 * @param sourceTypes
 * @param packageBinding
 */
public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
	// find most enclosing type first (needed when explicit askForType(...) is done 
	// with a member type (e.g. p.A$B))
	ISourceType sourceType = sourceTypes[0];
	while (sourceType.getEnclosingType() != null)
		sourceType = sourceType.getEnclosingType();
	
	// build corresponding compilation unit
	CompilationResult result = new CompilationResult(sourceType.getFileName(), 1, 1, this.options.maxProblemsPerUnit);
	CompilationUnitDeclaration unit =
		SourceTypeConverter.buildCompilationUnit(
			new ISourceType[] {sourceType}, // ignore secondary types, to improve laziness
			SourceTypeConverter.MEMBER_TYPE, // need member types
			// no need for field initialization
			this.lookupEnvironment.problemReporter, 
			result);
		
	// build bindings
	if (unit != null) {
		try {
			this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
			
			org.eclipse.jdt.core.ICompilationUnit cu = ((SourceTypeElementInfo)sourceType).getHandle().getCompilationUnit();
			rememberAllTypes(unit, cu, false);

			this.lookupEnvironment.completeTypeBindings(unit, true/*build constructor only*/);
		} catch (AbortCompilation e) {
			// missing 'java.lang' package: ignore
		}
	}
}
/*
 * Find the super class of the given type in the cache.
 * Returns a MissingType if the class is not found,
 * or null if type has no super class.
 */
private IGenericType findSuperClass(IGenericType type, ReferenceBinding typeBinding) {
	ReferenceBinding superBinding = typeBinding.superclass();
	if (superBinding != null) {
		superBinding = (ReferenceBinding) superBinding.erasure();
		if (superBinding.id == TypeIds.T_JavaLangObject && typeBinding.isHierarchyInconsistent()) {
			char[] superclassName;
			char separator;
			if (type instanceof IBinaryType) {
				superclassName = ((IBinaryType)type).getSuperclassName();
				separator = '/';
			} else if (type instanceof ISourceType) {
				superclassName = ((ISourceType)type).getSuperclassName();
				separator = '.';
			} else if (type instanceof HierarchyType) {
				superclassName = ((HierarchyType)type).superclassName;
				separator = '.';
			} else {
				return null;
			}
			
			if (superclassName != null) { // check whether subclass of Object due to broken hierarchy (as opposed to explicitly extending it)
				int lastSeparator = CharOperation.lastIndexOf(separator, superclassName);
				char[] simpleName = lastSeparator == -1 ? superclassName : CharOperation.subarray(superclassName, lastSeparator+1, superclassName.length);
				if (!CharOperation.equals(simpleName, TypeConstants.OBJECT)) {
					this.hasMissingSuperClass = true;
					return new MissingType(new String(simpleName));
				}
			}
		}
		for (int t = this.typeIndex; t >= 0; t--) {
			if (this.typeBindings[t] == superBinding) {
				return this.typeModels[t];
			}
		}
	} 
	return null;
}
/*
 * Find the super interfaces of the given type in the cache.
 * Returns a MissingType if the interface is not found.
 */
private IGenericType[] findSuperInterfaces(IGenericType type, ReferenceBinding typeBinding) {
	char[][] superInterfaceNames;
	char separator;
	if (type instanceof IBinaryType) {
		superInterfaceNames = ((IBinaryType)type).getInterfaceNames();
		separator = '/';
	} else if (type instanceof ISourceType) {
		ISourceType sourceType = (ISourceType)type;
		if (sourceType.getName().length == 0) { // if anonymous type
			if (typeBinding.superInterfaces() != null && typeBinding.superInterfaces().length > 0) {
				superInterfaceNames = new char[][] {sourceType.getSuperclassName()};
			} else {
				superInterfaceNames = sourceType.getInterfaceNames();
			}
		} else {
			if (sourceType.getKind() == IGenericType.ANNOTATION_TYPE_DECL)
				superInterfaceNames = new char[][] {TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION};
			else
				superInterfaceNames = sourceType.getInterfaceNames();
		}
		separator = '.';
	} else if (type instanceof HierarchyType) {
		HierarchyType hierarchyType = (HierarchyType)type;
		if (hierarchyType.name.length == 0) { // if anonymous type
			if (typeBinding.superInterfaces() != null && typeBinding.superInterfaces().length > 0) {
				superInterfaceNames = new char[][] {hierarchyType.superclassName};
			} else {
				superInterfaceNames = hierarchyType.superInterfaceNames;
			}
		} else {
			superInterfaceNames = hierarchyType.superInterfaceNames;
		}
		separator = '.';
	} else{
		return null;
	}
	
	ReferenceBinding[] interfaceBindings = typeBinding.superInterfaces();
	int bindingIndex = 0;
	int bindingLength = interfaceBindings == null ? 0 : interfaceBindings.length;
	int length = superInterfaceNames == null ? 0 : superInterfaceNames.length;
	IGenericType[] superinterfaces = new IGenericType[length];
	next : for (int i = 0; i < length; i++) {
		char[] superInterfaceName = superInterfaceNames[i];
		int lastSeparator = CharOperation.lastIndexOf(separator, superInterfaceName);
		int start = lastSeparator + 1; 
		int end = superInterfaceName.length;
		
		// case of binary inner type -> take the last part
		int lastDollar = CharOperation.lastIndexOf('$', superInterfaceName, start);
		if (lastDollar != -1) start = lastDollar + 1;
		
		// case of a parameterized type -> take the first part
		int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, superInterfaceName, start);
		if (genericStart != -1) end = genericStart;
		
		char[] simpleName = CharOperation.subarray(superInterfaceName, start, end);
		
		if (bindingIndex < bindingLength) {
			ReferenceBinding interfaceBinding = (ReferenceBinding) interfaceBindings[bindingIndex].erasure();

			// ensure that the binding corresponds to the interface defined by the user
			if (CharOperation.equals(simpleName, interfaceBinding.sourceName)) {
				bindingIndex++;
				for (int t = this.typeIndex; t >= 0; t--) {
					if (this.typeBindings[t] == interfaceBinding) {
						superinterfaces[i] = this.typeModels[t];
						continue next;
					}
				}
			}
		}
		superinterfaces[i] = new MissingType(new String(simpleName));
	}
	return superinterfaces;
}
private void remember(IGenericType suppliedType, ReferenceBinding typeBinding) {
	if (typeBinding == null) return;
	
	if (++this.typeIndex == this.typeModels.length) {
		System.arraycopy(this.typeModels, 0, this.typeModels = new IGenericType[this.typeIndex * 2], 0, this.typeIndex);
		System.arraycopy(this.typeBindings, 0, this.typeBindings = new ReferenceBinding[this.typeIndex * 2], 0, this.typeIndex);
	}
	this.typeModels[this.typeIndex] = suppliedType;
	this.typeBindings[this.typeIndex] = typeBinding;
}
private void remember(IType type, ReferenceBinding typeBinding) {
	if (((CompilationUnit)type.getCompilationUnit()).isOpen()) {
		try {
			IGenericType genericType = (IGenericType)((JavaElement)type).getElementInfo();
			remember(genericType, typeBinding);
		} catch (JavaModelException e) {
			// cannot happen since element is open
			return;
		}
	} else {
		if (typeBinding == null) return;
		
		TypeDeclaration typeDeclaration = ((SourceTypeBinding)typeBinding).scope.referenceType();
	
		// simple super class name
		char[] superclassName = null;
		TypeReference superclass;
		if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
			superclass = typeDeclaration.allocation.type;
		} else {
			superclass = typeDeclaration.superclass;
		}
		if (superclass != null) {
			char[][] typeName = superclass.getTypeName();
			superclassName = typeName == null ? null : typeName[typeName.length-1];
		}
		
		// simple super interface names
		char[][] superInterfaceNames = null;
		TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
		if (superInterfaces != null) {
			int length = superInterfaces.length;
			superInterfaceNames = new char[length][];
			for (int i = 0; i < length; i++) {
				TypeReference superInterface = superInterfaces[i];
				char[][] typeName = superInterface.getTypeName();
				superInterfaceNames[i] = typeName[typeName.length-1];
			}
		}
	
		HierarchyType hierarchyType = new HierarchyType(
			type, 
			typeDeclaration.kind(),
			typeDeclaration.name,
			typeDeclaration.binding.modifiers,
			superclassName,
			superInterfaceNames);
		remember(hierarchyType, typeDeclaration.binding);
	}

}
/*
 * Remembers all type bindings defined in the given parsed unit, adding local/anonymous types if specified.
 */
private void rememberAllTypes(CompilationUnitDeclaration parsedUnit, org.eclipse.jdt.core.ICompilationUnit cu, boolean includeLocalTypes) {
	TypeDeclaration[] types = parsedUnit.types;
	if (types != null) {
		for (int i = 0, length = types.length; i < length; i++) {
			TypeDeclaration type = types[i];
			rememberWithMemberTypes(type, cu.getType(new String(type.name)));
		}
	}
	if (includeLocalTypes && parsedUnit.localTypes != null) {
		HandleFactory factory = new HandleFactory();
		HashSet existingElements = new HashSet(parsedUnit.localTypeCount);
		HashMap knownScopes = new HashMap(parsedUnit.localTypeCount);
		for (int i = 0; i < parsedUnit.localTypeCount; i++) {
			LocalTypeBinding localType = parsedUnit.localTypes[i];
			ClassScope classScope = localType.scope;
			TypeDeclaration typeDecl = classScope.referenceType();
			IType typeHandle = (IType)factory.createElement(classScope, cu, existingElements, knownScopes);
			rememberWithMemberTypes(typeDecl, typeHandle);
		}
	}
}
private void rememberWithMemberTypes(TypeDeclaration typeDecl, IType typeHandle) {
	remember(typeHandle, typeDecl.binding);
	
	TypeDeclaration[] memberTypes = typeDecl.memberTypes;
	if (memberTypes != null) {
		for (int i = 0, length = memberTypes.length; i < length; i++) {
			TypeDeclaration memberType = memberTypes[i];
			rememberWithMemberTypes(memberType, typeHandle.getType(new String(memberType.name)));
		}
	}
}
/*
 * Reports the hierarchy from the remembered bindings.
 * Note that 'binaryTypeBinding' is null if focus type is a source type.
 */
private void reportHierarchy(IType focus, CompilationUnitDeclaration parsedUnit, ReferenceBinding binaryTypeBinding) {
	
	// set focus type binding
	if (focus != null) {
		if (binaryTypeBinding != null) {
			// binary type
			this.focusType = binaryTypeBinding;
		} else {
			// source type
			Member declaringMember = ((Member)focus).getOuterMostLocalContext();
			if (declaringMember == null) {
				// top level or member type
				char[] fullyQualifiedName = focus.getFullyQualifiedName().toCharArray();
				setFocusType(CharOperation.splitOn('.', fullyQualifiedName));
			} else {
				// anonymous or local type
				if (parsedUnit != null) {
					TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(focus);
					if (typeDecl != null) {
						this.focusType = typeDecl.binding;
					}
				} 
			}
		}
	}
	
	int objectIndex = -1;
	for (int current = this.typeIndex; current >= 0; current--) {
		ReferenceBinding typeBinding = this.typeBindings[current];

		// java.lang.Object treated at the end
		if (typeBinding.id == TypeIds.T_JavaLangObject) {
			objectIndex = current;
			continue;
		}

		IGenericType suppliedType = this.typeModels[current];

		if (!subOrSuperOfFocus(typeBinding)) {
			continue; // ignore types outside of hierarchy
		}

		IGenericType superclass;
		if (typeBinding.isInterface()){ // do not connect interfaces to Object
			superclass = null;
		} else {
			superclass = findSuperClass(suppliedType, typeBinding);
		}
		IGenericType[] superinterfaces = findSuperInterfaces(suppliedType, typeBinding);
		
		this.requestor.connect(suppliedType, superclass, superinterfaces);
	}
	// add java.lang.Object only if the super class is not missing
	if (!this.hasMissingSuperClass && objectIndex > -1) {
		this.requestor.connect(this.typeModels[objectIndex], null, null);
	}
}
private void reset(){
	this.lookupEnvironment.reset();

	this.focusType = null;
	this.superTypesOnly = false;
	this.typeIndex = -1;
	this.typeModels = new IGenericType[5];
	this.typeBindings = new ReferenceBinding[5];
}

/**
 * Resolve the supertypes for the supplied source type.
 * Inform the requestor of the resolved supertypes using:
 *    connect(ISourceType suppliedType, IGenericType superclass, IGenericType[] superinterfaces)
 * @param suppliedType
 */
public void resolve(IGenericType suppliedType) {
	try {
		if (suppliedType.isBinaryType()) {
			BinaryTypeBinding binaryTypeBinding = this.lookupEnvironment.cacheBinaryType((IBinaryType) suppliedType, null /*no access restriction*/);
			remember(suppliedType, binaryTypeBinding);
			// We still need to add superclasses and superinterfaces bindings (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53095)
			int startIndex = this.typeIndex;
			for (int i = startIndex; i <= this.typeIndex; i++) {
				IGenericType igType = this.typeModels[i];
				if (igType != null && igType.isBinaryType()) {
					// fault in its hierarchy...
					try {
						ReferenceBinding typeBinding = this.typeBindings[i];
						typeBinding.superclass();
						typeBinding.superInterfaces();
					} catch (AbortCompilation e) {
						// classpath problem for this type: ignore
					}
				}
			}		
			this.superTypesOnly = true;
			reportHierarchy(this.requestor.getType(), null, binaryTypeBinding);
		} else {
			org.eclipse.jdt.core.ICompilationUnit cu = ((SourceTypeElementInfo)suppliedType).getHandle().getCompilationUnit();
			HashSet localTypes = new HashSet();
			localTypes.add(cu.getPath().toString());
			this.superTypesOnly = true;
			resolve(new Openable[] {(Openable)cu}, localTypes, null);
		}
	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
	} finally {
		reset();
	}
}

/**
 * Resolve the supertypes for the types contained in the given openables (ICompilationUnits and/or IClassFiles).
 * Inform the requestor of the resolved supertypes for each
 * supplied source type using:
 *    connect(ISourceType suppliedType, IGenericType superclass, IGenericType[] superinterfaces)
 *
 * Also inform the requestor of the supertypes of each
 * additional requested super type which is also a source type
 * instead of a binary type.
 * @param openables
 * @param localTypes
 * @param monitor
 */
public void resolve(Openable[] openables, HashSet localTypes, IProgressMonitor monitor) {
	try {
		int openablesLength = openables.length;
		CompilationUnitDeclaration[] parsedUnits = new CompilationUnitDeclaration[openablesLength];
		boolean[] hasLocalType = new boolean[openablesLength];
		org.eclipse.jdt.core.ICompilationUnit[] cus = new org.eclipse.jdt.core.ICompilationUnit[openablesLength];
		int unitsIndex = 0;
		
		CompilationUnitDeclaration focusUnit = null;
		ReferenceBinding focusBinaryBinding = null;
		IType focus = this.requestor.getType();
		Openable focusOpenable = null;
		if (focus != null) {
			if (focus.isBinary()) {
				focusOpenable = (Openable)focus.getClassFile();
			} else {
				focusOpenable = (Openable)focus.getCompilationUnit();
			}
		}
		
		// build type bindings
		Parser parser = new Parser(this.lookupEnvironment.problemReporter, true);
		for (int i = 0; i < openablesLength; i++) {
			Openable openable = openables[i];
			if (openable instanceof org.eclipse.jdt.core.ICompilationUnit) {
				org.eclipse.jdt.core.ICompilationUnit cu = (org.eclipse.jdt.core.ICompilationUnit)openable;

				// contains a potential subtype as a local or anonymous type?
				boolean containsLocalType = false;
				if (localTypes == null) { // case of hierarchy on region
					containsLocalType = true;
				} else {
					IPath path = cu.getPath();
					containsLocalType = localTypes.contains(path.toString());
				}
				
				// build parsed unit
				CompilationUnitDeclaration parsedUnit = null;
				if (cu.isOpen()) {
					// create parsed unit from source element infos
					CompilationResult result = new CompilationResult(((ICompilationUnit)cu).getFileName(), i, openablesLength, this.options.maxProblemsPerUnit);
					SourceTypeElementInfo[] typeInfos = null;
					try {
						IType[] topLevelTypes = cu.getTypes();
						int topLevelLength = topLevelTypes.length;
						if (topLevelLength == 0) continue; // empty cu: no need to parse (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=65677)
						typeInfos = new SourceTypeElementInfo[topLevelLength];
						for (int j = 0; j < topLevelLength; j++) {
							IType topLevelType = topLevelTypes[j];
							typeInfos[j] = (SourceTypeElementInfo)((JavaElement)topLevelType).getElementInfo();
						}
					} catch (JavaModelException e) {
						// types/cu exist since cu is opened
					}
					int flags = !containsLocalType 
						? SourceTypeConverter.MEMBER_TYPE 
						: SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE | SourceTypeConverter.LOCAL_TYPE;
					parsedUnit = 
						SourceTypeConverter.buildCompilationUnit(
							typeInfos, 
							flags,
							this.lookupEnvironment.problemReporter, 
							result);
					if (containsLocalType) 	parsedUnit.bits |= ASTNode.HasAllMethodBodies;
				} else {
					// create parsed unit from file
					IResource file = cu.getResource();
					String osPath = file.getLocation().toOSString();
					ICompilationUnit sourceUnit = this.requestor.createCompilationUnitFromPath(openable, osPath);
					
					CompilationResult unitResult = new CompilationResult(sourceUnit, i, openablesLength, this.options.maxProblemsPerUnit); 
					parsedUnit = parser.dietParse(sourceUnit, unitResult);
				}

				if (parsedUnit != null) {
					hasLocalType[unitsIndex] = containsLocalType;
					cus[unitsIndex] = cu;
					parsedUnits[unitsIndex++] = parsedUnit;
					try {
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
						if (openable.equals(focusOpenable)) {
							focusUnit = parsedUnit;
						}
					} catch (AbortCompilation e) {
						// classpath problem for this type: ignore
					}
				}
			} else {
				// cache binary type binding
				ClassFile classFile = (ClassFile)openable;
				IBinaryType binaryType = null;
				if (classFile.isOpen()) {
					// create binary type from info
					IType type = classFile.getType();
					try {
						binaryType = (IBinaryType)((JavaElement)type).getElementInfo();
					} catch (JavaModelException e) {
						// type exists since class file is opened
					}
				} else {
					// create binary type from file
					if (classFile.getPackageFragmentRoot().isArchive()) {
						binaryType = this.requestor.createInfoFromClassFileInJar(classFile);
					} else {
						IResource file = classFile.getResource();
						String osPath = file.getLocation().toOSString();
						binaryType = this.requestor.createInfoFromClassFile(classFile, osPath);
					}
				}
				if (binaryType != null) {
					try {
						BinaryTypeBinding binaryTypeBinding = this.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
						remember(binaryType, binaryTypeBinding);
						if (openable.equals(focusOpenable)) {
							focusBinaryBinding = binaryTypeBinding;
						}
					} catch (AbortCompilation e) {
						// classpath problem for this type: ignore
					}
				}
			}
		}
		
		for (int i = 0; i <= this.typeIndex; i++) {
			IGenericType suppliedType = this.typeModels[i];
			if (suppliedType != null && suppliedType.isBinaryType()) {
				// fault in its hierarchy...
				try {
					ReferenceBinding typeBinding = this.typeBindings[i];
					typeBinding.superclass();
					typeBinding.superInterfaces();
				} catch (AbortCompilation e) {
					// classpath problem for this type: ignore
				}
			}
		}		
		
		// complete type bindings (ie. connect super types)
		for (int i = 0; i < unitsIndex; i++) {
			CompilationUnitDeclaration parsedUnit = parsedUnits[i];
			if (parsedUnit != null) {
				try {
					boolean containsLocalType = hasLocalType[i];
					if (containsLocalType) { // NB: no-op if method bodies have been already parsed
						parser.getMethodBodies(parsedUnit);
					}
					this.lookupEnvironment.completeTypeBindings(parsedUnit, true/*build constructor only*/);
				} catch (AbortCompilation e) {
					// classpath problem for this type: don't try to resolve (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49809)
					hasLocalType[i] = false;
				}
			}
			worked(monitor, 1);
		}
		
		// remember type bindings
		for (int i = 0; i < unitsIndex; i++) {
			CompilationUnitDeclaration parsedUnit = parsedUnits[i];
			if (parsedUnit != null) {
				boolean containsLocalType = hasLocalType[i];
				if (containsLocalType) {
					parsedUnit.scope.faultInTypes();
					parsedUnit.resolve();
				}
					
				rememberAllTypes(parsedUnit, cus[i], containsLocalType);
			}
		}
		
		// if no potential subtype was a real subtype of the binary focus type, no need to go further
		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=54043)
		if (focusBinaryBinding == null && focus != null && focus.isBinary()) {
			char[] fullyQualifiedName = focus.getFullyQualifiedName().toCharArray();
			focusBinaryBinding = this.lookupEnvironment.getCachedType(CharOperation.splitOn('.', fullyQualifiedName));
			if (focusBinaryBinding == null) 
				return;
		}

		reportHierarchy(focus, focusUnit, focusBinaryBinding);
		
	} catch (ClassCastException e){ // work-around for 1GF5W1S - can happen in case duplicates are fed to the hierarchy with binaries hiding sources
	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
		if (TypeHierarchy.DEBUG)
			e.printStackTrace();
	} finally {
		reset();
	}
}
private void setEnvironment(LookupEnvironment lookupEnvironment, HierarchyBuilder requestor) {
	this.lookupEnvironment = lookupEnvironment;
	this.requestor = requestor;

	this.typeIndex = -1;
	this.typeModels = new IGenericType[5];
	this.typeBindings = new ReferenceBinding[5];
}

/*
 * Set the focus type (ie. the type that this resolver is computing the hierarch for.
 * Returns the binding of this focus type or null if it could not be found.
 */
public ReferenceBinding setFocusType(char[][] compoundName) {
	if (compoundName == null || this.lookupEnvironment == null) return null;
	this.focusType = this.lookupEnvironment.getCachedType(compoundName);
	if (this.focusType == null) {
		this.focusType = this.lookupEnvironment.askForType(compoundName);
	}
	return this.focusType;
}
public boolean subOrSuperOfFocus(ReferenceBinding typeBinding) {
	if (this.focusType == null) return true; // accept all types (case of hierarchy in a region)
	try {
		if (this.subTypeOfType(this.focusType, typeBinding)) return true;
		if (!this.superTypesOnly && this.subTypeOfType(typeBinding, this.focusType)) return true;
	} catch (AbortCompilation e) {
		// unresolved superclass/superinterface -> ignore
	}
	return false;
}
private boolean subTypeOfType(ReferenceBinding subType, ReferenceBinding typeBinding) {
	if (typeBinding == null || subType == null) return false;
	if (subType == typeBinding) return true;
	ReferenceBinding superclass = subType.superclass();
	if (superclass != null) superclass = (ReferenceBinding) superclass.erasure();
//	if (superclass != null && superclass.id == TypeIds.T_JavaLangObject && subType.isHierarchyInconsistent()) return false;
	if (this.subTypeOfType(superclass, typeBinding)) return true;
	ReferenceBinding[] superInterfaces = subType.superInterfaces();
	if (superInterfaces != null) {
		for (int i = 0, length = superInterfaces.length; i < length; i++) {
			ReferenceBinding superInterface = (ReferenceBinding) superInterfaces[i].erasure();
			if (this.subTypeOfType(superInterface, typeBinding)) return true;
		} 
	}
	return false;
}
protected void worked(IProgressMonitor monitor, int work) {
	if (monitor != null) {
		if (monitor.isCanceled()) {
			throw new OperationCanceledException();
		} else {
			monitor.worked(work);
		}
	}
}
}
