/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
 *     						Bug 328281 - visibility leaks not detected when analyzing unused field in private class
 *     						Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
 *     						Bug 354536 - compiling package-info.java still depends on the order of compilation units
 *     						Bug 349326 - [1.7] new warning for missing try-with-resources
 *     						Bug 358903 - Filter practically unimportant resource leak warnings
 *							Bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
 *							Bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
 *							Bug 416176 - [1.8][compiler][null] null type annotations cause grief on type variables
 *							Bug 427199 - [1.8][resource] avoid resource leak warnings on Streams that have no resource
 *							Bug 429958 - [1.8][null] evaluate new DefaultLocation attribute of @NonNullByDefault
 *							Bug 434570 - Generic type mismatch for parametrized class annotation attribute with inner class
 *							Bug 444024 - [1.8][compiler][null] Type mismatch error in annotation generics assignment which happens "sometimes"
 *							Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
 *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *                          Bug 415821 - [1.8][compiler] CLASS_EXTENDS target type annotation missing for anonymous classes
 *     het@google.com - Bug 456986 - Bogus error when annotation processor generates annotation type
 *     Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
 *     						Bug 473178
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.CompilationResult.CheckPoint;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression.DecapsulationState;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.RecordComponent;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.IProblemRechecker;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeValueParameter;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.WordValueAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutScope;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.OTClassScope;
import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.RoleModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.copyinheritance.CopyInheritance;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleMigrationImplementor;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.RoleSplitter;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.StandardElementGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.IAlienScopeTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.Protections;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.Sorting;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer;

/**
 * OTDT changes:
 *
 * GENERAL:
 * What: Additional setup:
 * 		 + Super-team linkage (connectSuperTeam() from connectAllSupers())
 * 		 + Base-class linkage (connectBaseclass() from buildFieldsAndMethods())
 *       + build method mappings (buildCallinCallouts() from buildFieldsAndMethods())
 * 	     + setup RoleFileCache for team (from buildType())
 *
 * What: Connect building of local type bindings with Dependencies.
 * Why:  Local types are found late, need to catch up in the translation process
 *
 * What: Do additional setup when linking referenceContext to its binding.
 * How:  Use TypeDeclaration.setBinding() instead of a direct assignment.
 *
 * What: Create OTClassScope for nested teams.
 * Why:  While nested teams are member types (not created by CompilationUnitScope)
 *       they still need a specialized scope.
 *
 * What: Add generated elements (addGenerated{Type,Field,Method}())
 *       These methods create (unresolved) bindings.
 *
 * What: Public entries for connecting generated elements
 * Which: + connectTypeHierarchyForGenerated()
 * 		  + connectSuperclassForGenerated()
 *        + buildFieldsAndMethodsForGenerated()
 *
 * ROLE FILES:
 * What: Add member types also to the enclosing team-package
 *
 * What: Manipulate order of processing for role files.
 * Why:  Establishing STATE_BINDINGS_COMPLETE may trigger introduction of role files.
 *       Compiler.accept will try to complete these which conflicts with the current process.
 * How:  + TypeModel._currentlyProcessedState and TeamModel._blockCatchup
 *         capture the state of processing
 *       + buildFieldsAndMethods() and connectTypeHierarchy() bail out during blockCatchup
 *       + traversing members in buildFieldsAndMethods() and connectMemberTypes()
 *         include newly introduces role files within their loops.
 *
 * VALIDITY:
 * What: Allow interfaces in nested teams.
 *
 * What: Flags/modifiers:
 * 		 + check for role / team modifiers
 *       + accept AccRole and AccSynthetic
 * 		 + accept AccProtected for roles in role files
 * 		   Why: top level types cannot be protected, but role files are not top-level ;-)
 *
 * What: Team.Confined must not have a superclass.
 *
 * What: Team must not extend non-team and vice versa.
 *
 * LOOKUP:
 * What: if findSupertype() failed, consider dropping __OT__
 * Why:  RoleSplitter might have been over-eager.
 * How:  need to roll back: remove problem binding, remove IProblem.
 */
@SuppressWarnings({"rawtypes"})
public class ClassScope extends Scope {

	public TypeDeclaration referenceContext;
	public TypeReference superTypeReference;
	java.util.ArrayList<Object> deferredBoundChecks; // contains TypeReference or Runnable. TODO consider making this a List<Runnable>

	public ClassScope(Scope parent, TypeDeclaration context) {
		super(Scope.CLASS_SCOPE, parent);
		this.referenceContext = context;
		this.deferredBoundChecks = null; // initialized if required
	}

	void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) {
		LocalTypeBinding anonymousType = buildLocalType(enclosingType, enclosingType.fPackage);
		anonymousType.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // tag all anonymous types as used locally
		int inheritedBits = supertype.typeBits; // for anonymous class assume same properties as its super (as a closeable) ...
		// ... unless it overrides close():
		if ((inheritedBits & TypeIds.BitWrapperCloseable) != 0) {
			AbstractMethodDeclaration[] methods = this.referenceContext.methods;
			if (methods != null) {
				for (int i=0; i<methods.length; i++) {
					if (CharOperation.equals(TypeConstants.CLOSE, methods[i].selector) && methods[i].arguments == null) {
						inheritedBits &= TypeIds.InheritableBits;
						break;
					}
				}
			}
		}
		anonymousType.typeBits |= inheritedBits;
		anonymousType.setPermittedTypes(Binding.NO_PERMITTEDTYPES); // JLS 15 JEP 360 Preview - Sec 15.9.5
		if (supertype.isInterface()) {
			anonymousType.setSuperClass(getJavaLangObject());
			anonymousType.setSuperInterfaces(new ReferenceBinding[] { supertype });
			TypeReference typeReference = this.referenceContext.allocation.type;
			if (typeReference != null) {
				this.referenceContext.superInterfaces = new TypeReference[] { typeReference };
				if ((supertype.tagBits & TagBits.HasDirectWildcard) != 0) {
					problemReporter().superTypeCannotUseWildcard(anonymousType, typeReference, supertype);
					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
					anonymousType.setSuperInterfaces(Binding.NO_SUPERINTERFACES);
				}
			}
		} else {
			anonymousType.setSuperClass(supertype);
			anonymousType.setSuperInterfaces(Binding.NO_SUPERINTERFACES);
			checkForEnumSealedPreview(supertype, anonymousType);
			TypeReference typeReference = this.referenceContext.allocation.type;
			if (typeReference != null) { // no check for enum constant body
				this.referenceContext.superclass = typeReference;
				if (supertype.erasure().id == TypeIds.T_JavaLangEnum) {
					problemReporter().cannotExtendEnum(anonymousType, typeReference, supertype);
					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
					anonymousType.setSuperClass(getJavaLangObject());
				} else if (supertype.erasure().id == TypeIds.T_JavaLangRecord) {
					if (!(this.referenceContext.isRecord())) {
						problemReporter().recordCannotExtendRecord(anonymousType, typeReference, supertype);
						anonymousType.tagBits |= TagBits.HierarchyHasProblems;
						anonymousType.setSuperClass(getJavaLangObject());
					}
				} else if (supertype.isFinal()) {
					problemReporter().anonymousClassCannotExtendFinalClass(typeReference, supertype);
					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
					anonymousType.setSuperClass(getJavaLangObject());
				} else if ((supertype.tagBits & TagBits.HasDirectWildcard) != 0) {
					problemReporter().superTypeCannotUseWildcard(anonymousType, typeReference, supertype);
					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
					anonymousType.setSuperClass(getJavaLangObject());
				} else if (supertype.isSealed()) {
					problemReporter().sealedAnonymousClassCannotExtendSealedType(typeReference, supertype);
					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
					anonymousType.setSuperClass(getJavaLangObject());
				}
			}
		}
		connectMemberTypes();
		buildFieldsAndMethods();
//{ObjectTeams: catchup also in OT-specific process (see class comment concerning local types in Dependencies):
	  if (this.referenceContext.isRole()) {
		RoleModel role = this.referenceContext.getRoleModel();
		Dependencies.ensureRoleState(role, ITranslationStates.STATE_FAULT_IN_TYPES-1);
/*orig*/anonymousType.faultInTypesForFieldsAndMethods();
		Dependencies.ensureRoleState(role, ITranslationStates.STATE_METHODS_VERIFIED-1);
	  } else {
// orig:
		anonymousType.faultInTypesForFieldsAndMethods();
// :giro
	  }
// SH}
		anonymousType.verifyMethods(environment().methodVerifier());
	}

	private void checkForEnumSealedPreview(ReferenceBinding supertype, LocalTypeBinding anonymousType) {
		if (compilerOptions().sourceLevel < ClassFileConstants.JDK15
				|| !compilerOptions().enablePreviewFeatures
				|| !supertype.isEnum()
				|| !(supertype instanceof SourceTypeBinding))
			return;

		SourceTypeBinding sourceSuperType = (SourceTypeBinding) supertype;
		ReferenceBinding[] permTypes = sourceSuperType.permittedTypes();
		int sz = permTypes == null ? 0 : permTypes.length;
		if (sz == 0) {
			permTypes = new ReferenceBinding[] {anonymousType};
		} else {
			System.arraycopy(permTypes, 0,
					permTypes = new ReferenceBinding[sz + 1], 0,
					sz);
			permTypes[sz] = anonymousType;
		}
		sourceSuperType.setPermittedTypes(permTypes);
	}

	void buildComponents() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (!sourceType.isRecord()) return;
		if (sourceType.areComponentsInitialized()) return;
		if (this.referenceContext.recordComponents == null) {
			sourceType.setComponents(Binding.NO_COMPONENTS);
			return;
		}
		// count the number of fields vs. initializers
		RecordComponent[] recComps = this.referenceContext.recordComponents;
		int size = recComps.length;
		int count = size;

		// iterate the field declarations to create the bindings, lose all duplicates
		RecordComponentBinding[] componentBindings = new RecordComponentBinding[count];
		HashtableOfObject knownComponentNames = new HashtableOfObject(count);
		count = 0;
		for (int i = 0; i < size; i++) {
			RecordComponent recComp = recComps[i];
			RecordComponentBinding compBinding = new RecordComponentBinding(sourceType, recComp, null,
					recComp.modifiers | ExtraCompilerModifiers.AccUnresolved);
			compBinding.id = count;
			checkAndSetModifiersForComponents(compBinding, recComp);

			if (knownComponentNames.containsKey(recComp.name)) {
				RecordComponentBinding previousBinding = (RecordComponentBinding) knownComponentNames.get(recComp.name);
				if (previousBinding != null) {
					for (int f = 0; f < i; f++) {
						RecordComponent previousComponent = recComps[f];
						if (previousComponent.binding == previousBinding) {
							// flag the duplicate component name error here.
							problemReporter().recordDuplicateComponent(previousComponent);
							break;
						}
					}
				}
				knownComponentNames.put(recComp.name, null); // ensure that the duplicate field is found & removed
				problemReporter().recordDuplicateComponent(recComp);
				recComp.binding = null;
			} else {
				knownComponentNames.put(recComp.name, compBinding);
				// remember that we have seen a component with this name
				componentBindings[count++] = compBinding;
			}
		}
		// remove duplicate components
		if (count != componentBindings.length)
			System.arraycopy(componentBindings, 0, componentBindings = new RecordComponentBinding[count], 0, count);
		sourceType.setComponents(componentBindings);
	}
	private void checkAndSetModifiersForComponents(RecordComponentBinding compBinding, RecordComponent comp) {
		int modifiers = compBinding.modifiers;
		int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
		if (realModifiers  != 0 && comp != null){
			problemReporter().recordComponentsCannotHaveModifiers(comp);
		}
	}

	void buildFields() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (sourceType.areFieldsInitialized()) return;
//{ObjectTeams: prepare for merging value parameters into fields:
		int valueParamCount = valueParamCount(this.referenceContext.typeParameters);
		if (this.referenceContext.fields == null && valueParamCount > 0)
			this.referenceContext.fields = new FieldDeclaration[0];
// SH}
		if (this.referenceContext.fields == null) {
			sourceType.setFields(Binding.NO_FIELDS);
			return;
		}
		// count the number of fields vs. initializers
		FieldDeclaration[] fields = this.referenceContext.fields;
		int size = fields.length;
//{ObjectTeams: value parameters:
/* orig:
		int count = 0;
*/
		int count = valueParamCount;
// SH}
		for (int i = 0; i < size; i++) {
			switch (fields[i].getKind()) {
				case AbstractVariableDeclaration.FIELD:
				case AbstractVariableDeclaration.ENUM_CONSTANT:
					count++;
			}
		}

		// iterate the field declarations to create the bindings, lose all duplicates
		FieldBinding[] fieldBindings = new FieldBinding[count];
		HashtableOfObject knownFieldNames = new HashtableOfObject(count);
//{ObjectTeams: add fields from value parameters
	  if (this.referenceContext.typeParameters != null) {
		TypeValueParameter.resolveValueParameters(this.referenceContext.typeParameters, this, fieldBindings, knownFieldNames);
		count = valueParamCount;
	  } else
// SH}
		count = 0;
		for (int i = 0; i < size; i++) {
			FieldDeclaration field = fields[i];
			if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
				// We used to report an error for initializers declared inside interfaces, but
				// now this error reporting is moved into the parser itself. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=212713
			} else {
				FieldBinding fieldBinding = new FieldBinding(field, null, field.modifiers | ExtraCompilerModifiers.AccUnresolved, sourceType);
				fieldBinding.id = count;
				// field's type will be resolved when needed for top level types
				checkAndSetModifiersForField(fieldBinding, field);

				if (knownFieldNames.containsKey(field.name)) {
					FieldBinding previousBinding = (FieldBinding) knownFieldNames.get(field.name);
					if (previousBinding != null) {
						for (int f = 0; f < i; f++) {
							FieldDeclaration previousField = fields[f];
							if (previousField.binding == previousBinding) {
								problemReporter().duplicateFieldInType(sourceType, previousField);
								break;
							}
						}
					}
					knownFieldNames.put(field.name, null); // ensure that the duplicate field is found & removed
					problemReporter().duplicateFieldInType(sourceType, field);
					field.binding = null;
				} else {
					knownFieldNames.put(field.name, fieldBinding);
					// remember that we have seen a field with this name
					fieldBindings[count++] = fieldBinding;
				}
			}
		}
		// remove duplicate fields
		if (count != fieldBindings.length)
			System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count);
		sourceType.tagBits &= ~(TagBits.AreFieldsSorted|TagBits.AreFieldsComplete); // in case some static imports reached already into this type
		sourceType.setFields(fieldBindings);
	}

//{ObjectTeams: helper for the above
	private int valueParamCount(TypeParameter[] typeParameters) {
		int count = 0;
		if (typeParameters != null)
			for (int i = 0; i < typeParameters.length; i++)
				if (typeParameters[i] instanceof TypeValueParameter)
					count++;

		return count;
	}
// SH}

	void buildFieldsAndMethods() {
//{ObjectTeams: signal proccessing:
		if (!StateHelper.startProcessing(this.referenceContext,
									   ITranslationStates.STATE_LENV_DONE_FIELDS_AND_METHODS,
									   LookupEnvironment.BUILD_FIELDS_AND_METHODS))
			return; // catchup was blocked.
// SH}
		buildComponents();
		buildFields();
		buildMethods();
//{ObjectTeams: build callins and callouts
		buildCallinCallouts();
		// now, as we have field bindings, connect baseclass (which might depend on a field as anchor):
		connectBaseclass();
// Markus Witte}

		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (!sourceType.isPrivate() && sourceType.superclass instanceof SourceTypeBinding && sourceType.superclass.isPrivate())
			((SourceTypeBinding) sourceType.superclass).tagIndirectlyAccessibleMembers();

		if (sourceType.isMemberType() && !sourceType.isLocalType())
			 ((MemberTypeBinding) sourceType).checkSyntheticArgsAndFields();

//{ObjectTeams: similar for value parameters:
		if (this.referenceContext.typeParameters != null) {
			TypeParameter[] typeParameters = this.referenceContext.typeParameters;
			for (int i = 0; i < typeParameters.length; i++) {
				if (typeParameters[i] instanceof TypeValueParameter) {
					TypeValueParameter param = (TypeValueParameter)typeParameters[i];
					sourceType.addSyntheticArgForValParam(param);
				}
			}
			// 2. go: type anchors may refer to value parameters (connected above)
			for (int i = 0; i < typeParameters.length; i++) {
				if (!(typeParameters[i] instanceof TypeValueParameter))
					typeParameters[i].connectTypeAnchors(this);
			}
		}
// SH}
//{ObjectTeams: don't cache member types/length, new role files might be added during the loop:
/* Orig:
		ReferenceBinding[] memberTypes = sourceType.memberTypes;
		for (int i = 0, length = memberTypes.length; i < length; i++)
  :giro */
		for (int i = 0; i < sourceType.memberTypes.length; i++) {
		  ReferenceBinding memberType = sourceType.memberTypes[i];

//addition: roles can be binary! or already compiled along some other path
		  if (   !memberType.isBinaryBinding()
			  && !StateHelper.hasState(memberType, ITranslationStates.STATE_FINAL))
/* orig:
			 ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods();
  :giro */
			((SourceTypeBinding) memberType).scope.buildFieldsAndMethods();
		}
// SH}
	}

	private LocalTypeBinding buildLocalType(SourceTypeBinding enclosingType, PackageBinding packageBinding) {

		this.referenceContext.scope = this;
		this.referenceContext.staticInitializerScope = new MethodScope(this, this.referenceContext, true);
		this.referenceContext.initializerScope = new MethodScope(this, this.referenceContext, false);

		// build the binding or the local type
		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, innermostSwitchCase());
//{ObjectTeams: was assignment; use setter to allow additional setup
	/* @original
		this.referenceContext.binding = localType;
	 */
		this.referenceContext.setBinding(localType);
// SH}
		checkAndSetModifiers();
		buildTypeVariables();

		// Look at member types
		ReferenceBinding[] memberTypeBindings = Binding.NO_MEMBER_TYPES;
		if (this.referenceContext.memberTypes != null) {
			int size = this.referenceContext.memberTypes.length;
			memberTypeBindings = new ReferenceBinding[size];
			int count = 0;
			nextMember : for (int i = 0; i < size; i++) {
				TypeDeclaration memberContext = this.referenceContext.memberTypes[i];
				switch(TypeDeclaration.kind(memberContext.modifiers)) {
					case TypeDeclaration.INTERFACE_DECL :
					case TypeDeclaration.ANNOTATION_TYPE_DECL :
						problemReporter().illegalLocalTypeDeclaration(memberContext);
						continue nextMember;
				}
				ReferenceBinding type = localType;
				// check that the member does not conflict with an enclosing type
				do {
					if (CharOperation.equals(type.sourceName, memberContext.name)) {
						problemReporter().typeCollidesWithEnclosingType(memberContext);
						continue nextMember;
					}
					type = type.enclosingType();
				} while (type != null);
				// check the member type does not conflict with another sibling member type
				for (int j = 0; j < i; j++) {
					if (CharOperation.equals(this.referenceContext.memberTypes[j].name, memberContext.name)) {
						problemReporter().duplicateNestedType(memberContext);
						continue nextMember;
					}
				}
				ClassScope memberScope = new ClassScope(this, this.referenceContext.memberTypes[i]);
				LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, packageBinding);
				memberBinding.setAsMemberType();
				memberTypeBindings[count++] = memberBinding;
			}
			if (count != size)
				System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count);
		}
		localType.setMemberTypes(memberTypeBindings);
		return localType;
	}

	void buildLocalTypeBinding(SourceTypeBinding enclosingType) {

		LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage);
		connectTypeHierarchy();
		connectImplicitPermittedTypes();
		if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
			checkParameterizedTypeBounds();
			checkParameterizedSuperTypeCollisions();
		}
		buildFieldsAndMethods();
//{ObjectTeams: catchup also in OT-specific process (see class comment concerning local types in Dependencies).
	  if (this.referenceContext.isRole()) {
		RoleModel role = this.referenceContext.getRoleModel();
		Dependencies.ensureRoleState(role, ITranslationStates.STATE_FAULT_IN_TYPES-1);
/*orig*/localType.faultInTypesForFieldsAndMethods();
		Dependencies.ensureRoleState(role, ITranslationStates.STATE_METHODS_VERIFIED-1);
	  } else {
// orig:
		localType.faultInTypesForFieldsAndMethods();
// :giro
		}
// SH}

		this.referenceContext.binding.verifyMethods(environment().methodVerifier());
	}

	private void buildMemberTypes(AccessRestriction accessRestriction) {
	    SourceTypeBinding sourceType = this.referenceContext.binding;
		ReferenceBinding[] memberTypeBindings = Binding.NO_MEMBER_TYPES;
		if (this.referenceContext.memberTypes != null) {
			int length = this.referenceContext.memberTypes.length;
			memberTypeBindings = new ReferenceBinding[length];
			int count = 0;
			nextMember : for (int i = 0; i < length; i++) {
				TypeDeclaration memberContext = this.referenceContext.memberTypes[i];
				if (this.environment().root.isProcessingAnnotations && this.environment().isMissingType(memberContext.name)) {
					throw new SourceTypeCollisionException(); // resolved a type ref before APT generated the type
				}
				switch(TypeDeclaration.kind(memberContext.modifiers)) {
					case TypeDeclaration.INTERFACE_DECL :
					case TypeDeclaration.ANNOTATION_TYPE_DECL :
						if (sourceType.isNestedType()
								&& sourceType.isClass() // no need to check for enum, since implicitly static
//{ObjectTeams: check for team (may indeed contain interface):
								&& !sourceType.isTeam()
// SH}
								&& !sourceType.isStatic()) {
							problemReporter().illegalLocalTypeDeclaration(memberContext);
							continue nextMember;
						}
					break;
				}
				ReferenceBinding type = sourceType;
				// check that the member does not conflict with an enclosing type
				do {
					if (CharOperation.equals(type.sourceName, memberContext.name)) {
						problemReporter().typeCollidesWithEnclosingType(memberContext);
//{ObjectTeams: tagging the type should suffice, keep going (otherwise breaks B.1.1-otjld-sh-15)
						break;
/* orig:
						continue nextMember;
  :giro */
// SH}
					}
					type = type.enclosingType();
				} while (type != null);
				// check that the member type does not conflict with another sibling member type
				for (int j = 0; j < i; j++) {
					if (CharOperation.equals(this.referenceContext.memberTypes[j].name, memberContext.name)) {
						problemReporter().duplicateNestedType(memberContext);
						continue nextMember;
					}
				}

//{ObjectTeams: what kind of scope is needed?
/* orig:
				ClassScope memberScope = new ClassScope(this, memberContext);
  :giro */
				ClassScope memberScope = memberContext.isTeam() ? 	// only for teams, no OTClassScope for inline roles.
					OTClassScope.createMemberOTClassScope(this, memberContext) :
					new ClassScope(this, memberContext);
// SH}
				memberTypeBindings[count++] = memberScope.buildType(sourceType, sourceType.fPackage, accessRestriction);
			}
			if (count != length)
				System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count);
		}
		sourceType.setMemberTypes(memberTypeBindings);
	}

	void buildMethods() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (sourceType.areMethodsInitialized()) return;

		boolean isEnum = TypeDeclaration.kind(this.referenceContext.modifiers) == TypeDeclaration.ENUM_DECL;
		if (this.referenceContext.methods == null && !(isEnum || sourceType.isRecord())) {
			this.referenceContext.binding.setMethods(Binding.NO_METHODS);
			return;
		}

		// iterate the method declarations to create the bindings
		AbstractMethodDeclaration[] methods = this.referenceContext.methods;
		int size = methods == null ? 0 : methods.length;
		// look for <clinit> method
		int clinitIndex = -1;
		for (int i = 0; i < size; i++) {
			if (methods[i].isClinit()) {
				clinitIndex = i;
				break;
			}
		}

		int count = isEnum ? 2 : 0; // reserve 2 slots for special enum methods: #values() and #valueOf(String)
		MethodBinding[] methodBindings = new MethodBinding[(clinitIndex == -1 ? size : size - 1) + count];
		// create special methods for enums
		if (isEnum) {
			methodBindings[0] = sourceType.addSyntheticEnumMethod(TypeConstants.VALUES); // add <EnumType>[] values()
			methodBindings[1] = sourceType.addSyntheticEnumMethod(TypeConstants.VALUEOF); // add <EnumType> valueOf()
		}
		// create bindings for source methods
		boolean hasNativeMethods = false;
		if (sourceType.isAbstract()) {
			for (int i = 0; i < size; i++) {
				if (i != clinitIndex) {
//{ObjectTeams: Twisted scope for methods moved from a role to its team:
/* orig:
					MethodScope scope = new MethodScope(this, methods[i], false);
  :giro */
					MethodScope scope = createMethodScope(methods[i]);
// SH}
					MethodBinding methodBinding = scope.createMethod(methods[i]);
					if (methodBinding != null) { // is null if binding could not be created
						methodBindings[count++] = methodBinding;
						hasNativeMethods = hasNativeMethods || methodBinding.isNative();
					}
				}
			}
		} else {
			boolean hasAbstractMethods = false;
			for (int i = 0; i < size; i++) {
				if (i != clinitIndex) {
//{ObjectTeams: Twisted scope for methods moved from a role to its team:
/* orig:
					MethodScope scope = new MethodScope(this, methods[i], false);
  :giro */
					MethodScope scope = createMethodScope(methods[i]);
// SH}
					MethodBinding methodBinding = scope.createMethod(methods[i]);
					if (methodBinding != null) { // is null if binding could not be created
						methodBindings[count++] = methodBinding;
						hasAbstractMethods = hasAbstractMethods || methodBinding.isAbstract();
						hasNativeMethods = hasNativeMethods || methodBinding.isNative();
					}
				}
			}
			if (hasAbstractMethods)
//{ObjectTeams: support rechecking, because callout implementation might remove abstractness:
			{
			  if (sourceType.isDirectRole())
				problemReporter()
					.setRechecker(new IProblemRechecker() {		@Override
					public boolean shouldBeReported(IrritantSet[] foundIrritants) {
						for (MethodBinding methodBinding : ClassScope.this.referenceContext.binding.methods())
							if (methodBinding.isAbstract())
								return true;
						return false; // false alarm
					}})
					.abstractMethodInConcreteClass(sourceType);
			  else
// orig:
				problemReporter().abstractMethodInConcreteClass(sourceType);
// :giro
			}
// SH}
		}
		if (sourceType.isRecord()) {
			assert this.referenceContext.isRecord();
			methodBindings = sourceType.checkAndAddSyntheticRecordMethods(methodBindings, count);
			count = methodBindings.length;
		}
		if (count != methodBindings.length)
			System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[count], 0, count);
		sourceType.tagBits &= ~(TagBits.AreMethodsSorted|TagBits.AreMethodsComplete); // in case some static imports reached already into this type
		sourceType.setMethods(methodBindings);
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=243917, conservatively tag all methods and fields as
		// being in use if there is a native method in the class.
		if (hasNativeMethods) {
			for (int i = 0; i < methodBindings.length; i++) {
				methodBindings[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
			}
			FieldBinding[] fields = sourceType.unResolvedFields(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=301683
			for (int i = 0; i < fields.length; i++) {
				fields[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
			}
		}
		if (isEnum && compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
			// mark return types of values & valueOf as nonnull (needed to wait till after setMethods() to avoid reentrance):
			LookupEnvironment environment = this.environment();
			((SyntheticMethodBinding)methodBindings[0]).markNonNull(environment);
			((SyntheticMethodBinding)methodBindings[1]).markNonNull(environment);
		}
	}

//{ObjectTeams: accessible to sub-class:
	protected
// SH}
	SourceTypeBinding buildType(SourceTypeBinding enclosingType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
		// provide the typeDeclaration with needed scopes
		this.referenceContext.scope = this;
		this.referenceContext.staticInitializerScope = new MethodScope(this, this.referenceContext, true);
		this.referenceContext.initializerScope = new MethodScope(this, this.referenceContext, false);

//{ObjectTeams: ROFI:
		boolean isRoleFile = false;
//SH}

		if (enclosingType == null) {
			char[][] className = CharOperation.arrayConcat(packageBinding.compoundName, this.referenceContext.name);
//{ObjectTeams: was assignment; use setter to allow additional setup:
	/* @original
			this.referenceContext.binding = new SourceTypeBinding(className, packageBinding, this);
	 */
			this.referenceContext.setBinding(new SourceTypeBinding(className, packageBinding, this));
// SH}
		} else {
//{ObjectTeams: ROFI:
			isRoleFile = enclosingType.teamPackage != null;
// SH}
			char[][] className = CharOperation.deepCopy(enclosingType.compoundName);
			className[className.length - 1] =
				CharOperation.concat(className[className.length - 1], this.referenceContext.name, '$');
			if (packageBinding.hasType0Any(className[className.length - 1])) {
				// report the error against the parent - its still safe to answer the member type
//{ObjectTeams: role files are handled below:
			  if (!isRoleFile)
//SH}
				this.parent.problemReporter().duplicateNestedType(this.referenceContext);
			}
//{ObjectTeams: was assignment; use setter to allow additional setup:
	/* @original
			this.referenceContext.binding = new MemberTypeBinding(className, this, enclosingType);
	 */
			this.referenceContext.setBinding(new MemberTypeBinding(className, this, enclosingType));
// SH}
		}

		SourceTypeBinding sourceType = this.referenceContext.binding;
		sourceType.module = module();
		environment().setAccessRestriction(sourceType, accessRestriction);
		ICompilationUnit compilationUnit = this.referenceContext.compilationResult.getCompilationUnit();
		if (compilationUnit != null && compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
			String externalAnnotationPath = compilationUnit.getExternalAnnotationPath(CharOperation.toString(sourceType.compoundName));
			if (externalAnnotationPath != null) {
				ExternalAnnotationSuperimposer.apply(sourceType, externalAnnotationPath);
			}
		}

		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
		sourceType.typeVariables = typeParameters == null || typeParameters.length == 0 ? Binding.NO_TYPE_VARIABLES : null;
		sourceType.fPackage.addType(sourceType);
//{ObjectTeams: ROFI
		if (isRoleFile) {
			// role types should be found also in the corresponding team package:
			enclosingType.teamPackage.addType(sourceType);
			// check duplicates:
			if (this.referenceContext.compilationUnit != null) // non-ROFI is analyzed below
			{
				TypeDeclaration[] memberTypes = this.parent.referenceType().memberTypes;
				for (int i = 0; i < memberTypes.length; i++) {
					if (   CharOperation.equals(memberTypes[i].name, this.referenceContext.name)
						&& TypeBinding.notEquals(memberTypes[i].binding, sourceType))
					{
						// mark the existing type (first in list of member types),
						// because ReferenceBinding.getMemberType() prefers elements
						// towards the end of the array, wouldn't want to continue
						// working with the type marked erroneous.

						// report only for interface part, has the nicer name ;-)
						if (this.referenceContext.isInterface())
							// while marking existing type still use this type's positions.
							problemReporter().duplicateNestedType(memberTypes[i], this.referenceContext.sourceStart, this.referenceContext.sourceEnd);
						else
							memberTypes[i].tagAsHavingErrors();
						break;
					}
				}
			}
		}
		if (TypeAnalyzer.isOrgObjectteamsTeam(sourceType)) {// handle the case of compiling org.objectteams.Team up front
			this.referenceContext.adjustOrgObjectteamsTeam();
			this.environment().getTeamMethodGenerator().registerOOTeamClass(sourceType);
		}
// SH}
		checkAndSetModifiers();
		buildTypeVariables();

		buildMemberTypes(accessRestriction);
//{ObjectTeams: setup cache for known role files:
		if (this.referenceContext.isTeam())
			this.referenceContext.getTeamModel().setupRoFiCache(this, environment());
// SH}
		return sourceType;
	}

	private void buildTypeVariables() {

	    SourceTypeBinding sourceType = this.referenceContext.binding;
		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, If they exist at all, process type parameters irrespective of source level.
		if (typeParameters == null || typeParameters.length == 0) {
		    sourceType.setTypeVariables(Binding.NO_TYPE_VARIABLES);
		    return;
		}
		sourceType.setTypeVariables(Binding.NO_TYPE_VARIABLES); // safety

		if (sourceType.id == TypeIds.T_JavaLangObject) { // handle the case of redefining java.lang.Object up front
			problemReporter().objectCannotBeGeneric(this.referenceContext);
			return;
		}
//{ObjectTeams: remove type value parameters
		typeParameters = filterTypeValueVariables(typeParameters);
		if (typeParameters.length == 0)
			return; // consumed all parameters
// SH}
		sourceType.setTypeVariables(createTypeVariables(typeParameters, sourceType));
		sourceType.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
	}

//{ObjectTeams: build additional structural elements
	/**
	 * @param typeParameters all type parameters perhaps including type value parameters.
	 * @return remaining unconsumed type parameters.
	 */
	private TypeParameter[] filterTypeValueVariables(TypeParameter[] typeParameters)
	{
		int count = 0;
		TypeParameter[] filteredParams = new TypeParameter[typeParameters.length];
		for (int i = 0; i < typeParameters.length; i++) {
			if (!(typeParameters[i] instanceof TypeValueParameter))
				filteredParams[count++] = typeParameters[i];
		}
		if (count < typeParameters.length) {
			TypeParameter[] remainder = new TypeParameter[count];
			System.arraycopy(filteredParams, 0, remainder, 0, count);
			return remainder;
		}
		return typeParameters;
	}
	/**
	 * build Callin and Callout
	 */
	public void buildCallinCallouts() {
		if (this.referenceContext.callinCallouts == null) {
			this.referenceContext.binding.callinCallouts = Binding.NO_CALLIN_CALLOUT_BINDINGS;
			return;
		}

		if (!this.referenceContext.isSourceRole()) {
			problemReporter().methodMappingNotInBoundRole(this.referenceContext.callinCallouts[0], this.referenceContext);
			this.referenceContext.callinCallouts = null;
			this.referenceContext.binding.callinCallouts = Binding.NO_CALLIN_CALLOUT_BINDINGS;
			return;
		}

		if (this.referenceContext.binding.callinCallouts != null)
			return; // already done

		// iterate the binding declarations to create the bindings
		AbstractMethodMappingDeclaration[] callinCallouts = this.referenceContext.callinCallouts;
		int size = callinCallouts.length;
		CallinCalloutBinding[] bindings = new CallinCalloutBinding[size];

		int count = 0;
		HashSet<String> labels = new HashSet<String>();
		for (int i = 0; i < size; i++) {
			if (this.referenceContext.isInterface() && callinCallouts[i].mappings != null) {
				problemReporter().paramMapInInterface(callinCallouts[i], this.referenceContext.binding);
				continue;
			}

			CallinCalloutScope scope = new CallinCalloutScope(this, callinCallouts[i]);
			CallinCalloutBinding binding = scope.createBinding(callinCallouts[i]);
			if (binding != null) // is null if binding could not be created
				bindings[count++] = binding;
			if (callinCallouts[i].isCallin()) {
				CallinMappingDeclaration callinMapping = (CallinMappingDeclaration)callinCallouts[i];
				if (callinMapping.name[0] != '<') { // generated name?
					String label = String.valueOf(callinMapping.name);
					if (!labels.contains(label))
						labels.add(label);
					else
						scope.problemReporter().duplicateCallinName(callinMapping);
				}
			}
		}
		if (count != bindings.length)
			System.arraycopy(bindings, 0, bindings = new CallinCalloutBinding[count], 0, count);
		this.referenceContext.binding.callinCallouts = bindings;
		this.referenceContext.binding.modifiers |= ExtraCompilerModifiers.AccUnresolved; // until methods() is sent
	}

	public void addGeneratedType (TypeDeclaration memberTypeDeclaration)
	{
		SourceTypeBinding sourceType = this.referenceContext.binding;

		// FIXME(SH): if memberType is a team, don't we need an OTClassScope?
		ClassScope memberScope = new ClassScope(this, memberTypeDeclaration);
		if ((memberTypeDeclaration.bits & ASTNode.IsLocalType) != 0)
		{
			// not added to member types
			memberScope.buildLocalType(sourceType, getCurrentPackage());
			// ensure the copy has the same relative constant pool name (e.g., "1" as in T$__OT__R$1)
			char[] computedConstantPoolName = CharOperation.concatWith(
						new char[][]{sourceType.constantPoolName(), memberTypeDeclaration.name}, '$');
			LocalTypeBinding localTypeBinding = (LocalTypeBinding)memberTypeDeclaration.binding;
			localTypeBinding.setConstantPoolName(computedConstantPoolName);
			referenceCompilationUnit().record(localTypeBinding);
		} else {
			assert (this.referenceContext.memberTypes != null);

			// build the binding:
			SourceTypeBinding newBinding;
			if (memberTypeDeclaration.isRoleFile()) {
				memberScope.environment().internalBuildTypeBindings(memberTypeDeclaration.compilationUnit, null);
				newBinding= memberTypeDeclaration.binding;
			} else {
				newBinding= memberScope.buildType(sourceType, getCurrentPackage(), /*accessRestriction*/null);
			}

			// search for an equal but binary type binding:
			int size = sourceType.memberTypes.length;
			for (int i=0; i<size; i++) {
				ReferenceBinding member = sourceType.memberTypes[i];
				if (   member.isBinaryBinding()
					&& CharOperation.equals(member.compoundName, newBinding.compoundName))
				{
					sourceType.memberTypes[i] = newBinding; // found, simply replace
					return;
				}
			}

			if (!memberTypeDeclaration.isRoleFile()) { // otherwise OTClassScope.buildType() did this.
				// need to actually add:
				ReferenceBinding[] newMembers = new ReferenceBinding[size+1];
				System.arraycopy(sourceType.memberTypes, 0, newMembers, 0, size);
				newMembers[size]= newBinding;
				sourceType.setMemberTypes(newMembers);
			}
		}
	}

	public FieldBinding addGeneratedField(FieldDeclaration fieldDeclaration, boolean hasTypeProblem) {

		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (sourceType.model.getState() >= ITranslationStates.STATE_BYTE_CODE_PREPARED)
		{
			problemReporter().compilationOrderProblem("Too late to add a field", this.referenceContext); //$NON-NLS-1$
			return null;
		}
		// perform initialization according to buildFields()
		FieldBinding fieldBinding = new FieldBinding(
				fieldDeclaration, null, fieldDeclaration.modifiers|ExtraCompilerModifiers.AccUnresolved, sourceType);

		sourceType.addField(fieldBinding);
		checkAndSetModifiersForField(fieldBinding, fieldDeclaration);

// FIXME(SH): does this improve robustness?
//		if ((sourceType.tagBits & TagBits.AreMethodsComplete) != 0)
			// trigger resolveTypeFor(FieldBinding)
		if (!hasTypeProblem)
			sourceType.getField(fieldDeclaration.name, true);
		return fieldBinding;
	}

	// TODO(SH): migrate clients to use SourceTypeBinding.addMethod() directly
    public SourceTypeBinding addGeneratedMethod(MethodBinding methodBinding)
    {
    	SourceTypeBinding sourceType = this.referenceContext.binding;
    	sourceType.addMethod(methodBinding);
    	this.referenceContext.binding.modifiers |= ExtraCompilerModifiers.AccUnresolved; // until methods() is sent
    	return sourceType;
    }

    MethodBinding createMethod(AbstractMethodDeclaration methodDecl) {
    	if (methodDecl.binding != null)
    		return methodDecl.binding; // nothing to do, observed on accessors for callout to private role field
        MethodScope scope = createMethodScope(methodDecl);
        return scope.createMethod(methodDecl);
    }

	private MethodScope createMethodScope(AbstractMethodDeclaration methodDecl) {
		MethodScope scope;
		if (methodDecl.model != null && methodDecl.model._sourceDeclaringType != null) {
        	TypeDeclaration foreignType = methodDecl.model._sourceDeclaringType;
        	scope = new MethodScope(foreignType.scope, methodDecl, false) {
        		@Override
        		public TypeDeclaration referenceType() {
        			return ClassScope.this.referenceContext;
        		}
        		@Override
        		public Object[] getEmulationPath(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean denyEnclosingArgInConstructorCall) {
        			Scope parentSave = this.parent;
        			try {
        				this.parent = ClassScope.this;
        				return super.getEmulationPath(targetEnclosingType, onlyExactMatch,
        					denyEnclosingArgInConstructorCall);
        			} finally {
        				this.parent = parentSave;
        			}
        		}
        	};
        } else {
        	scope = new MethodScope(this, methodDecl, false);
        }
		return scope;
	}
//Markus Witte}

	@Override
	void resolveTypeParameter(TypeParameter typeParameter) {
		typeParameter.resolve(this);
	}

	private void checkAndSetModifiers() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		int modifiers = sourceType.modifiers;
		boolean isPreviewEnabled = compilerOptions().sourceLevel == ClassFileConstants.getLatestJDKLevel() &&
				compilerOptions().enablePreviewFeatures;
		boolean flagSealedNonModifiers = isPreviewEnabled &&
				(modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
		if (sourceType.isRecord()) {
			/* JLS 14 Records Sec 8.10 - A record declaration is implicitly final. */
			modifiers |= ClassFileConstants.AccFinal;
		}
		if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
			problemReporter().duplicateModifierForType(sourceType);
		ReferenceBinding enclosingType = sourceType.enclosingType();
		boolean isMemberType = sourceType.isMemberType();
//{ObjectTeams: OT_CLASS_FLAGS attribute:
		WordValueAttribute.maybeCreateClassFlagsAttribute(this.referenceContext);
// SH}
		if (isMemberType) {
			if (sourceType.hasEnclosingInstanceContext())
				modifiers |= (enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
			modifiers |= (enclosingType.modifiers & ClassFileConstants.AccStrictfp);
			// checks for member types before local types to catch local members
			if (enclosingType.isInterface())
				modifiers |= ClassFileConstants.AccPublic;
//{ObjectTeams: check for role / team modifiers
			modifiers = Protections.checkRoleModifiers(modifiers, this.referenceContext, this);
// SH}
			if (sourceType.isEnum()) {
				if (!enclosingType.isStatic())
					problemReporter().nonStaticContextForEnumMemberType(sourceType);
				else
					modifiers |= ClassFileConstants.AccStatic;
			} else if (sourceType.isInterface()) {
				modifiers |= ClassFileConstants.AccStatic; // 8.5.1
			} else if (sourceType.isRecord()) {
				/* JLS 14 Records Sec 8.10 A nested record type is implicitly static */
				modifiers |= ClassFileConstants.AccStatic;
			}
		} else if (sourceType.isLocalType()) {
			if (sourceType.isEnum()) {
				if (!isPreviewEnabled) {
					problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
					sourceType.modifiers = 0;
//{ObjectTeams: if inside a role mark as role instead of enum (possible by very broken code only):
					if (enclosingType.isRole())	{
						sourceType.roleModel = this.referenceContext.getRoleModel();
						sourceType.roleModel.setBinding(sourceType);
					}
// SH}
					return;
				}
				final int UNEXPECTED_MODIFIERS =~(ClassFileConstants.AccEnum | ClassFileConstants.AccStrictfp);
				if ((modifiers & ExtraCompilerModifiers.AccJustFlag & UNEXPECTED_MODIFIERS) != 0
						|| flagSealedNonModifiers) {
					problemReporter().illegalModifierForLocalEnumDeclaration(sourceType);
					return;
				}
				modifiers |= ClassFileConstants.AccStatic;
			} else if (sourceType.isRecord()) {
				if (enclosingType != null && enclosingType.isLocalType()) {
					problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
					return;
				}
				if ((modifiers & ClassFileConstants.AccStatic) != 0) {
					problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
					return;
				}
				modifiers |= ClassFileConstants.AccStatic;
			}
			if (sourceType.isAnonymousType()) {
				if (compilerOptions().complianceLevel < ClassFileConstants.JDK9)
					modifiers |= ClassFileConstants.AccFinal;
			    // set AccEnum flag for anonymous body of enum constants
			    if (this.referenceContext.allocation.type == null)
			    	modifiers |= ClassFileConstants.AccEnum;
			}
			Scope scope = this;
			do {
				switch (scope.kind) {
					case METHOD_SCOPE :
						MethodScope methodScope = (MethodScope) scope;
						if (methodScope.isLambdaScope())
							methodScope = methodScope.namedMethodScope();
						if (methodScope.isInsideInitializer()) {
							SourceTypeBinding type = ((TypeDeclaration) methodScope.referenceContext).binding;

							// inside field declaration ? check field modifier to see if deprecated
							if (methodScope.initializedField != null) {
									// currently inside this field initialization
								if (methodScope.initializedField.isViewedAsDeprecated() && !sourceType.isDeprecated())
									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
							} else {
								if (type.isStrictfp())
									modifiers |= ClassFileConstants.AccStrictfp;
								if (type.isViewedAsDeprecated() && !sourceType.isDeprecated())
									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
							}
						} else {
							MethodBinding method = ((AbstractMethodDeclaration) methodScope.referenceContext).binding;
							if (method != null) {
								if (method.isStrictfp())
									modifiers |= ClassFileConstants.AccStrictfp;
								if (method.isViewedAsDeprecated() && !sourceType.isDeprecated())
									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
							}
						}
						break;
					case CLASS_SCOPE :
						// local member
						if (enclosingType.isStrictfp())
							modifiers |= ClassFileConstants.AccStrictfp;
						if (enclosingType.isViewedAsDeprecated() && !sourceType.isDeprecated()) {
							modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
							sourceType.tagBits |= enclosingType.tagBits & TagBits.AnnotationTerminallyDeprecated;
						}
						break;
				}
				scope = scope.parent;
			} while (scope != null);
		}

		// after this point, tests on the 16 bits reserved.
//{ObjectTeams: also include _some_ extra modifiers like AccTeam / AccRole:
/* orig:
		int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
  :giro */
		int realModifiers = modifiers & ExtraCompilerModifiers.AccOTTypeJustFlag;
// SH}

		if ((realModifiers & ClassFileConstants.AccInterface) != 0) { // interface and annotation type
			// detect abnormal cases for interfaces
			if (isMemberType) {
				final int UNEXPECTED_MODIFIERS =
					~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation
//{ObjectTeams more flags allowed for interfaces:
					  | ExtraCompilerModifiers.AccRole | ClassFileConstants.AccSynthetic
// SH}
					 );
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
					if ((realModifiers & ClassFileConstants.AccAnnotation) != 0)
						problemReporter().illegalModifierForAnnotationMemberType(sourceType);
					else
						problemReporter().illegalModifierForMemberInterface(sourceType);
//{ObjectTeams: prevent downstream problems with types illegally marked as team:
					modifiers &= ~ExtraCompilerModifiers.AccTeam;
					this.referenceContext.modifiers &= ~ExtraCompilerModifiers.AccTeam;
// SH}
				}
				/*
				} else if (sourceType.isLocalType()) { //interfaces cannot be defined inside a method
					int unexpectedModifiers = ~(AccAbstract | AccInterface | AccStrictfp);
					if ((realModifiers & unexpectedModifiers) != 0)
						problemReporter().illegalModifierForLocalInterface(sourceType);
				*/
			} else 	if (isPreviewEnabled && sourceType.isLocalType()) {
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface
						| ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation);
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers)
					problemReporter().localStaticsIllegalVisibilityModifierForInterfaceLocalType(sourceType);
//				if ((modifiers & ClassFileConstants.AccStatic) != 0) {
//					problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
//				}
				modifiers |= ClassFileConstants.AccStatic;
			} else {
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation
//{ObjectTeams
										   | ClassFileConstants.AccSynthetic
										   );
//SH}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
					if ((realModifiers & ClassFileConstants.AccAnnotation) != 0)
						problemReporter().illegalModifierForAnnotationType(sourceType);
					else
						problemReporter().illegalModifierForInterface(sourceType);
				}
			}
			/*
			 * AccSynthetic must be set if the target is greater than 1.5. 1.5 VM don't support AccSynthetics flag.
			 */
			if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME && compilerOptions().targetJDK > ClassFileConstants.JDK1_5) {
				modifiers |= ClassFileConstants.AccSynthetic;
			}
			modifiers |= ClassFileConstants.AccAbstract;
			} else if ((realModifiers & ClassFileConstants.AccEnum) != 0) {
			// detect abnormal cases for enums
			if (isMemberType) { // includes member types defined inside local types
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum
//{ObjectTeams more flags allowed for types:
					                      | ExtraCompilerModifiers.AccRole | ExtraCompilerModifiers.AccTeam | ClassFileConstants.AccSynthetic
										  );
// Markus Witte}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers) {
					problemReporter().illegalModifierForMemberEnum(sourceType);
					modifiers &= ~ClassFileConstants.AccAbstract; // avoid leaking abstract modifier
					realModifiers &= ~ClassFileConstants.AccAbstract;
//					modifiers &= ~(realModifiers & UNEXPECTED_MODIFIERS);
//					realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
				}
			} else if (sourceType.isLocalType()) {
//				if (flagSealedNonModifiers)
//					problemReporter().illegalModifierForLocalEnum(sourceType);
				// each enum constant is an anonymous local type and its modifiers were already checked as an enum constant field
			} else {
				int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum
//{ObjectTeams more flags allowed for types
								           | ExtraCompilerModifiers.AccTeam | ExtraCompilerModifiers.AccRole);
				if ((realModifiers & ExtraCompilerModifiers.AccRole) != 0)
					UNEXPECTED_MODIFIERS ^= ClassFileConstants.AccProtected; // even toplevel roles may be protected.
// Markus Witte+SH}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers)
					problemReporter().illegalModifierForEnum(sourceType);
			}
			if (!sourceType.isAnonymousType()) {
				checkAbstractEnum: {
					// does define abstract methods ?
					if ((this.referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
						modifiers |= ClassFileConstants.AccAbstract;
						break checkAbstractEnum;
					}
					// body of enum constant must implement any inherited abstract methods
					// enum type needs to implement abstract methods if one of its constants does not supply a body
					TypeDeclaration typeDeclaration = this.referenceContext;
					FieldDeclaration[] fields = typeDeclaration.fields;
					int fieldsLength = fields == null ? 0 : fields.length;
					if (fieldsLength == 0) break checkAbstractEnum; // has no constants so must implement the method itself
					AbstractMethodDeclaration[] methods = typeDeclaration.methods;
					int methodsLength = methods == null ? 0 : methods.length;
					// TODO (kent) cannot tell that the superinterfaces are empty or that their methods are implemented
					boolean definesAbstractMethod = typeDeclaration.superInterfaces != null;
					for (int i = 0; i < methodsLength && !definesAbstractMethod; i++)
						definesAbstractMethod = methods[i].isAbstract();
					if (!definesAbstractMethod) break checkAbstractEnum; // all methods have bodies
					boolean needAbstractBit = false;
					for (int i = 0; i < fieldsLength; i++) {
						FieldDeclaration fieldDecl = fields[i];
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
							if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
								needAbstractBit = true;
							} else {
								break checkAbstractEnum;
							}
						}
					}
					// tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
					// as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
					if (needAbstractBit) {
						modifiers |= ClassFileConstants.AccAbstract;
					}
				}
				// final if no enum constant with anonymous body
				checkFinalEnum: {
					TypeDeclaration typeDeclaration = this.referenceContext;
					FieldDeclaration[] fields = typeDeclaration.fields;
					if (fields != null) {
						for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
							FieldDeclaration fieldDecl = fields[i];
							if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
								if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
									break checkFinalEnum;
								}
							}
						}
					}
					modifiers |= ClassFileConstants.AccFinal;
				}
				if (isPreviewEnabled && (modifiers & ClassFileConstants.AccFinal) == 0)
					modifiers |= ExtraCompilerModifiers.AccSealed;
			}
		} else if (sourceType.isRecord()) {
			int UNEXPECTED_MODIFIERS = ExtraCompilerModifiers.AccNonSealed | ExtraCompilerModifiers.AccSealed;
			if (isMemberType) {
				final int EXPECTED_MODIFIERS = (ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
				if ((realModifiers & ~EXPECTED_MODIFIERS) != 0 || (modifiers & UNEXPECTED_MODIFIERS) != 0)
					problemReporter().illegalModifierForInnerRecord(sourceType);
			} else if (sourceType.isLocalType()) {
				final int EXPECTED_MODIFIERS = (ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp | ClassFileConstants.AccStatic);
				if ((realModifiers & ~EXPECTED_MODIFIERS) != 0 || (modifiers & UNEXPECTED_MODIFIERS) != 0)
					problemReporter().illegalModifierForLocalRecord(sourceType);
			} else {
				final int EXPECTED_MODIFIERS = (ClassFileConstants.AccPublic |  ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
				if ((realModifiers & ~EXPECTED_MODIFIERS) != 0 || (modifiers & UNEXPECTED_MODIFIERS) != 0)
					problemReporter().illegalModifierForRecord(sourceType);
			}
			// JLS 14 8.10 : It is a compile-time error if a record declaration has the modifier abstract.

			/* Section 8.10 http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html#jls-8.10
			 * It is a compile-time error if a record declaration has the modifier abstract.
			 *
			 * A record declaration is implicitly final. It is permitted for the declaration of a record type
			 * to redundantly specify the final modifier.
			 *
			 * A nested record type is implicitly static. It is permitted for the declaration of a nested record
			 * type to redundantly specify the static modifier.
			 *
			 * This implies that it is impossible to declare a record type in the body of an inner class (8.1.3),
			 * because an inner class cannot have static members except for constant variables.
			 *
			 * It is a compile-time error if the same keyword appears more than once as a modifier for a record declaration,
			 * or if a record declaration has more than one of the access modifiers public, protected, and private (6.6).
			 */
		} else {
			// detect abnormal cases for classes
			if (isMemberType) { // includes member types defined inside local types
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp
//{ObjectTeams more flags allowed for types:
										    | ExtraCompilerModifiers.AccRole | ExtraCompilerModifiers.AccTeam | ClassFileConstants.AccSynthetic
					                        );
//SH}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
					problemReporter().illegalModifierForMemberClass(sourceType);
			} else if (sourceType.isLocalType()) {
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp
//{ObjectTeams more flags allowed for types:
											| ExtraCompilerModifiers.AccRole
											);
//SH}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0 || flagSealedNonModifiers)
					problemReporter().illegalModifierForLocalClass(sourceType);
			} else {
				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp
//{ObjectTeams more flags allowed for types:
											| ExtraCompilerModifiers.AccRole | ExtraCompilerModifiers.AccTeam | ClassFileConstants.AccSynthetic
				  							);
// SH}
				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
					problemReporter().illegalModifierForClass(sourceType);
			}

			// check that Final and Abstract are not set together
			if ((realModifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract)) == (ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract))
				problemReporter().illegalModifierCombinationFinalAbstractForClass(sourceType);
		}

		if (isMemberType) {
			// test visibility modifiers inconsistency, isolate the accessors bits
			if (enclosingType.isInterface()) {
				if ((realModifiers & (ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) != 0) {
					problemReporter().illegalVisibilityModifierForInterfaceMemberType(sourceType);

					// need to keep the less restrictive
					if ((realModifiers & ClassFileConstants.AccProtected) != 0)
						modifiers &= ~ClassFileConstants.AccProtected;
					if ((realModifiers & ClassFileConstants.AccPrivate) != 0)
						modifiers &= ~ClassFileConstants.AccPrivate;
				}
			} else {
				int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
				if ((accessorBits & (accessorBits - 1)) > 1) {
					problemReporter().illegalVisibilityModifierCombinationForMemberType(sourceType);

					// need to keep the less restrictive so disable Protected/Private as necessary
					if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
						if ((accessorBits & ClassFileConstants.AccProtected) != 0)
							modifiers &= ~ClassFileConstants.AccProtected;
						if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
							modifiers &= ~ClassFileConstants.AccPrivate;
					} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
						modifiers &= ~ClassFileConstants.AccPrivate;
					}
				}
			}

			// static modifier test
			if ((realModifiers & ClassFileConstants.AccStatic) == 0) {
				if (enclosingType.isInterface())
					modifiers |= ClassFileConstants.AccStatic;
			} else if (!enclosingType.isStatic()) {
//{ObjectTeams: member-interfaces are always (implicitly) static,
			  // role interfaces need to be members (at any level of nesting)!
			  if (!sourceType.isRole()) {
// SH}
				if (sourceType.isRecord())
					problemReporter().recordNestedRecordInherentlyStatic(sourceType);
				else
					// error the enclosing type of a static field must be static or a top-level type
					problemReporter().illegalStaticModifierForMemberType(sourceType);
/* OT: */	  }
			}
		}

		sourceType.modifiers = modifiers;
	}

	/* This method checks the modifiers of a field.
	*
	* 9.3 & 8.3
	* Need to integrate the check for the final modifiers for nested types
	*
	* Note : A scope is accessible by : fieldBinding.declaringClass.scope
	*/
	private void checkAndSetModifiersForField(FieldBinding fieldBinding, FieldDeclaration fieldDecl) {
//{ObjectTeams: share model if set:
		if (fieldDecl.model  != null)
			fieldDecl.model.setBinding(fieldBinding);
// SH}
		int modifiers = fieldBinding.modifiers;
		final ReferenceBinding declaringClass = fieldBinding.declaringClass;
		if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
			problemReporter().duplicateModifierForField(declaringClass, fieldDecl);

//{ObjectTeams: synthetic role interfaces may have any access modifier.
	/*@original
		if (declaringClass.isInterface()) {
	 */
		if (declaringClass.isRegularInterface()) {
// SH}
			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
			// set the modifiers
			modifiers |= IMPLICIT_MODIFIERS;

			// and then check that they are the only ones
			if ((modifiers & ExtraCompilerModifiers.AccJustFlag) != IMPLICIT_MODIFIERS) {
				if ((declaringClass.modifiers  & ClassFileConstants.AccAnnotation) != 0)
					problemReporter().illegalModifierForAnnotationField(fieldDecl);
				else
					problemReporter().illegalModifierForInterfaceField(fieldDecl);
			}
			fieldBinding.modifiers = modifiers;
			return;
		} else if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
			// check that they are not modifiers in source
			if ((modifiers & ExtraCompilerModifiers.AccJustFlag) != 0)
				problemReporter().illegalModifierForEnumConstant(declaringClass, fieldDecl);

			// set the modifiers
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=267670. Force all enumerators to be marked
			// as used locally. We are unable to track the usage of these reliably as they could be used
			// in non obvious ways via the synthesized methods values() and valueOf(String) or by using
			// Enum.valueOf(Class<T>, String).
			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccEnum | ExtraCompilerModifiers.AccLocallyUsed;
			fieldBinding.modifiers|= IMPLICIT_MODIFIERS;
			return;
		}

		// after this point, tests on the 16 bits reserved.
		int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
		final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccFinal | ClassFileConstants.AccStatic | ClassFileConstants.AccTransient | ClassFileConstants.AccVolatile
//{ObjectTeams: synthetic fields
									| ClassFileConstants.AccSynthetic);
//MacWitte}
		if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
			problemReporter().illegalModifierForField(declaringClass, fieldDecl);
			modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS;
		}

		int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
		if ((accessorBits & (accessorBits - 1)) > 1) {
			problemReporter().illegalVisibilityModifierCombinationForField(declaringClass, fieldDecl);

			// need to keep the less restrictive so disable Protected/Private as necessary
			if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
				if ((accessorBits & ClassFileConstants.AccProtected) != 0)
					modifiers &= ~ClassFileConstants.AccProtected;
				if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
					modifiers &= ~ClassFileConstants.AccPrivate;
			} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
				modifiers &= ~ClassFileConstants.AccPrivate;
			}
		}
//{ObjectTeams: static role fields must be final (limitation):
		if (declaringClass.isRole() && ((modifiers & ClassFileConstants.AccStatic) != 0)) {
			if ((modifiers & ClassFileConstants.AccFinal) == 0) {
				problemReporter().staticRoleFieldMustBeFinal(fieldDecl);
			}
		}
// SH}

		if ((realModifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccVolatile)) == (ClassFileConstants.AccFinal | ClassFileConstants.AccVolatile))
			problemReporter().illegalModifierCombinationFinalVolatileForField(declaringClass, fieldDecl);

		if (fieldDecl.initialization == null && (modifiers & ClassFileConstants.AccFinal) != 0)
			modifiers |= ExtraCompilerModifiers.AccBlankFinal;
		fieldBinding.modifiers = modifiers;
	}

	public void checkParameterizedSuperTypeCollisions() {
		// check for parameterized interface collisions (when different parameterizations occur)
		SourceTypeBinding sourceType = this.referenceContext.binding;
		ReferenceBinding[] interfaces = sourceType.superInterfaces;
		Map invocations = new HashMap(2);
		ReferenceBinding itsSuperclass = sourceType.isInterface() ? null : sourceType.superclass;
		nextInterface: for (int i = 0, length = interfaces.length; i < length; i++) {
			ReferenceBinding one =  interfaces[i];
			if (one == null) continue nextInterface;
//{ObjectTeams: confined have no superclass/superinterface
			if (TypeAnalyzer.isTopConfined(one))
				continue nextInterface;
//SH}
			if (itsSuperclass != null && hasErasedCandidatesCollisions(itsSuperclass, one, invocations, sourceType, this.referenceContext))
				continue nextInterface;
			nextOtherInterface: for (int j = 0; j < i; j++) {
				ReferenceBinding two = interfaces[j];
				if (two == null) continue nextOtherInterface;
				if (hasErasedCandidatesCollisions(one, two, invocations, sourceType, this.referenceContext))
					continue nextInterface;
			}
		}

		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
		nextVariable : for (int i = 0, paramLength = typeParameters == null ? 0 : typeParameters.length; i < paramLength; i++) {
			TypeParameter typeParameter = typeParameters[i];
			TypeVariableBinding typeVariable = typeParameter.binding;
			if (typeVariable == null || !typeVariable.isValidBinding()) continue nextVariable;

			TypeReference[] boundRefs = typeParameter.bounds;
			if (boundRefs != null) {
				boolean checkSuperclass = TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass);
				for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
					TypeReference typeRef = boundRefs[j];
					TypeBinding superType = typeRef.resolvedType;
					if (superType == null || !superType.isValidBinding()) continue;

					// check against superclass
					if (checkSuperclass)
						if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef))
							continue nextVariable;
					// check against superinterfaces
					for (int index = typeVariable.superInterfaces.length; --index >= 0;)
						if (hasErasedCandidatesCollisions(superType, typeVariable.superInterfaces[index], invocations, typeVariable, typeRef))
							continue nextVariable;
				}
			}
		}

		ReferenceBinding[] memberTypes = this.referenceContext.binding.memberTypes;
		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES)
			for (int i = 0, size = memberTypes.length; i < size; i++)
//{ObjectTeams: consider binary role files, and fully translated ones:
			   if (   !memberTypes[i].isBinaryBinding()
				   && !StateHelper.hasState(memberTypes[i], ITranslationStates.STATE_FINAL))
// SH}
				 ((SourceTypeBinding) memberTypes[i]).scope.checkParameterizedSuperTypeCollisions();
	}

	private void checkForInheritedMemberTypes(SourceTypeBinding sourceType) {
		// search up the hierarchy of the sourceType to see if any superType defines a member type
		// when no member types are defined, tag the sourceType & each superType with the HasNoMemberTypes bit
		// assumes super types have already been checked & tagged
		ReferenceBinding currentType = sourceType;
		ReferenceBinding[] interfacesToVisit = null;
		int nextPosition = 0;
		do {
			if (currentType.hasMemberTypes()) // avoid resolving member types eagerly
				return;

			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			// in code assist cases when source types are added late, may not be finished connecting hierarchy
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
				if (interfacesToVisit == null) {
					interfacesToVisit = itsInterfaces;
					nextPosition = interfacesToVisit.length;
				} else {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		} while ((currentType = currentType.superclass()) != null && (currentType.tagBits & TagBits.HasNoMemberTypes) == 0);

		if (interfacesToVisit != null) {
			// contains the interfaces between the sourceType and any superclass, which was tagged as having no member types
			boolean needToTag = false;
			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding anInterface = interfacesToVisit[i];
				if ((anInterface.tagBits & TagBits.HasNoMemberTypes) == 0) { // skip interface if it already knows it has no member types
					if (anInterface.hasMemberTypes()) // avoid resolving member types eagerly
						return;

					needToTag = true;
					ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
					if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
						int itsLength = itsInterfaces.length;
						if (nextPosition + itsLength >= interfacesToVisit.length)
							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
						nextInterface : for (int a = 0; a < itsLength; a++) {
							ReferenceBinding next = itsInterfaces[a];
							for (int b = 0; b < nextPosition; b++)
								if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface;
							interfacesToVisit[nextPosition++] = next;
						}
					}
				}
			}

			if (needToTag) {
				for (int i = 0; i < nextPosition; i++)
					interfacesToVisit[i].tagBits |= TagBits.HasNoMemberTypes;
			}
		}

		// tag the sourceType and all of its superclasses, unless they have already been tagged
		currentType = sourceType;
		do {
			currentType.tagBits |= TagBits.HasNoMemberTypes;
		} while ((currentType = currentType.superclass()) != null && (currentType.tagBits & TagBits.HasNoMemberTypes) == 0);
	}

	// Perform deferred bound checks for parameterized type references (only done after hierarchy is connected)
	public void  checkParameterizedTypeBounds() {
//{ObjectTeams: expect re-entry:
/* orig:
		for (int i = 0, l = this.deferredBoundChecks == null ? 0 : this.deferredBoundChecks.size(); i < l; i++) {
			Object toCheck = this.deferredBoundChecks.get(i);
			if (toCheck instanceof TypeReference)
				((TypeReference) toCheck).checkBounds(this);
			else if (toCheck instanceof Runnable)
				((Runnable) toCheck).run();
		}
		this.deferredBoundChecks = null;
  :giro */
		ArrayList toCheckList = this.deferredBoundChecks;
		this.deferredBoundChecks = null;
		for (int i = 0, l = toCheckList == null ? 0 : toCheckList.size(); i < l; i++) {
			Object toCheck = toCheckList.get(i);
			if (toCheck instanceof TypeReference)
				((TypeReference) toCheck).checkBounds(this);
			else if (toCheck instanceof Runnable)
				((Runnable) toCheck).run();
		}
// SH}

		ReferenceBinding[] memberTypes = this.referenceContext.binding.memberTypes;
		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES)
			for (int i = 0, size = memberTypes.length; i < size; i++)
//{ObjectTeams: binary roles need not be checked again (hopefully) (nor do completely translated ones)
			   if (   !memberTypes[i].isBinaryBinding()
				   && !StateHelper.hasState(memberTypes[i], ITranslationStates.STATE_FINAL))
// SH}
				 ((SourceTypeBinding) memberTypes[i]).scope.checkParameterizedTypeBounds();
	}

	private void connectMemberTypes() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
//{ObjectTeams: extracted treatment of teams to new method:
		if (this.referenceContext.isTeam()) {
			connectTeamMemberTypes();
			return;
		}
// SH}
		ReferenceBinding[] memberTypes = sourceType.memberTypes;
		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
			for (int i = 0, size = memberTypes.length; i < size; i++)
//{ObjectTeams: respect reused binary members:
			  if (!memberTypes[i].isBinaryBinding())
// SH}
				 ((SourceTypeBinding) memberTypes[i]).scope.connectTypeHierarchy();
		}
	}
//{ObjectTeams: different order, more to do, for members of a team:
	// @PRE: current is a team.
	private void connectTeamMemberTypes() {

		// 1. shallow connecting of roles:
		SourceTypeBinding sourceType = this.referenceContext.binding;
		// don't cache memberTypes/size, loop might introduce new role files
		if (sourceType.memberTypes != null && sourceType.memberTypes != Binding.NO_MEMBER_TYPES) {
			for (int i = 0; i < sourceType.memberTypes.length; i++) {
				ReferenceBinding memberType = sourceType.memberTypes[i];
				// cope with binary role in source type team and pre-translated roles
				if (   !memberType.isBinaryBinding()
					&& !StateHelper.hasState(memberType, ITranslationStates.STATE_FINAL))
				{
					((SourceTypeBinding) memberType).scope.connectTypeHierarchyWithoutMembers();
				}
			}
		}

		// 2. copy roles and create OT-specific connections:
		if (   !isOrgObjectteamsTeam(sourceType)
			&& (sourceType.tagBits & TagBits.HierarchyHasProblems) == 0)
		{
			CopyInheritance.copyRoles(sourceType);
		}

		// 3. descend into roles:
		if (sourceType.memberTypes != null && sourceType.memberTypes != Binding.NO_MEMBER_TYPES) {
			Sorting.sortMemberTypes(sourceType);
			for (int i = 0; i < sourceType.memberTypes.length; i++) {
				ReferenceBinding memberType = sourceType.memberTypes[i];
				// cope with binary role in source type team and pre-translated roles
				if (   !memberType.isBinaryBinding()
					&& !StateHelper.hasState(memberType, ITranslationStates.STATE_FINAL))
				{
					((SourceTypeBinding) memberType).scope.connectMemberTypes();
				}
			}
		}
	}
// SH}

	/*
		Our current belief based on available JCK tests is:
			inherited member types are visible as a potential superclass.
			inherited interfaces are not visible when defining a superinterface.

		Error recovery story:
			ensure the superclass is set to java.lang.Object if a problem is detected
			resolving the superclass.

		Answer false if an error was reported against the sourceType.
	*/
	private boolean connectSuperclass() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
//{ObjectTeams: propagate hierarchy problems:
		if (sourceType.isRole() && ((sourceType.enclosingType().tagBits & TagBits.HierarchyHasProblems) != 0))
			sourceType.tagBits |= TagBits.HierarchyHasProblems;
		// separate treatment for team classes:
		if (sourceType.isTeam())
			return connectSuperteam();
// SH}
		if (sourceType.id == TypeIds.T_JavaLangObject) { // handle the case of redefining java.lang.Object up front
			sourceType.setSuperClass(null);
			sourceType.setSuperInterfaces(Binding.NO_SUPERINTERFACES);
			sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
			if (!sourceType.isClass())
				problemReporter().objectMustBeClass(sourceType);
			if (this.referenceContext.superclass != null || (this.referenceContext.superInterfaces != null && this.referenceContext.superInterfaces.length > 0))
				problemReporter().objectCannotHaveSuperTypes(sourceType);
			return true; // do not propagate Object's hierarchy problems down to every subtype
		}
		if (this.referenceContext.superclass == null) {
//{ObjectTeams: Confined roles may have no superclass
			if (TypeAnalyzer.isTopConfined(sourceType))
				return true;
// SH}
			if (sourceType.isEnum() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) // do not connect if source < 1.5 as enum already got flagged as syntax error
				return connectEnumSuperclass();
			sourceType.setSuperClass(getJavaLangObject());
			return !detectHierarchyCycle(sourceType, sourceType.superclass, null);
		}
		TypeReference superclassRef = this.referenceContext.superclass;
//{ObjectTeams: option to roll back problems:
		CheckPoint cp = this.referenceContext.compilationResult.getCheckPoint(this.referenceContext);
// SH}
		ReferenceBinding superclass = findSupertype(superclassRef);
//{ObjectTeams: for roles give a second chance
	    if (superclass == null || superclass.erasure() instanceof MissingTypeBinding) { // problem binding is in superclassRef.resolvedType
            ReferenceBinding adjustedSuperclass = checkAdjustSuperclass(this.referenceContext.superclass, cp);
            if (adjustedSuperclass == null || adjustedSuperclass.isValidBinding())
            	superclass = adjustedSuperclass;
	    }
// SH}
		if (superclass != null) { // is null if a cycle was detected cycle or a problem
//{ObjectTeams: additional check:
   			if (!Protections.checkCompatibleEnclosingForRoles(
   	                this,
   	                this.referenceContext,
   	                this.referenceContext.binding,
   	                superclass)) {
   				// nop, already reported inside
   			} else
// SH}
			if (!superclass.isClass() && (superclass.tagBits & TagBits.HasMissingType) == 0) {
				problemReporter().superclassMustBeAClass(sourceType, superclassRef, superclass);
			} else if (superclass.isFinal()) {
				problemReporter().classExtendFinalClass(sourceType, superclassRef, superclass);
			} else if ((superclass.tagBits & TagBits.HasDirectWildcard) != 0) {
				problemReporter().superTypeCannotUseWildcard(sourceType, superclassRef, superclass);
			} else if (superclass.erasure().id == TypeIds.T_JavaLangEnum) {
				problemReporter().cannotExtendEnum(sourceType, superclassRef, superclass);
			} else if (superclass.erasure().id == TypeIds.T_JavaLangRecord) {
				if (!(this.referenceContext.isRecord())) {
					problemReporter().recordCannotExtendRecord(sourceType, superclassRef, superclass);
				} else {
					return connectRecordSuperclass();
				}
			} else if ((superclass.tagBits & TagBits.HierarchyHasProblems) != 0
					|| !superclassRef.resolvedType.isValidBinding()) {
				sourceType.setSuperClass(superclass);
				sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype
				return superclassRef.resolvedType.isValidBinding(); // reported some error against the source type ?
//{ObjectTeams: team super class only allowed for teams
            } else if ((isOrgObjectteamsTeam(superclass) || superclass.isTeam())
                        && !sourceType.isTeam())
            {
            	problemReporter().regularExtendsTeam(sourceType, this.referenceContext.superclass, superclass);
// SH}
			} else {
				// only want to reach here when no errors are reported
				sourceType.setSuperClass(superclass);
				sourceType.typeBits |= (superclass.typeBits & TypeIds.InheritableBits);
				// further analysis against white lists for the unlikely case we are compiling java.io.*:
				if ((sourceType.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0)
					sourceType.typeBits |= sourceType.applyCloseableClassWhitelists(this.compilerOptions());
				return true;
			}
		}
		sourceType.tagBits |= TagBits.HierarchyHasProblems;
		sourceType.setSuperClass(sourceType.isRecord() ? getJavaLangRecord() : getJavaLangObject());
		if ((sourceType.superclass.tagBits & TagBits.BeginHierarchyCheck) == 0)
			detectHierarchyCycle(sourceType, sourceType.superclass, null);
		return false; // reported some error against the source type
	}

	/**
	 *  enum X (implicitly) extends Enum<X>
	 */
	private boolean connectEnumSuperclass() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		ReferenceBinding rootEnumType = getJavaLangEnum();
		if ((rootEnumType.tagBits & TagBits.HasMissingType) != 0) {
			sourceType.tagBits |= TagBits.HierarchyHasProblems; // mark missing supertpye
			sourceType.setSuperClass(rootEnumType);
			return false;
		}
		boolean foundCycle = detectHierarchyCycle(sourceType, rootEnumType, null);
		// arity check for well-known Enum<E>
		TypeVariableBinding[] refTypeVariables = rootEnumType.typeVariables();
		if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic
			problemReporter().nonGenericTypeCannotBeParameterized(0, null, rootEnumType, new TypeBinding[]{ sourceType });
			return false; // cannot reach here as AbortCompilation is thrown
		} else if (1 != refTypeVariables.length) { // check arity
			problemReporter().incorrectArityForParameterizedType(null, rootEnumType, new TypeBinding[]{ sourceType });
			return false; // cannot reach here as AbortCompilation is thrown
		}
		// check argument type compatibility
		ParameterizedTypeBinding  superType = environment().createParameterizedType(
			rootEnumType,
			new TypeBinding[]{
				environment().convertToRawType(sourceType, false /*do not force conversion of enclosing types*/),
			} ,
			null);
		sourceType.tagBits |= (superType.tagBits & TagBits.HierarchyHasProblems); // propagate if missing supertpye
		sourceType.setSuperClass(superType);
		// bound check (in case of bogus definition of Enum type)
		if (!refTypeVariables[0].boundCheck(superType, sourceType, this, null).isOKbyJLS()) {
			problemReporter().typeMismatchError(rootEnumType, refTypeVariables[0], sourceType, null);
		}
		return !foundCycle;
	}
	// Call only when we know there's no explicit permits clause and this is a sealed type
	private void connectImplicitPermittedTypes(SourceTypeBinding sourceType) {
		List<SourceTypeBinding> types = new ArrayList<>();
		for (TypeDeclaration typeDecl : this.referenceCompilationUnit().types) {
			types.addAll(sourceType.collectAllTypeBindings(typeDecl, this.compilationUnitScope()));
		}
		Set<ReferenceBinding> permSubTypes = new LinkedHashSet<>();
		for (ReferenceBinding type : types) {
			if (!TypeBinding.equalsEquals(type, sourceType) && type.findSuperTypeOriginatingFrom(sourceType) != null) {
				permSubTypes.add(type);
			}
		}
		if (sourceType.isSealed() && sourceType.isLocalType()) {
			// bug xxxx flag Error and return;
		}
		if (permSubTypes.size() == 0) {
			if (!sourceType.isLocalType()) // error flagged already
				problemReporter().sealedSealedTypeMissingPermits(sourceType, this.referenceContext);
			return;
		}
		sourceType.setPermittedTypes(permSubTypes.toArray(new ReferenceBinding[0]));
	}
/**
	 * @see #connectPermittedTypes()
	 */
	void connectImplicitPermittedTypes() {
		TypeDeclaration typeDecl = this.referenceContext;
		SourceTypeBinding sourceType = typeDecl.binding;
		if (sourceType.id == TypeIds.T_JavaLangObject || sourceType.isEnum() || sourceType.isRecord()) // already handled
			return;
		if (sourceType.isSealed() && (typeDecl.permittedTypes == null ||
				typeDecl.permittedTypes.length == 0)) {
			connectImplicitPermittedTypes(sourceType);
		}
		ReferenceBinding[] memberTypes = sourceType.memberTypes;
		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
			for (int i = 0, size = memberTypes.length; i < size; i++)
//{ObjectTeams: protect against binary member:
			  if (memberTypes[i] instanceof SourceTypeBinding)
// SH}
				 ((SourceTypeBinding) memberTypes[i]).scope.connectImplicitPermittedTypes();
		}
	}
	/**
	 * This method only deals with the permitted types that are explicitly declared
	 * in a type's permits clause. The implicitly permitted types are all filled in
	 * in {@link #connectImplicitPermittedTypes()}. The reason being, the implicitly
	 * permitted types require the complete type hierarchy to be ready. Therefore, this
	 * method is called inside {@link #connectTypeHierarchy()} and connectImplicitPermittedTypes()
	 * is called after the connectTypeHierarchy(). Why can't we do both after connectTypeHierarchy()?
	 * That is because, in a very specific case of one of an explicitly permitted type also being
	 * a member type and is referenced in the permits clause without type qualifier, we would allow
	 * the following incorrect code:
	 * <pre>
	 * 	public sealed class X permits Y {
	 *		final class Y extends X {}
	 *	}
	 *	</pre>
	 *  If we were to resolve <code>Y</code> in <code>permits Y</code> after resolving
	 *  the hierarchy, Y is resolved in current scope. However, Y should only be
	 *  allowed with the qualifier, in this case, X.Y.
	 */
	void connectPermittedTypes() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
		if (this.referenceContext.permittedTypes == null) {
			return;
		}
		if (sourceType.id == TypeIds.T_JavaLangObject || sourceType.isEnum()) // already handled
			return;

		int length = this.referenceContext.permittedTypes.length;
		ReferenceBinding[] permittedTypeBindings = new ReferenceBinding[length];
		int count = 0;
		nextPermittedType : for (int i = 0; i < length; i++) {
			TypeReference permittedTypeRef = this.referenceContext.permittedTypes[i];
			ReferenceBinding permittedType = findPermittedtype(permittedTypeRef);
			if (permittedType == null) { // detected cycle
				continue nextPermittedType;
			}
			// check for simple interface collisions
			// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
			for (int j = 0; j < i; j++) {
				if (TypeBinding.equalsEquals(permittedTypeBindings[j], permittedType)) {
					problemReporter().sealedDuplicateTypeInPermits(sourceType, permittedTypeRef, permittedType);
					continue nextPermittedType;
				}
			}
			// only want to reach here when no errors are reported
			permittedTypeBindings[count++] = permittedType;
		}
		// hold onto all correctly resolved superinterfaces
		if (count > 0) {
			if (count != length)
				System.arraycopy(permittedTypeBindings, 0, permittedTypeBindings = new ReferenceBinding[count], 0, count);
			sourceType.setPermittedTypes(permittedTypeBindings);
		} else {
			sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
		}
	}

//{ObjectTeams connect and adjust more class relationships:

    // RoleSplitter might have been over-eager: would we be better of, if we strip
    // the OT_DELIM prefix of our superclass?
    // We only get called, when the long name did not find a class, i.e.,
    // it can't be a role.
    private ReferenceBinding checkAdjustSuperclass(TypeReference superRef, CheckPoint cp)
    {
    	ReferenceBinding found = (ReferenceBinding)superRef.resolvedType;
    	if (found != null && found.isValidBinding())
    		found = null;    // returning found shall signal errors
    		// Note, that indeed superRef.resolveType() may have returned null,
    	    // yet superRef.resolvedType can be a valid type. This happens, e.g.,
    	 	// in org.eclipse.jdt.core.tests.compiler.regression.JavadocTest_1_4
    		// testcasses testBug83127*: a parameterized type reference refers
    		// to a valid class but its parameters have errors.
        if (!this.referenceContext.isSourceRole()) {
        	if ((this.referenceContext.binding.tagBits & TagBits.HierarchyHasProblems) != 0)
        		return null; // already detected a cycle, don't use 'found'!
            return found;
        }
        if (superRef instanceof SingleTypeReference) {
            SingleTypeReference singRef = (SingleTypeReference)superRef;
            if (!RoleSplitter.isClassPartName(singRef.token))
                return found;
            singRef.token = RoleSplitter.getInterfacePartName(singRef.token);
        } else if (superRef instanceof QualifiedTypeReference) {
            QualifiedTypeReference qualRef = (QualifiedTypeReference)superRef;
            int pos = qualRef.tokens.length-1;
            char[] lastToken = qualRef.tokens[pos];
            if (!RoleSplitter.isClassPartName(lastToken))
                return found;
            lastToken = RoleSplitter.getInterfacePartName(lastToken);
            qualRef.tokens[pos] = lastToken;
        }
        // before the second attempt delete first error:
        superRef.resolvedType = null;                    // remove problem binding.
        this.referenceContext.compilationResult.rollBack(cp); // remove IProblem
        return findSupertype(superRef);
    }

	public boolean connectBaseclass() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		if (!this.referenceContext.isDirectRole()) {
			if (this.referenceContext.baseclass != null)
				problemReporter().playedByInRegularClass(sourceType, this.referenceContext.baseclass);
			return true;
		}
		if (sourceType.isSynthInterface())
			return true; // will transfer baseclass to the ifc part in Dependencies.linkBaseclass
        if (this.referenceContext.baseclass == null) {
        	// leave sourceType.baseclass untouched, might be set by CopyInheritance.copyBaseclass()
            return true;
		}
        if (sourceType.roleModel == null) {
        	// if we already have errors silently quit, otherwise there's a bug here:
        	if (!this.referenceContext.ignoreFurtherInvestigation)
        		throw new InternalCompilerError("Missing role model"); //$NON-NLS-1$
        	return false;
        }
        try {
        	TypeReference baseclassRef = this.referenceContext.baseclass;

	        ReferenceBinding baseclass= findBaseclass(baseclassRef);

	        // detect cycle wrt. containment:
	        ReferenceBinding currentType = sourceType;
	        while (currentType != null && baseclass != null) {
	        	if (TypeBinding.equalsEquals(currentType, baseclass)) {
	        		problemReporter().playedByEnclosing(sourceType, this.referenceContext.baseclass, baseclass);
	        		sourceType.roleModel._playedByEnclosing = true;
	        		break;
	        	}
	        	currentType = currentType.enclosingType();
	        }

	        // check illegal containment cycle:
	        if (baseclass != null) {
	        	ReferenceBinding currentClass = baseclass;
	        	while (currentClass != null) {
	        		if (TypeBinding.equalsEquals(currentClass, sourceType)) {
	        			problemReporter().baseclassIsMember(sourceType, baseclassRef, baseclass);
	        			baseclass = null;
	        			break;
	        		}
	        		currentClass = currentClass.enclosingType();
	        	}
	        }

			if (baseclass != null) { // is null if a cycle was detected

				if (   baseclass.isRole()
					&& !baseclass.isRoleType())
				{
					if (RoleModel.isRoleFromOuterEnclosing(sourceType, baseclass)) {
						TeamModel outerTeam = baseclass.enclosingType().getTeamModel();
						baseclass = (ReferenceBinding)outerTeam.getTThis().getRoleTypeBinding(baseclass, 0);
					} else {
						// unused: TypeReference roleClassRef = TypeAnalyzer.getRoleClassReference(baseclassRef);
						// TODO (SH): replace with general lookup of common enclosing team?
						//            (cf. RoleTypeBinding.findCommonEnclosingTeam())
						if (  TypeBinding.equalsEquals(baseclass.enclosingType(), sourceType.enclosingType())
						   || TypeBinding.equalsEquals(baseclass.enclosingType(), sourceType.enclosingType().superclass()))
						{
							problemReporter().baseclassIsRoleOfTheSameTeam(sourceType, this.referenceContext.baseclass, baseclass);
							sourceType.baseclass = null;
							baseclassRef.resolvedType = null;
							RoleModel.setTagBit(sourceType, RoleModel.BaseclassHasProblems);
							this.referenceContext.pushDownBindingProblem();
							return false;
						}
						problemReporter().missingTypeAnchor(this.referenceContext.baseclass, baseclass);
					}
				}
				TypeVariableBinding[] roleVariables = sourceType.typeVariables;
				if (baseclass.isParameterizedType()) {
					if (!areEqualTypeParameters(roleVariables, ((ParameterizedTypeBinding) baseclass).arguments)) {
						problemReporter().parameterizedBaseclass(baseclassRef, baseclass);
						baseclass = (ReferenceBinding)baseclass.erasure();
					}
				} else if (sourceType.typeVariables() != Binding.NO_TYPE_VARIABLES) {
					problemReporter().nonParameterizedBaseclass(baseclassRef, sourceType);
				}

				if (baseclass.isFinal())
					problemReporter().decapsulationOfFinal(baseclassRef, baseclass);
				if (baseclass instanceof BinaryTypeBinding
					&& ((BinaryTypeBinding)baseclass).version >= ClassFileConstants.JDK1_8
					&& compilerOptions().weavingScheme == WeavingScheme.OTRE) {
					problemReporter().otreCannotWeaveIntoJava8(baseclassRef, baseclass, (int) (((BinaryTypeBinding)baseclass).version >> 16));
				}
				if (/*   !sourceType.isInterface() // FIXME(SH): ifc playedBy ifc is currently incompatible with add/removeRole infrastructure.
                    && */baseclass.isInterface() && (baseclass.tagBits & TagBits.HasMissingType) == 0)
				{
					// Continue after reporting.
					if (!baseclass.isSynthInterface()) // un-anchored reference to role type? (already reported above).
						problemReporter().baseclassMustBeAClass(sourceType, this.referenceContext.baseclass, baseclass);
				}
				if ((baseclass.tagBits & TagBits.HierarchyHasProblems) != 0)
					RoleModel.setTagBit(sourceType, RoleModel.BaseclassHasProblems);
				if (!baseclass.isValidBinding() && baseclass instanceof ProblemReferenceBinding) {
					TypeBinding match= ((ProblemReferenceBinding)baseclass).closestMatch();
					if (match instanceof ReferenceBinding) {
						if (baseclassRef.getBaseclassDecapsulation() != DecapsulationState.CONFINED) //=> decaps confined already reported
							problemReporter().invalidType(this.referenceContext.baseclass, baseclass);
					}
				} else if (sourceType.id == TypeIds.T_JavaLangObject) {
					// can only happen if Object extends another type... will never happen unless we're testing for it.
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					sourceType.baseclass = null;
					return true;
				} else {
					// only want to reach here when no errors are reported
					sourceType.baseclass = baseclass;

					RoleModel roleModel = sourceType.roleModel;
					roleModel._state.addJob(ITranslationStates.STATE_ROLES_LINKED, new Runnable() {
						@Override
						public void run() {
							checkBaseClassRedefinition(ClassScope.this.referenceContext);
						}
					});

					char[] packageName = baseclass.compoundName[0];
					if (   CharOperation.equals(packageName, "java".toCharArray())   //$NON-NLS-1$
						|| CharOperation.equals(packageName, "javax".toCharArray())) //$NON-NLS-1$
						problemReporter().tryingToWeaveIntoSystemClass(this.referenceContext.baseclass, baseclass);

					// pretend "implements o.o.IBoundBase", will be generated by the OTRE:
					baseclass.setIsBoundBase(sourceType);

					boolean createBinding = sourceType.unResolvedFields() != Binding.UNINITIALIZED_FIELDS; // don't create field binding if none have been built yet
					StandardElementGenerator.checkCreateBaseField(this.referenceContext, baseclass, createBinding);
					return true;
				}
		    }
        } finally {
			// trap for selection/completion only after checking base.R things:
			this.referenceContext.baseclass.aboutToResolve(this);
        }
		RoleModel.setTagBit(sourceType, RoleModel.BaseclassHasProblems);
        // give at least some legal base class:
		sourceType.baseclass = getJavaLangObject();
		if ((sourceType.baseclass.tagBits & TagBits.BeginHierarchyCheck) == 0)
			detectHierarchyCycle(sourceType, sourceType.baseclass, null);

        this.referenceContext.pushDownBindingProblem();

		return false; // reported some error against the source type
	}

	public void connectBaseclassRecurse() {
		connectBaseclass();
		TypeDeclaration[] members = this.referenceContext.memberTypes;
		if (members != null)
			for (TypeDeclaration member : members)
				member.scope.connectBaseclassRecurse();
	}

	private boolean areEqualTypeParameters(TypeVariableBinding[] roleTypeVariables, TypeBinding[] baseTypeArguments) {
		if (roleTypeVariables.length != baseTypeArguments.length)
			return false;
		for (int i = 0; i < roleTypeVariables.length; i++) {
			if (TypeBinding.notEquals(roleTypeVariables[i], baseTypeArguments[i]))
				return false;
		}
		return true;
	}

	// check OTJLD 2.1(c) and OTJLD 2.1(d)
	void checkBaseClassRedefinition(TypeDeclaration roleDecl)
	{
		ReferenceBinding baseclass = roleDecl.binding.baseclass;
		Dependencies.ensureBindingState(baseclass, ITranslationStates.STATE_ROLES_LINKED);

		ReferenceBinding superclass = roleDecl.binding.superclass;
		if (superclass != null) {
			ReferenceBinding superBase = superclass.rawBaseclass();
			if (   superBase != null
				&& !baseclass.isCompatibleWith(superBase))
			{
				problemReporter().illegalPlayedByRedefinition(roleDecl.baseclass, baseclass,
															  superclass,		  superBase);
			}
		}
		// for comparison with tsuper's baseclass separately check type and type-anchor:
		ITeamAnchor baseAnchor = null;
		if (RoleTypeBinding.isRoleWithExplicitAnchor(baseclass)) {
			baseAnchor = ((RoleTypeBinding)baseclass)._teamAnchor;
			baseclass = baseclass.getRealType();
		}
		for (ReferenceBinding tsuperRole: roleDecl.getRoleModel().getTSuperRoleBindings()) {
			ReferenceBinding tsuperBase = tsuperRole.baseclass();
			if (   tsuperBase != null && TypeBinding.notEquals(tsuperBase, baseclass)) {
				ITeamAnchor tsuperAnchor = null;
				if (RoleTypeBinding.isRoleWithExplicitAnchor(tsuperBase)) {
					tsuperAnchor = ((RoleTypeBinding)tsuperBase)._teamAnchor;
					tsuperBase = tsuperBase.getRealType();
				}
				if (   !(TypeBinding.equalsEquals(baseclass, tsuperBase) || TSuperHelper.isTSubOf(baseclass, tsuperBase))
					|| !TSuperHelper.isEquivalentField(baseAnchor, tsuperAnchor))
				{
					problemReporter().overridesPlayedBy(ClassScope.this.referenceContext, tsuperBase);
				}
			}
		}
	}

	// mostly like connectSuperclass
	private boolean connectSuperteam() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
// team: handle o.o.Team vaguely similar to j.l.Object:
		if (isOrgObjectteamsTeam(sourceType)) { // handle the case of redefining org.objectteams.Team up front
			this.referenceContext.modifiers |= ExtraCompilerModifiers.AccTeam;
			sourceType.superclass = getJavaLangObject();
			if (   this.referenceContext.superclass != null)
				problemReporter().teamCannotHaveSuperTypes(sourceType);
			return true; // do not propagate Team's hierarchy problems down to every subtype
		}
// :maet

		if (this.referenceContext.superclass == null) {
			if (sourceType.isEnum() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) // do not connect if source < 1.5 as enum already got flagged as syntax error
// team: enum not allowed for team, different default superclass
			{
				problemReporter().illegalModifierForTeam(this.referenceContext);
				return false;
			}
			LookupEnvironment environment = environment();
			try {
				environment.missingClassFileLocation = this.referenceContext;
				sourceType.superclass = getOrgObjectteamsTeam();
				if (sourceType.superclass == null || (sourceType.superclass.tagBits & TagBits.HasMissingType) != 0) {
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					return false; // o.o.Team not found
				}
			} finally {
				environment.missingClassFileLocation = null;
			}
// :maet
			return !detectHierarchyCycle(sourceType, sourceType.superclass, null);
		}
		TypeReference superclassRef = this.referenceContext.superclass;
//{ObjectTeams: option to roll back problems:
		CheckPoint cp = this.referenceContext.compilationResult.getCheckPoint(this.referenceContext);
// SH}
		ReferenceBinding superclass = findSupertype(superclassRef);
//{ObjectTeams: second chance.
	    if (superclass == null || superclass instanceof MissingTypeBinding) { // problem binding is in superclassRef.resolvedType
            ReferenceBinding adjustedSuperclass = checkAdjustSuperclass(superclassRef, cp);
            if (adjustedSuperclass != null && adjustedSuperclass.isValidBinding())
            	superclass = adjustedSuperclass;
	    }
// SH}

		if (superclass != null) { // is null if a cycle was detected cycle or a problem
//{ObjectTeams: additional checks:
	        if (!Protections.checkCompatibleEnclosingForRoles(
	                this,
	                this.referenceContext,
	                this.referenceContext.binding,
	                superclass)) {
	        	// nop, already reported inside
			} else
// SH}
			if (!superclass.isClass() && (superclass.tagBits & TagBits.HasMissingType) == 0) {
				problemReporter().superclassMustBeAClass(sourceType, superclassRef, superclass);
			} else if (superclass.isFinal()) {
				problemReporter().classExtendFinalClass(sourceType, superclassRef, superclass);
			} else if ((superclass.tagBits & TagBits.HasDirectWildcard) != 0) {
				problemReporter().superTypeCannotUseWildcard(sourceType, superclassRef, superclass);
			} else if (superclass.erasure().id == TypeIds.T_JavaLangEnum) {
				problemReporter().cannotExtendEnum(sourceType, superclassRef, superclass);
			} else if ((superclass.tagBits & TagBits.HierarchyHasProblems) != 0
					|| !superclassRef.resolvedType.isValidBinding()) {
				sourceType.superclass = superclass;
				sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype
				return superclassRef.resolvedType.isValidBinding(); // reported some error against the source type ?
// :maet
			} else {
				// only want to reach here when no errors are reported
				sourceType.superclass = superclass;

// team:
				// if superclass is not o.o.Team add "implements org.objectteams.ITeam":
				if (!superclass.isTeam()) {
					AstGenerator gen = new AstGenerator(this.referenceContext);
					QualifiedTypeReference additionalSuperIfc = gen.qualifiedTypeReference(IOTConstants.ORG_OBJECTTEAMS_ITEAM);
					if (this.referenceContext.superInterfaces != null) {
						int len = this.referenceContext.superInterfaces.length;
						System.arraycopy(this.referenceContext.superInterfaces, 0, this.referenceContext.superInterfaces = new TypeReference[len+1], 0, len);
						this.referenceContext.superInterfaces[len] = additionalSuperIfc;
					} else {
						this.referenceContext.superInterfaces = new TypeReference[] { additionalSuperIfc };
					}
				}

				// might need line numbers of super team, although parser thought we would not..
                if (   superclass instanceof SourceTypeBinding
                     && superclass.model.getState() != ITranslationStates.STATE_FINAL)
                {
                	CompilationUnitDeclaration result = ((SourceTypeBinding)superclass).scope.referenceCompilationUnit();
                	if (result.compilationResult.lineSeparatorPositions == null)
                		result.compilationResult.lineSeparatorPositions = new int[0];
                }
// :maet
				return true;
			}
		}
		sourceType.tagBits |= TagBits.HierarchyHasProblems;
		if (!isOrgObjectteamsTeam(sourceType)) {
			sourceType.superclass = getOrgObjectteamsTeam();
			if ((sourceType.superclass.tagBits & TagBits.BeginHierarchyCheck) == 0)
				detectHierarchyCycle(sourceType, sourceType.superclass, null);
		}
		return false; // reported some error against the source type
	}
// Markus Witte+SH}


	private boolean connectRecordSuperclass() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		ReferenceBinding rootRecordType = getJavaLangRecord();
		sourceType.setSuperClass(rootRecordType);
		if ((rootRecordType.tagBits & TagBits.HasMissingType) != 0) {
			sourceType.tagBits |= TagBits.HierarchyHasProblems; // mark missing supertpye
			return false;
		}
		return !detectHierarchyCycle(sourceType, rootRecordType, null);
	}
	/*
		Our current belief based on available JCK 1.3 tests is:
			inherited member types are visible as a potential superclass.
			inherited interfaces are visible when defining a superinterface.

		Error recovery story:
			ensure the superinterfaces contain only valid visible interfaces.

		Answer false if an error was reported against the sourceType.
	*/
	private boolean connectSuperInterfaces() {
		SourceTypeBinding sourceType = this.referenceContext.binding;
		sourceType.setSuperInterfaces(Binding.NO_SUPERINTERFACES);
		if (this.referenceContext.superInterfaces == null) {
			if (sourceType.isAnnotationType() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) {
				ReferenceBinding annotationType = getJavaLangAnnotationAnnotation();
				boolean foundCycle = detectHierarchyCycle(sourceType, annotationType, null);
				sourceType.setSuperInterfaces(new ReferenceBinding[] { annotationType });
				return !foundCycle;
			}
			return true;
		}
		if (sourceType.id == TypeIds.T_JavaLangObject) // already handled the case of redefining java.lang.Object
			return true;

		boolean noProblems = true;
		int length = this.referenceContext.superInterfaces.length;
		ReferenceBinding[] interfaceBindings = new ReferenceBinding[length];
		int count = 0;
		nextInterface : for (int i = 0; i < length; i++) {
		    TypeReference superInterfaceRef = this.referenceContext.superInterfaces[i];
			ReferenceBinding superInterface = findSupertype(superInterfaceRef);
			if (superInterface == null) { // detected cycle
				sourceType.tagBits |= TagBits.HierarchyHasProblems;
				noProblems = false;
				continue nextInterface;
			}
//{ObjectTeams: check special rules for "implements IXXXMigratable"
			noProblems &= RoleMigrationImplementor.checkMigratableInterfaces(sourceType, superInterfaceRef, superInterface, this);
			if (!noProblems) {
				sourceType.tagBits |= TagBits.HierarchyHasProblems;
				continue nextInterface;
			}
			if (   sourceType.isInterface()
				&& TypeAnalyzer.isConfined(superInterface)
				&& this.referenceContext.superclass == null)
			{
				sourceType.superclass = null; // cancel premature superclass j.l.Object
			}
// SH}

			// check for simple interface collisions
			// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
			for (int j = 0; j < i; j++) {
				if (TypeBinding.equalsEquals(interfaceBindings[j], superInterface)) {
					problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface);
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					noProblems = false;
					continue nextInterface;
				}
			}
			if (!superInterface.isInterface() && (superInterface.tagBits & TagBits.HasMissingType) == 0) {
				problemReporter().superinterfaceMustBeAnInterface(sourceType, superInterfaceRef, superInterface);
				sourceType.tagBits |= TagBits.HierarchyHasProblems;
				noProblems = false;
				continue nextInterface;
			} else if (superInterface.isAnnotationType()){
				problemReporter().annotationTypeUsedAsSuperinterface(sourceType, superInterfaceRef, superInterface);
			}
			if ((superInterface.tagBits & TagBits.HasDirectWildcard) != 0) {
				problemReporter().superTypeCannotUseWildcard(sourceType, superInterfaceRef, superInterface);
				sourceType.tagBits |= TagBits.HierarchyHasProblems;
				noProblems = false;
				continue nextInterface;
			}
			if ((superInterface.tagBits & TagBits.HierarchyHasProblems) != 0
					|| !superInterfaceRef.resolvedType.isValidBinding()) {
				sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype
				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
			}
			// only want to reach here when no errors are reported
			sourceType.typeBits |= (superInterface.typeBits & TypeIds.InheritableBits);
			// further analysis against white lists for the unlikely case we are compiling java.util.stream.Stream:
			if ((sourceType.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0)
				sourceType.typeBits |= sourceType.applyCloseableInterfaceWhitelists();
			interfaceBindings[count++] = superInterface;
		}
		// hold onto all correctly resolved superinterfaces
		if (count > 0) {
			if (count != length)
				System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count);
			sourceType.setSuperInterfaces(interfaceBindings);
		}
		return noProblems;
	}

//{ObjectTeams: special entries for generated types.
	/**
	 * connect hierarchy for a generate type.
	 * @param full should be do all steps of connectTypeHierarchy() or save descending for later?
	 */
	public void connectTypeHierarchyForGenerated(boolean full) {
		if (full)
			connectTypeHierarchy();
		else
			connectTypeHierarchyWithoutMembers();
	}

	public void buildFieldsAndMethodsForLateRole(){
		assert (   this.referenceContext.isGenerated
				|| this.referenceContext.isPurelyCopied
				|| this.referenceContext.binding.isLocalType()
				|| this.referenceContext.isRoleFile()) : "Only applicable for late roles"; //$NON-NLS-1$
		buildFieldsAndMethods();
	}
//Markus Witte}

	void connectTypeHierarchy() {
//{ObjectTeams:
		// already done?
		if (StateHelper.hasState(this.referenceContext.binding,
				                 ITranslationStates.STATE_LENV_CONNECT_TYPE_HIERARCHY))
			return;
		// signal proccessing:
		if (!StateHelper.startProcessing(this.referenceContext,
				   ITranslationStates.STATE_LENV_CONNECT_TYPE_HIERARCHY,
				   LookupEnvironment.CONNECT_TYPE_HIERARCHY))
			return; // catchup was blocked.
// SH}
		SourceTypeBinding sourceType = this.referenceContext.binding;
		CompilationUnitScope compilationUnitScope = compilationUnitScope();
		boolean wasAlreadyConnecting = compilationUnitScope.connectingHierarchy;
		compilationUnitScope.connectingHierarchy = true;
		try {
			if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
				sourceType.tagBits |= TagBits.BeginHierarchyCheck;
				environment().typesBeingConnected.add(sourceType);
				boolean noProblems = connectSuperclass();
				noProblems &= connectSuperInterfaces();
				connectPermittedTypes();
				environment().typesBeingConnected.remove(sourceType);
				sourceType.tagBits |= TagBits.EndHierarchyCheck;
				noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
				sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
				if (noProblems && sourceType.isHierarchyInconsistent())
					problemReporter().hierarchyHasProblems(sourceType);
			}
//{ObjectTeams: top level source super-team must be fully loaded/connected:
			ReferenceBinding superType= sourceType.superclass;
			if (   superType != null
					&& superType.isTeam())
			{
				ReferenceBinding superOriginal = (ReferenceBinding) superType.original();
				if (!superOriginal.isBinaryBinding()) {
					ClassScope superScope = ((SourceTypeBinding) superOriginal).scope;
					if (superScope != null)
						superScope.connectTypeHierarchy();
				}
			}
// SH}
			connectMemberTypes();
		} finally {
			compilationUnitScope.connectingHierarchy = wasAlreadyConnecting;
		}
		LookupEnvironment env = environment();
		try {
			env.missingClassFileLocation = this.referenceContext;
			checkForInheritedMemberTypes(sourceType);
		} catch (AbortCompilation e) {
			e.updateContext(this.referenceContext, referenceCompilationUnit().compilationResult);
			throw e;
		} finally {
			env.missingClassFileLocation = null;
		}
	}

	@Override
	public boolean deferCheck(Runnable check) {
		if (compilationUnitScope().connectingHierarchy) {
			if (this.deferredBoundChecks == null)
				this.deferredBoundChecks = new ArrayList<>();
			this.deferredBoundChecks.add(check);
			return true;
		} else {
			return false;
		}
	}

//{ObejctTeams: accessible from CopyInheritance:
/* orig:
	private void connectTypeHierarchyWithoutMembers() {
  :giro */
	public void connectTypeHierarchyWithoutMembers() {
// SH}
		// must ensure the imports are resolved
//{ObjectTeams: RoFi?
		if (this.referenceContext.isRoleFile())
			checkRoleFileImports();
// SH}
		if (this.parent instanceof CompilationUnitScope) {
			if (((CompilationUnitScope) this.parent).imports == null)
				 ((CompilationUnitScope) this.parent).checkAndSetImports();
		} else if (this.parent instanceof ClassScope) {
			// ensure that the enclosing type has already been checked
			 ((ClassScope) this.parent).connectTypeHierarchyWithoutMembers();
		}

		// double check that the hierarchy search has not already begun...
		SourceTypeBinding sourceType = this.referenceContext.binding;
		if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) != 0)
			return;

		CompilationUnitScope compilationUnitScope = compilationUnitScope();
		boolean wasAlreadyConnecting = compilationUnitScope.connectingHierarchy;
		compilationUnitScope.connectingHierarchy = true;
		try {
			sourceType.tagBits |= TagBits.BeginHierarchyCheck;
			environment().typesBeingConnected.add(sourceType);
			boolean noProblems = connectSuperclass();
			noProblems &= connectSuperInterfaces();
			connectPermittedTypes();
			environment().typesBeingConnected.remove(sourceType);
			sourceType.tagBits |= TagBits.EndHierarchyCheck;
			noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
			sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
			if (noProblems && sourceType.isHierarchyInconsistent())
				problemReporter().hierarchyHasProblems(sourceType);
		} finally {
			compilationUnitScope.connectingHierarchy = wasAlreadyConnecting;
		}
	}

//{ObjectTeams: ROFI (to be overridden in OTClassScope)
	protected void checkRoleFileImports() {
		CompilationUnitScope cuScope= compilationUnitScope();
		if (cuScope.imports == null)
			cuScope.checkAndSetImports();
	}
// SH}

	public boolean detectHierarchyCycle(TypeBinding superType, TypeReference reference) {
		if (!(superType instanceof ReferenceBinding)) return false;

		if (reference == this.superTypeReference) { // see findSuperType()
			if (superType.isTypeVariable())
				return false; // error case caught in resolveSuperType()
			// abstract class X<K,V> implements java.util.Map<K,V>
			//    static abstract class M<K,V> implements Entry<K,V>
			if (superType.isParameterizedType())
				superType = ((ParameterizedTypeBinding) superType).genericType();
			compilationUnitScope().recordSuperTypeReference(superType); // to record supertypes
			return detectHierarchyCycle(this.referenceContext.binding, (ReferenceBinding) superType, reference);
		}
		// Reinstate the code deleted by the fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=205235
		// For details, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057.
		if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0 && superType instanceof SourceTypeBinding)
			// ensure if this is a source superclass that it has already been checked
			((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();

		return false;
	}

	// Answer whether a cycle was found between the sourceType & the superType
	private boolean detectHierarchyCycle(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) {
		if (superType.isRawType())
//{ObjectTeams: relax the cast to include half-raw dependent types:
/* orig:
			superType = ((RawTypeBinding) superType).genericType();
  :giro */
			superType = ((ParameterizedTypeBinding) superType).genericType();
// SH}
		// by this point the superType must be a binary or source type

		if (TypeBinding.equalsEquals(sourceType, superType)) {
			problemReporter().hierarchyCircularity(sourceType, superType, reference);
			sourceType.tagBits |= TagBits.HierarchyHasProblems;
			return true;
		}

		if (superType.isMemberType()) {
			ReferenceBinding current = superType.enclosingType();
			do {
				if (current.isHierarchyBeingActivelyConnected()) {
					problemReporter().hierarchyCircularity(sourceType, current, reference);
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					current.tagBits |= TagBits.HierarchyHasProblems;
					return true;
				}
			} while ((current = current.enclosingType()) != null);
		}

		if (superType.isBinaryBinding()) {
			// force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of:
			//		- a binary type... this case MUST be caught & reported here
			//		- another source type... this case is reported against the other source type
			if (superType.problemId() != ProblemReasons.NotFound && (superType.tagBits & TagBits.HierarchyHasProblems) != 0) {
				sourceType.tagBits |= TagBits.HierarchyHasProblems;
				problemReporter().hierarchyHasProblems(sourceType);
				return true;
			}
			boolean hasCycle = false;
			ReferenceBinding parentType = superType.superclass();
			if (parentType != null) {
				if (TypeBinding.equalsEquals(sourceType, parentType)) {
					problemReporter().hierarchyCircularity(sourceType, superType, reference);
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					superType.tagBits |= TagBits.HierarchyHasProblems;
					return true;
				}
				if (parentType.isParameterizedType())
					parentType = ((ParameterizedTypeBinding) parentType).genericType();
				hasCycle |= detectHierarchyCycle(sourceType, parentType, reference);
				if ((parentType.tagBits & TagBits.HierarchyHasProblems) != 0) {
					sourceType.tagBits |= TagBits.HierarchyHasProblems;
					parentType.tagBits |= TagBits.HierarchyHasProblems; // propagate down the hierarchy
				}
			}

			ReferenceBinding[] itsInterfaces = superType.superInterfaces();
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
				for (int i = 0, length = itsInterfaces.length; i < length; i++) {
					ReferenceBinding anInterface = itsInterfaces[i];
					if (TypeBinding.equalsEquals(sourceType, anInterface)) {
						problemReporter().hierarchyCircularity(sourceType, superType, reference);
						sourceType.tagBits |= TagBits.HierarchyHasProblems;
						superType.tagBits |= TagBits.HierarchyHasProblems;
						return true;
					}
					if (anInterface.isParameterizedType())
						anInterface = ((ParameterizedTypeBinding) anInterface).genericType();
					hasCycle |= detectHierarchyCycle(sourceType, anInterface, reference);
					if ((anInterface.tagBits & TagBits.HierarchyHasProblems) != 0) {
						sourceType.tagBits |= TagBits.HierarchyHasProblems;
						superType.tagBits |= TagBits.HierarchyHasProblems;
					}
				}
			}
			return hasCycle;
		}

		if (superType.isHierarchyBeingActivelyConnected()) {
			org.eclipse.jdt.internal.compiler.ast.TypeReference ref = ((SourceTypeBinding) superType).scope.superTypeReference;
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133071
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=121734
			if (ref != null && ref.resolvedType != null) {
				ReferenceBinding s = (ReferenceBinding) ref.resolvedType;
				do {
					if (s.isHierarchyBeingActivelyConnected()) {
						problemReporter().hierarchyCircularity(sourceType, superType, reference);
						sourceType.tagBits |= TagBits.HierarchyHasProblems;
						superType.tagBits |= TagBits.HierarchyHasProblems;
						return true;
					}
				} while ((s = s.enclosingType()) != null);
			}
			if (ref != null && ref.resolvedType == null) {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=319885 Don't cry foul prematurely.
				// Check the edges traversed to see if there really is a cycle.
				char [] referredName = ref.getLastToken();
				for (Iterator iter = environment().typesBeingConnected.iterator(); iter.hasNext();) {
					SourceTypeBinding type = (SourceTypeBinding) iter.next();
					if (CharOperation.equals(referredName, type.sourceName())) {
						problemReporter().hierarchyCircularity(sourceType, superType, reference);
						sourceType.tagBits |= TagBits.HierarchyHasProblems;
						superType.tagBits |= TagBits.HierarchyHasProblems;
						return true;
					}
				}
			}
		}
		if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
			// ensure if this is a source superclass that it has already been checked
			if (superType.isValidBinding() && !superType.isUnresolvedType())
				((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();
		}
		if ((superType.tagBits & TagBits.HierarchyHasProblems) != 0)
			sourceType.tagBits |= TagBits.HierarchyHasProblems;
		return false;
	}

	private ReferenceBinding findSupertype(TypeReference typeReference) {
		CompilationUnitScope unitScope = compilationUnitScope();
		LookupEnvironment env = unitScope.environment;
		try {
			env.missingClassFileLocation = typeReference;
			typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes
/* FIXME(SH): want to override parent.getTypeOrPackage(), call chain is:
 *            typeReference.resolveSuperType(Scope)
 *  		  TypeReference.getTypeBinding(Scope)
 *  		  Scope.getTypeOrPackage() -> loops over parents.
 *           Does OTClassScope need to override getTypeOrPackage/getPackage ??
 */
			unitScope.recordQualifiedReference(typeReference.getTypeName());
			this.superTypeReference = typeReference;
			ReferenceBinding superType = (ReferenceBinding) typeReference.resolveSuperType(this);
//{ObjectTeams:	anchor.R is not allowed in this position
			if (superType != null && superType.isRoleType())
			{
				RoleTypeBinding superRole = (RoleTypeBinding)superType;
				if (superRole.hasExplicitAnchor()) {
					typeReference.resolvedType = new ProblemReferenceBinding(typeReference.getTypeName(), superType, ProblemReasons.NotVisible);
					problemReporter().externalizedRoleNotAllowedHere(typeReference, superRole);
					return null;
				}
			}
// SH}
			return superType;
		} catch (AbortCompilation e) {
			SourceTypeBinding sourceType = this.referenceContext.binding;
			if (sourceType.superInterfaces == null)  sourceType.setSuperInterfaces(Binding.NO_SUPERINTERFACES); // be more resilient for hierarchies (144976)
			if (sourceType.permittedTypes == null)  sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
			e.updateContext(typeReference, referenceCompilationUnit().compilationResult);
			throw e;
		} finally {
			env.missingClassFileLocation = null;
			this.superTypeReference = null;
		}
	}

//{ObjectTeams: similar to findSupertype but for "playedBy"
	private ReferenceBinding findBaseclass(TypeReference typeReference) {
		CompilationUnitScope unitScope = compilationUnitScope();
		LookupEnvironment env = unitScope.environment;
		try {
			env.missingClassFileLocation = typeReference;

// a problem be _returned_ in any case (selection may otherwise _throw_ a problem!)
/* orig:
			typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes
  :giro */
// SH}
/* FIXME(SH): want to override parent.getTypeOrPackage(), call chain is:
 *            typeReference.resolveSuperType(Scope)
 *  		  TypeReference.getTypeBinding(Scope)
 *  		  Scope.getTypeOrPackage() -> loops over parents.
 *           Does OTClassScope need to override getTypeOrPackage/getPackage ??
 */
			unitScope.recordQualifiedReference(typeReference.getTypeName());
//{ObjectTeams: preferably resolve using base import scope:
/* orig:
			ReferenceBinding superType = (ReferenceBinding) typeReference.resolveSuperType(this);
 */
			typeReference.deprecationProblemId = IProblem.DeprecatedBaseclass;
			ReferenceBinding superType;
			if (typeReference.checkResolveUsingBaseImportScope(this, 0, false) != null) {
				superType = (ReferenceBinding)typeReference.resolvedType;
			} else {
				superType = (ReferenceBinding) typeReference.resolveSuperType(this);
				if (isImportedType(typeReference)) {
					problemReporter().regularlyImportedBaseclass(typeReference);
				} else if (   typeReference instanceof QualifiedTypeReference 							// could mean several things:
						   && superType != null && superType.isValidBinding()) 							// (only investigate if valid)
				{
	        		if (   !RoleTypeBinding.isRoleWithExplicitAnchor(superType) 					    // old style externalized still tolerated
	        			&& ((QualifiedTypeReference)typeReference).tokens.length > superType.depth()+1)	// if lenght == depth+1: qualifiation by enclosing types only
	        		{
	        			problemReporter().qualifiedReferenceToBaseclass(typeReference);					// qualified unimported base class is deprecated
	        		}
	        	}
			}
			return superType;
		} catch (AbortCompilation e) {
			e.updateContext(typeReference, referenceCompilationUnit().compilationResult);
			throw e;
		} finally {
			env.missingClassFileLocation = null;
		}
	}

	private boolean isImportedType(TypeReference typeReference)
	{
		if (!(typeReference instanceof SingleTypeReference) || (typeReference instanceof IAlienScopeTypeReference))
			return false;
		if (typeReference instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference paramType = (ParameterizedSingleTypeReference) typeReference;
			if (paramType.typeAnchors != null && paramType.typeAnchors.length>0)
				return false; // resolved via anchor not via import
		}
		TypeBinding type= typeReference.resolvedType;
		if (type == null || !type.isValidBinding() || !(type instanceof ReferenceBinding))
			return false;
		PackageBinding aPackage= ((ReferenceBinding)type).fPackage;
		return aPackage != getCurrentPackage()
			&& !CharOperation.equals(aPackage.compoundName, TypeConstants.JAVA_LANG);
	}
// SH}

	private ReferenceBinding findPermittedtype(TypeReference typeReference) {
		CompilationUnitScope unitScope = compilationUnitScope();
		LookupEnvironment env = unitScope.environment;
		try {
			env.missingClassFileLocation = typeReference;
			typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes
			unitScope.recordQualifiedReference(typeReference.getTypeName());
			ReferenceBinding permittedType = (ReferenceBinding) typeReference.resolveType(this);
			return permittedType;
		} catch (AbortCompilation e) {
			SourceTypeBinding sourceType = this.referenceContext.binding;
			if (sourceType.permittedTypes == null)  sourceType.setPermittedTypes(Binding.NO_PERMITTEDTYPES);
			e.updateContext(typeReference, referenceCompilationUnit().compilationResult);
			throw e;
		} finally {
			env.missingClassFileLocation = null;
		}
	}
	/* Answer the problem reporter to use for raising new problems.
	*
	* Note that as a side-effect, this updates the current reference context
	* (unit, type or method) in case the problem handler decides it is necessary
	* to abort.
	*/
	@Override
	public ProblemReporter problemReporter() {
		MethodScope outerMethodScope;
		if ((outerMethodScope = outerMostMethodScope()) == null) {
			ProblemReporter problemReporter = referenceCompilationUnit().problemReporter;
			problemReporter.referenceContext = this.referenceContext;
			return problemReporter;
		}
		return outerMethodScope.problemReporter();
	}

	/* Answer the reference type of this scope.
	* It is the nearest enclosing type of this scope.
	*/
	@Override
	public TypeDeclaration referenceType() {
		return this.referenceContext;
	}

	@Override
	public boolean hasDefaultNullnessFor(int location, int sourceStart) {
		int nonNullByDefaultValue = localNonNullByDefaultValue(sourceStart);
		if (nonNullByDefaultValue != 0) {
			return (nonNullByDefaultValue & location) != 0;
		}
		SourceTypeBinding binding = this.referenceContext.binding;
		if (binding != null) {
			int nullDefault = binding.getNullDefault();
			if (nullDefault != 0) {
				return (nullDefault & location) != 0;
			}
		}
		return this.parent.hasDefaultNullnessFor(location, sourceStart);
	}

	@Override
	public /* @Nullable */ Binding checkRedundantDefaultNullness(int nullBits, int sourceStart) {
		Binding target = localCheckRedundantDefaultNullness(nullBits, sourceStart);
		if (target != null) {
			return target;
		}
		SourceTypeBinding binding = this.referenceContext.binding;
		if (binding != null) {
			int nullDefault = binding.getNullDefault();
			if (nullDefault != 0) {
				return (nullDefault == nullBits) ? binding : null;
			}
		}
		return this.parent.checkRedundantDefaultNullness(nullBits, sourceStart);
	}

	@Override
	public String toString() {
		if (this.referenceContext != null)
			return "--- Class Scope ---\n\n"  //$NON-NLS-1$
							+ this.referenceContext.binding.toString();
		return "--- Class Scope ---\n\n Binding not initialized" ; //$NON-NLS-1$
	}
//{ObjectTeams: does this class's compulation unit have ignoreFurtherInvestigation set?
	public boolean cuIgnoreFurtherInvestigation() {
		return referenceCompilationUnit() == null || referenceCompilationUnit().ignoreFurtherInvestigation;
	}
// SH}
}
