/*******************************************************************************
 * Copyright (c) 2008, 2017 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 *
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler;

import java.util.ArrayList;
import java.util.Map;

import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.ParameterInfo;
import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.TypeParameterInfo;
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.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.ExportsStatement;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
import org.eclipse.jdt.internal.compiler.ast.OpensStatement;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
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.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
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.CalloutMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer.MethodSignatureEnhancer;

@SuppressWarnings({"rawtypes", "unchecked"})
public class SourceElementNotifier {
	/**
	 * An ast visitor that visits local type declarations.
	 */
	public class LocalDeclarationVisitor extends ASTVisitor {
		public ImportReference currentPackage;
		ArrayList declaringTypes;
		public void pushDeclaringType(TypeDeclaration declaringType) {
			if (this.declaringTypes == null) {
				this.declaringTypes = new ArrayList();
			}
			this.declaringTypes.add(declaringType);
		}
		public void popDeclaringType() {
			this.declaringTypes.remove(this.declaringTypes.size()-1);
		}
		public TypeDeclaration peekDeclaringType() {
			if (this.declaringTypes == null) return null;
			int size = this.declaringTypes.size();
			if (size == 0) return null;
			return (TypeDeclaration) this.declaringTypes.get(size-1);
		}
		@Override
		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
			notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
			return false; // don't visit members as this was done during notifySourceElementRequestor(...)
		}
		@Override
		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
			notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
			return false; // don't visit members as this was done during notifySourceElementRequestor(...)
		}
	}

	ISourceElementRequestor requestor;
	boolean reportReferenceInfo;
	char[][] typeNames;
	char[][] superTypeNames;
	int nestedTypeIndex;
	LocalDeclarationVisitor localDeclarationVisitor = null;

	HashtableOfObjectToInt sourceEnds;
	Map<ASTNode,char[][]> nodesToCategories;

	int initialPosition;
	int eofPosition;

public SourceElementNotifier(ISourceElementRequestor requestor, boolean reportLocalDeclarations) {
	this.requestor = requestor;
	if (reportLocalDeclarations) {
		this.localDeclarationVisitor = new LocalDeclarationVisitor();
	}
	this.typeNames = new char[4][];
	this.superTypeNames = new char[4][];
	this.nestedTypeIndex = 0;
}
protected Object[][] getArgumentInfos(Argument[] arguments) {
	int argumentLength = arguments.length;
	char[][] argumentTypes = new char[argumentLength][];
	char[][] argumentNames = new char[argumentLength][];
	ParameterInfo[] parameterInfos = new ParameterInfo[argumentLength];
	for (int i = 0; i < argumentLength; i++) {
		Argument argument = arguments[i];
		argumentTypes[i] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.');
		char[] name = argument.name;
		argumentNames[i] = name;
		ParameterInfo parameterInfo = new ParameterInfo();
		parameterInfo.declarationStart = argument.declarationSourceStart;
		parameterInfo.declarationEnd = argument.declarationSourceEnd;
		parameterInfo.nameSourceStart = argument.sourceStart;
		parameterInfo.nameSourceEnd = argument.sourceEnd;
		parameterInfo.modifiers = argument.modifiers;
		parameterInfo.name = name;
		parameterInfos[i] = parameterInfo;
	}

	return new Object[][] { parameterInfos, new char[][][] { argumentTypes, argumentNames } };
}
protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) {
	char[][] interfaceNames = null;
	int superInterfacesLength = 0;
	TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
	if (superInterfaces != null) {
		superInterfacesLength = superInterfaces.length;
		interfaceNames = new char[superInterfacesLength][];
	} else {
		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
			// see PR 3442
			QualifiedAllocationExpression alloc = typeDeclaration.allocation;
			if (alloc != null && alloc.type != null) {
				superInterfaces = new TypeReference[] { alloc.type};
				superInterfacesLength = 1;
				interfaceNames = new char[1][];
			}
		}
	}
	if (superInterfaces != null) {
		for (int i = 0; i < superInterfacesLength; i++) {
			interfaceNames[i] =
				CharOperation.concatWith(superInterfaces[i].getParameterizedTypeName(), '.');
		}
	}
	return interfaceNames;
}
protected char[] getSuperclassName(TypeDeclaration typeDeclaration) {
	TypeReference superclass = typeDeclaration.superclass;
	return superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null;
}
protected char[][] getThrownExceptions(AbstractMethodDeclaration methodDeclaration) {
	char[][] thrownExceptionTypes = null;
	TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
	if (thrownExceptions != null) {
		int thrownExceptionLength = thrownExceptions.length;
		thrownExceptionTypes = new char[thrownExceptionLength][];
		for (int i = 0; i < thrownExceptionLength; i++) {
			thrownExceptionTypes[i] =
				CharOperation.concatWith(thrownExceptions[i].getParameterizedTypeName(), '.');
		}
	}
	return thrownExceptionTypes;
}
protected char[][] getTypeParameterBounds(TypeParameter typeParameter) {
	TypeReference firstBound = typeParameter.type;
	TypeReference[] otherBounds = typeParameter.bounds;
	char[][] typeParameterBounds = null;
	if (firstBound != null) {
		if (otherBounds != null) {
			int otherBoundsLength = otherBounds.length;
			char[][] boundNames = new char[otherBoundsLength+1][];
			boundNames[0] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.');
			for (int j = 0; j < otherBoundsLength; j++) {
				boundNames[j+1] =
					CharOperation.concatWith(otherBounds[j].getParameterizedTypeName(), '.');
			}
			typeParameterBounds = boundNames;
		} else {
			typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')};
		}
	} else {
		typeParameterBounds = CharOperation.NO_CHAR_CHAR;
	}

	return typeParameterBounds;
}
private TypeParameterInfo[] getTypeParameterInfos(TypeParameter[] typeParameters) {
	if (typeParameters == null) return null;
	int typeParametersLength = typeParameters.length;
	TypeParameterInfo[] result = new TypeParameterInfo[typeParametersLength];
	for (int i = 0; i < typeParametersLength; i++) {
		TypeParameter typeParameter = typeParameters[i];
		char[][] typeParameterBounds = getTypeParameterBounds(typeParameter);
		ISourceElementRequestor.TypeParameterInfo typeParameterInfo = new ISourceElementRequestor.TypeParameterInfo();
		typeParameterInfo.typeAnnotated = ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0);
		typeParameterInfo.declarationStart = typeParameter.declarationSourceStart;
		typeParameterInfo.declarationEnd = typeParameter.declarationSourceEnd;
		typeParameterInfo.name = typeParameter.name;
		typeParameterInfo.nameSourceStart = typeParameter.sourceStart;
		typeParameterInfo.nameSourceEnd = typeParameter.sourceEnd;
		typeParameterInfo.bounds = typeParameterBounds;
//{ObjectTeams: value parameter / <B base R> ?
		if (typeParameter.getKind() == AbstractVariableDeclaration.TYPE_VALUE_PARAMETER)
			typeParameterInfo.isValueParameter= true;
		if (typeParameter.hasBaseBound())
			typeParameterInfo.hasBaseBound= true;
// SH}
		result[i] = typeParameterInfo;
	}
	return result;
}
/*
 * Checks whether one of the annotations is the @Deprecated annotation
 * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807)
 */
private boolean hasDeprecatedAnnotation(Annotation[] annotations) {
	if (annotations != null) {
		for (int i = 0, length = annotations.length; i < length; i++) {
			Annotation annotation = annotations[i];
			if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) {
				return true;
			}
		}
	}
	return false;
}
/*
 * Update the bodyStart of the corresponding parse node
 */
protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {

	// range check
	boolean isInRange =
				this.initialPosition <= methodDeclaration.declarationSourceStart
				&& this.eofPosition >= methodDeclaration.declarationSourceEnd;

	if (methodDeclaration.isClinit()) {
		this.visitIfNeeded(methodDeclaration);
		return;
	}

	if (methodDeclaration.isDefaultConstructor()) {
		if (this.reportReferenceInfo) {
			ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
			ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
			if (constructorCall != null) {
				switch(constructorCall.accessMode) {
					case ExplicitConstructorCall.This :
						this.requestor.acceptConstructorReference(
							this.typeNames[this.nestedTypeIndex-1],
							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
							constructorCall.sourceStart);
						break;
					case ExplicitConstructorCall.Super :
					case ExplicitConstructorCall.ImplicitSuper :
						this.requestor.acceptConstructorReference(
							this.superTypeNames[this.nestedTypeIndex-1],
							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
							constructorCall.sourceStart);
						break;
				}
			}
		}
		return;
	}
	char[][] argumentTypes = null;
	char[][] argumentNames = null;
	boolean isVarArgs = false;
//{ObjectTeams: retrench signature of callin method:
/* orig:
	Argument[] arguments = methodDeclaration.arguments;
  :giro */
	Argument[] arguments = MethodSignatureEnhancer.getSourceArguments(methodDeclaration);
	boolean [] baseclassFlags = null;
// SH}
	ParameterInfo[] parameterInfos = null; 
	ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
	methodInfo.typeAnnotated = ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0);

	if (arguments != null) {
		Object[][] argumentInfos = getArgumentInfos(arguments);
		parameterInfos = (ParameterInfo[]) argumentInfos[0];
		argumentTypes = (char[][]) argumentInfos[1][0];
		argumentNames = (char[][]) argumentInfos[1][1];

		isVarArgs = arguments[arguments.length-1].isVarArgs();

//{ObjectTeams:	compute flag array
		baseclassFlags = new boolean[arguments.length];
		for (int i = 0; i < arguments.length; i++)
			// LTRs resolve in base-import scope, if present.
			baseclassFlags[i] = (arguments[i].type instanceof LiftingTypeReference);
// SH}
	}
	char[][] thrownExceptionTypes = getThrownExceptions(methodDeclaration);
	// by default no selector end position
	int selectorSourceEnd = -1;
	if (methodDeclaration.isConstructor()) {
		selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
		if (isInRange){
			int currentModifiers = methodDeclaration.modifiers;
			currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated;
			if (isVarArgs)
				currentModifiers |= ClassFileConstants.AccVarargs;
			if (hasDeprecatedAnnotation(methodDeclaration.annotations))
				currentModifiers |= ClassFileConstants.AccDeprecated;

			methodInfo.isConstructor = true;
			methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
			methodInfo.modifiers = currentModifiers;
// Note(SH): OT: no callin flag in constructor ;-)
			methodInfo.name = methodDeclaration.selector;
			methodInfo.nameSourceStart = methodDeclaration.sourceStart;
			methodInfo.nameSourceEnd = selectorSourceEnd;
			methodInfo.parameterTypes = argumentTypes;
			methodInfo.parameterNames = argumentNames;
//{ObjectTeams: store additional array
			methodInfo.parameterBaseclassFlags = baseclassFlags;
// SH}
			methodInfo.exceptionTypes = thrownExceptionTypes;
			methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
			methodInfo.parameterInfos = parameterInfos;
			methodInfo.categories = this.nodesToCategories.get(methodDeclaration);
			methodInfo.annotations = methodDeclaration.annotations;
			methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
			methodInfo.declaringTypeModifiers = declaringType.modifiers;
			methodInfo.extraFlags = ExtraFlags.getExtraFlags(declaringType);
			methodInfo.node = methodDeclaration;
			this.requestor.enterConstructor(methodInfo);
		}
		if (this.reportReferenceInfo) {
			ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
			ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
			if (constructorCall != null) {
				switch(constructorCall.accessMode) {
					case ExplicitConstructorCall.This :
						this.requestor.acceptConstructorReference(
							this.typeNames[this.nestedTypeIndex-1],
							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
							constructorCall.sourceStart);
						break;
					case ExplicitConstructorCall.Super :
					case ExplicitConstructorCall.ImplicitSuper :
						this.requestor.acceptConstructorReference(
							this.superTypeNames[this.nestedTypeIndex-1],
							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
							constructorCall.sourceStart);
						break;
				}
			}
		}
		this.visitIfNeeded(methodDeclaration);
		if (isInRange){
			this.requestor.exitConstructor(methodDeclaration.declarationSourceEnd);
		}
		return;
	}
	selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
	if (isInRange) {
		int currentModifiers = methodDeclaration.modifiers;
//{ObjectTeams: additionally pass AccCallin:
	/* orig:
		currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated | ClassFileConstants.AccAnnotationDefault | ExtraCompilerModifiers.AccDefaultMethod;
    :giro */
		currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ExtraCompilerModifiers.AccCallin | ClassFileConstants.AccDeprecated | ClassFileConstants.AccAnnotationDefault | ExtraCompilerModifiers.AccDefaultMethod;
// SH}
		if (isVarArgs)
			currentModifiers |= ClassFileConstants.AccVarargs;
		if (hasDeprecatedAnnotation(methodDeclaration.annotations))
			currentModifiers |= ClassFileConstants.AccDeprecated;

		TypeReference returnType = methodDeclaration instanceof MethodDeclaration
			? ((MethodDeclaration) methodDeclaration).returnType
			: null;
		methodInfo.isAnnotation = methodDeclaration instanceof AnnotationMethodDeclaration;
		methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
		methodInfo.modifiers = currentModifiers;
		methodInfo.returnType = returnType == null ? null : CharOperation.concatWith(returnType.getParameterizedTypeName(), '.');
		methodInfo.name = methodDeclaration.selector;
		methodInfo.nameSourceStart = methodDeclaration.sourceStart;
		methodInfo.nameSourceEnd = selectorSourceEnd;
		methodInfo.parameterTypes = argumentTypes;
		methodInfo.parameterNames = argumentNames;
//{ObjectTeams: store additional array
		methodInfo.parameterBaseclassFlags = baseclassFlags;
// SH}
		methodInfo.exceptionTypes = thrownExceptionTypes;
		methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
		methodInfo.parameterInfos = parameterInfos;
		methodInfo.categories = this.nodesToCategories.get(methodDeclaration);
		methodInfo.annotations = methodDeclaration.annotations;
		methodInfo.node = methodDeclaration;
		methodInfo.enclosingType = declaringType;
		methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
		this.requestor.enterMethod(methodInfo);
	}

	this.visitIfNeeded(methodDeclaration);

	if (isInRange) {
		if (methodDeclaration instanceof AnnotationMethodDeclaration) {
			AnnotationMethodDeclaration annotationMethodDeclaration = (AnnotationMethodDeclaration) methodDeclaration;
			Expression expression = annotationMethodDeclaration.defaultValue;
			if (expression != null) {
				this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, expression);
				return;
			}
		}
		this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, null);
	}
}
//{OTDTUI: needed for method mappings
private char[] returnTypeName(MethodSpec spec) {
	return (!spec.hasSignature || spec.returnType == null) ?
			null : CharOperation.concatWith(spec.returnType.getParameterizedTypeName(), '.');
}

  public void notifySourceElementRequestor(AbstractMethodMappingDeclaration mapping)
  {
	// range check
	boolean isInRange =
				this.initialPosition <= mapping.sourceStart
				&& this.eofPosition >= mapping.sourceEnd;

		if (isInRange)
		{
			if (mapping instanceof CalloutMappingDeclaration)
			{
				CalloutMappingDeclaration callout = (CalloutMappingDeclaration)mapping;

				// role method spec:
				ISourceElementRequestor.MethodSpecInfo roleInfo= new ISourceElementRequestor.MethodSpecInfo();
				boolean isDeclaration = false;
				if (callout.roleMethodSpec != null) {
					roleInfo.node = callout.roleMethodSpec;
					roleInfo.parameterTypes= argumentTypes(callout.roleMethodSpec);
					roleInfo.parameterNames= argumentNames(callout.roleMethodSpec);
					roleInfo.selector= callout.roleMethodSpec.selector;
					roleInfo.returnType= returnTypeName(callout.roleMethodSpec);
					isDeclaration= callout.roleMethodSpec.isDeclaration;
				}
				// prepare base side:
                char[] baseReturnTypeName = null;
				char[] baseSelector = null;
                if (callout.baseMethodSpec != null) {
                	baseReturnTypeName= returnTypeName(callout.baseMethodSpec);
    				baseSelector= callout.baseMethodSpec.selector;
                }
				if (callout.isCalloutToField())
                {
					ISourceElementRequestor.CalloutToFieldInfo info= new ISourceElementRequestor.CalloutToFieldInfo();
                	info.isSetter= ((FieldAccessSpec)callout.baseMethodSpec).isSetter();
    				info.declarationSourceStart= mapping.declarationSourceStart;
    				info.sourceStart= mapping.sourceStart;
    				info.hasSignature= callout.hasSignature;
    				info.isDeclaration= isDeclaration;
    				info.isOverride= mapping.isCalloutOverride();
    				info.declaredModifiers= callout.declaredModifiers;

    				info.left= roleInfo;

    				// base field spec:
    				info.rightSelector= baseSelector;
    				info.rightReturnType= baseReturnTypeName;

    				info.annotations = mapping.annotations;

					this.requestor.enterCalloutToFieldMapping(info);
                	visitIfNeeded(callout);
                } else {
    				ISourceElementRequestor.CalloutInfo info= new ISourceElementRequestor.CalloutInfo();
    				info.declarationSourceStart= mapping.declarationSourceStart;
    				info.sourceStart= mapping.sourceStart;
    				info.hasSignature= callout.hasSignature;
    				info.isDeclaration= isDeclaration;
    				info.isOverride= mapping.isCalloutOverride();
    				info.declaredModifiers= callout.declaredModifiers;

    				info.left= roleInfo;

    				// base method spec:
    				ISourceElementRequestor.MethodSpecInfo baseInfo= new ISourceElementRequestor.MethodSpecInfo();
    				baseInfo.node = callout.baseMethodSpec;
    				baseInfo.selector= baseSelector;
    				baseInfo.returnType= baseReturnTypeName;
    				baseInfo.parameterTypes= argumentTypes(callout.baseMethodSpec);
    				baseInfo.parameterNames= argumentNames(callout.baseMethodSpec);
    				info.right= baseInfo;

    				info.annotations = mapping.annotations;

    				this.requestor.enterCalloutMapping(info);
    				visitIfNeeded(callout);
                }
			} else {
				CallinMappingDeclaration callinDecl = (CallinMappingDeclaration)mapping;
				ISourceElementRequestor.CallinInfo info= new ISourceElementRequestor.CallinInfo();
				info.declarationSourceStart= mapping.declarationSourceStart;
				info.sourceStart= mapping.sourceStart;
				info.callinName= callinDecl.name;
				info.callinKind= callinDecl.callinModifier;
				info.hasSignature= callinDecl.hasSignature;

				ISourceElementRequestor.MethodSpecInfo roleInfo= new ISourceElementRequestor.MethodSpecInfo();
				roleInfo.node = callinDecl.roleMethodSpec;
				roleInfo.selector= callinDecl.roleMethodSpec.selector;
				roleInfo.returnType= returnTypeName(callinDecl.roleMethodSpec);
				roleInfo.parameterTypes= argumentTypes(callinDecl.roleMethodSpec);
				roleInfo.parameterNames= argumentNames(callinDecl.roleMethodSpec);
				roleInfo.typeParameters = getTypeParameterInfos(callinDecl.roleMethodSpec.typeParameters);
				info.left= roleInfo;

				int baseSpecsLength = (callinDecl.baseMethodSpecs == null) ? 0 : callinDecl.baseMethodSpecs.length;
				ISourceElementRequestor.MethodSpecInfo[] baseInfos= new ISourceElementRequestor.MethodSpecInfo[baseSpecsLength];
				for (int idx=0; idx < baseSpecsLength; idx++)
				{
					MethodSpec spec = callinDecl.baseMethodSpecs[idx];
					baseInfos[idx]= new ISourceElementRequestor.MethodSpecInfo();
				    baseInfos[idx].node = spec;
					baseInfos[idx].selector= spec.selector;
					if (callinDecl.hasSignature) {
						int argListLength = spec.arguments == null ? 0: spec.arguments.length;
						char[][] baseArgTypes= new char[argListLength][];
						char[][] baseArgNames= new char[argListLength][];

						for(int argIdx = 0; argIdx < argListLength; argIdx++)
						{
							char[] argType = Signature.toQualifiedName(spec.arguments[argIdx].type.getParameterizedTypeName());
							baseArgTypes[argIdx] = argType;
							baseArgNames[argIdx] = spec.arguments[argIdx].name;

						}
						baseInfos[idx].parameterNames= baseArgNames;
						baseInfos[idx].parameterTypes= baseArgTypes;
						if (spec.returnType != null)
						    baseInfos[idx].returnType = Signature.toQualifiedName(spec.returnType.getParameterizedTypeName());
					}
				}
				info.right= baseInfos;
				info.covariantReturn= callinDecl.hasCovariantReturn();

				info.annotations = mapping.annotations;

				this.requestor.enterCallinMapping(info);
				visitIfNeeded(callinDecl);
			}
		}

		if (isInRange)
		{
			if (mapping instanceof CalloutMappingDeclaration)
			{
                CalloutMappingDeclaration callout = (CalloutMappingDeclaration)mapping;
                if (callout.isCalloutToField())
                    this.requestor.exitCalloutToFieldMapping(callout.sourceEnd, callout.declarationSourceEnd);
                else
                	this.requestor.exitCalloutMapping(mapping.sourceEnd, mapping.declarationSourceEnd);
			}
			else
			{
				this.requestor.exitCallinMapping(mapping.sourceEnd, mapping.declarationSourceEnd);
			}
		}
  }

  private void visitIfNeeded(CalloutMappingDeclaration callout)
  {
  	if (this.localDeclarationVisitor != null && (callout.bits & ASTNode.HasLocalType) != 0) {
	      if (callout.mappings != null)
  	      {
  	          for (int i = 0; i < callout.mappings.length; i++)
  	          {
  	              callout.mappings[i].traverse(this.localDeclarationVisitor, callout.scope);
  	          }
  	      }
  		}
  }

  private void visitIfNeeded(CallinMappingDeclaration callinDecl)
  {
  	  if (this.localDeclarationVisitor != null && (callinDecl.bits & ASTNode.HasLocalType) != 0) {
  	      if (callinDecl.mappings != null)
  	      {
  	          for (int i = 0; i < callinDecl.mappings.length; i++)
  	          {
  	              callinDecl.mappings[i].traverse(this.localDeclarationVisitor, callinDecl.scope);
  	          }
  	      }
  	  }
  }

	private char[][] argumentNames(MethodSpec methodSpec)
	{
		if (methodSpec == null)
			return null;
		char[][]   argumentNames = null;
		Argument[] arguments     = methodSpec.arguments;

		if (methodSpec.hasSignature && arguments != null)
		{
			int argumentLength = arguments.length;
			argumentNames      = new char[argumentLength][];
			for (int idx = 0; idx < argumentLength; idx++)
			{
				argumentNames[idx] = arguments[idx].name;
			}
		}

		return argumentNames;
	}

	private char[][] argumentTypes(MethodSpec methodSpec)
	{
		if (methodSpec == null)
			return null;
		char[][]   argumentTypes = null;
		Argument[] arguments     = methodSpec.arguments;

		if (methodSpec.hasSignature && arguments != null)
		{
			int argumentLength = arguments.length;
			argumentTypes      = new char[argumentLength][];
			for (int idx = 0; idx < argumentLength; idx++)
			{
				argumentTypes[idx] = CharOperation.concatWith(arguments[idx].type.getParameterizedTypeName(), '.');
			}
		}

		return argumentTypes;
	}
//ak}
/*
 * Update the bodyStart of the corresponding parse node
 */
public void notifySourceElementRequestor(
		CompilationUnitDeclaration parsedUnit,
		int sourceStart,
		int sourceEnd,
		boolean reportReference,
		HashtableOfObjectToInt sourceEndsMap,
		Map nodesToCategoriesMap) {

	this.initialPosition = sourceStart;
	this.eofPosition = sourceEnd;

	this.reportReferenceInfo = reportReference;
	this.sourceEnds = sourceEndsMap;
	this.nodesToCategories = nodesToCategoriesMap;

	try {
		// range check
		boolean isInRange =
					this.initialPosition <= parsedUnit.sourceStart
					&& this.eofPosition >= parsedUnit.sourceEnd;

		// collect the top level ast nodes
		int length = 0;
		ASTNode[] nodes = null;
		if (isInRange) {
			this.requestor.enterCompilationUnit();
		}
		ImportReference currentPackage = parsedUnit.currentPackage;
		if (this.localDeclarationVisitor !=  null) {
			this.localDeclarationVisitor.currentPackage = currentPackage;
		}
		ImportReference[] imports = parsedUnit.imports;
		TypeDeclaration[] types = parsedUnit.types;
		length =
			(currentPackage == null ? 0 : 1)
			+ (imports == null ? 0 : imports.length)
			+ (types == null ? 0 : types.length)
			+ (parsedUnit.moduleDeclaration == null ? 0 : 1);
		nodes = new ASTNode[length];
		int index = 0;
		if (currentPackage != null) {
			nodes[index++] = currentPackage;
		}
		if (imports != null) {
			for (int i = 0, max = imports.length; i < max; i++) {
				nodes[index++] = imports[i];
			}
		}
		if (types != null) {
			for (int i = 0, max = types.length; i < max; i++) {
				nodes[index++] = types[i];
			}
		}
		
		if (parsedUnit.moduleDeclaration != null)
			nodes[index++] = parsedUnit.moduleDeclaration;

		// notify the nodes in the syntactical order
		if (length > 0) {
			quickSort(nodes, 0, length-1);
			for (int i=0;i<length;i++) {
				ASTNode node = nodes[i];
				if (node instanceof ImportReference) {
					ImportReference importRef = (ImportReference)node;
					if (node == parsedUnit.currentPackage) {
						notifySourceElementRequestor(importRef, true);
					} else {
						notifySourceElementRequestor(importRef, false);
					}
				} else if (node instanceof TypeDeclaration) {
					notifySourceElementRequestor((TypeDeclaration)node, true, null, currentPackage);
				} else if (node instanceof ModuleDeclaration) {
					notifySourceElementRequestor(parsedUnit.moduleDeclaration);
				}
			}
		}

		if (isInRange) {
			this.requestor.exitCompilationUnit(parsedUnit.sourceEnd);
		}
	} finally {
		reset();
	}
}

/*
* Update the bodyStart of the corresponding parse node
*/
protected void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) {

	// range check
	boolean isInRange =
				this.initialPosition <= fieldDeclaration.declarationSourceStart
				&& this.eofPosition >= fieldDeclaration.declarationSourceEnd;

	switch(fieldDeclaration.getKind()) {
		case AbstractVariableDeclaration.ENUM_CONSTANT:
			if (this.reportReferenceInfo) {
				// accept constructor reference for enum constant
				if (fieldDeclaration.initialization instanceof AllocationExpression) {
					AllocationExpression alloc = (AllocationExpression) fieldDeclaration.initialization;
					this.requestor.acceptConstructorReference(
						declaringType.name,
						alloc.arguments == null ? 0 : alloc.arguments.length,
						alloc.sourceStart);
				}
			}
			// $FALL-THROUGH$
		case AbstractVariableDeclaration.FIELD:
			int fieldEndPosition = this.sourceEnds.get(fieldDeclaration);
			if (fieldEndPosition == -1) {
				// use the declaration source end by default
				fieldEndPosition = fieldDeclaration.declarationSourceEnd;
			}
			if (isInRange) {
				int currentModifiers = fieldDeclaration.modifiers;

				// remember deprecation so as to not lose it below
				boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(fieldDeclaration.annotations);

				char[] typeName = null;
				if (fieldDeclaration.type == null) {
					// enum constant
					typeName = declaringType.name;
					currentModifiers |= ClassFileConstants.AccEnum;
				} else {
					// regular field
					typeName = CharOperation.concatWith(fieldDeclaration.type.getParameterizedTypeName(), '.');
				}
				ISourceElementRequestor.FieldInfo fieldInfo = new ISourceElementRequestor.FieldInfo();
				fieldInfo.typeAnnotated = ((fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0);
				fieldInfo.declarationStart = fieldDeclaration.declarationSourceStart;
				fieldInfo.name = fieldDeclaration.name;
				fieldInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
				fieldInfo.type = typeName;
				fieldInfo.nameSourceStart = fieldDeclaration.sourceStart;
				fieldInfo.nameSourceEnd = fieldDeclaration.sourceEnd;
				fieldInfo.categories = this.nodesToCategories.get(fieldDeclaration);
				fieldInfo.annotations = fieldDeclaration.annotations;
				fieldInfo.node = fieldDeclaration;
				this.requestor.enterField(fieldInfo);
			}
			this.visitIfNeeded(fieldDeclaration, declaringType);
			if (isInRange){
				this.requestor.exitField(
					// filter out initializations that are not a constant (simple check)
					(fieldDeclaration.initialization == null
							|| fieldDeclaration.initialization instanceof ArrayInitializer
							|| fieldDeclaration.initialization instanceof AllocationExpression
							|| fieldDeclaration.initialization instanceof ArrayAllocationExpression
							|| fieldDeclaration.initialization instanceof Assignment
							|| fieldDeclaration.initialization instanceof ClassLiteralAccess
							|| fieldDeclaration.initialization instanceof MessageSend
							|| fieldDeclaration.initialization instanceof ArrayReference
							|| fieldDeclaration.initialization instanceof ThisReference) ?
						-1 :
						fieldDeclaration.initialization.sourceStart,
					fieldEndPosition,
					fieldDeclaration.declarationSourceEnd);
			}
			break;
		case AbstractVariableDeclaration.INITIALIZER:
			if (isInRange){
				this.requestor.enterInitializer(
					fieldDeclaration.declarationSourceStart,
					fieldDeclaration.modifiers);
			}
			this.visitIfNeeded((Initializer)fieldDeclaration);
			if (isInRange){
				this.requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
			}
			break;
	}
}
protected void notifySourceElementRequestor(
	ImportReference importReference,
	boolean isPackage) {
	if (isPackage) {
		this.requestor.acceptPackage(importReference);
	} else {
		final boolean onDemand = (importReference.bits & ASTNode.OnDemand) != 0;
		this.requestor.acceptImport(
			importReference.declarationSourceStart,
			importReference.declarationSourceEnd,
			importReference.sourceStart,
			onDemand ? importReference.trailingStarPosition : importReference.sourceEnd,
			importReference.tokens,
			onDemand,
			importReference.modifiers);
	}
}
protected void notifySourceElementRequestor(ModuleDeclaration moduleDeclaration) {
	boolean isInRange =
			this.initialPosition <= moduleDeclaration.declarationSourceStart
			&& this.eofPosition >= moduleDeclaration.declarationSourceEnd;
	ISourceElementRequestor.ModuleInfo info = new ISourceElementRequestor.ModuleInfo();
	if (isInRange) {

		int currentModifiers = moduleDeclaration.modifiers;

		// remember deprecation so as to not lose it below
		boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(moduleDeclaration.annotations);

		info.declarationStart = moduleDeclaration.declarationSourceStart;
		info.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
		info.name = TypeConstants.MODULE_INFO_NAME;
		info.nameSourceStart = moduleDeclaration.sourceStart;
		info.nameSourceEnd = moduleDeclaration.sourceEnd;
		info.moduleName = moduleDeclaration.moduleName;
		info.annotations = moduleDeclaration.annotations;
		info.node = moduleDeclaration;
		info.categories = this.nodesToCategories.get(moduleDeclaration);
		fillModuleInfo(moduleDeclaration, info);
		this.requestor.enterModule(info);
		this.requestor.exitModule(moduleDeclaration.declarationSourceEnd);
	}
}
protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {

//{ObjectTeams: don't convert generated types (role ifc part):
	if (typeDeclaration.isGenerated) return;
// SH}

	if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return;

	// range check
	boolean isInRange =
		this.initialPosition <= typeDeclaration.declarationSourceStart
		&& this.eofPosition >= typeDeclaration.declarationSourceEnd;

	FieldDeclaration[] fields = typeDeclaration.fields;
	AbstractMethodDeclaration[] methods = typeDeclaration.methods;
	TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
//{ObjectTeams: treatment for method mappings
	AbstractMethodMappingDeclaration[] bindings    = typeDeclaration.callinCallouts;
//ak}
	int fieldCounter = fields == null ? 0 : fields.length;
	int methodCounter = methods == null ? 0 : methods.length;
	int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
//{ObjectTeams: treatment for method mappings
	int bindingCount = (bindings == null) ? 0 : bindings.length;
//ak}
	int fieldIndex = 0;
	int methodIndex = 0;
	int memberTypeIndex = 0;
//ObjectTeams: treatment for method mappings
	int bindingIndex = 0;
//ak}

	if (notifyTypePresence){
		char[][] interfaceNames = getInterfaceNames(typeDeclaration);
//{ObjectTeams: construction of baseclass's name
		char[] baseclassName = null;
		char[] baseclassAnchor= null;
		if (typeDeclaration.baseclass != null)
		{
			baseclassName = CharOperation.concatWith(
								typeDeclaration.baseclass.getTypeName(),
								'.');
			char[][] anchorNames= ParameterizedSingleTypeReference.getTypeAnchor(typeDeclaration.baseclass);
			if (anchorNames != null)
				baseclassAnchor = CharOperation.concatWith(anchorNames, '.');
		}
//ak}
		int kind = TypeDeclaration.kind(typeDeclaration.modifiers);
		char[] implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
		ISourceElementRequestor.TypeInfo typeInfo = new ISourceElementRequestor.TypeInfo();
		typeInfo.typeAnnotated = ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) != 0);
		if (isInRange) {
			int currentModifiers = typeDeclaration.modifiers;

			// remember deprecation so as to not lose it below
			boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(typeDeclaration.annotations);

			boolean isEnumInit = typeDeclaration.allocation != null && typeDeclaration.allocation.enumConstant != null;
			char[] superclassName;
			if (isEnumInit) {
				currentModifiers |= ClassFileConstants.AccEnum;
				superclassName = declaringType.name;
			} else {
				superclassName = getSuperclassName(typeDeclaration);
			}
			if (typeDeclaration.allocation == null) {
				typeInfo.declarationStart = typeDeclaration.declarationSourceStart;
			} else if (isEnumInit) {
				typeInfo.declarationStart = typeDeclaration.allocation.enumConstant.sourceStart;
			} else {
				typeInfo.declarationStart = typeDeclaration.allocation.sourceStart;
			}
//{ObjectTeams: let Role/Team flags pass through, strip __OT__ prefix
/* orig:
  			typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
			typeInfo.name = typeDeclaration.name;
  :giro */
			typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccOTTypeJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccOTTypeJustFlag;
			typeInfo.name = typeDeclaration.name;
			// existing __OT__ prefix and special treatment for o.o.Team.Confined:
			if (CharOperation.prefixEquals(IOTConstants.OT_DELIM_NAME, typeInfo.name)) {
				typeInfo.name = CharOperation.subarray(typeInfo.name, IOTConstants.OT_DELIM_LEN, -1);
				if (CharOperation.equals(IOTConstants.CONFINED, typeInfo.name) && CharOperation.equals(new char[][]{IOTConstants.CONFINED}, interfaceNames)) {
					// avoid Confined implements Confined (revert manual role splitting)
					superclassName = null;
					interfaceNames = null;
				}
				// filtering interface o.o.T.Confined is already done at the call site.
			}
// SH}
			typeInfo.nameSourceStart = isEnumInit ? typeDeclaration.allocation.enumConstant.sourceStart : typeDeclaration.sourceStart;
			typeInfo.nameSourceEnd = sourceEnd(typeDeclaration);
			typeInfo.superclass = superclassName;
			typeInfo.superinterfaces = interfaceNames;
			typeInfo.typeParameters = getTypeParameterInfos(typeDeclaration.typeParameters);
			typeInfo.categories = this.nodesToCategories.get(typeDeclaration);
			typeInfo.secondary = typeDeclaration.isSecondary();
			typeInfo.anonymousMember = typeDeclaration.allocation != null && typeDeclaration.allocation.enclosingInstance != null;
			typeInfo.annotations = typeDeclaration.annotations;
			typeInfo.extraFlags = ExtraFlags.getExtraFlags(typeDeclaration);
			typeInfo.node = typeDeclaration;
//{ObjectTeams: added baseclass reference, isRoleFile:
			typeInfo.baseclassName = baseclassName; // yes, interfaces will have a baseclass, too. (Current compiler limitation though).
			typeInfo.baseclassAnchor = baseclassAnchor;
			typeInfo.isRoleFile = typeDeclaration.isRoleFile();
//haebor,km});
			this.requestor.enterType(typeInfo);
			switch (kind) {
				case TypeDeclaration.CLASS_DECL :
					if (superclassName != null)
						implicitSuperclassName = superclassName;
					break;
				case TypeDeclaration.INTERFACE_DECL :
					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
					break;
				case TypeDeclaration.ENUM_DECL :
					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ENUM;
					break;
				case TypeDeclaration.ANNOTATION_TYPE_DECL :
					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION;
					break;
			}
		}
		if (this.nestedTypeIndex == this.typeNames.length) {
			// need a resize
			System.arraycopy(this.typeNames, 0, (this.typeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
			System.arraycopy(this.superTypeNames, 0, (this.superTypeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
		}
		this.typeNames[this.nestedTypeIndex] = typeDeclaration.name;
		this.superTypeNames[this.nestedTypeIndex++] = implicitSuperclassName;
	}
	while ((fieldIndex < fieldCounter)
			|| (memberTypeIndex < memberTypeCounter)
			|| (methodIndex < methodCounter)
// {ObjectTeams: treatment for method mappings
		    || (bindingIndex < bindingCount))
// orig:
	{
		FieldDeclaration nextFieldDeclaration = null;
		AbstractMethodDeclaration nextMethodDeclaration = null;
		TypeDeclaration nextMemberDeclaration = null;
// :giro
		AbstractMethodMappingDeclaration nextBindingDeclaration = null;
//ak}

		int position = Integer.MAX_VALUE;
		int nextDeclarationType = -1;
		if (fieldIndex < fieldCounter) {
			nextFieldDeclaration = fields[fieldIndex];
			if (nextFieldDeclaration.declarationSourceStart < position) {
				position = nextFieldDeclaration.declarationSourceStart;
				nextDeclarationType = 0; // FIELD
			}
		}
		if (methodIndex < methodCounter) {
			nextMethodDeclaration = methods[methodIndex];
			if (nextMethodDeclaration.declarationSourceStart < position) {
				position = nextMethodDeclaration.declarationSourceStart;
				nextDeclarationType = 1; // METHOD
			}
		}
		if (memberTypeIndex < memberTypeCounter) {
			nextMemberDeclaration = memberTypes[memberTypeIndex];
			if (nextMemberDeclaration.declarationSourceStart < position) {
				position = nextMemberDeclaration.declarationSourceStart;
				nextDeclarationType = 2; // MEMBER
			}
		}
//{ObjectTeams: treatment for method mappings
		if (bindingIndex < bindingCount)
		{
			nextBindingDeclaration = bindings[bindingIndex];
			if (nextBindingDeclaration.sourceStart < position)
			{
				position = nextBindingDeclaration.sourceStart;
				nextDeclarationType = 3; // BINDING
			}
		}
//ak}
		switch (nextDeclarationType) {
			case 0 :
				fieldIndex++;
//{ObjectTeams: don't convert _OT$.. fields:
				if (   nextFieldDeclaration.name != null
					&& CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, nextFieldDeclaration.name))
					break;
// SH}
				notifySourceElementRequestor(nextFieldDeclaration, typeDeclaration);
				break;
			case 1 :
				methodIndex++;
//{ObjectTeams: don't convert generated methods:
				if (nextMethodDeclaration.isGenerated && !(nextMethodDeclaration instanceof GuardPredicateDeclaration)) 
					break;
// SH}
				notifySourceElementRequestor(nextMethodDeclaration, typeDeclaration, currentPackage);
				break;
			case 2 :
				memberTypeIndex++;
//{ObjectTeams: don't convert interface o.o.T.Confined:
				if (   currentPackage != null && CharOperation.equals(IOTConstants.ORG_OBJECTTEAMS, currentPackage.tokens)
					&& CharOperation.equals(IOTConstants.TEAM, typeDeclaration.name)
					&& CharOperation.equals(IOTConstants.CONFINED, nextMemberDeclaration.name))
					break;
				notifySourceElementRequestor(nextMemberDeclaration, true, null, currentPackage);
//{ObjectTeams: treatment for method mappings
				break;
            case 3:
            	bindingIndex++;
            	notifySourceElementRequestor(nextBindingDeclaration);
            	break;
//ak}
		}
	}
	if (notifyTypePresence){
		if (isInRange){
			this.requestor.exitType(typeDeclaration.declarationSourceEnd);
		}
		this.nestedTypeIndex--;
	}
}
private void fillModuleInfo(ModuleDeclaration mod, ISourceElementRequestor.ModuleInfo modInfo) {
	if (mod.requiresCount > 0) {
		ISourceElementRequestor.RequiresInfo reqs[] = new ISourceElementRequestor.RequiresInfo[mod.requiresCount];
		for (int i = 0; i < mod.requiresCount; i++) {
			ISourceElementRequestor.RequiresInfo req = new ISourceElementRequestor.RequiresInfo();
			req.moduleName = CharOperation.concatWith(mod.requires[i].module.tokens, '.');
			req.modifiers = mod.requires[i].modifiers;
			reqs[i] = req;
		}
		modInfo.requires = reqs;
	}
	if (mod.exportsCount > 0) {
		ISourceElementRequestor.PackageExportInfo exps[] = new ISourceElementRequestor.PackageExportInfo[mod.exportsCount];
		for (int i = 0; i < mod.exportsCount; i++) {
			ISourceElementRequestor.PackageExportInfo exp = new ISourceElementRequestor.PackageExportInfo();
			ExportsStatement exportsStatement = mod.exports[i];
			exp.pkgName = exportsStatement.pkgName;
			if (exportsStatement.targets == null) {
				exp.targets = CharOperation.NO_CHAR_CHAR;
			} else {
				exp.targets = new char[exportsStatement.targets.length][];
				for(int j = 0; j < exp.targets.length; j++) {
					exp.targets[j] = CharOperation.concatWith(exportsStatement.targets[j].tokens, '.');
				}
			}
			exps[i] = exp;
		}					
		modInfo.exports = exps;
	}
	if (mod.servicesCount > 0) {
		ISourceElementRequestor.ServicesInfo[] services = new ISourceElementRequestor.ServicesInfo[mod.servicesCount];
		for (int i = 0; i < services.length; i++) {
			ISourceElementRequestor.ServicesInfo ser = new ISourceElementRequestor.ServicesInfo();
			ser.serviceName = CharOperation.concatWith(mod.services[i].serviceInterface.getParameterizedTypeName(), '.');
			ser.implNames = new char[mod.services[i].implementations.length][];
			for (int j = 0; j < ser.implNames.length; j++) {
				ser.implNames[j] = CharOperation.concatWith(mod.services[i].implementations[j].getParameterizedTypeName(), '.');
			}
			services[i] = ser;
		}
		modInfo.services = services;
	}
	if (mod.usesCount > 0) {
		char[][] uses = new char[mod.usesCount][];
		for (int i = 0; i < uses.length; i++) {
			uses[i] = CharOperation.concatWith(mod.uses[i].serviceInterface.getParameterizedTypeName(), '.');
		}
		modInfo.usedServices = uses;
	}
	if (mod.opensCount > 0) {
		ISourceElementRequestor.PackageExportInfo opens[] = new ISourceElementRequestor.PackageExportInfo[mod.opensCount];
		for (int i = 0; i < mod.opensCount; i++) {
			ISourceElementRequestor.PackageExportInfo op = new ISourceElementRequestor.PackageExportInfo();
			OpensStatement openStmt = mod.opens[i];
			op.pkgName = openStmt.pkgName;
			if (openStmt.targets == null) {
				op.targets = CharOperation.NO_CHAR_CHAR;
			} else {
				op.targets = new char[openStmt.targets.length][];
				for(int j = 0; j < op.targets.length; j++) {
					op.targets[j] = CharOperation.concatWith(openStmt.targets[j].tokens, '.');
				}
			}
			opens[i] = op;
		}
		modInfo.opens = opens;
	}
}
/*
 * Sort the given ast nodes by their positions.
 */
private static void quickSort(ASTNode[] sortedCollection, int left, int right) {
	int original_left = left;
	int original_right = right;
	ASTNode mid = sortedCollection[left +  (right - left) / 2];
	do {
		while (sortedCollection[left].sourceStart < mid.sourceStart) {
			left++;
		}
		while (mid.sourceStart < sortedCollection[right].sourceStart) {
			right--;
		}
		if (left <= right) {
			ASTNode tmp = sortedCollection[left];
			sortedCollection[left] = sortedCollection[right];
			sortedCollection[right] = tmp;
			left++;
			right--;
		}
	} while (left <= right);
	if (original_left < right) {
		quickSort(sortedCollection, original_left, right);
	}
	if (left < original_right) {
		quickSort(sortedCollection, left, original_right);
	}
}
private void reset() {
	this.typeNames = new char[4][];
	this.superTypeNames = new char[4][];
	this.nestedTypeIndex = 0;

	this.sourceEnds = null;
}
private int sourceEnd(TypeDeclaration typeDeclaration) {
	if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
		QualifiedAllocationExpression allocation = typeDeclaration.allocation;
		if (allocation.enumConstant != null) // case of enum constant body
			return allocation.enumConstant.sourceEnd;
		return allocation.type.sourceEnd;
	} else {
		return typeDeclaration.sourceEnd;
	}
}
private void visitIfNeeded(AbstractMethodDeclaration method) {
	if (this.localDeclarationVisitor != null
		&& (method.bits & ASTNode.HasLocalType) != 0) {
			if (method instanceof ConstructorDeclaration) {
				ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method;
				if (constructorDeclaration.constructorCall != null) {
					constructorDeclaration.constructorCall.traverse(this.localDeclarationVisitor, method.scope);
				}
			}
			if (method.statements != null) {
				int statementsLength = method.statements.length;
				for (int i = 0; i < statementsLength; i++)
					method.statements[i].traverse(this.localDeclarationVisitor, method.scope);
			}
	}
}

private void visitIfNeeded(FieldDeclaration field, TypeDeclaration declaringType) {
	if (this.localDeclarationVisitor != null
		&& (field.bits & ASTNode.HasLocalType) != 0) {
			if (field.initialization != null) {
				try {
					this.localDeclarationVisitor.pushDeclaringType(declaringType);
					field.initialization.traverse(this.localDeclarationVisitor, (MethodScope) null);
				} finally {
					this.localDeclarationVisitor.popDeclaringType();
				}
			}
	}
}

private void visitIfNeeded(Initializer initializer) {
	if (this.localDeclarationVisitor != null
		&& (initializer.bits & ASTNode.HasLocalType) != 0) {
			if (initializer.block != null) {
				initializer.block.traverse(this.localDeclarationVisitor, null);
			}
	}
}
}
