/*******************************************************************************
 * 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.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.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.ElementInfoConverter;
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 IDependent#getFileName()
		 */
		public char[] getFileName() {
			return null;
		}
		
		/*
		 * @see IGenericType#getModifiers()
		 */
		public int getModifiers() {
			return 0;
		}
	
		/*
		 * @see IGenericType#isBinaryType()
		 */
		public boolean isBinaryType() {
			return false;
		}
	
		/*
		 * @see IGenericType#isClass()
		 */
		public boolean isClass() {
			return false;
		}
	
		/*
		 * @see IGenericType#isInterface()
		 */
		public boolean isInterface() {
			return false;
		}
		
		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) {
	BinaryTypeBinding typeBinding = this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding);
	try {
		this.remember(binaryType, typeBinding);
	} catch (AbortCompilation e) {
		// ignore
	}
}

/**
 * Add an additional compilation unit.
 * @param sourceUnit
 */
public void accept(ICompilationUnit sourceUnit) {
	//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) {
	// 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);
			
			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) {
		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 {
			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);
		char[] simpleName = lastSeparator == -1 ? superInterfaceName : CharOperation.subarray(superInterfaceName, lastSeparator+1, superInterfaceName.length);
		
		// case of binary inner type -> take the last part
		int start = CharOperation.lastIndexOf('$', simpleName) + 1;
		if (start != 0) {
			int nameLength = simpleName.length - start;
			System.arraycopy(simpleName, start, simpleName = new char[nameLength], 0, nameLength);
		}
		
		if (bindingIndex < bindingLength) {
			ReferenceBinding interfaceBinding = interfaceBindings[bindingIndex];

			// 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.isInterface(),
			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);
			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;
						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
					}
					if (!containsLocalType) {
						parsedUnit = 
							SourceTypeConverter.buildCompilationUnit(
								typeInfos, 
								SourceTypeConverter.MEMBER_TYPE, // need member types
								// no need for field initialization
								this.lookupEnvironment.problemReporter, 
								result);
					} else {
						parsedUnit =
							ElementInfoConverter.buildCompilationUnit(
								typeInfos, 
								true, // need local types
								this.lookupEnvironment.problemReporter, 
								result);
						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);
						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);
						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
	} 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.
 * @param compoundName
 * @return
 */
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.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++) {
			if (this.subTypeOfType(superInterfaces[i], 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);
		}
	}
}
}
