/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann - Contribution for
 *								bug 393719 - [compiler] inconsistent warnings on iteration variables
 *******************************************************************************/

package org.eclipse.jdt.core.dom;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.ModuleModifier.ModuleModifierKeyword;
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.Argument;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.ModuleReference;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.WrapperKind;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.core.dom.SourceRangeVerifier;
import org.eclipse.jdt.internal.core.util.Util;
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.BaseReference;
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.LiftingTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ParameterMapping;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TsuperReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.WithinStatement;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.lifting.Lowering;
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.statemachine.transformer.MethodSignatureEnhancer;

/**
 * Internal class for converting internal compiler ASTs into public ASTs.
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
class ASTConverter {

	protected AST ast;
	private ASTNode referenceContext;
	protected Comment[] commentsTable;
	char[] compilationUnitSource;
	int compilationUnitSourceLength;
	protected DocCommentParser docParser;
	// comments
	protected boolean insideComments;
	protected IProgressMonitor monitor;
	protected Set pendingNameScopeResolution;
	protected Set pendingThisExpressionScopeResolution;
	protected boolean resolveBindings;
	Scanner scanner;
	private DefaultCommentMapper commentMapper;
//{ObjectTeams: one more configuration option:
	private boolean includeRoleFiles= false;
	private WeavingScheme weavingScheme = WeavingScheme.OTRE; // avoid null
// SH}

	public ASTConverter(Map<String, String> options, boolean resolveBindings, IProgressMonitor monitor) {
		this.resolveBindings = resolveBindings;
		this.referenceContext = null;
		String sourceModeSetting = options.get(JavaCore.COMPILER_SOURCE);
		long sourceLevel = CompilerOptions.versionToJdkLevel(sourceModeSetting);
		if (sourceLevel == 0) {
			// unknown sourceModeSetting
			sourceLevel = ClassFileConstants.JDK1_3;
		}
//{ObjectTeams: one more configuration option:
		Object roleFileOption= options.get(JavaCore.AST_INCLUDES_ROLE_FILES);
		if (roleFileOption != null)
			this.includeRoleFiles= JavaCore.ENABLED.equals(roleFileOption);
// SH}

		this.scanner = new Scanner(
			true /*comment*/,
			false /*whitespace*/,
			false /*nls*/,
			sourceLevel /*sourceLevel*/,
			null /*taskTags*/,
			null/*taskPriorities*/,
			true/*taskCaseSensitive*/,
			JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES)));
		this.monitor = monitor;
		this.insideComments = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
//{ObjectTeams: initialize scanner mode from options
		this.scanner.setOTFlags(new CompilerOptions(options));
		Object option = options.get(JavaCore.COMPILER_OPT_WEAVING_SCHEME);
		if (option != null)
			this.weavingScheme = WeavingScheme.valueOf((String) option);
// SH}
	}

	protected void adjustSourcePositionsForParent(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
		int start = expression.sourceStart;
		int end = expression.sourceEnd;
		int leftParentCount = 1;
		int rightParentCount = 0;
		this.scanner.resetTo(start, end);
		try {
			int token = this.scanner.getNextToken();
			expression.sourceStart = this.scanner.currentPosition;
			boolean stop = false;
			while (!stop && ((token  = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) {
				switch(token) {
					case TerminalTokens.TokenNameLPAREN:
						leftParentCount++;
						break;
					case TerminalTokens.TokenNameRPAREN:
						rightParentCount++;
						if (rightParentCount == leftParentCount) {
							// we found the matching parenthesis
							stop = true;
						}
				}
			}
			expression.sourceEnd = this.scanner.startPosition - 1;
		} catch(InvalidInputException e) {
			// ignore
		}
	}

	protected void buildBodyDeclarations(
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration,
			AbstractTypeDeclaration typeDecl,
			boolean isInterface) {
		// add body declaration in the lexical order
		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = typeDeclaration.memberTypes;
		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = typeDeclaration.fields;
		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = typeDeclaration.methods;

		int fieldsLength = fields == null? 0 : fields.length;
		int methodsLength = methods == null? 0 : methods.length;
		int membersLength = members == null ? 0 : members.length;
		int fieldsIndex = 0;
		int methodsIndex = 0;
		int membersIndex = 0;

//{ObjectTeams: more setup before the loop:
		// members were sorted by inheritance, restore lexical order:
		if (typeDeclaration.isTeam() && members != null)
			Arrays.sort(members, new Comparator<org.eclipse.jdt.internal.compiler.ast.TypeDeclaration>() {
				@Override
				public int compare(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration t1,
								   org.eclipse.jdt.internal.compiler.ast.TypeDeclaration t2) {
					return (t1.sourceStart < t2.sourceStart) ? -1 : 1;
			}});

		// method mapping declarations (callins, callouts)
		org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration[] callinCallouts = typeDeclaration.callinCallouts;
		int methodMappingsLength = callinCallouts == null ? 0 : callinCallouts.length;
		int methodMappingsIndex = 0;
//gbr+SH}

		while ((fieldsIndex < fieldsLength)
			|| (membersIndex < membersLength)
//{ObjectTeams
			|| (methodMappingsIndex < methodMappingsLength)
//gbr}
			|| (methodsIndex < methodsLength)) {
			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
//{ObjectTeams
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration nextMethodMappingDeclaration = null;
//gbr}

			int position = Integer.MAX_VALUE;
			int nextDeclarationType = -1;
//{ObjectTeams: skip generated / synthetic elements:
			while (fieldsIndex < fieldsLength && shouldIgnore(fields[fieldsIndex]))
				fieldsIndex++;
			while (methodsIndex < methodsLength && shouldIgnore(methods[methodsIndex]))
				methodsIndex++;
			while (membersIndex < membersLength && shouldIgnore(members[membersIndex]))
				membersIndex++;
// SH}
			if (fieldsIndex < fieldsLength) {
				nextFieldDeclaration = fields[fieldsIndex];
				if (nextFieldDeclaration.declarationSourceStart < position) {
					position = nextFieldDeclaration.declarationSourceStart;
					nextDeclarationType = 0; // FIELD
				}
			}
			if (methodsIndex < methodsLength) {
				nextMethodDeclaration = methods[methodsIndex];
				if (nextMethodDeclaration.declarationSourceStart < position) {
					position = nextMethodDeclaration.declarationSourceStart;
					nextDeclarationType = 1; // METHOD
				}
			}
			if (membersIndex < membersLength) {
				nextMemberDeclaration = members[membersIndex];
				if (nextMemberDeclaration.declarationSourceStart < position) {
					position = nextMemberDeclaration.declarationSourceStart;
					nextDeclarationType = 2; // MEMBER
				}
			}
//{ObjectTeams: case added for method mappings
			if (methodMappingsIndex < methodMappingsLength)
			{
				nextMethodMappingDeclaration = callinCallouts[methodMappingsIndex];
				if (nextMethodMappingDeclaration.sourceStart < position)
				{
					position = nextMethodMappingDeclaration.sourceStart;
					nextDeclarationType = 3; // METHOD_MAPPING
				}
			}
//gbr}
			switch (nextDeclarationType) {
				case 0 :
					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
						typeDecl.bodyDeclarations().add(convert(nextFieldDeclaration));
					} else {
						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, typeDecl.bodyDeclarations());
					}
					fieldsIndex++;
					break;
				case 1 :
					methodsIndex++;
					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
						typeDecl.bodyDeclarations().add(convert(isInterface, nextMethodDeclaration));
					}
//{ObjectTeams: convert reused abstract method declaration
					else if (isReusedAbstractMethodDeclaration(typeDeclaration,nextMethodDeclaration))
					{
						typeDecl.bodyDeclarations().add(convertReusedAbstractMethodDeclaration(isInterface, nextMethodDeclaration));
					}
//jsv}
					break;
				case 2 :
					membersIndex++;
					ASTNode node = convert(nextMemberDeclaration);
					if (node == null) {
						typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
					} else {
						typeDecl.bodyDeclarations().add(node);
					}
//{ObjectTeams: case statement added for method mappings
					break;
				case 3 :
					methodMappingsIndex++;
                    if (nextMethodMappingDeclaration != null)
                    {
                        typeDecl.bodyDeclarations().add(convert(nextMethodMappingDeclaration));
                    }
//gbr}
			}
		}
		// Convert javadoc
		convert(typeDeclaration.javadoc, typeDecl);
	}

	protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2, EnumDeclaration enumDeclaration) {
		// add body declaration in the lexical order
		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = enumDeclaration2.memberTypes;
		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = enumDeclaration2.fields;
		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = enumDeclaration2.methods;

		int fieldsLength = fields == null? 0 : fields.length;
		int methodsLength = methods == null? 0 : methods.length;
		int membersLength = members == null ? 0 : members.length;
		int fieldsIndex = 0;
		int methodsIndex = 0;
		int membersIndex = 0;

		while ((fieldsIndex < fieldsLength)
			|| (membersIndex < membersLength)
			|| (methodsIndex < methodsLength)) {
			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;

			int position = Integer.MAX_VALUE;
			int nextDeclarationType = -1;
			if (fieldsIndex < fieldsLength) {
				nextFieldDeclaration = fields[fieldsIndex];
				if (nextFieldDeclaration.declarationSourceStart < position) {
					position = nextFieldDeclaration.declarationSourceStart;
					nextDeclarationType = 0; // FIELD
				}
			}
			if (methodsIndex < methodsLength) {
				nextMethodDeclaration = methods[methodsIndex];
				if (nextMethodDeclaration.declarationSourceStart < position) {
					position = nextMethodDeclaration.declarationSourceStart;
					nextDeclarationType = 1; // METHOD
				}
			}
			if (membersIndex < membersLength) {
				nextMemberDeclaration = members[membersIndex];
				if (nextMemberDeclaration.declarationSourceStart < position) {
					position = nextMemberDeclaration.declarationSourceStart;
					nextDeclarationType = 2; // MEMBER
				}
			}
			switch (nextDeclarationType) {
				case 0 :
					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
						enumDeclaration.enumConstants().add(convert(nextFieldDeclaration));
					} else {
						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, enumDeclaration.bodyDeclarations());
					}
					fieldsIndex++;
					break;
				case 1 :
					methodsIndex++;
					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
						enumDeclaration.bodyDeclarations().add(convert(false, nextMethodDeclaration));
					}
					break;
				case 2 :
					membersIndex++;
					enumDeclaration.bodyDeclarations().add(convert(nextMemberDeclaration));
					break;
			}
		}
		convert(enumDeclaration2.javadoc, enumDeclaration);
	}

	protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration expression, AnonymousClassDeclaration anonymousClassDeclaration) {
		// add body declaration in the lexical order
		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = expression.memberTypes;
		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = expression.fields;
		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = expression.methods;

		int fieldsLength = fields == null? 0 : fields.length;
		int methodsLength = methods == null? 0 : methods.length;
		int membersLength = members == null ? 0 : members.length;
		int fieldsIndex = 0;
		int methodsIndex = 0;
		int membersIndex = 0;

		while ((fieldsIndex < fieldsLength)
			|| (membersIndex < membersLength)
			|| (methodsIndex < methodsLength)) {
			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;

			int position = Integer.MAX_VALUE;
			int nextDeclarationType = -1;
//{ObjectTeams: skip generated / synthetic elements:
			while (fieldsIndex < fieldsLength && shouldIgnore(fields[fieldsIndex]))
				fieldsIndex++;
			while (methodsIndex < methodsLength && shouldIgnore(methods[methodsIndex]))
				methodsIndex++;
			while (membersIndex < membersLength && shouldIgnore(members[membersIndex]))
				membersIndex++;
// SH}
			if (fieldsIndex < fieldsLength) {
				nextFieldDeclaration = fields[fieldsIndex];
				if (nextFieldDeclaration.declarationSourceStart < position) {
					position = nextFieldDeclaration.declarationSourceStart;
					nextDeclarationType = 0; // FIELD
				}
			}
			if (methodsIndex < methodsLength) {
				nextMethodDeclaration = methods[methodsIndex];
				if (nextMethodDeclaration.declarationSourceStart < position) {
					position = nextMethodDeclaration.declarationSourceStart;
					nextDeclarationType = 1; // METHOD
				}
			}
			if (membersIndex < membersLength) {
				nextMemberDeclaration = members[membersIndex];
				if (nextMemberDeclaration.declarationSourceStart < position) {
					position = nextMemberDeclaration.declarationSourceStart;
					nextDeclarationType = 2; // MEMBER
				}
			}
			switch (nextDeclarationType) {
				case 0 :
					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
						anonymousClassDeclaration.bodyDeclarations().add(convert(nextFieldDeclaration));
					} else {
						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, anonymousClassDeclaration.bodyDeclarations());
					}
					fieldsIndex++;
					break;
				case 1 :
					methodsIndex++;
					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
						anonymousClassDeclaration.bodyDeclarations().add(convert(false, nextMethodDeclaration));
					}
//{ObjectTeams: convert reused abstract method declaration
					else if (isReusedAbstractMethodDeclaration(expression, nextMethodDeclaration))
					{
						anonymousClassDeclaration.bodyDeclarations().add(convertReusedAbstractMethodDeclaration(false, nextMethodDeclaration));
					}
//jsv}
					break;
				case 2 :
					membersIndex++;
					ASTNode node = convert(nextMemberDeclaration);
					if (node == null) {
						anonymousClassDeclaration.setFlags(anonymousClassDeclaration.getFlags() | ASTNode.MALFORMED);
					} else {
						anonymousClassDeclaration.bodyDeclarations().add(node);
					}
			}
		}
	}

	private void checkAndSetMalformed(ASTNode spannedNode, ASTNode spanningNode) {
		if ((spannedNode.getFlags() & ASTNode.MALFORMED) != 0) {
			spanningNode.setFlags(spanningNode.getFlags() | ASTNode.MALFORMED);
		}
	}
	/**
	 * Internal access method to SwitchCase#setExpression() for avoiding deprecated warnings
	 * @param switchCase
	 * @param exp
	 * @deprecated
	 */
	private static void internalSetExpression(SwitchCase switchCase, Expression exp) {
		switchCase.setExpression(exp);
	}
	/** 
	 * Internal access method to SingleVariableDeclaration#setExtraDimensions() for avoiding deprecated warnings
	 *
	 * @param node
	 * @param dimensions
	 * @deprecated
	 */
	private static void internalSetExtraDimensions(SingleVariableDeclaration node, int dimensions) {
		node.setExtraDimensions(dimensions);
	}
	/** 
	 * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings
	 *
	 * @param node
	 * @param dimensions
	 * @deprecated
	 */
	private static void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) {
		node.setExtraDimensions(dimensions);
	}
	/** 
	 * Internal access method to MethodDeclaration#setExtraDimension() for avoiding deprecated warnings
	 *
	 * @param node
	 * @param dimensions
	 * @deprecated
	 */
	private static void internalSetExtraDimensions(MethodDeclaration node, int dimensions) {
		node.setExtraDimensions(dimensions);
	}
	/** 
	 * Internal access method to MethodDeclaration#thrownExceptions() for avoiding deprecated warnings
	 *
	 * @param node
	 * @deprecated
	 */
	private static List internalThownExceptions(MethodDeclaration node) {
		return node.thrownExceptions();
	}

//{ObjectTeams: detect synthetic elements to ignore:
	private boolean shouldIgnore(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration field) {
		return field.isGenerated || field.copyInheritanceSrc != null || Flags.isSynthetic(field.modifiers);
	}

	private boolean shouldIgnore(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration method) {
		// always skip guard predicates which come as methods (are converted via field TypeDeclaration.predicate):
		if (method instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration)
			return true;
		// other than predicates do not skip abstract methods reused for a callout:
		if (method.isReusingSourceMethod && method.isMappingWrapper == WrapperKind.CALLOUT)
			return false;
		return method.isGenerated || method.isCopied;
	}

	private boolean shouldIgnore(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration type) {
		return type.isGenerated || Flags.isSynthetic(type.modifiers)
				// also skip generated members and role files when visited via enclosing team - conditionally:
				|| (!this.includeRoleFiles && type.isRoleFile());
	}
// SH}

	/**
	 * @param compilationUnit
	 * @param comments
	 */
	void buildCommentsTable(CompilationUnit compilationUnit, int[][] comments) {
		// Build comment table
		this.commentsTable = new Comment[comments.length];
		int nbr = 0;
		for (int i = 0; i < comments.length; i++) {
			Comment comment = createComment(comments[i]);
			if (comment != null) {
				comment.setAlternateRoot(compilationUnit);
				this.commentsTable[nbr++] = comment;
			}
		}
		// Resize table if  necessary
		if (nbr<comments.length) {
			Comment[] newCommentsTable = new Comment[nbr];
			System.arraycopy(this.commentsTable, 0, newCommentsTable, 0, nbr);
			this.commentsTable = newCommentsTable;
		}
		compilationUnit.setCommentTable(this.commentsTable);
	}

	protected void checkAndAddMultipleFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List bodyDeclarations) {
//{ObjecTeams: ignore generated field declarations
        if (Flags.isSynthetic(fields[index].modifiers) || fields[index].copyInheritanceSrc != null)
        {
            return;
        }
//jwl}
		if (fields[index] instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
			org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) fields[index];
			Initializer initializer = new Initializer(this.ast);
			initializer.setBody(convert(oldInitializer.block));
			setModifiers(initializer, oldInitializer);
			initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
			// The javadoc comment is now got from list store in compilation unit declaration
			convert(oldInitializer.javadoc, initializer);
			bodyDeclarations.add(initializer);
			return;
		}
		if (index > 0 && fields[index - 1].declarationSourceStart == fields[index].declarationSourceStart) {
			// we have a multiple field declaration
			// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
			FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclarations.get(bodyDeclarations.size() - 1);
			fieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fields[index]));
		} else {
			// we can create a new FieldDeclaration
			bodyDeclarations.add(convertToFieldDeclaration(fields[index]));
		}
	}

	protected void checkAndAddMultipleLocalDeclaration(org.eclipse.jdt.internal.compiler.ast.Statement[] stmts, int index, List blockStatements) {
		if (index > 0
				&& stmts[index - 1] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration
//{ObjectTeams: ignore generated variable declarations within blocks
				&& !((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]).isGenerated) {
//jwl}
			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local1 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index - 1];
			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local2 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index];
			if (local1.declarationSourceStart == local2.declarationSourceStart) {
				// we have a multiple local declarations
				// We retrieve the existing VariableDeclarationStatement to add the new VariableDeclarationFragment
				VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) blockStatements.get(blockStatements.size() - 1);
				variableDeclarationStatement.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
			} else {
				// we can create a new FieldDeclaration
				blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
			}
		} else {
			// we can create a new FieldDeclaration
			blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
		}
	}

	protected void checkCanceled() {
		if (this.monitor != null && this.monitor.isCanceled())
			throw new OperationCanceledException();
	}

	private int checkLength(int start, int end) {
		int len = end - start + 1;
		return len > 0 ? len : 0;
	}
	protected void completeRecord(ArrayType arrayType, org.eclipse.jdt.internal.compiler.ast.ASTNode astNode) {
		ArrayType array = arrayType;
		this.recordNodes(arrayType, astNode);
		if (this.ast.apiLevel() >= AST.JLS8_INTERNAL) {
			this.recordNodes(arrayType.getElementType(), astNode);
			return;
		}
		int dimensions = array.getDimensions();
		for (int i = 0; i < dimensions; i++) {
			Type componentType = componentType(array);
			this.recordNodes(componentType, astNode);
			if (componentType.isArrayType()) {
				array = (ArrayType) componentType;
			}
		}
	}
	
	/**
	 * @deprecated
	 */
	private Type componentType(ArrayType array) {
		return array.getComponentType();
	}

	public ASTNode convert(boolean isInterface, org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
		checkCanceled();
		if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) {
			return convert((org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) methodDeclaration);
		}
		MethodDeclaration methodDecl = new MethodDeclaration(this.ast);
		ASTNode oldReferenceContext = this.referenceContext;
		this.referenceContext = methodDecl;
		setModifiers(methodDecl, methodDeclaration);
		boolean isConstructor = methodDeclaration.isConstructor();
		methodDecl.setConstructor(isConstructor);
		final SimpleName methodName = new SimpleName(this.ast);
		methodName.internalSetIdentifier(new String(methodDeclaration.selector));
		int start = methodDeclaration.sourceStart;
		int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
		if (end < start)
			end = start + methodDeclaration.selector.length;// naive recovery with method name
		methodName.setSourceRange(start, end - start + 1);
		methodDecl.setName(methodName);
		org.eclipse.jdt.internal.compiler.ast.TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
		int methodHeaderEnd = methodDeclaration.sourceEnd;
		int thrownExceptionsLength = thrownExceptions == null ? 0 : thrownExceptions.length;
		if (thrownExceptionsLength > 0) {
			if (this.ast.apiLevel() < AST.JLS8_INTERNAL) {
				Name thrownException;
				int i = 0;
				do {
					TypeReference typeRef = thrownExceptions[i++];
					thrownException = convert(typeRef);
					if (typeRef.annotations != null && typeRef.annotations.length > 0) {
						thrownException.setFlags(thrownException.getFlags() | ASTNode.MALFORMED);
					}
					internalThownExceptions(methodDecl).add(thrownException);
				} while (i < thrownExceptionsLength);
				methodHeaderEnd = thrownException.getStartPosition() + thrownException.getLength();				
			} else {
				Type thrownExceptionType;
				int i = 0;
				do {
					thrownExceptionType = convertType(thrownExceptions[i++]);
					methodDecl.thrownExceptionTypes().add(thrownExceptionType);
				} while (i < thrownExceptionsLength);
				methodHeaderEnd = thrownExceptionType.getStartPosition() + thrownExceptionType.getLength();				
			}
		}

		if (methodDeclaration.receiver != null) {
			if(this.ast.apiLevel >= AST.JLS8_INTERNAL) {
				convertAndSetReceiver(methodDeclaration, methodDecl);
			} else {
				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
			}
		}
//{ObjectTeams:
/* orig:
		org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = methodDeclaration.arguments;
  :giro */
		org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = MethodSignatureEnhancer.getSourceArguments(methodDeclaration, this.weavingScheme);
// SH}
		int parametersLength = parameters == null ? 0 : parameters.length;
		if (parametersLength > 0) {
			SingleVariableDeclaration parameter;
			int i = 0;
			do {
				parameter = convert(parameters[i++]);
				methodDecl.parameters().add(parameter);
			} while (i < parametersLength);
			if (thrownExceptionsLength == 0) {
				methodHeaderEnd = parameter.getStartPosition() + parameter.getLength();
			}
		}
		org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall explicitConstructorCall = null;
		if (isConstructor) {
			if (isInterface) {
				// interface cannot have a constructor
				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
			}
			org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
			explicitConstructorCall = constructorDeclaration.constructorCall;
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					// set the return type to VOID
					PrimitiveType returnType = new PrimitiveType(this.ast);
					returnType.setPrimitiveTypeCode(PrimitiveType.VOID);
					returnType.setSourceRange(methodDeclaration.sourceStart, 0);
					methodDecl.internalSetReturnType(returnType);
					break;
				default :
					methodDecl.setReturnType2(null);
			}
		} else if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) {
			org.eclipse.jdt.internal.compiler.ast.MethodDeclaration method = (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) methodDeclaration;
			org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = method.returnType;
			if (typeReference != null) {
				Type returnType = convertType(typeReference);
				// get the positions of the right parenthesis
				int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd);
				int extraDimensions = typeReference.extraDimensions();
				if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
					setExtraAnnotatedDimensions(rightParenthesisPosition, method.bodyEnd, typeReference,
												methodDecl.extraDimensions(), extraDimensions);
				} else {
					internalSetExtraDimensions(methodDecl, extraDimensions);
				}
				setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions);
			} else {
				// no return type for a method that is not a constructor
				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						break;
					default :
						methodDecl.setReturnType2(null);
				}
			}
//{ObjectTeams:
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration guard = method.predicate;
			if (guard != null)
				methodDecl.setGuardPredicate(convertGuardPredicate(guard));
// SH}
		}
		int declarationSourceStart = methodDeclaration.declarationSourceStart;
		int bodyEnd = methodDeclaration.bodyEnd;
		methodDecl.setSourceRange(declarationSourceStart, checkLength(declarationSourceStart, bodyEnd));
		int declarationSourceEnd = methodDeclaration.declarationSourceEnd;
//{ObjectTeams: adjust positions for callout wrappers reusing a source method:
		if (declarationSourceEnd < declarationSourceStart) {
			assert (methodDeclaration.isCalloutWrapper() && methodDeclaration.isReusingSourceMethod): "should only happen for reused source methods"; //$NON-NLS-1$
			// declarationSourceStart is pointing to the abstract method declaration,
			// here we need positions for the generated wrapper which are derived from the callout mapping:
			declarationSourceStart= methodDeclaration.bodyStart;
			methodDecl.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
		}
// SH}
		int rightBraceOrSemiColonPositionStart = bodyEnd == declarationSourceEnd ? bodyEnd : bodyEnd + 1;
		int closingPosition = retrieveRightBraceOrSemiColonPosition(rightBraceOrSemiColonPositionStart, declarationSourceEnd);
		if (closingPosition != -1) {
			int startPosition = methodDecl.getStartPosition();
			methodDecl.setSourceRange(startPosition, closingPosition - startPosition + 1);

			org.eclipse.jdt.internal.compiler.ast.Statement[] statements = methodDeclaration.statements;

			start = retrieveStartBlockPosition(methodHeaderEnd, methodDeclaration.bodyStart);
			if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
			end = retrieveRightBrace(methodDeclaration.bodyEnd + 1, declarationSourceEnd);
			Block block = null;
			if (start != -1 && end != -1) {
				/*
				 * start or end can be equal to -1 if we have an interface's method.
				 */
				block = new Block(this.ast);
				block.setSourceRange(start, closingPosition - start + 1);
				methodDecl.setBody(block);
			}
			if (block != null && (statements != null || explicitConstructorCall != null)) {
				if (explicitConstructorCall != null && explicitConstructorCall.accessMode != org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall.ImplicitSuper) {
					block.statements().add(convert(explicitConstructorCall));
				}
				int statementsLength = statements == null ? 0 : statements.length;
				for (int i = 0; i < statementsLength; i++) {
//{ObjectTeams: ignore generated local declarations within method declarations
                    if ((statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)
                          && ((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statements[i]).isGenerated) {
                        continue;
                    }
//jwl}
					if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
						checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
					} else {
						final Statement statement = convert(statements[i]);
						if (statement != null) {
							block.statements().add(statement);
						}
					}
				}
			}
			if (block != null) {
				if ((methodDeclaration.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccNative)) != 0
						|| (isInterface && (this.ast.apiLevel < AST.JLS8_INTERNAL ||
							(methodDeclaration.modifiers & (ClassFileConstants.AccStatic | ExtraCompilerModifiers.AccDefaultMethod |
									(this.ast.apiLevel > AST.JLS8_INTERNAL ? ClassFileConstants.AccPrivate : 0))) == 0))) {
					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
				}
			}
		} else {
			// syntax error in this method declaration
			methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
			if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract()) {
				start = retrieveStartBlockPosition(methodHeaderEnd, bodyEnd);
				if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
				end = methodDeclaration.bodyEnd;
				// try to get the best end position
				CategorizedProblem[] problems = methodDeclaration.compilationResult().problems;
				if (problems != null) {
					for (int i = 0, max = methodDeclaration.compilationResult().problemCount; i < max; i++) {
						CategorizedProblem currentProblem = problems[i];
						if (currentProblem.getSourceStart() == start && currentProblem.getID() == IProblem.ParsingErrorInsertToComplete) {
							end = currentProblem.getSourceEnd();
							break;
						}
					}
				}
				int startPosition = methodDecl.getStartPosition();
				methodDecl.setSourceRange(startPosition, checkLength(startPosition, end));
				if (start != -1 && end != -1) {
					/*
					 * start or end can be equal to -1 if we have an interface's method.
					 */
					Block block = new Block(this.ast);
					block.setSourceRange(start, checkLength(start, end));
					methodDecl.setBody(block);
				}
			}
		}

		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = methodDeclaration.typeParameters();
		if (typeParameters != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					for (int i = 0, max = typeParameters.length; i < max; i++) {
						methodDecl.typeParameters().add(convert(typeParameters[i]));
					}
			}
		}

		// The javadoc comment is now got from list store in compilation unit declaration
		convert(methodDeclaration.javadoc, methodDecl);
		if (this.resolveBindings) {
			recordNodes(methodDecl, methodDeclaration);
			recordNodes(methodName, methodDeclaration);
			methodDecl.resolveBinding();
		}
		this.referenceContext = oldReferenceContext;
		return methodDecl;
	}

	public ClassInstanceCreation convert(org.eclipse.jdt.internal.compiler.ast.AllocationExpression expression) {
		ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
		if (this.resolveBindings) {
			recordNodes(classInstanceCreation, expression);
		}
		if (expression.typeArguments != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					for (int i = 0, max = expression.typeArguments.length; i < max; i++) {
						classInstanceCreation.typeArguments().add(convertType(expression.typeArguments[i]));
					}
			}
		}
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				classInstanceCreation.internalSetName(convert(expression.type));
				break;
			default :
				classInstanceCreation.setType(convertType(expression.type));
		}
		classInstanceCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
		if (arguments != null) {
			int length = arguments.length;
			for (int i = 0; i < length; i++) {
				classInstanceCreation.arguments().add(convert(arguments[i]));
			}
		}
		return classInstanceCreation;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression expression) {
		InfixExpression infixExpression = new InfixExpression(this.ast);
		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
		if (this.resolveBindings) {
			this.recordNodes(infixExpression, expression);
		}
		final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
			// create an extended string literal equivalent => use the extended operands list
			infixExpression.extendedOperands().add(convert(expression.right));
			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
			do {
				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
				 	List extendedOperands = infixExpression.extendedOperands();
				 	InfixExpression temp = new InfixExpression(this.ast);
					if (this.resolveBindings) {
						this.recordNodes(temp, expression);
					}
				 	temp.setOperator(getOperatorFor(expressionOperatorID));
				 	Expression leftSide = convert(leftOperand);
					temp.setLeftOperand(leftSide);
					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
					int size = extendedOperands.size();
				 	for (int i = 0; i < size - 1; i++) {
				 		Expression expr = temp;
				 		temp = new InfixExpression(this.ast);

						if (this.resolveBindings) {
							this.recordNodes(temp, expression);
						}
				 		temp.setLeftOperand(expr);
					 	temp.setOperator(getOperatorFor(expressionOperatorID));
						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
				 	}
				 	infixExpression = temp;
				 	for (int i = 0; i < size; i++) {
				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
				 		temp.setRightOperand(extendedOperand);
				 		int startPosition = temp.getLeftOperand().getStartPosition();
				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
				 			temp = (InfixExpression) temp.getLeftOperand();
				 		}
				 	}
				 	setInfixSourcePositions(infixExpression, expression.sourceStart);
					if (this.resolveBindings) {
						this.recordNodes(infixExpression, expression);
					}
					return infixExpression;
				}
				infixExpression.extendedOperands().add(0, convert(rightOperand));
				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
			Expression leftExpression = convert(leftOperand);
			infixExpression.setLeftOperand(leftExpression);
			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
		 	setInfixSourcePositions(infixExpression, expression.sourceStart);
			return infixExpression;
		}
		Expression leftExpression = convert(expression.left);
		infixExpression.setLeftOperand(leftExpression);
		infixExpression.setRightOperand(convert(expression.right));
		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
	 	setInfixSourcePositions(infixExpression, expression.sourceStart);
		return infixExpression;
	}

	private AnnotationTypeDeclaration convertToAnnotationDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
		checkCanceled();
		if (this.scanner.sourceLevel < ClassFileConstants.JDK1_5) return null;
		AnnotationTypeDeclaration typeDecl = this.ast.newAnnotationTypeDeclaration();
		setModifiers(typeDecl, typeDeclaration);
		final SimpleName typeName = new SimpleName(this.ast);
		typeName.internalSetIdentifier(new String(typeDeclaration.name));
		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
		typeDecl.setName(typeName);
		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);

		buildBodyDeclarations(typeDeclaration, typeDecl, false);
		// The javadoc comment is now got from list store in compilation unit declaration
		if (this.resolveBindings) {
			recordNodes(typeDecl, typeDeclaration);
			recordNodes(typeName, typeDeclaration);
			typeDecl.resolveBinding();
		}
		return typeDecl;
	}

	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
		checkCanceled();
		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
			return null;
		}
		AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = new AnnotationTypeMemberDeclaration(this.ast);
		setModifiers(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
		final SimpleName methodName = new SimpleName(this.ast);
		methodName.internalSetIdentifier(new String(annotationTypeMemberDeclaration.selector));
		int start = annotationTypeMemberDeclaration.sourceStart;
		int end = retrieveIdentifierEndPosition(start, annotationTypeMemberDeclaration.sourceEnd);
		methodName.setSourceRange(start, end - start + 1);
		annotationTypeMemberDeclaration2.setName(methodName);
		org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = annotationTypeMemberDeclaration.returnType;
		if (typeReference != null) {
			Type returnType = convertType(typeReference);
			setTypeForMethodDeclaration(annotationTypeMemberDeclaration2, returnType, 0);
		}
		int declarationSourceStart = annotationTypeMemberDeclaration.declarationSourceStart;
		int declarationSourceEnd = annotationTypeMemberDeclaration.bodyEnd;
		annotationTypeMemberDeclaration2.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
		// The javadoc comment is now got from list store in compilation unit declaration
		convert(annotationTypeMemberDeclaration.javadoc, annotationTypeMemberDeclaration2);
		org.eclipse.jdt.internal.compiler.ast.Expression memberValue = annotationTypeMemberDeclaration.defaultValue;
		if (memberValue != null) {
			annotationTypeMemberDeclaration2.setDefault(convert(memberValue));
		}
		if (this.resolveBindings) {
			recordNodes(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
			recordNodes(methodName, annotationTypeMemberDeclaration);
			annotationTypeMemberDeclaration2.resolveBinding();
		}
		return annotationTypeMemberDeclaration2;
	}

	private void convertAndSetReceiver(AbstractMethodDeclaration method, MethodDeclaration methodDecl) {
		Receiver receiver = method.receiver;
		if (receiver.qualifyingName != null) {
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(receiver.qualifyingName.getName()[0]));
			int start = receiver.qualifyingName.sourceStart;
			int nameEnd = receiver.qualifyingName.sourceEnd;
			name.setSourceRange(start, nameEnd - start + 1);
			methodDecl.setReceiverQualifier(name);
			if (this.resolveBindings) {
				recordNodes(name, receiver);
			}
		}
		Type type = convertType(receiver.type);
		methodDecl.setReceiverType(type);
		if (receiver.modifiers != 0) {
			methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
		}
		if (this.resolveBindings) {
			recordNodes(type, receiver);
			type.resolveBinding();
		}
	}

	public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) {
		SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
		setModifiers(variableDecl, argument);
		final SimpleName name = new SimpleName(this.ast);
//{ObjectTeams: we have to check the variable name e.g. in a LiftingType
		String[] tokens = (new String(argument.name)).split("\\"+IOTConstants.JAVA_SEPARATOR); //$NON-NLS-1$
		String realName = tokens[tokens.length-1];
		name.internalSetIdentifier(realName);
/* orig:
		name.internalSetIdentifier(new String(argument.name));
  :giro */
//jsv}
		if (argument instanceof Receiver) {
			name.setFlags(name.getFlags() | ASTNode.MALFORMED);
		}
		int start = argument.sourceStart;
		int nameEnd = argument.sourceEnd;
		name.setSourceRange(start, nameEnd - start + 1);
		variableDecl.setName(name);
		final int typeSourceEnd = argument.type.sourceEnd;
		TypeReference typeReference = argument.type;
		final int extraDimensions = typeReference.extraDimensions();
		if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
			setExtraAnnotatedDimensions(nameEnd + 1, typeSourceEnd, typeReference,
										variableDecl.extraDimensions(), extraDimensions);
		} else {
			internalSetExtraDimensions(variableDecl, extraDimensions);
		}
		final boolean isVarArgs = argument.isVarArgs();
		if (isVarArgs && extraDimensions == 0) {
			// remove the ellipsis from the type source end
			argument.type.sourceEnd = retrieveEllipsisStartPosition(argument.type.sourceStart, typeSourceEnd);
		}
		Type type = convertType(argument.type);
		int typeEnd = type.getStartPosition() + type.getLength() - 1;
		int rightEnd = Math.max(typeEnd, argument.declarationSourceEnd);
		/*
		 * There is extra work to do to set the proper type positions
		 * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
		 */
		if (isVarArgs) {
			Dimension lastDimension = null;
			if (this.ast.apiLevel() >= AST.JLS8_INTERNAL) {
				if (type.isArrayType()) { // should always be true
					List dimensions = ((ArrayType) type).dimensions();
					if (!dimensions.isEmpty()) {
						lastDimension = (Dimension) dimensions.get(dimensions.size() - 1);
					}
				}
			}
			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1);
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898
			if (this.ast.apiLevel() >= AST.JLS8_INTERNAL) {
				if (lastDimension != null) { // should always be true
					List annotations = lastDimension.annotations();
					Iterator iter = annotations.iterator();
					while (iter.hasNext()) {
						Annotation annotation = (Annotation) iter.next();
						annotation.setParent(null, null);
						variableDecl.varargsAnnotations().add(annotation);
					}
				}
			}
			if (extraDimensions != 0) {
				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
			}
		} else {
			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
		}
		variableDecl.setSourceRange(argument.declarationSourceStart, rightEnd - argument.declarationSourceStart + 1);

		if (isVarArgs) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					variableDecl.setVarargs(true);
			}
		}
		if (this.resolveBindings) {
			recordNodes(name, argument);
			recordNodes(variableDecl, argument);
			variableDecl.resolveBinding();
		}
		return variableDecl;
	}


	public Annotation convert(org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
		if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) {
			return convert((org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) annotation);
		} else if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) {
			return convert((org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) annotation);
		} else {
			return convert((org.eclipse.jdt.internal.compiler.ast.NormalAnnotation) annotation);
		}
	}

	public ArrayCreation convert(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression expression) {
		ArrayCreation arrayCreation = new ArrayCreation(this.ast);
		if (this.resolveBindings) {
			recordNodes(arrayCreation, expression);
		}
		arrayCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		org.eclipse.jdt.internal.compiler.ast.Expression[] dimensions = expression.dimensions;

		int dimensionsLength = dimensions.length;
		for (int i = 0; i < dimensionsLength; i++) {
			if (dimensions[i] != null) {
				Expression dimension = convert(dimensions[i]);
				if (this.resolveBindings) {
					recordNodes(dimension, dimensions[i]);
				}
				arrayCreation.dimensions().add(dimension);
			}
		}
		Type type = convertType(expression.type);
		if (this.resolveBindings) {
			recordNodes(type, expression.type);
		}
		ArrayType arrayType = null;
		if (type.isArrayType()) {
			arrayType = (ArrayType) type;
			if (expression.annotationsOnDimensions != null) {
				if (this.ast.apiLevel() < AST.JLS8_INTERNAL) {
					arrayType.setFlags(arrayType.getFlags() | ASTNode.MALFORMED);
				} else {
					setTypeAnnotationsAndSourceRangeOnArray(arrayType, expression.annotationsOnDimensions);
				}
			}
		} else {
			arrayType = convertToArray(type, type.getStartPosition(), -1, dimensionsLength, expression.annotationsOnDimensions);
		}
		arrayCreation.setType(arrayType);
		if (this.resolveBindings) {
			completeRecord(arrayType, expression);
		}
		if (expression.initializer != null) {
			arrayCreation.setInitializer(convert(expression.initializer));
		}
		return arrayCreation;
	}

	public ArrayInitializer convert(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer expression) {
		ArrayInitializer arrayInitializer = new ArrayInitializer(this.ast);
		if (this.resolveBindings) {
			recordNodes(arrayInitializer, expression);
		}
		arrayInitializer.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = expression.expressions;
		if (expressions != null) {
			int length = expressions.length;
			for (int i = 0; i < length; i++) {
				Expression expr = convert(expressions[i]);
				if (this.resolveBindings) {
					recordNodes(expr, expressions[i]);
				}
				arrayInitializer.expressions().add(expr);
			}
		}
		return arrayInitializer;
	}

	public ArrayAccess convert(org.eclipse.jdt.internal.compiler.ast.ArrayReference reference) {
		ArrayAccess arrayAccess = new ArrayAccess(this.ast);
		if (this.resolveBindings) {
			recordNodes(arrayAccess, reference);
		}
		arrayAccess.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
		arrayAccess.setArray(convert(reference.receiver));
		arrayAccess.setIndex(convert(reference.position));
		return arrayAccess;
	}

	public AssertStatement convert(org.eclipse.jdt.internal.compiler.ast.AssertStatement statement) {
		AssertStatement assertStatement = new AssertStatement(this.ast);
		final Expression assertExpression = convert(statement.assertExpression);
		Expression searchingNode = assertExpression;
		assertStatement.setExpression(assertExpression);
		org.eclipse.jdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
		if (exceptionArgument != null) {
			final Expression exceptionMessage = convert(exceptionArgument);
			assertStatement.setMessage(exceptionMessage);
			searchingNode = exceptionMessage;
		}
		int start = statement.sourceStart;
		int sourceEnd = retrieveSemiColonPosition(searchingNode);
		if (sourceEnd == -1) {
			sourceEnd = searchingNode.getStartPosition() + searchingNode.getLength() - 1;
			assertStatement.setSourceRange(start, sourceEnd - start + 1);
		} else {
			assertStatement.setSourceRange(start, sourceEnd - start + 1);
		}
		return assertStatement;
	}

	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.Assignment expression) {
		Assignment assignment = new Assignment(this.ast);
		if (this.resolveBindings) {
			recordNodes(assignment, expression);
		}
		Expression lhs = convert(expression.lhs);
		assignment.setLeftHandSide(lhs);
		assignment.setOperator(Assignment.Operator.ASSIGN);
		Expression rightHandSide = convert(expression.expression);
		assignment.setRightHandSide(rightHandSide);
		int start = lhs.getStartPosition();
		int end = rightHandSide.getStartPosition() + rightHandSide.getLength() - 1;
		assignment.setSourceRange(start, end - start + 1);
		return assignment;
	}

	/*
	 * Internal use only
	 * Used to convert class body declarations
	 */
	public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes) {
		final TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
		ASTNode oldReferenceContext = this.referenceContext;
		this.referenceContext = typeDecl;
		typeDecl.setInterface(false);
		int nodesLength = nodes.length;
		for (int i = 0; i < nodesLength; i++) {
			org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodes[i];
			if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
				org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) node;
				Initializer initializer = new Initializer(this.ast);
				initializer.setBody(convert(oldInitializer.block));
				setModifiers(initializer, oldInitializer);
				initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
//				setJavaDocComment(initializer);
//				initializer.setJavadoc(convert(oldInitializer.javadoc));
				convert(oldInitializer.javadoc, initializer);
				typeDecl.bodyDeclarations().add(initializer);
			} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
				org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
				if (i > 0
					&& (nodes[i - 1] instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)
					&& ((org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)nodes[i - 1]).declarationSourceStart == fieldDeclaration.declarationSourceStart) {
					// we have a multiple field declaration
					// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
					FieldDeclaration currentFieldDeclaration = (FieldDeclaration) typeDecl.bodyDeclarations().get(typeDecl.bodyDeclarations().size() - 1);
					currentFieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fieldDeclaration));
				} else {
					// we can create a new FieldDeclaration
					typeDecl.bodyDeclarations().add(convertToFieldDeclaration(fieldDeclaration));
				}
			} else if(node instanceof org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) {
				AbstractMethodDeclaration nextMethodDeclaration = (AbstractMethodDeclaration) node;
				if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
//{ObjectTeams: ignore generated and copied method declarations
                    if (!nextMethodDeclaration.isGenerated && !nextMethodDeclaration.isCopied)
//jwl}
					typeDecl.bodyDeclarations().add(convert(false, nextMethodDeclaration));
				}
//{ObjectTeams: method mappings:
			} else if (node instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration) {
				AbstractMethodMappingDeclaration nextMethodMapping = convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration) node);
				if (nextMethodMapping == null) {
					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
				} else {
					typeDecl.bodyDeclarations().add(nextMethodMapping);
				}
// SH}
			} else if(node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
				ASTNode nextMemberDeclarationNode = convert(nextMemberDeclaration);
				if (nextMemberDeclarationNode == null) {
					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
				} else {
//{ObjectTeams: ignore generated role interfaces
	                 if (!Flags.isSynthetic(nextMemberDeclaration.modifiers))
//	jwl}
					typeDecl.bodyDeclarations().add(nextMemberDeclarationNode);
				}
			}
		}
		this.referenceContext = oldReferenceContext;
		return typeDecl;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.BinaryExpression expression) {
		InfixExpression infixExpression = new InfixExpression(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(infixExpression, expression);
		}

		int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
		infixExpression.setOperator(getOperatorFor(expressionOperatorID));

		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
			// create an extended string literal equivalent => use the extended operands list
			infixExpression.extendedOperands().add(convert(expression.right));
			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
			do {
				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
				 	List extendedOperands = infixExpression.extendedOperands();
				 	InfixExpression temp = new InfixExpression(this.ast);
					if (this.resolveBindings) {
						this.recordNodes(temp, expression);
					}
				 	temp.setOperator(getOperatorFor(expressionOperatorID));
				 	Expression leftSide = convert(leftOperand);
					temp.setLeftOperand(leftSide);
					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
					int size = extendedOperands.size();
				 	for (int i = 0; i < size - 1; i++) {
				 		Expression expr = temp;
				 		temp = new InfixExpression(this.ast);

						if (this.resolveBindings) {
							this.recordNodes(temp, expression);
						}
				 		temp.setLeftOperand(expr);
					 	temp.setOperator(getOperatorFor(expressionOperatorID));
						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
				 	}
				 	infixExpression = temp;
				 	for (int i = 0; i < size; i++) {
				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
				 		temp.setRightOperand(extendedOperand);
				 		int startPosition = temp.getLeftOperand().getStartPosition();
				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
				 			temp = (InfixExpression) temp.getLeftOperand();
				 		}
				 	}
					setInfixSourcePositions(infixExpression, infixExpression.getLeftOperand().getStartPosition());
					if (this.resolveBindings) {
						this.recordNodes(infixExpression, expression);
					}
					return infixExpression;
				}
				infixExpression.extendedOperands().add(0, convert(rightOperand));
				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
			Expression leftExpression = convert(leftOperand);
			infixExpression.setLeftOperand(leftExpression);
			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
			int startPosition = leftExpression.getStartPosition();
			setInfixSourcePositions(infixExpression, startPosition);
			return infixExpression;
		} else if (expression.left instanceof StringLiteralConcatenation
				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)
				&& (OperatorIds.PLUS == expressionOperatorID)) {
			StringLiteralConcatenation literal = (StringLiteralConcatenation) expression.left;
			final org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = literal.literals;
			infixExpression.setLeftOperand(convert(stringLiterals[0]));
			infixExpression.setRightOperand(convert(stringLiterals[1]));
			for (int i = 2; i < literal.counter; i++) {
				infixExpression.extendedOperands().add(convert(stringLiterals[i]));
			}
			infixExpression.extendedOperands().add(convert(expression.right));
			int startPosition = literal.sourceStart;
			setInfixSourcePositions(infixExpression, startPosition);
			return infixExpression;
		}
		Expression leftExpression = convert(expression.left);
		infixExpression.setLeftOperand(leftExpression);
		infixExpression.setRightOperand(convert(expression.right));
		int startPosition = leftExpression.getStartPosition();
		setInfixSourcePositions(infixExpression, startPosition);
		return infixExpression;
	}

	public Block convert(org.eclipse.jdt.internal.compiler.ast.Block statement) {
		Block block = new Block(this.ast);
		if (statement.sourceEnd > 0) {
			block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		}
		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
		if (statements != null) {
			int statementsLength = statements.length;
			for (int i = 0; i < statementsLength; i++) {
				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration
//{ObjectTeams: ignore generated local declarations within blocs
                        && !((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statements[i]).isGenerated) {
//jwl}
					checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
				} else {
					Statement statement2 = convert(statements[i]);
					if (statement2 != null) {
						block.statements().add(statement2);
					}
				}
			}
		}
		return block;
	}

	public BreakStatement convert(org.eclipse.jdt.internal.compiler.ast.BreakStatement statement)  {
		BreakStatement breakStatement = new BreakStatement(this.ast);
		breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		if (statement.label != null) {
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(statement.label));
			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
			breakStatement.setLabel(name);
		}
		return breakStatement;
	}

	public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
		SwitchCase switchCase = new SwitchCase(this.ast);
		if (this.ast.isPreviewEnabled()) {
			org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = statement.constantExpressions;
			if (expressions == null || expressions.length == 0) {
				switchCase.expressions().clear();
			} else {
				for (org.eclipse.jdt.internal.compiler.ast.Expression expression : expressions) {
					switchCase.expressions().add(convert(expression));
				}
			}
		} else {
			org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
			if (constantExpression == null) {
				internalSetExpression(switchCase, null);
			} else {
				internalSetExpression(switchCase, convert(constantExpression));
			}
		}
		if (this.ast.isPreviewEnabled()) {
			switchCase.setSwitchLabeledRule(statement.isExpr);
		}
		switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		if (statement.isExpr) {
			retrieveArrowPosition(switchCase);
		} else {
			retrieveColonPosition(switchCase);
		}
		return switchCase;
	}

	public CastExpression convert(org.eclipse.jdt.internal.compiler.ast.CastExpression expression) {
		CastExpression castExpression = new CastExpression(this.ast);
		castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		TypeReference type = expression.type;
		trimWhiteSpacesAndComments(type);
		castExpression.setType(convertType(type));
		castExpression.setExpression(convert(expression.expression));
		if (this.resolveBindings) {
			recordNodes(castExpression, expression);
		}
		return castExpression;
	}

	public CharacterLiteral convert(org.eclipse.jdt.internal.compiler.ast.CharLiteral expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		CharacterLiteral literal = new CharacterLiteral(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}
	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess expression) {
		TypeLiteral typeLiteral = new TypeLiteral(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(typeLiteral, expression);
		}
		typeLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		typeLiteral.setType(convertType(expression.type));
		return typeLiteral;
	}

	public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
		try {
			if(unit.compilationResult.recoveryScannerData != null) {
				RecoveryScanner recoveryScanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused());
				this.scanner = recoveryScanner;
				this.docParser.scanner = this.scanner;
			}
			this.compilationUnitSource = source;
			this.compilationUnitSourceLength = source.length;
			this.scanner.setSource(source, unit.compilationResult);
			CompilationUnit compilationUnit = new CompilationUnit(this.ast);
			compilationUnit.setStatementsRecoveryData(unit.compilationResult.recoveryScannerData);
	
			// Parse comments
			int[][] comments = unit.comments;
			if (comments != null) {
				buildCommentsTable(compilationUnit, comments);
			}
	
			// handle the package declaration immediately
			// There is no node corresponding to the package declaration
			if (this.resolveBindings) {
				recordNodes(compilationUnit, unit);
			}
			if (unit.currentPackage != null) {
				PackageDeclaration packageDeclaration = convertPackage(unit);
				compilationUnit.setPackage(packageDeclaration);
			}
			org.eclipse.jdt.internal.compiler.ast.ImportReference[] imports = unit.imports;
			if (imports != null) {
				int importLength = imports.length;
				for (int i = 0; i < importLength; i++) {
					compilationUnit.imports().add(convertImport(imports[i]));
				}
			}
	
			org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration mod = unit.moduleDeclaration;
			if (mod != null) {
				ASTNode declaration = convertToModuleDeclaration(mod);
				if (declaration == null) {
					compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
				} else {
					compilationUnit.setModule((ModuleDeclaration) declaration);
				}
			} else {
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
				if (types != null) {
					int typesLength = types.length;
					for (int i = 0; i < typesLength; i++) {
						org.eclipse.jdt.internal.compiler.ast.TypeDeclaration declaration = types[i];
						if (CharOperation.equals(declaration.name, TypeConstants.PACKAGE_INFO_NAME)) {
							continue;
						}
						ASTNode type = convert(declaration);
						if (type == null) {
							compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
						} else {
							if (type instanceof ModuleDeclaration)
								compilationUnit.setModule((ModuleDeclaration) type);
							else
//{ObjectTeams: ignore generated role interfaces
		                      if (!Flags.isSynthetic(types[i].modifiers))
// jwl}
								compilationUnit.types().add(type);
						}
					}
				}
			}
			compilationUnit.setSourceRange(unit.sourceStart, unit.sourceEnd - unit.sourceStart  + 1);

			int problemLength = unit.compilationResult.problemCount;
			if (problemLength != 0) {
				CategorizedProblem[] resizedProblems = null;
				final CategorizedProblem[] problems = unit.compilationResult.getProblems();
				final int realProblemLength=problems.length;
				if (realProblemLength == problemLength) {
					resizedProblems = problems;
				} else {
					System.arraycopy(problems, 0, (resizedProblems = new CategorizedProblem[realProblemLength]), 0, realProblemLength);
				}
				ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
				compilationUnit.accept(syntaxErrorPropagator);
				ASTRecoveryPropagator recoveryPropagator =
					new ASTRecoveryPropagator(resizedProblems, unit.compilationResult.recoveryScannerData);
				compilationUnit.accept(recoveryPropagator);
				compilationUnit.setProblems(resizedProblems);
			}
			if (this.resolveBindings) {
				lookupForScopes();
			}
			compilationUnit.initCommentMapper(this.scanner);
			if (SourceRangeVerifier.DEBUG) {
				String bugs = new SourceRangeVerifier().process(compilationUnit);
				if (bugs != null) {
					StringBuffer message = new StringBuffer("Bad AST node structure:");  //$NON-NLS-1$
					String lineDelimiter = Util.findLineSeparator(source);
					if (lineDelimiter == null) lineDelimiter = System.getProperty("line.separator");//$NON-NLS-1$
					message.append(lineDelimiter);
					message.append(bugs.replaceAll("\n", lineDelimiter)); //$NON-NLS-1$
					message.append(lineDelimiter);
					message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
					message.append(lineDelimiter);
					message.append(source);
					message.append(lineDelimiter);
					message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
					Util.log(new IllegalStateException("Bad AST node structure"), message.toString()); //$NON-NLS-1$
					if (SourceRangeVerifier.DEBUG_THROW) {
						throw new IllegalStateException(message.toString());
					}
				}
			}
			return compilationUnit;
		} catch(IllegalArgumentException e) {
			StringBuffer message = new StringBuffer("Exception occurred during compilation unit conversion:");  //$NON-NLS-1$
			String lineDelimiter = Util.findLineSeparator(source);
			if (lineDelimiter == null) lineDelimiter = System.getProperty("line.separator");//$NON-NLS-1$
			message.append(lineDelimiter);
			message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
			message.append(lineDelimiter);
			message.append(source);
			message.append(lineDelimiter);
			message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
			Util.log(e, message.toString());
			throw e;
		}
	}

	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment expression) {
		Assignment assignment = new Assignment(this.ast);
		Expression lhs = convert(expression.lhs);
		assignment.setLeftHandSide(lhs);
		int start = lhs.getStartPosition();
		assignment.setSourceRange(start, expression.sourceEnd - start + 1);
		switch (expression.operator) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
				assignment.setOperator(Assignment.Operator.PLUS_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
				assignment.setOperator(Assignment.Operator.MINUS_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
				assignment.setOperator(Assignment.Operator.TIMES_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
				assignment.setOperator(Assignment.Operator.DIVIDE_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
				assignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
				assignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
				assignment.setOperator(Assignment.Operator.BIT_XOR_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
				assignment.setOperator(Assignment.Operator.REMAINDER_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
				assignment.setOperator(Assignment.Operator.LEFT_SHIFT_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
				assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
				assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN);
				break;
		}
		assignment.setRightHandSide(convert(expression.expression));
		if (this.resolveBindings) {
			recordNodes(assignment, expression);
		}
		return assignment;
	}

	public ConditionalExpression convert(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression expression) {
		ConditionalExpression conditionalExpression = new ConditionalExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(conditionalExpression, expression);
		}
		conditionalExpression.setExpression(convert(expression.condition));
		conditionalExpression.setThenExpression(convert(expression.valueIfTrue));
		Expression elseExpression = convert(expression.valueIfFalse);
		conditionalExpression.setElseExpression(elseExpression);
		conditionalExpression.setSourceRange(expression.sourceStart, elseExpression.getStartPosition() + elseExpression.getLength() - expression.sourceStart);
		return conditionalExpression;
	}

	public ContinueStatement convert(org.eclipse.jdt.internal.compiler.ast.ContinueStatement statement)  {
		ContinueStatement continueStatement = new ContinueStatement(this.ast);
		continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		if (statement.label != null) {
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(statement.label));
			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
			continueStatement.setLabel(name);
		}
		return continueStatement;
	}

	public DoStatement convert(org.eclipse.jdt.internal.compiler.ast.DoStatement statement) {
		DoStatement doStatement = new DoStatement(this.ast);
		doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		doStatement.setExpression(convert(statement.condition));
		final Statement action = convert(statement.action);
		if (action == null) return null;
		doStatement.setBody(action);
		return doStatement;
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	public EmptyStatement convert(org.eclipse.jdt.internal.compiler.ast.EmptyStatement statement) {
		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
		emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		return emptyStatement;
	}

	// field is an enum constant
	public EnumConstantDeclaration convert(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration enumConstant) {
		checkCanceled();
		EnumConstantDeclaration enumConstantDeclaration = new EnumConstantDeclaration(this.ast);
		final SimpleName typeName = new SimpleName(this.ast);
		typeName.internalSetIdentifier(new String(enumConstant.name));
		typeName.setSourceRange(enumConstant.sourceStart, enumConstant.sourceEnd - enumConstant.sourceStart + 1);
		enumConstantDeclaration.setName(typeName);
		int declarationSourceStart = enumConstant.declarationSourceStart;
		int declarationSourceEnd = enumConstant.declarationSourceEnd;
		final org.eclipse.jdt.internal.compiler.ast.Expression initialization = enumConstant.initialization;
		if (initialization != null) {
			if (initialization instanceof QualifiedAllocationExpression) {
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousType = ((QualifiedAllocationExpression) initialization).anonymousType;
				if (anonymousType != null) {
					AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
					int start = retrieveStartBlockPosition(anonymousType.sourceEnd, anonymousType.bodyEnd);
					int end = retrieveRightBrace(anonymousType.bodyEnd +1, declarationSourceEnd);
					if (end == -1) end = anonymousType.bodyEnd;
					anonymousClassDeclaration.setSourceRange(start, end - start + 1);
					enumConstantDeclaration.setAnonymousClassDeclaration(anonymousClassDeclaration);
					buildBodyDeclarations(anonymousType, anonymousClassDeclaration);
					if (this.resolveBindings) {
						recordNodes(anonymousClassDeclaration, anonymousType);
						anonymousClassDeclaration.resolveBinding();
					}
					enumConstantDeclaration.setSourceRange(declarationSourceStart, end - declarationSourceStart + 1);
				}
			} else {
				enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
			}
			final org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = ((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) initialization).arguments;
			if (arguments != null) {
				for (int i = 0, max = arguments.length; i < max; i++) {
					enumConstantDeclaration.arguments().add(convert(arguments[i]));
				}
			}
		} else {
			enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
		}
		setModifiers(enumConstantDeclaration, enumConstant);
		if (this.resolveBindings) {
			recordNodes(enumConstantDeclaration, enumConstant);
			recordNodes(typeName, enumConstant);
			enumConstantDeclaration.resolveVariable();
		}
		convert(enumConstant.javadoc, enumConstantDeclaration);
		return enumConstantDeclaration;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.EqualExpression expression) {
		InfixExpression infixExpression = new InfixExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(infixExpression, expression);
		}
		Expression leftExpression = convert(expression.left);
		infixExpression.setLeftOperand(leftExpression);
		infixExpression.setRightOperand(convert(expression.right));
		int startPosition = leftExpression.getStartPosition();
		setInfixSourcePositions(infixExpression, startPosition);
		switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
				infixExpression.setOperator(InfixExpression.Operator.EQUALS);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
				infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
		}
		return infixExpression;

	}

	public Statement convert(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall statement) {
		Statement newStatement;
		int sourceStart = statement.sourceStart;
//{ObjectTeams: convert tsuper constructor invocation
        if (statement.isTsuperAccess())
        {
            TSuperConstructorInvocation result = this.ast.newTSuperConstructorInvocation();
            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
            if (arguments != null)
            {
                int length = arguments.length;
                length--; // remove last marker argument
                for (int i = 0; i < length; i++)
                {
                    result.getArguments().add(convert(arguments[i]));
                }
            }
            newStatement = result;
        } else
//mkr}
		if (statement.isSuperAccess() || statement.isSuper()) {
			SuperConstructorInvocation superConstructorInvocation = new SuperConstructorInvocation(this.ast);
			if (statement.qualification != null) {
				superConstructorInvocation.setExpression(convert(statement.qualification));
			}
			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
			if (arguments != null) {
				int length = arguments.length;
				for (int i = 0; i < length; i++) {
					superConstructorInvocation.arguments().add(convert(arguments[i]));
				}
			}
			if (statement.typeArguments != null) {
				if (sourceStart > statement.typeArgumentsSourceStart) {
					sourceStart = statement.typeArgumentsSourceStart;
				}
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						superConstructorInvocation.setFlags(superConstructorInvocation.getFlags() | ASTNode.MALFORMED);
						break;
					default :
						for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
							superConstructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
						}
						break;
				}
			}
			newStatement = superConstructorInvocation;
		} else {
			ConstructorInvocation constructorInvocation = new ConstructorInvocation(this.ast);
			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
			if (arguments != null) {
				int length = arguments.length;
				for (int i = 0; i < length; i++) {
					constructorInvocation.arguments().add(convert(arguments[i]));
				}
			}
			if (statement.typeArguments != null) {
				if (sourceStart > statement.typeArgumentsSourceStart) {
					sourceStart = statement.typeArgumentsSourceStart;
				}
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
						break;
					default :
						for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
							constructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
						}
					break;
				}
			}
			if (statement.qualification != null) {
				// this is an error
				constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
			}
			newStatement = constructorInvocation;
		}
		newStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
		if (this.resolveBindings) {
			recordNodes(newStatement, statement);
		}
		return newStatement;
	}

	private ModulePackageAccess getPackageVisibilityStatement(
			org.eclipse.jdt.internal.compiler.ast.PackageVisibilityStatement pvsStmt, ModulePackageAccess stmt) {
		int sourceEnd = pvsStmt.declarationSourceEnd;
		if (pvsStmt.declarationEnd > sourceEnd) sourceEnd = pvsStmt.declarationEnd; // TODO: working around a compiler issue
		Name name = getImportName(pvsStmt.pkgRef);
		stmt.setName(name);
		if (this.resolveBindings) {
			recordNodes(name, pvsStmt.pkgRef);
		}
		int tmp = sourceEnd;
		if (pvsStmt.targets != null && pvsStmt.targets.length > 0) {
			List<Name> modules = stmt.modules();
			for (ModuleReference moduleRef : pvsStmt.getTargetedModules()) {
				Name target = getName(moduleRef, CharOperation.splitOn('.', moduleRef.moduleName), moduleRef.sourcePositions);
				modules.add(target);
				if (tmp < moduleRef.sourceEnd) tmp = moduleRef.sourceEnd;
				if (this.resolveBindings) {
					this.recordNodes(target, moduleRef);
				}

			}
		}
		if (tmp > sourceEnd) sourceEnd = tmp;
		stmt.setSourceRange(pvsStmt.declarationSourceStart, sourceEnd - pvsStmt.declarationSourceStart + 1);
		return stmt;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
		if ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
			return convertToParenthesizedExpression(expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
			return convert((org.eclipse.jdt.internal.compiler.ast.Annotation) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CastExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.CastExpression) expression);
		}
		// switch between all types of expression
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AllocationExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PrefixExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.PrefixExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PostfixExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.PostfixExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) {
			return convert((org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Assignment) {
			return convert((org.eclipse.jdt.internal.compiler.ast.Assignment) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FalseLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.FalseLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TrueLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.TrueLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.NullLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.NullLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CharLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.CharLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FloatLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.FloatLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) {
			return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) {
			return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteral) expression);
		}
		if (expression instanceof StringLiteralConcatenation) {
			return convert((StringLiteralConcatenation) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TextBlock) {
			return convert((org.eclipse.jdt.internal.compiler.ast.TextBlock) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.StringLiteral) {
			return convert((org.eclipse.jdt.internal.compiler.ast.StringLiteral) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.EqualExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.EqualExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.UnaryExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.UnaryExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.MessageSend) {
			return convert((org.eclipse.jdt.internal.compiler.ast.MessageSend) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Reference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.Reference) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.TypeReference) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.LambdaExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) expression);
		}
		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.SwitchExpression) {
			return convert((org.eclipse.jdt.internal.compiler.ast.SwitchExpression) expression);
		}
//{ObjectTeams: more expressions:
		if (expression instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend)
		{
			return convert(((org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend) expression));
		}
		if (expression instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.ParameterMapping)
		{
			return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.ParameterMapping) expression);
		}
		if (expression instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.PotentialTranslationExpression)
		{
			// Note (SH): this includes Potential{Lifting,Lowering}Expresssion:
			return convert(((org.eclipse.objectteams.otdt.internal.core.compiler.ast.PotentialTranslationExpression)expression).expression);
		}
		org.eclipse.jdt.internal.compiler.ast.Expression unwrapped = Lowering.unwrapExpression(expression);
		if (unwrapped != null)
		{
			return convert(unwrapped);
		}
//gbr}
		return null;
	}

	public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral expression) {
		expression.computeConstant();
		StringLiteral literal = new StringLiteral(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setLiteralValue(expression.constant.stringValue());
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}

	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.FalseLiteral expression) {
		final BooleanLiteral literal =  new BooleanLiteral(this.ast);
		literal.setBooleanValue(false);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.FieldReference reference) {
		if (reference.receiver.isSuper()) {
			final SuperFieldAccess superFieldAccess = new SuperFieldAccess(this.ast);
			if (this.resolveBindings) {
				recordNodes(superFieldAccess, reference);
			}
			if (reference.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
				Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference.receiver);
				superFieldAccess.setQualifier(qualifier);
				if (this.resolveBindings) {
					recordNodes(qualifier, reference.receiver);
				}
			}
			final SimpleName simpleName = new SimpleName(this.ast);
			simpleName.internalSetIdentifier(new String(reference.token));
			int sourceStart = (int)(reference.nameSourcePosition>>>32);
			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
			simpleName.setSourceRange(sourceStart, length);
			superFieldAccess.setName(simpleName);
			if (this.resolveBindings) {
				recordNodes(simpleName, reference);
			}
			superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
			return superFieldAccess;
		} else {
			final FieldAccess fieldAccess = new FieldAccess(this.ast);
			if (this.resolveBindings) {
				recordNodes(fieldAccess, reference);
			}
			Expression receiver = convert(reference.receiver);
			fieldAccess.setExpression(receiver);
			final SimpleName simpleName = new SimpleName(this.ast);
			simpleName.internalSetIdentifier(new String(reference.token));
			int sourceStart = (int)(reference.nameSourcePosition>>>32);
			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
			simpleName.setSourceRange(sourceStart, length);
			fieldAccess.setName(simpleName);
			if (this.resolveBindings) {
				recordNodes(simpleName, reference);
			}
			fieldAccess.setSourceRange(receiver.getStartPosition(), reference.sourceEnd - receiver.getStartPosition() + 1);
			return fieldAccess;
		}
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.FloatLiteral expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	public Statement convert(ForeachStatement statement) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				return createFakeEmptyStatement(statement);
			default :
				EnhancedForStatement enhancedForStatement = new EnhancedForStatement(this.ast);
				enhancedForStatement.setParameter(convertToSingleVariableDeclaration(statement.elementVariable));
				org.eclipse.jdt.internal.compiler.ast.Expression collection = statement.collection;
				if (collection == null) return null;
				enhancedForStatement.setExpression(convert(collection));
				final Statement action = convert(statement.action);
				if (action == null) return null;
				enhancedForStatement.setBody(action);
				int start = statement.sourceStart;
				int end = statement.sourceEnd;
				enhancedForStatement.setSourceRange(start, end - start + 1);
				return enhancedForStatement;
		}
	}

	public ForStatement convert(org.eclipse.jdt.internal.compiler.ast.ForStatement statement) {
		ForStatement forStatement = new ForStatement(this.ast);
		forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		org.eclipse.jdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
		if (initializations != null) {
			// we know that we have at least one initialization
			if (initializations[0] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
				org.eclipse.jdt.internal.compiler.ast.LocalDeclaration initialization = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[0];
				VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(initialization);
				int initializationsLength = initializations.length;
				for (int i = 1; i < initializationsLength; i++) {
					initialization = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)initializations[i];
					variableDeclarationExpression.fragments().add(convertToVariableDeclarationFragment(initialization));
				}
				if (initializationsLength != 1) {
					int start = variableDeclarationExpression.getStartPosition();
					int end = ((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[initializationsLength - 1]).declarationSourceEnd;
					variableDeclarationExpression.setSourceRange(start, end - start + 1);
				}
				forStatement.initializers().add(variableDeclarationExpression);
			} else {
				int initializationsLength = initializations.length;
				for (int i = 0; i < initializationsLength; i++) {
					Expression initializer = convertToExpression(initializations[i]);
					if (initializer != null) {
						forStatement.initializers().add(initializer);
					} else {
						forStatement.setFlags(forStatement.getFlags() | ASTNode.MALFORMED);
					}
				}
			}
		}
		if (statement.condition != null) {
			forStatement.setExpression(convert(statement.condition));
		}
		org.eclipse.jdt.internal.compiler.ast.Statement[] increments = statement.increments;
		if (increments != null) {
			int incrementsLength = increments.length;
			for (int i = 0; i < incrementsLength; i++) {
				forStatement.updaters().add(convertToExpression(increments[i]));
			}
		}
		final Statement action = convert(statement.action);
		if (action == null) return null;
		forStatement.setBody(action);
		return forStatement;
	}

	public IfStatement convert(org.eclipse.jdt.internal.compiler.ast.IfStatement statement) {
		IfStatement ifStatement = new IfStatement(this.ast);
		ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		ifStatement.setExpression(convert(statement.condition));
		final Statement thenStatement = convert(statement.thenStatement);
		if (thenStatement == null) return null;
		ifStatement.setThenStatement(thenStatement);
		org.eclipse.jdt.internal.compiler.ast.Statement statement2 = statement.elseStatement;
		if (statement2 != null) {
			final Statement elseStatement = convert(statement2);
			if (elseStatement != null) {
				ifStatement.setElseStatement(elseStatement);
			}
		}
		return ifStatement;
	}

	public InstanceofExpression convert(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression expression) {
		InstanceofExpression instanceOfExpression = new InstanceofExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(instanceOfExpression, expression);
		}
		Expression leftExpression = convert(expression.expression);
		instanceOfExpression.setLeftOperand(leftExpression);
		final Type convertType = convertType(expression.type);
		instanceOfExpression.setRightOperand(convertType);
		int startPosition = leftExpression.getStartPosition();
		int sourceEnd = convertType.getStartPosition() + convertType.getLength() - 1;
		instanceOfExpression.setSourceRange(startPosition, sourceEnd - startPosition + 1);
		return instanceOfExpression;
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteral expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		final NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	interface IGetJavaDoc {
		Javadoc getJavaDoc();
	}
	interface ISetJavaDoc {
		void setJavadoc(Javadoc javadoc);
	}
	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, IGetJavaDoc getJ, ISetJavaDoc setJ) {
		if (getJ.getJavaDoc() == null) {
			Javadoc docComment = convert(javadoc);
			if (docComment != null) 
				setJ.setJavadoc(docComment);
		}
	}
	private Javadoc convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc) {
		Javadoc docComment = null;
		if (javadoc != null) {
			if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
				this.commentMapper = new DefaultCommentMapper(this.commentsTable);
			}
			Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
			if (comment != null && comment.isDocComment() && comment.getParent() == null) {
				docComment = (Javadoc) comment;
				if (this.resolveBindings) {
					recordNodes(docComment, javadoc);
					// resolve member and method references binding
					Iterator tags = docComment.tags().listIterator();
					while (tags.hasNext()) {
						recordNodes(javadoc, (TagElement) tags.next());
					}
				}
			}
		}
		return docComment;
	}
	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
		convert(javadoc, bodyDeclaration::getJavadoc, bodyDeclaration::setJavadoc);
	}
	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, ModuleDeclaration moduleDeclaration) {
		convert(javadoc, moduleDeclaration::getJavadoc, moduleDeclaration::setJavadoc);
	}

	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, PackageDeclaration packageDeclaration) {
		if (this.ast.apiLevel == AST.JLS2_INTERNAL) return;
		convert(javadoc, packageDeclaration::getJavadoc, packageDeclaration::setJavadoc);
	}

	public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
		LabeledStatement labeledStatement = new LabeledStatement(this.ast);
		final int sourceStart = statement.sourceStart;
		labeledStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
		Statement body = convert(statement.statement);
		if (body == null) return null;
		labeledStatement.setBody(body);
		final SimpleName name = new SimpleName(this.ast);
		name.internalSetIdentifier(new String(statement.label));
		name.setSourceRange(sourceStart, statement.labelEnd - sourceStart + 1);
		labeledStatement.setLabel(name);
		return labeledStatement;
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteral expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		final NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		final NumberLiteral literal = new NumberLiteral(this.ast);
		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(sourceStart, length);
		removeLeadingAndTrailingCommentsFromLiteral(literal);
		return literal;
	}

	public Expression convert(MessageSend expression) {
		// will return a MethodInvocation or a SuperMethodInvocation or
		Expression expr;
		int sourceStart = expression.sourceStart;

//{ObjectTeams: convert tsuper.methodName() and return TSuperMessageSend

        // conversion of compiler ast nodes for tsuper method invocation.
        // The compiler ast uses TSuperMessageSend instead of MessageSend.
        if (expression instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend)
        {
            org.eclipse.jdt.core.dom.TSuperMessageSend result = this.ast.newTSuperMessageSend();
            result.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);


            SimpleName name = this.ast.newSimpleName(new String(expression.selector));
            int start = (int)(expression.nameSourcePosition >>> 32);
            int end = (int)(expression.nameSourcePosition & 0xFFFFFFFF);
            name.setSourceRange(start, end-start+1);

            if (this.resolveBindings) {
                recordNodes(name, expression);
                recordNodes(result, expression);
            }
            result.setName(name);
            // extract optional qualification from tsuperReference:
            org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend send =
            		(org.eclipse.objectteams.otdt.internal.core.compiler.ast.TSuperMessageSend)expression;
            org.eclipse.objectteams.otdt.internal.core.compiler.ast.TsuperReference tsuperRef = send.tsuperReference;
            TypeReference typeReference = tsuperRef.qualification;
			if (typeReference != null) {
	        	Name qualification = null;
            	if (typeReference instanceof QualifiedTypeReference)
            	{
                	long[] poss = ((QualifiedTypeReference)typeReference).sourcePositions;
                	qualification = setQualifiedNameNameAndSourceRanges(typeReference.getTypeName(), poss, tsuperRef);
            	} else {
            		qualification = this.ast.newSimpleName(new String(((SingleTypeReference)typeReference).token));
            		qualification.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd);
            	}
            	result.setQualification(qualification);
				if (this.resolveBindings)
					recordNodes(qualification, send.tsuperReference);
            }
            org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
            if (arguments != null) {
                int argumentsLength = arguments.length;
                for (int idx = 0; idx < argumentsLength; idx++) {
                    Expression argExpr = convert(arguments[idx]);
                    if (this.resolveBindings) {
                        recordNodes(argExpr, arguments[idx]);
                    }
                    result.getArguments().add(argExpr);
                }
            }
            return result;
        }
//mkr}
		if (expression.isSuperAccess()) {
			// returns a SuperMethodInvocation
			final SuperMethodInvocation superMethodInvocation = new SuperMethodInvocation(this.ast);
			if (this.resolveBindings) {
				recordNodes(superMethodInvocation, expression);
			}
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(expression.selector));
			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
			int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
			name.setSourceRange(nameSourceStart, nameSourceLength);
			if (this.resolveBindings) {
				recordNodes(name, expression);
			}
			superMethodInvocation.setName(name);
			// expression.receiver is either a QualifiedSuperReference or a SuperReference
			// so the casting cannot fail
			if (expression.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
				Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) expression.receiver);
				superMethodInvocation.setQualifier(qualifier);
				if (this.resolveBindings) {
					recordNodes(qualifier, expression.receiver);
				}
				if (qualifier != null) {
					sourceStart = qualifier.getStartPosition();
				}
			}
			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
			if (arguments != null) {
				int argumentsLength = arguments.length;
				for (int i = 0; i < argumentsLength; i++) {
					Expression expri = convert(arguments[i]);
					if (this.resolveBindings) {
						recordNodes(expri, arguments[i]);
					}
					superMethodInvocation.arguments().add(expri);
				}
			}
			final TypeReference[] typeArguments = expression.typeArguments;
			if (typeArguments != null) {
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						superMethodInvocation.setFlags(superMethodInvocation.getFlags() | ASTNode.MALFORMED);
						break;
					default :
						for (int i = 0, max = typeArguments.length; i < max; i++) {
							superMethodInvocation.typeArguments().add(convertType(typeArguments[i]));
						}
						break;
				}
			}
			expr = superMethodInvocation;
		} else {
			// returns a MethodInvocation
			final MethodInvocation methodInvocation = new MethodInvocation(this.ast);
			if (this.resolveBindings) {
				recordNodes(methodInvocation, expression);
			}
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(expression.selector));
			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
			int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
			name.setSourceRange(nameSourceStart, nameSourceLength);
			methodInvocation.setName(name);
			if (this.resolveBindings) {
				recordNodes(name, expression);
			}
			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
			if (arguments != null) {
				int argumentsLength = arguments.length;
				for (int i = 0; i < argumentsLength; i++) {
					Expression expri = convert(arguments[i]);
					if (this.resolveBindings) {
						recordNodes(expri, arguments[i]);
					}
					methodInvocation.arguments().add(expri);
				}
			}
			Expression qualifier = null;
			org.eclipse.jdt.internal.compiler.ast.Expression receiver = expression.receiver;
			if (receiver instanceof MessageSend) {
				if ((receiver.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
					qualifier = convertToParenthesizedExpression(receiver);
				} else {
					qualifier = convert((MessageSend) receiver);
				}
			} else {
				qualifier = convert(receiver);
			}
			if (qualifier instanceof Name && this.resolveBindings) {
				recordNodes(qualifier, receiver);
			}
			methodInvocation.setExpression(qualifier);
			if (qualifier != null) {
				sourceStart = qualifier.getStartPosition();
			}
			final TypeReference[] typeArguments = expression.typeArguments;
			if (typeArguments != null) {
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						methodInvocation.setFlags(methodInvocation.getFlags() | ASTNode.MALFORMED);
						break;
					default :
						for (int i = 0, max = typeArguments.length; i < max; i++) {
							methodInvocation.typeArguments().add(convertType(typeArguments[i]));
						}
						break;
				}
			}
			expr = methodInvocation;
		}
		expr.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);
		return expr;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambda) {
		if (this.ast.apiLevel < AST.JLS8_INTERNAL) {
			return createFakeNullLiteral(lambda);		
		}
		final LambdaExpression	lambdaExpression = new LambdaExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(lambdaExpression, lambda);
		}
		org.eclipse.jdt.internal.compiler.ast.Argument[] arguments = lambda.arguments();
		if (arguments != null) {
			int argumentsLength = arguments.length;
			for (int i = 0; i < argumentsLength; i++) {
				org.eclipse.jdt.internal.compiler.ast.Argument argument = arguments[i];
				if (argument.type == null) {
					VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
					SimpleName simpleName = new SimpleName(this.ast);
					simpleName.internalSetIdentifier(new String(argument.name));
					int start = argument.sourceStart;
					int end = argument.sourceEnd;
					simpleName.setSourceRange(start, end - start + 1);
					if (this.resolveBindings) {
						recordNodes(simpleName, argument);
						recordNodes(variableDeclarationFragment, argument);
						variableDeclarationFragment.resolveBinding();
					}
					variableDeclarationFragment.setName(simpleName);
					variableDeclarationFragment.setSourceRange(start, end - start + 1);
					lambdaExpression.parameters().add(variableDeclarationFragment);					
				} else {
					SingleVariableDeclaration singleVariableDeclaration = convert(argument);
					lambdaExpression.parameters().add(singleVariableDeclaration);					
				}
			}
		}
		final org.eclipse.jdt.internal.compiler.ast.Statement body = lambda.body();
		if (body instanceof org.eclipse.jdt.internal.compiler.ast.Expression &&
				((org.eclipse.jdt.internal.compiler.ast.Expression) body).isTrulyExpression()) {
			lambdaExpression.setBody(convert((org.eclipse.jdt.internal.compiler.ast.Expression) body));
		} else {
			lambdaExpression.setBody(convert((org.eclipse.jdt.internal.compiler.ast.Block) body));
		}
		int sourceStart = lambda.sourceStart;
		lambdaExpression.setSourceRange(sourceStart, lambda.sourceEnd - sourceStart + 1);
		lambdaExpression.setParentheses(lambda.hasParentheses);
		return lambdaExpression;
	}

	public MarkerAnnotation convert(org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation annotation) {
		final MarkerAnnotation markerAnnotation = new MarkerAnnotation(this.ast);
		setTypeNameForAnnotation(annotation, markerAnnotation);
		int start = annotation.sourceStart;
		int end = annotation.declarationSourceEnd;
		markerAnnotation.setSourceRange(start, end - start + 1);
		if (this.resolveBindings) {
			recordNodes(markerAnnotation, annotation);
			markerAnnotation.resolveAnnotationBinding();
		}
		return markerAnnotation;
	}

	public MemberValuePair convert(org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair) {
		final MemberValuePair pair = new MemberValuePair(this.ast);
		final SimpleName simpleName = new SimpleName(this.ast);
		simpleName.internalSetIdentifier(new String(memberValuePair.name));
		int start = memberValuePair.sourceStart;
		int end = memberValuePair.sourceEnd;
		simpleName.setSourceRange(start, end - start + 1);
		pair.setName(simpleName);
		final Expression value = convert(memberValuePair.value);
		pair.setValue(value);
		start = memberValuePair.sourceStart;
		end = value.getStartPosition() + value.getLength() - 1;
		pair.setSourceRange(start, end - start + 1);

		if (memberValuePair.value instanceof SingleNameReference &&
				((SingleNameReference)memberValuePair.value).token == RecoveryScanner.FAKE_IDENTIFIER) {
			pair.setFlags(pair.getFlags() | ASTNode.RECOVERED);
		}

		if (this.resolveBindings) {
			recordNodes(simpleName, memberValuePair);
			recordNodes(pair, memberValuePair);
		}
		return pair;
	}

	public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference);
		} else {
			return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference);
		}
	}

	public InfixExpression convert(StringLiteralConcatenation expression) {
		expression.computeConstant();
		final InfixExpression infixExpression = new InfixExpression(this.ast);
		infixExpression.setOperator(InfixExpression.Operator.PLUS);
		org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = expression.literals;
		infixExpression.setLeftOperand(convert(stringLiterals[0]));
		infixExpression.setRightOperand(convert(stringLiterals[1]));
		for (int i = 2; i < expression.counter; i++) {
			infixExpression.extendedOperands().add(convert(stringLiterals[i]));
		}
		if (this.resolveBindings) {
			this.recordNodes(infixExpression, expression);
		}
		infixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return infixExpression;
	}

	public NormalAnnotation convert(org.eclipse.jdt.internal.compiler.ast.NormalAnnotation annotation) {
		final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast);
		setTypeNameForAnnotation(annotation, normalAnnotation);

		int start = annotation.sourceStart;
		int end = annotation.declarationSourceEnd;

		org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
		if (memberValuePairs != null) {
			for (int i = 0, max = memberValuePairs.length; i < max; i++) {
				MemberValuePair memberValuePair = convert(memberValuePairs[i]);
				int memberValuePairEnd = memberValuePair.getStartPosition() + memberValuePair.getLength() - 1;
				if (end == memberValuePairEnd) {
					normalAnnotation.setFlags(normalAnnotation.getFlags() | ASTNode.RECOVERED);
				}
				normalAnnotation.values().add(memberValuePair);
			}
		}

		normalAnnotation.setSourceRange(start, end - start + 1);
		if (this.resolveBindings) {
			recordNodes(normalAnnotation, annotation);
			normalAnnotation.resolveAnnotationBinding();
		}
		return normalAnnotation;
	}

	public NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
		final NullLiteral literal = new NullLiteral(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression expression) {
		InfixExpression infixExpression = new InfixExpression(this.ast);
		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
		if (this.resolveBindings) {
			this.recordNodes(infixExpression, expression);
		}
		final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
			// create an extended string literal equivalent => use the extended operands list
			infixExpression.extendedOperands().add(convert(expression.right));
			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
			do {
				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
				 	List extendedOperands = infixExpression.extendedOperands();
				 	InfixExpression temp = new InfixExpression(this.ast);
					if (this.resolveBindings) {
						this.recordNodes(temp, expression);
					}
				 	temp.setOperator(getOperatorFor(expressionOperatorID));
				 	Expression leftSide = convert(leftOperand);
					temp.setLeftOperand(leftSide);
					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
					int size = extendedOperands.size();
				 	for (int i = 0; i < size - 1; i++) {
				 		Expression expr = temp;
				 		temp = new InfixExpression(this.ast);

						if (this.resolveBindings) {
							this.recordNodes(temp, expression);
						}
				 		temp.setLeftOperand(expr);
					 	temp.setOperator(getOperatorFor(expressionOperatorID));
						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
				 	}
				 	infixExpression = temp;
				 	for (int i = 0; i < size; i++) {
				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
				 		temp.setRightOperand(extendedOperand);
				 		int startPosition = temp.getLeftOperand().getStartPosition();
				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
				 			temp = (InfixExpression) temp.getLeftOperand();
				 		}
				 	}
				 	setInfixSourcePositions(infixExpression, expression.sourceStart);
					if (this.resolveBindings) {
						this.recordNodes(infixExpression, expression);
					}
					return infixExpression;
				}
				infixExpression.extendedOperands().add(0, convert(rightOperand));
				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
			Expression leftExpression = convert(leftOperand);
			infixExpression.setLeftOperand(leftExpression);
			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
		 	setInfixSourcePositions(infixExpression, expression.sourceStart);
			return infixExpression;
		}
		Expression leftExpression = convert(expression.left);
		infixExpression.setLeftOperand(leftExpression);
		infixExpression.setRightOperand(convert(expression.right));
		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
	 	setInfixSourcePositions(infixExpression, expression.sourceStart);
		return infixExpression;
	}

	private void setInfixSourcePositions(InfixExpression infixExpression, int sourceStart) {
		int n = infixExpression.extendedOperands().size();
		Expression rightMostExp = n <= 0 ? infixExpression.getRightOperand() : (Expression) infixExpression.extendedOperands().get(n - 1);
		int rightSourceEnd = rightMostExp.getStartPosition() + rightMostExp.getLength() - 1;
		int infixSourceEnd = infixExpression.getStartPosition() + infixExpression.getLength() - 1;
		infixSourceEnd = rightSourceEnd > infixSourceEnd ? rightSourceEnd : infixSourceEnd;
		infixExpression.setSourceRange(sourceStart, infixSourceEnd - sourceStart + 1);
	}

	public PostfixExpression convert(org.eclipse.jdt.internal.compiler.ast.PostfixExpression expression) {
		final PostfixExpression postfixExpression = new PostfixExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(postfixExpression, expression);
		}
		postfixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		postfixExpression.setOperand(convert(expression.lhs));
		switch (expression.operator) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
				postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
				postfixExpression.setOperator(PostfixExpression.Operator.DECREMENT);
				break;
		}
		return postfixExpression;
	}

	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.PrefixExpression expression) {
		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(prefixExpression, expression);
		}
		prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		prefixExpression.setOperand(convert(expression.lhs));
		switch (expression.operator) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
				prefixExpression.setOperator(PrefixExpression.Operator.INCREMENT);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
				prefixExpression.setOperator(PrefixExpression.Operator.DECREMENT);
				break;
		}
		return prefixExpression;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
		final ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
		if (allocation.enclosingInstance != null) {
			classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
		}
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				classInstanceCreation.internalSetName(convert(allocation.type));
				break;
			default :
				classInstanceCreation.setType(convertType(allocation.type));
		}
		org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
		if (arguments != null) {
			int length = arguments.length;
			for (int i = 0; i < length; i++) {
				Expression argument = convert(arguments[i]);
				if (this.resolveBindings) {
					recordNodes(argument, arguments[i]);
				}
				classInstanceCreation.arguments().add(argument);
			}
		}
		if (allocation.typeArguments != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					for (int i = 0, max = allocation.typeArguments.length; i < max; i++) {
						classInstanceCreation.typeArguments().add(convertType(allocation.typeArguments[i]));
					}
			}
		}
		if (allocation.anonymousType != null) {
			int declarationSourceStart = allocation.sourceStart;
			classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
			final AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
			int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
			anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
			classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
			buildBodyDeclarations(allocation.anonymousType, anonymousClassDeclaration);
			if (this.resolveBindings) {
				recordNodes(classInstanceCreation, allocation.anonymousType);
				recordNodes(anonymousClassDeclaration, allocation.anonymousType);
				anonymousClassDeclaration.resolveBinding();
			}
			return classInstanceCreation;
		} else {
			final int start = allocation.sourceStart;
			classInstanceCreation.setSourceRange(start, allocation.sourceEnd - start + 1);
			if (this.resolveBindings) {
				recordNodes(classInstanceCreation, allocation);
			}
			return classInstanceCreation;
		}
	}

	public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference nameReference) {
		return setQualifiedNameNameAndSourceRanges(nameReference.tokens, nameReference.sourcePositions, nameReference);
	}

	public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference reference) {
		return convert(reference.qualification);
	}

	public ThisExpression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference reference) {
		final ThisExpression thisExpression = new ThisExpression(this.ast);
		thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
		thisExpression.setQualifier(convert(reference.qualification));
		if (this.resolveBindings) {
			recordNodes(thisExpression, reference);
			recordPendingThisExpressionScopeResolution(thisExpression);
		}
		return thisExpression;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.Reference reference) {
		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.NameReference) reference);
		}
//{ObjectTeams: cases added for converting OT-specific internal types TSuperReference
//      and BaseReference
		if (reference instanceof TsuperReference)
		{
		    return convert((TsuperReference)reference);
		}
		if (reference instanceof BaseReference)
		{
		    return convert((BaseReference)reference);
		}
//gbr}
		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ThisReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ThisReference) reference);
		}
		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ArrayReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayReference) reference);
		}
		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.FieldReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.FieldReference) reference);
		}
		return null; // cannot be reached
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression reference) {
		if (this.ast.apiLevel < AST.JLS8_INTERNAL) {
			return createFakeNullLiteral(reference);
		}
		Expression result = null;
		org.eclipse.jdt.internal.compiler.ast.Expression lhs = reference.lhs;
		org.eclipse.jdt.internal.compiler.ast.TypeReference[] arguments = reference.typeArguments;
		int start = arguments != null && arguments.length > 0 ? arguments[arguments.length - 1].sourceEnd + 1 : reference.lhs.sourceEnd + 1;
		final SimpleName name = new SimpleName(this.ast);
		retrieveIdentifierAndSetPositions(start, reference.sourceEnd, name);
		name.internalSetIdentifier(new String(reference.selector));
		if (this.resolveBindings) {
			recordNodes(name, reference);
		}
		List typeArguments = null;
		if (name.getStartPosition() == -1 && name.getIdentifier().equals("<init>")) { // check for "new"  //$NON-NLS-1$
			retrieveInitAndSetPositions(start, reference.sourceEnd, name);
			Type type = null;
			if (lhs instanceof TypeReference) {
				type = convertType((TypeReference) lhs);
			} else if (lhs instanceof NameReference) {
				Name typeName = convert((NameReference) lhs);
				SimpleType simpleType = new SimpleType(this.ast);
				simpleType.setName(typeName);
				if (this.resolveBindings) {
					recordNodes(simpleType, lhs);
				}
				simpleType.setSourceRange(lhs.sourceStart, lhs.sourceEnd - lhs.sourceStart + 1);
				type = simpleType;
			}
			CreationReference creationReference = new CreationReference(this.ast);
			creationReference.setType(type);
			typeArguments = creationReference.typeArguments();
			result = creationReference;
		} else if (lhs instanceof TypeReference) {
			TypeMethodReference typeMethodReference = new TypeMethodReference(this.ast);
			typeMethodReference.setType(convertType((TypeReference) lhs));
			typeMethodReference.setName(name);
			typeArguments = typeMethodReference.typeArguments();
			result = typeMethodReference;
		} else if (lhs instanceof SuperReference) {
			SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
			superMethodReference.setName(name);
			typeArguments = superMethodReference.typeArguments();
			result = superMethodReference;
		} else if (lhs instanceof QualifiedSuperReference) {
			SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
			superMethodReference.setQualifier(convert((QualifiedSuperReference)lhs));
			superMethodReference.setName(name);
			typeArguments = superMethodReference.typeArguments();
			result = superMethodReference;
		} else {
			ExpressionMethodReference expressionMethodReference = new ExpressionMethodReference(this.ast);
			expressionMethodReference.setExpression(convert(lhs));
			typeArguments = expressionMethodReference.typeArguments();
			expressionMethodReference.setName(name);
			result = expressionMethodReference;
		}
		if (typeArguments != null && arguments != null) {
			int argumentsLength = arguments.length;
			for (int i = 0; i < argumentsLength; i++) {
				org.eclipse.jdt.internal.compiler.ast.TypeReference argument = arguments[i];
				typeArguments.add(convertType(argument));
			}
		}
		if (this.resolveBindings) {
			recordNodes(result, reference);
		}
		int sourceStart = reference.sourceStart; 
		result.setSourceRange(sourceStart, reference.sourceEnd - sourceStart + 1);
		return result;
	}

	
	public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
		final ReturnStatement returnStatement = new ReturnStatement(this.ast);
		returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		if (statement.expression != null) {
//{ObjectTeams: don't convert synthetic _OT$result in return statement:
		  org.eclipse.jdt.internal.compiler.ast.Expression expr = statement.expression;
		  if (expr.isGenerated() && expr instanceof SingleNameReference) {
			  if (CharOperation.equals(((SingleNameReference)expr).token, IOTConstants.OT_RESULT))
				  return returnStatement;
		  }
// SH}
			returnStatement.setExpression(convert(statement.expression));
		}
		return returnStatement;
	}

	public SingleMemberAnnotation convert(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation annotation) {
		final SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(this.ast);
		setTypeNameForAnnotation(annotation, singleMemberAnnotation);
		singleMemberAnnotation.setValue(convert(annotation.memberValue));
		int start = annotation.sourceStart;
		int end = annotation.declarationSourceEnd;
		singleMemberAnnotation.setSourceRange(start, end - start + 1);
		if (this.resolveBindings) {
			recordNodes(singleMemberAnnotation, annotation);
			singleMemberAnnotation.resolveAnnotationBinding();
		}
		return singleMemberAnnotation;
	}

	public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) {
		final SimpleName name = new SimpleName(this.ast);
		name.internalSetIdentifier(new String(nameReference.token));
		if (this.resolveBindings) {
			recordNodes(name, nameReference);
		}
		name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1);
		return name;
	}

	public Statement convert(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
//{ObjectTeams: don't convert generated statements
		if (statement != null && statement.isGenerated())
			return null;
// SH}
		if (statement instanceof ForeachStatement) {
			return convert((ForeachStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statement;
			return convertToVariableDeclarationStatement(localDeclaration);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.AssertStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.AssertStatement) statement);
		}
//{ObjectTeams: case added for converting OT-specific node WithinStatement
		if (statement instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.WithinStatement)
		{
		    return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.WithinStatement)statement);
		}
//gbr}
//{ObjectTeams: handle BaseConstructorMessageSend. Note: might be unresolvable, i.e. incomplete rhs!
        if (statement instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseAllocationExpression) {
            return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseAllocationExpression) statement);
        }
//carp}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Block) {
			return convert((org.eclipse.jdt.internal.compiler.ast.Block) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.BreakStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.BreakStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ContinueStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ContinueStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.CaseStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.CaseStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.DoStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.DoStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.EmptyStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.EmptyStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ForStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ForStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.IfStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.IfStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LabeledStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.LabeledStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ReturnStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ReturnStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SwitchStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.SwitchStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ThrowStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.ThrowStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TryStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.TryStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
			ASTNode result = convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement);
			if (result == null || !(result instanceof TypeDeclaration)) {
				return createFakeEmptyStatement(statement);
			}
			// annotation and enum type declarations are not returned by the parser inside method bodies
			TypeDeclaration typeDeclaration = (TypeDeclaration) result;
			TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
			typeDeclarationStatement.setDeclaration(typeDeclaration);
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					TypeDeclaration typeDecl = typeDeclarationStatement.internalGetTypeDeclaration();
					typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
					break;
				default :
					AbstractTypeDeclaration typeDeclAST3 = typeDeclarationStatement.getDeclaration();
					typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());
					break;
			}
			return typeDeclarationStatement;
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.WhileStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.WhileStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.YieldStatement) {
			return convert((org.eclipse.jdt.internal.compiler.ast.YieldStatement) statement);
		}
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression &&
				((org.eclipse.jdt.internal.compiler.ast.Expression) statement).isTrulyExpression()) {
			org.eclipse.jdt.internal.compiler.ast.Expression statement2 = (org.eclipse.jdt.internal.compiler.ast.Expression) statement;
			final Expression expr = convert(statement2);
			final ExpressionStatement stmt = new ExpressionStatement(this.ast);
			stmt.setExpression(expr);
			int sourceStart = expr.getStartPosition();
			int sourceEnd = statement2.statementEnd;
			stmt.setSourceRange(sourceStart, sourceEnd - sourceStart + 1);
			return stmt;
		}
		return createFakeEmptyStatement(statement);
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.StringLiteral expression) {
		if (expression instanceof StringLiteralConcatenation) {
			return convert((StringLiteralConcatenation) expression);
		}
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		StringLiteral literal = new StringLiteral(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}
	
	public Expression convert(org.eclipse.jdt.internal.compiler.ast.SwitchExpression expression) {
		if (!this.ast.isPreviewEnabled()) {
			return createFakeNullLiteral(expression);		
		}
		SwitchExpression switchExpression = new SwitchExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(switchExpression, expression);
		}
		switchExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		switchExpression.setExpression(convert(expression.expression));
		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = expression.statements;
		if (statements != null) {
			int statementsLength = statements.length;
			for (int i = 0; i < statementsLength; i++) {
				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
					checkAndAddMultipleLocalDeclaration(statements, i, switchExpression.statements());
				} else {
					final Statement currentStatement = convert(statements[i]);
					if (currentStatement != null) {
						switchExpression.statements().add(currentStatement);
					}
				}
			}
		}
		return switchExpression;
	}
	
	public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
		SwitchStatement switchStatement = new SwitchStatement(this.ast);
		switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		switchStatement.setExpression(convert(statement.expression));
		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
		if (statements != null) {
			int statementsLength = statements.length;
			for (int i = 0; i < statementsLength; i++) {
				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
					checkAndAddMultipleLocalDeclaration(statements, i, switchStatement.statements());
				} else {
					final Statement currentStatement = convert(statements[i]);
					if (currentStatement != null) {
						switchStatement.statements().add(currentStatement);
					}
				}
			}
		}
		return switchStatement;
	}

	public SynchronizedStatement convert(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement statement) {
		SynchronizedStatement synchronizedStatement = new SynchronizedStatement(this.ast);
		synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		synchronizedStatement.setBody(convert(statement.block));
		synchronizedStatement.setExpression(convert(statement.expression));
		return synchronizedStatement;
	}

	public Expression convert(org.eclipse.jdt.internal.compiler.ast.TextBlock expression) {
		int length = expression.sourceEnd - expression.sourceStart + 1;
		int sourceStart = expression.sourceStart;
		TextBlock literal = new TextBlock(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}
	
	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ThisReference reference) {
		if (reference.isImplicitThis()) {
			// There is no source associated with an implicit this
			return null;
		} else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference);
		} else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) {
			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) reference);
		}  else {
			ThisExpression thisExpression = new ThisExpression(this.ast);
			thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
			if (this.resolveBindings) {
				recordNodes(thisExpression, reference);
				recordPendingThisExpressionScopeResolution(thisExpression);
			}
			return thisExpression;
		}
	}

	public ThrowStatement convert(org.eclipse.jdt.internal.compiler.ast.ThrowStatement statement) {
		final ThrowStatement throwStatement = new ThrowStatement(this.ast);
		throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		throwStatement.setExpression(convert(statement.exception));
		return throwStatement;
	}

	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.TrueLiteral expression) {
		final BooleanLiteral literal = new BooleanLiteral(this.ast);
		literal.setBooleanValue(true);
		if (this.resolveBindings) {
			this.recordNodes(literal, expression);
		}
		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return literal;
	}

	public TryStatement convert(org.eclipse.jdt.internal.compiler.ast.TryStatement statement) {
		final TryStatement tryStatement = new TryStatement(this.ast);
		tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		int resourcesLength = statement.resources.length;
		if (resourcesLength > 0) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
				case AST.JLS3_INTERNAL :
					// convert it to a simple try statement tagged as MALFORMED
					tryStatement.setFlags(tryStatement.getFlags() | ASTNode.MALFORMED);
					break;
				case AST.JLS4_INTERNAL:
				case AST.JLS8_INTERNAL:
					for (int i = 0; i < resourcesLength; i++) {
						if (!(statement.resources[i] instanceof LocalDeclaration)) {
							tryStatement.setFlags(tryStatement.getFlags() | ASTNode.MALFORMED);
							break;
						}
						LocalDeclaration localDeclaration = (LocalDeclaration)statement.resources[i];
						VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(localDeclaration);
						int start = variableDeclarationExpression.getStartPosition();
						int end = localDeclaration.declarationEnd;
						variableDeclarationExpression.setSourceRange(start, end - start + 1);
						tryStatement.resources().add(variableDeclarationExpression);
					}
					break;
				default:
					for (int i = 0; i < resourcesLength; i++) {
						org.eclipse.jdt.internal.compiler.ast.Statement resource = statement.resources[i];
						if (resource instanceof LocalDeclaration) {
							LocalDeclaration localDeclaration = (LocalDeclaration)resource;
							VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(localDeclaration);
							int start = variableDeclarationExpression.getStartPosition();
							int end = localDeclaration.declarationEnd;
							variableDeclarationExpression.setSourceRange(start, end - start + 1);
							tryStatement.resources().add(variableDeclarationExpression);
						} else if (resource instanceof NameReference) {
							tryStatement.resources().add(convert((NameReference) resource));
						} else if (resource instanceof FieldReference) {
							tryStatement.resources().add(convert((FieldReference) resource));
						} else {
							tryStatement.setFlags(tryStatement.getFlags() | ASTNode.MALFORMED);
							break;
						}
					}
					break;
			}
		}
		tryStatement.setBody(convert(statement.tryBlock));
		org.eclipse.jdt.internal.compiler.ast.Argument[] catchArguments = statement.catchArguments;
		if (catchArguments != null) {
			int catchArgumentsLength = catchArguments.length;
			org.eclipse.jdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
			int start = statement.tryBlock.sourceEnd;
			for (int i = 0; i < catchArgumentsLength; i++) {
				CatchClause catchClause = new CatchClause(this.ast);
				int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
				catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);
				catchClause.setBody(convert(catchBlocks[i]));
				catchClause.setException(convert(catchArguments[i]));
				tryStatement.catchClauses().add(catchClause);
				start = catchBlocks[i].sourceEnd;
			}
		}
		if (statement.finallyBlock != null) {
			tryStatement.setFinally(convert(statement.finallyBlock));
		}
		return tryStatement;
	}

	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
		int kind = org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.kind(typeDeclaration.modifiers);
		switch (kind) {
			case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ENUM_DECL :
				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
					return null;
				} else {
					return convertToEnumDeclaration(typeDeclaration);
				}
			case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ANNOTATION_TYPE_DECL :
				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
					return null;
				} else {
					return convertToAnnotationDeclaration(typeDeclaration);
				}
		}

		checkCanceled();
		TypeDeclaration typeDecl; // OT: initialized below
		ASTNode oldReferenceContext = this.referenceContext;
//{ObjectTeams: if TypeDeclaration is a role, it is a RoleTypeDeclaration, otherwise it is just a
    	//TypeDeclaration
      if (!typeDeclaration.isRole())
      {
  		typeDecl = new TypeDeclaration(this.ast);
//ike}
		this.referenceContext = typeDecl;
		if (typeDeclaration.modifiersSourceStart != -1) {
			setModifiers(typeDecl, typeDeclaration);
		}
		boolean isInterface = kind == org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.INTERFACE_DECL;
		typeDecl.setInterface(isInterface);
//{ObjectTeams: type declaration can be a team class or a role class, too
   		typeDecl.setTeam(typeDeclaration.isTeam());
   		typeDecl.setRole(typeDeclaration.isSourceRole());
//gbr}
		final SimpleName typeName = new SimpleName(this.ast);
		typeName.internalSetIdentifier(new String(typeDeclaration.name));
		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
		typeDecl.setName(typeName);
		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);

		// need to set the superclass and super interfaces here since we cannot distinguish them at
		// the type references level.
		if (typeDeclaration.superclass != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					typeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));
					break;
				default :
					typeDecl.setSuperclassType(convertType(typeDeclaration.superclass));
					break;
			}
		}

		org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
		if (superInterfaces != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					for (int index = 0, length = superInterfaces.length; index < length; index++) {
						typeDecl.internalSuperInterfaces().add(convert(superInterfaces[index]));
					}
					break;
				default :
					for (int index = 0, length = superInterfaces.length; index < length; index++) {
						typeDecl.superInterfaceTypes().add(convertType(superInterfaces[index]));
					}
			}
		}
		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
		if (typeParameters != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					for (int index = 0, length = typeParameters.length; index < length; index++) {
						typeDecl.typeParameters().add(convert(typeParameters[index]));
					}
			}
		}
		buildBodyDeclarations(typeDeclaration, typeDecl, isInterface);
		if (this.resolveBindings) {
			recordNodes(typeDecl, typeDeclaration);
			recordNodes(typeName, typeDeclaration);
			typeDecl.resolveBinding();
		}
//{ObjectTeams: do OT-specific stuff
      }
      else
      {
    	typeDecl = buildRoleTypeDeclaration(typeDeclaration);
      }
	  org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration guard = typeDeclaration.predicate;
	  if (guard != null)
		typeDecl.setGuardPredicate(convertGuardPredicate(guard));
      if (typeDeclaration.precedences != null)
    	for (org.eclipse.objectteams.otdt.internal.core.compiler.ast.PrecedenceDeclaration aPrecedence : typeDeclaration.precedences)
    		typeDecl.precedences().add(convertPrecedence(aPrecedence));
//ike}
		this.referenceContext = oldReferenceContext;
		return typeDecl;
	}

	public TypeParameter convert(org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter) {
		final TypeParameter typeParameter2 = new TypeParameter(this.ast);
//{ObjectTeams: distinguish TypeValueParameter:
		if (typeParameter.getKind() == org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration.TYPE_VALUE_PARAMETER)
			typeParameter2.setIsValueParameter(true);
// SH}
		final SimpleName simpleName = new SimpleName(this.ast);
		simpleName.internalSetIdentifier(new String(typeParameter.name));
		int start = typeParameter.sourceStart;
		int end = typeParameter.sourceEnd;
		simpleName.setSourceRange(start, end - start + 1);
		typeParameter2.setName(simpleName);
		int annotationsStart = start;
		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = typeParameter.annotations;
		if (annotations != null) {
			if (annotations[0] != null)
				annotationsStart = annotations[0].sourceStart;
			annotateTypeParameter(typeParameter2, typeParameter.annotations);
		}
		final TypeReference superType = typeParameter.type;
		end = typeParameter.declarationSourceEnd;
		if (superType != null) {
			Type type = convertType(superType);
			typeParameter2.typeBounds().add(type);
			end = type.getStartPosition() + type.getLength() - 1;
		}
		TypeReference[] bounds = typeParameter.bounds;
		if (bounds != null) {
			Type type = null;
			for (int index = 0, length = bounds.length; index < length; index++) {
				type = convertType(bounds[index]);
				typeParameter2.typeBounds().add(type);
				end = type.getStartPosition() + type.getLength() - 1;
			}
//{ObjectTeams: mark <B base R>:
			if (typeParameter.hasBaseBound())
				typeParameter2.setHasBaseBound(true);
// SH}
		}
		start = annotationsStart < typeParameter.declarationSourceStart ? annotationsStart : typeParameter.declarationSourceStart;
		end = retrieveClosingAngleBracketPosition(end);
		typeParameter2.setSourceRange(start, end - start + 1);
		if (this.resolveBindings) {
			recordName(simpleName, typeParameter);
			recordNodes(typeParameter2, typeParameter);
			typeParameter2.resolveBinding();
		}
		return typeParameter2;
	}

	public Name convert(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
		char[][] typeName = typeReference.getTypeName();
		int length = typeName.length;
		if (length > 1) {
//{ObjectTeams: catch qualified lifting types
			// TODO (SH): we probably need information about both names in a lifting type??
			if (typeReference instanceof LiftingTypeReference)
				typeReference = ((LiftingTypeReference)typeReference).baseReference;
// SH}
			// QualifiedName
			org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
			final long[] positions = qualifiedTypeReference.sourcePositions;
			return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
		} else {
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(typeName[0]));
			name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
			name.index = 1;
			if (this.resolveBindings) {
				recordNodes(name, typeReference);
			}
			return name;
		}
	}

	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.UnaryExpression expression) {
		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
		if (this.resolveBindings) {
			this.recordNodes(prefixExpression, expression);
		}
		prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		prefixExpression.setOperand(convert(expression.expression));
		switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
				prefixExpression.setOperator(PrefixExpression.Operator.PLUS);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
				prefixExpression.setOperator(PrefixExpression.Operator.MINUS);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT :
				prefixExpression.setOperator(PrefixExpression.Operator.NOT);
				break;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.TWIDDLE :
				prefixExpression.setOperator(PrefixExpression.Operator.COMPLEMENT);
		}
		return prefixExpression;
	}

	public WhileStatement convert(org.eclipse.jdt.internal.compiler.ast.WhileStatement statement) {
		final WhileStatement whileStatement = new WhileStatement(this.ast);
		whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		whileStatement.setExpression(convert(statement.condition));
		final Statement action = convert(statement.action);
		if (action == null) return null;
		whileStatement.setBody(action);
		return whileStatement;
	}

	public Statement convert(org.eclipse.jdt.internal.compiler.ast.YieldStatement statement) {
		if (this.ast.apiLevel != AST.JLS13_INTERNAL) {
			return createFakeEmptyStatement(statement);		
		}
		YieldStatement yieldStatement = new YieldStatement(this.ast);
		// We don't need to record Nodes
		yieldStatement.setExpression(convert(statement.expression));
		yieldStatement.setImplicit(statement.isImplicit);
		yieldStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		return yieldStatement;
	}
	
	public ImportDeclaration convertImport(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
		final ImportDeclaration importDeclaration = new ImportDeclaration(this.ast);
		Name name = getImportName(importReference);
		importDeclaration.setName(name);
		final boolean onDemand = (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0;
		importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
		importDeclaration.setOnDemand(onDemand);
		int modifiers = importReference.modifiers;
		if (modifiers != ClassFileConstants.AccDefault) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
					break;
				default :
					if (modifiers == ClassFileConstants.AccStatic) {
						importDeclaration.setStatic(true);
//{ObjectTeams: base imports:
					} else if (modifiers == ExtraCompilerModifiers.AccBase) {
						importDeclaration.setBase(true);
// SH}
					} else {
						importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
					}
			}
		}
		if (this.resolveBindings) {
			recordNodes(importDeclaration, importReference);
		}
		return importDeclaration;
	}

	public Name getImportName(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
		return getName(importReference, importReference.tokens, importReference.sourcePositions);
	}

	private Name getName(org.eclipse.jdt.internal.compiler.ast.ASTNode node, final char[][] tokens,
			final long[] positions) {
		Name name;
		int length = tokens != null ? tokens.length : 0;
		if (length > 1) {
			name = setQualifiedNameNameAndSourceRanges(tokens, positions, node);
		} else {
			name = new SimpleName(this.ast);
			((SimpleName)name).internalSetIdentifier(new String(tokens[0]));
			final int start = (int)(positions[0]>>>32);
			final int end = (int)(positions[0] & 0xFFFFFFFF);
			name.setSourceRange(start, end - start + 1);
			name.index = 1;
			if (this.resolveBindings) {
				recordNodes(name, node);
			}
		}
		return name;
	}

	public PackageDeclaration convertPackage(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
		org.eclipse.jdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
		final PackageDeclaration packageDeclaration = new PackageDeclaration(this.ast);
		final char[][] tokens = importReference.tokens;
		final int length = importReference.tokens.length;
		long[] positions = importReference.sourcePositions;
		if (length > 1) {
			packageDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
		} else {
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(tokens[0]));
			int start = (int)(positions[0]>>>32);
			int end = (int)(positions[length - 1] & 0xFFFFFFFF);
			name.setSourceRange(start, end - start + 1);
			name.index = 1;
			packageDeclaration.setName(name);
			if (this.resolveBindings) {
				recordNodes(name, compilationUnitDeclaration);
			}
		}
		packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = importReference.annotations;
		if (annotations != null) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					packageDeclaration.setFlags(packageDeclaration.getFlags() & ASTNode.MALFORMED);
					break;
				default :
					for (int i = 0, max = annotations.length; i < max; i++) {
						packageDeclaration.annotations().add(convert(annotations[i]));
					}
			}
		}
		if (this.resolveBindings) {
			recordNodes(packageDeclaration, importReference);
		}
		// Set javadoc
		convert(compilationUnitDeclaration.javadoc, packageDeclaration);
//{ObjectTeams:
		if (importReference.isTeam()) {
			Modifier teamModifier = this.ast.newModifier(ModifierKeyword.TEAM_KEYWORD);
			teamModifier.setSourceRange(importReference.declarationSourceStart, 4);
			packageDeclaration.modifiers().add(teamModifier);
		}
// SH}
		return packageDeclaration;
	}

	private ArrayType convertToArray(Type elementType, int sourceStart, int length, int dimensions, org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDimensions) {
		ArrayType arrayType = this.ast.newArrayType(elementType, dimensions);
		if (length > 0) arrayType.setSourceRange(sourceStart, length);
		if (this.ast.apiLevel() < AST.JLS8_INTERNAL) {
			if (annotationsOnDimensions != null) {
				arrayType.setFlags(arrayType.getFlags() | ASTNode.MALFORMED);
			}
			ArrayType subarrayType = arrayType;
			int index = dimensions - 1;
			int arrayEnd = retrieveProperRightBracketPosition(dimensions, sourceStart);
			while (index > 0) {
				subarrayType = (ArrayType) componentType(subarrayType);
				int end = retrieveProperRightBracketPosition(index, sourceStart);
				subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
				index--;
			}
			if (length < arrayEnd - sourceStart) arrayType.setSourceRange(sourceStart, arrayEnd - sourceStart + 1);
			return arrayType;
		}

		setTypeAnnotationsAndSourceRangeOnArray(arrayType, annotationsOnDimensions);
		return arrayType;
	}

	private EnumDeclaration convertToEnumDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
		checkCanceled();
		// enum declaration cannot be built if the source is not >= 1.5, since enum is then seen as an identifier
		final EnumDeclaration enumDeclaration2 = new EnumDeclaration(this.ast);
		setModifiers(enumDeclaration2, typeDeclaration);
		final SimpleName typeName = new SimpleName(this.ast);
		typeName.internalSetIdentifier(new String(typeDeclaration.name));
		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
		enumDeclaration2.setName(typeName);
		enumDeclaration2.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);

		org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
		if (superInterfaces != null) {
			for (int index = 0, length = superInterfaces.length; index < length; index++) {
				enumDeclaration2.superInterfaceTypes().add(convertType(superInterfaces[index]));
			}
		}
		buildBodyDeclarations(typeDeclaration, enumDeclaration2);
		if (this.resolveBindings) {
			recordNodes(enumDeclaration2, typeDeclaration);
			recordNodes(typeName, typeDeclaration);
			enumDeclaration2.resolveBinding();
		}
		return enumDeclaration2;
	}
	public Expression convertToExpression(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression &&
				((org.eclipse.jdt.internal.compiler.ast.Expression) statement).isTrulyExpression()) {
			return convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
		} else {
			return null;
		}
	}

	protected FieldDeclaration convertToFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
		VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
		final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
		fieldDeclaration.fragments().add(variableDeclarationFragment);
		if (this.resolveBindings) {
			recordNodes(variableDeclarationFragment, fieldDecl);
			variableDeclarationFragment.resolveBinding();
		}
		fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
		Type type = convertType(fieldDecl.type);
		setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
		setModifiers(fieldDeclaration, fieldDecl);
		convert(fieldDecl.javadoc, fieldDeclaration);
		return fieldDeclaration;
	}

	/**
	 * If there is a parsing error causing a recovered module the source positions may be updated only partially. 
	 * See bug 518843 for a case where this issue occurred. This method provide a safety net with 
	 * source positions updated even in case of a recovery - if there is no recovery, the source positions will 
	 * be retained in-tact identical to the compile time ast module node.
	 */
	private int getKnownEnd(ModuleDeclaration md, int sourceEnd, int declSourceEnd) {
		int end =  retrieveRightBrace(md.getStartPosition() + 1, this.compilationUnitSourceLength);
		end = end > sourceEnd ? end : sourceEnd;
		end = end > declSourceEnd ? end : declSourceEnd;
		return end;
	}
	public ModuleDeclaration convertToModuleDeclaration(org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration) {
		checkCanceled();
		if (this.scanner.sourceLevel < ClassFileConstants.JDK9
				|| this.ast.apiLevel < AST.JLS9_INTERNAL) return null;
		ModuleDeclaration moduleDecl = this.ast.newModuleDeclaration();
		// TODO
		//convert(moduleDeclaration.javadoc, moduleDecl);
		setAnnotations(moduleDecl, moduleDeclaration); // only annotations
		moduleDecl.setOpen(moduleDeclaration.isOpen());
		Name moduleName = getName(moduleDeclaration, CharOperation.splitOn('.', moduleDeclaration.moduleName), moduleDeclaration.sourcePositions);
		moduleDecl.setName(moduleName);

		List<ModuleDirective> stmts = moduleDecl.moduleStatements();
		TreeSet<ModuleDirective> tSet = new TreeSet<> (new Comparator() {
			@Override
			public int compare(Object o1, Object o2) {
				int p1 = ((ModuleDirective) o1).getStartPosition();
				int p2 = ((ModuleDirective) o2).getStartPosition();
				return p1 < p2 ? -1 : p1 == p2 ? 0 : 1;
			}
		});
		for (int i = 0; i < moduleDeclaration.exportsCount; ++i) {
			tSet.add(getPackageVisibilityStatement(moduleDeclaration.exports[i], new ExportsDirective(this.ast)));
		}
		for (int i = 0; i < moduleDeclaration.opensCount; ++i) {
			tSet.add(getPackageVisibilityStatement(moduleDeclaration.opens[i], new OpensDirective(this.ast)));
		}
		for (int i = 0; i < moduleDeclaration.requiresCount; ++i) {
			org.eclipse.jdt.internal.compiler.ast.RequiresStatement req = moduleDeclaration.requires[i];
			ModuleReference moduleRef = req.module;
			RequiresDirective stmt = new RequiresDirective(this.ast);
			Name name = getName(moduleRef, CharOperation.splitOn('.', moduleRef.moduleName), moduleRef.sourcePositions);
			stmt.setName(name);
			if (this.resolveBindings) {
				recordNodes(name, moduleRef);
			}

			setModuleModifiers(req, stmt);
			stmt.setSourceRange(req.declarationSourceStart, req.declarationEnd - req.declarationSourceStart + 1);
			tSet.add(stmt);
		}
		for (int i = 0; i < moduleDeclaration.usesCount; ++i) {
			org.eclipse.jdt.internal.compiler.ast.UsesStatement usesStatement = moduleDeclaration.uses[i];
			UsesDirective stmt = new UsesDirective(this.ast);
			TypeReference usesRef = usesStatement.serviceInterface;
			Name name = convert(usesRef);
			stmt.setName(name);
			stmt.setSourceRange(usesStatement.declarationSourceStart, usesStatement.declarationSourceEnd - usesStatement.declarationSourceStart + 1);			
			tSet.add(stmt);
		}
		for (int i = 0; i < moduleDeclaration.servicesCount; ++i) {
			org.eclipse.jdt.internal.compiler.ast.ProvidesStatement pStmt = moduleDeclaration.services[i];
			ProvidesDirective stmt = new ProvidesDirective(this.ast);
			stmt.setName(convert(pStmt.serviceInterface));
			TypeReference[] impls = pStmt.implementations;
			for (TypeReference impl : impls) {
				stmt.implementations().add(convert(impl));
			}
			stmt.setSourceRange(pStmt.declarationSourceStart, pStmt.declarationSourceEnd - pStmt.declarationSourceStart + 1);
			tSet.add(stmt);
		}
		// The javadoc comment is now got from 	list store in compilation unit declaration
		if (this.resolveBindings) {
			recordNodes(moduleDecl, moduleDeclaration);
			recordNodes(moduleName, moduleDeclaration);
			moduleDecl.resolveBinding();
		}
		stmts.addAll(tSet);
		int end = getKnownEnd(moduleDecl, moduleDeclaration.sourceEnd, moduleDeclaration.declarationSourceEnd);
		moduleDecl.setSourceRange(moduleDeclaration.declarationSourceStart, end  - moduleDeclaration.declarationSourceStart + 1);
		return moduleDecl;
	}

	private void setModuleModifiers(org.eclipse.jdt.internal.compiler.ast.RequiresStatement req,	RequiresDirective stmt) {
		boolean fakeInModule = this.scanner.fakeInModule;
		this.scanner.fakeInModule = true;
		this.scanner.resetTo(req.declarationSourceStart, req.sourceEnd);
		try {
			int token;
			ModuleModifier modifier;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNamestatic:
						modifier = createModuleModifier(ModuleModifier.ModuleModifierKeyword.STATIC_KEYWORD);
						break;
					case TerminalTokens.TokenNametransitive:
						modifier = createModuleModifier(ModuleModifier.ModuleModifierKeyword.TRANSITIVE_KEYWORD);
						break;
					default :
						continue;
				}
				if (modifier != null) {
					stmt.modifiers().add(modifier);
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		} finally {
			this.scanner.fakeInModule = fakeInModule;
		}
	}

	public ParenthesizedExpression convertToParenthesizedExpression(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
		final ParenthesizedExpression parenthesizedExpression = new ParenthesizedExpression(this.ast);
		if (this.resolveBindings) {
			recordNodes(parenthesizedExpression, expression);
		}
		parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		adjustSourcePositionsForParent(expression);
		trimWhiteSpacesAndComments(expression);
		// decrement the number of parenthesis
		int numberOfParenthesis = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
		expression.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
		expression.bits |= (numberOfParenthesis - 1) << org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
		parenthesizedExpression.setExpression(convert(expression));
		return parenthesizedExpression;
	}

	protected VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
		final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
		variableDeclarationExpression.fragments().add(variableDeclarationFragment);
		if (this.resolveBindings) {
			recordNodes(variableDeclarationFragment, localDeclaration);
		}
		variableDeclarationExpression.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
		Type type = convertType(localDeclaration.type);
		setTypeForVariableDeclarationExpression(variableDeclarationExpression, type, variableDeclarationFragment.getExtraDimensions());
		if (localDeclaration.modifiersSourceStart != -1) {
			setModifiers(variableDeclarationExpression, localDeclaration);
		}
		return variableDeclarationExpression;
	}

	protected SingleVariableDeclaration convertToSingleVariableDeclaration(LocalDeclaration localDeclaration) {
		final SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
		setModifiers(variableDecl, localDeclaration);
		final SimpleName name = new SimpleName(this.ast);
		name.internalSetIdentifier(new String(localDeclaration.name));
		int start = localDeclaration.sourceStart;
		int nameEnd = localDeclaration.sourceEnd;
		name.setSourceRange(start, nameEnd - start + 1);
		variableDecl.setName(name);
		TypeReference typeReference = localDeclaration.type;
		final int extraDimensions = typeReference.extraDimensions();
		if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
			setExtraAnnotatedDimensions(nameEnd + 1, localDeclaration.declarationSourceEnd, typeReference,
					variableDecl.extraDimensions(), extraDimensions);
		} else {
			internalSetExtraDimensions(variableDecl, extraDimensions);
		}
		Type type = convertType(localDeclaration.type);
		int typeEnd = type.getStartPosition() + type.getLength() - 1;
		// https://bugs.eclipse.org/393719 - [compiler] inconsistent warnings on iteration variables
		// compiler considers collectionExpression as within the declarationSourceEnd, DOM AST must use the shorter range to avoid overlap
		int sourceEnd = ((localDeclaration.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsForeachElementVariable) != 0)  
				? localDeclaration.sourceEnd : localDeclaration.declarationSourceEnd;
		int rightEnd = Math.max(typeEnd, sourceEnd);
		/*
		 * There is extra work to do to set the proper type positions
		 * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
		 */
		setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
		variableDecl.setSourceRange(localDeclaration.declarationSourceStart, rightEnd - localDeclaration.declarationSourceStart + 1);
		if (this.resolveBindings) {
			recordNodes(name, localDeclaration);
			recordNodes(variableDecl, localDeclaration);
			variableDecl.resolveBinding();
		}
		return variableDecl;
	}

	private Dimension convertToDimensions(int start, int end, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotation) {
		int length = annotation == null ? 0 : annotation.length;
		Dimension dimension = this.ast.newDimension();
		for (int i = 0; i < length; i++) {
			Annotation annot = convert(annotation[i]);
			dimension.annotations().add(annot);
		}
		retrieveDimensionAndSetPositions(start, end, dimension);
		return dimension;
	}

	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
		final SimpleName name = new SimpleName(this.ast);
		name.internalSetIdentifier(new String(fieldDeclaration.name));
		name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
		variableDeclarationFragment.setName(name);
		int start = fieldDeclaration.sourceEnd;
		int end = start;
		TypeReference typeReference = fieldDeclaration.type;
		int extraDimensions = typeReference.extraDimensions();
		if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
			setExtraAnnotatedDimensions(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd,
					typeReference, variableDeclarationFragment.extraDimensions(), extraDimensions);
		} else {
			internalSetExtraDimensions(variableDeclarationFragment, extraDimensions);
		}
		if (fieldDeclaration.initialization != null) {
			final Expression expression = convert(fieldDeclaration.initialization);
			variableDeclarationFragment.setInitializer(expression);
			start = expression.getStartPosition() + expression.getLength();
			end = start - 1;
		} else {
			// we need to do it even if extendedDimension is null in case of syntax error in an array initializer
			// need the exclusive range for retrieveEndOfPotentialExtendedDimensions
			int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, fieldDeclaration.sourceEnd, fieldDeclaration.declarationSourceEnd);
			if (possibleEnd == Integer.MIN_VALUE) {
				end = fieldDeclaration.declarationSourceEnd;
				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
			} if (possibleEnd < 0) {
				end = -possibleEnd;
				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
			} else {
				end = possibleEnd;
			}
		}
		variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
		if (this.resolveBindings) {
			recordNodes(name, fieldDeclaration);
			recordNodes(variableDeclarationFragment, fieldDeclaration);
			variableDeclarationFragment.resolveBinding();
		}
		return variableDeclarationFragment;
	}

	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
		final SimpleName name = new SimpleName(this.ast);
		name.internalSetIdentifier(new String(localDeclaration.name));
		name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
		variableDeclarationFragment.setName(name);
		int start = localDeclaration.sourceEnd;
		org.eclipse.jdt.internal.compiler.ast.Expression initialization = localDeclaration.initialization;
		TypeReference typeReference = localDeclaration.type;
		int extraDimension = typeReference.extraDimensions();
		if (this.ast.apiLevel >= AST.JLS8_INTERNAL) {
			setExtraAnnotatedDimensions(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength,
					typeReference, variableDeclarationFragment.extraDimensions(), extraDimension);
		} else {
			internalSetExtraDimensions(variableDeclarationFragment, extraDimension);
		}

		boolean hasInitialization = initialization != null;
		int end;
		if (hasInitialization) {
			final Expression expression = convert(initialization);
			variableDeclarationFragment.setInitializer(expression);
			start = expression.getStartPosition() + expression.getLength();
			end = start - 1;
		} else {
			// we need to do it even if extendedDimension is null in case of syntax error in an array initializer
			// start + 1 because we need the exclusive range for retrieveEndOfPotentialExtendedDimensions
			int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, localDeclaration.sourceEnd, localDeclaration.declarationSourceEnd);
			if (possibleEnd == Integer.MIN_VALUE) {
				end = start;
				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
			} else if (possibleEnd < 0) {
				end = -possibleEnd;
				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
			} else {
				end = possibleEnd;
			}
		}
		variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
		if (this.resolveBindings) {
			recordNodes(variableDeclarationFragment, localDeclaration);
			recordNodes(name, localDeclaration);
			variableDeclarationFragment.resolveBinding();
		}
		return variableDeclarationFragment;
	}

	protected void setExtraAnnotatedDimensions(int start, int end, TypeReference type, final List extraAnnotatedDimensions, int extraDimension) {
		if (extraDimension > 0) {
			org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDims = type.getAnnotationsOnDimensions(true);
			int length = (annotationsOnDims == null) ? 0 : annotationsOnDims.length;
			for (int i = (length - extraDimension); i < length; i++) {
				Dimension dim = convertToDimensions(start, end, (annotationsOnDims == null) ? null : annotationsOnDims[i]);
				extraAnnotatedDimensions.add(dim);
				start = dim.getStartPosition() + dim.getLength();
			}
		}
	}

	private void setTypeAnnotationsOnDimension(Dimension currentDimension, org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDimensions, int dimension) {
		if (annotationsOnDimensions == null) return;
		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = annotationsOnDimensions[dimension];
		if (annotations != null) {
			for (int j = 0, length = annotations.length; j < length; j++) {
				Annotation annotation = convert(annotations[j]);
				currentDimension.annotations().add(annotation);
			}
		}
	}
	
	private void setTypeAnnotationsAndSourceRangeOnArray(ArrayType arrayType, org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDimensions) {
		List dimensions = arrayType.dimensions();
		Type elementType = arrayType.getElementType();

		// Object[] a
		// ^
		int start = elementType.getStartPosition();

		// Object[] a
		//       ^
		int startArray = start + elementType.getLength();

		// Object[] a
		//        ^
		int end = retrieveProperRightBracketPosition(dimensions.size(), startArray);
		if (end == -1) {
			end = startArray - 1;
		}
		arrayType.setSourceRange(start, end - start + 1);
		
		start = startArray;
		for (int i = 0; i < dimensions.size(); i++) {
			Dimension currentDimension = (Dimension) dimensions.get(i);
			setTypeAnnotationsOnDimension(currentDimension, annotationsOnDimensions, i);
			retrieveDimensionAndSetPositions(start, end, currentDimension);
			start = currentDimension.getStartPosition() + currentDimension.getLength();
		}
	}

	protected VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
		final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast);
		variableDeclarationStatement.fragments().add(variableDeclarationFragment);
		variableDeclarationStatement.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
		Type type = convertType(localDeclaration.type);
		setTypeForVariableDeclarationStatement(variableDeclarationStatement, type, variableDeclarationFragment.getExtraDimensions());
		if (this.resolveBindings) {
			recordNodes(variableDeclarationFragment, localDeclaration);
			if (this.ast.apiLevel() >= AST.JLS10_INTERNAL && type.isVar()) {
				SimpleName varName = (SimpleName) ((SimpleType) type).getName();
				varName.setVar(true);
				recordNodes(varName, localDeclaration);				
			}
		}
		if (localDeclaration.modifiersSourceStart != -1) {
			setModifiers(variableDeclarationStatement, localDeclaration);
		}
		return variableDeclarationStatement;
	}

	private int annotateType(AnnotatableType type, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) {
		int annotationsEnd = 0;
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
			case AST.JLS3_INTERNAL :
			case AST.JLS4_INTERNAL:
				type.setFlags(type.getFlags() | ASTNode.MALFORMED);
				break;
			default:
				if (annotations == null) break;
				int start = type.getStartPosition();
				int length = type.getLength();
				int annotationsLength = annotations.length;
				for (int i = 0; i < annotationsLength; i++) {
					org.eclipse.jdt.internal.compiler.ast.Annotation typeAnnotation = annotations[i];
					if (typeAnnotation != null) {
						Annotation annotation = convert(typeAnnotation);
						type.annotations().add(annotation);
						annotationsEnd = annotation.getStartPosition() + annotation.getLength();
					}
				}
				int annotationsStart;
				if (annotations[0] != null && (annotationsStart = annotations[0].sourceStart) < start && annotationsStart > 0) {
					length +=  start - annotationsStart;
					start = annotationsStart;
				}
				type.setSourceRange(start, length);
		}
		return annotationsEnd;
	}
	private void annotateTypeParameter(TypeParameter typeParameter, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
			case AST.JLS3_INTERNAL :
			case AST.JLS4_INTERNAL:
				typeParameter.setFlags(typeParameter.getFlags() | ASTNode.MALFORMED);
				break;
			default:
				int annotationsLength = annotations.length;
				for (int i = 0; i < annotationsLength; i++) {
					org.eclipse.jdt.internal.compiler.ast.Annotation typeAnnotation = annotations[i];
					if (typeAnnotation != null) {
						Annotation annotation = convert(typeAnnotation);
						typeParameter.modifiers().add(annotation);
					}
				}
		}
	}

	public Type convertType(TypeReference typeReference) {
		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations;
		if (typeReference instanceof Wildcard) {
			final Wildcard wildcard = (Wildcard) typeReference;
			final WildcardType wildcardType = new WildcardType(this.ast);
			if (wildcard.bound != null) {
				final Type bound = convertType(wildcard.bound);
				wildcardType.setBound(bound, wildcard.kind == Wildcard.EXTENDS);
				int start = wildcard.sourceStart;
				wildcardType.setSourceRange(start, bound.getStartPosition() + bound.getLength() - start);
			} else {
				final int start = wildcard.sourceStart;
				final int end = wildcard.sourceEnd;
				wildcardType.setSourceRange(start, end - start + 1);
			}
			if (this.resolveBindings) {
				recordNodes(wildcardType, typeReference);
			}
			if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
				annotateType(wildcardType, annotations);
			}
			return wildcardType;
		}
		Type type = null;
		int sourceStart = typeReference.sourceStart;
		int length = 0;
		int dimensions = typeReference.dimensions();
//{ObjectTeams: check for lifting type reference
		if (typeReference instanceof LiftingTypeReference)
		{
		    return convertType((LiftingTypeReference)typeReference);
		}
		if (typeReference instanceof TypeAnchorReference)
		{
		    return convertType((TypeAnchorReference)typeReference);
		}
//gbr+SH}
		if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) {
			annotations = typeReference.annotations != null ? typeReference.annotations[0] : null;
			int annotationsEnd = annotations != null ? annotations[annotations.length - 1].declarationSourceEnd + 1 : -1;
			// this is either an ArrayTypeReference or a SingleTypeReference
			char[] name = ((org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) typeReference).getTypeName()[0];
			length = typeReference.sourceEnd - typeReference.sourceStart + 1;
			// need to find out if this is an array type of primitive types or not
			if (isPrimitiveType(name)) {
				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart < annotationsEnd ? annotationsEnd : sourceStart, sourceStart + length);
				int end = positions[1];
				if (end == -1) {
					end = sourceStart + length - 1;
				}
				final PrimitiveType primitiveType = new PrimitiveType(this.ast);
				primitiveType.setPrimitiveTypeCode(getPrimitiveTypeCode(name));
				primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
				type = primitiveType;
				if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
					annotateType(primitiveType, annotations);
				}
			} else if (typeReference instanceof ParameterizedSingleTypeReference) {
				ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference;
				final SimpleName simpleName = new SimpleName(this.ast);
				simpleName.internalSetIdentifier(new String(name));
				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart < annotationsEnd ? annotationsEnd : sourceStart, sourceStart + length);
				int end = positions[1];
				if (end == -1) {
					end = sourceStart + length - 1;
				}
				if (positions[0] != -1) {
					simpleName.setSourceRange(positions[0], end - positions[0] + 1);
				} else {
					simpleName.setSourceRange(sourceStart, end - sourceStart + 1);					
				}

				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						SimpleType simpleType = new SimpleType(this.ast);
						simpleType.setName(simpleName);
						simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
						simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
						type = simpleType;
						if (this.resolveBindings) {
							this.recordNodes(simpleName, typeReference);
						}
						break;
					default :
						simpleType = new SimpleType(this.ast);
						simpleType.setName(simpleName);
						simpleType.setSourceRange(simpleName.getStartPosition(), simpleName.getLength());
						if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
							annotateType(simpleType, annotations);
						}
						int newSourceStart = simpleType.getStartPosition();
						if (newSourceStart > 0 && newSourceStart < sourceStart) 
							sourceStart = newSourceStart;
						final ParameterizedType parameterizedType = new ParameterizedType(this.ast);
						parameterizedType.setType(simpleType);
						type = parameterizedType;
//{ObjectTeams:??type anchors:
						TypeAnchorReference[] typeAnchors = parameterizedSingleTypeReference.typeAnchors;
						if (typeAnchors != null){
							for (TypeAnchorReference typeAnchor: typeAnchors) {
								TypeAnchor anchorRef = convertType(typeAnchor);
								parameterizedType.typeArguments().add(anchorRef);
								end = anchorRef.getStartPosition() + anchorRef.getLength() - 1;
							}
						}
// SH}
						TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
						if (typeArguments != null) {
							Type type2 = null;
							for (int i = 0, max = typeArguments.length; i < max; i++) {
								type2 = convertType(typeArguments[i]);
								((ParameterizedType) type).typeArguments().add(type2);
								end = type2.getStartPosition() + type2.getLength() - 1;
							}
							end = retrieveClosingAngleBracketPosition(end + 1);
							type.setSourceRange(sourceStart, end - sourceStart + 1);
						} else {
							type.setSourceRange(sourceStart, end - sourceStart + 1);
						}
						if (this.resolveBindings) {
							this.recordNodes(simpleName, typeReference);
							this.recordNodes(simpleType, typeReference);
						}
				}
			} else {
				final SimpleName simpleName = new SimpleName(this.ast);
				simpleName.internalSetIdentifier(new String(name));
				// we need to search for the starting position of the first brace in order to set the proper length
				// PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart < annotationsEnd ? annotationsEnd : sourceStart, sourceStart + length);
				int end = positions[1];
				if (end == -1) {
					end = sourceStart + length - 1;
				}
				if (positions[0] != -1) {
					simpleName.setSourceRange(positions[0], end - positions[0] + 1);
				} else {
					simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
				}
				final SimpleType simpleType = new SimpleType(this.ast);
				simpleType.setName(simpleName);
				type = simpleType;
				type.setSourceRange(sourceStart, end - sourceStart + 1);
				type = simpleType;
				if (this.ast.apiLevel() >= AST.JLS10_INTERNAL && type.isVar()) {
					simpleName.setVar(true);
				}
				if (this.resolveBindings) {
					this.recordNodes(simpleName, typeReference);
				}
				if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
					annotateType(simpleType, annotations);
				}
			}
			if (dimensions != 0) {
				type = convertToArray(type, sourceStart, length, dimensions, typeReference.getAnnotationsOnDimensions(true));
				if (this.resolveBindings) {
					// store keys for inner types
					completeRecord((ArrayType) type, typeReference);
				}
			}
		} else {
			if (typeReference instanceof ParameterizedQualifiedTypeReference) {
				ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference;
				char[][] tokens = parameterizedQualifiedTypeReference.tokens;
				TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
				org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = parameterizedQualifiedTypeReference.annotations;
				TypeReference[] arguments = null;
				int lenth = tokens.length;
				int firstTypeIndex = lenth - 1;
				long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL : {
						char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
						int nameLength = name.length;
						sourceStart = (int)(positions[0]>>>32);
						length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
						Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
						final SimpleType simpleType = new SimpleType(this.ast);
						simpleType.setName(qualifiedName);
						simpleType.setSourceRange(sourceStart, length);
						simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
						type = simpleType;
					}
					break;
					default :
						boolean isTypeArgumentBased = false;
						for (int i = 0; i < lenth; ++i) {
							if (typeArguments != null && typeArguments[i] != null) {
								firstTypeIndex = i;
								isTypeArgumentBased = true;
								break;
							}
							if (typeAnnotations != null && typeAnnotations[i] != null) {
								firstTypeIndex = i;
								isTypeArgumentBased = false;
								break;
							}
						}						
						int start = (int) (positions[0] >>> 32);
						int end = (int) positions[firstTypeIndex];
						
						Type currentType = createBaseType(typeReference, positions, typeAnnotations, tokens, lenth, firstTypeIndex, isTypeArgumentBased);
						int indexOfEnclosingType = 1;
						if (typeArguments != null && (arguments = typeArguments[firstTypeIndex]) != null) {
							int arglen = arguments.length;
							ParameterizedType parameterizedType = new ParameterizedType(this.ast);
							parameterizedType.index = indexOfEnclosingType;
							parameterizedType.setType(currentType);
							if (this.resolveBindings) {
								recordNodes(parameterizedType, typeReference);
							}
							Type type2 = null; 
							for (int i = 0; i < arglen; ++i ) {
								type2 = convertType(arguments[i]);
								parameterizedType.typeArguments().add(type2);
							}
							end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
							end = retrieveClosingAngleBracketPosition(end + 1);
							int baseStart = currentType.getStartPosition();
							start = start <= baseStart ? start : baseStart;
							parameterizedType.setSourceRange(start, end - start + 1);
							currentType = parameterizedType;
						}
						
						for (int i = firstTypeIndex + 1; i < lenth; ++i) {
							SimpleName simpleName = new SimpleName(this.ast);
							simpleName.setIdentifier(new String(tokens[i]));
							simpleName.index = i + 1;
							start = (int) (positions[i] >>> 32);
							end = (int) positions[i];
							simpleName.setSourceRange(start, end - start + 1);
							recordPendingNameScopeResolution(simpleName);
							QualifiedType qualifiedType = new QualifiedType(this.ast);
							qualifiedType.setQualifier(currentType);
							qualifiedType.setName(simpleName);
							start = currentType.getStartPosition();
							end = simpleName.getStartPosition() + simpleName.getLength() - 1;
							qualifiedType.setSourceRange(start, end - start + 1);
							if (typeAnnotations != null &&  (annotations = typeAnnotations[i]) != null) {
								int nextPosition = annotateType(qualifiedType, annotations);
								if (simpleName.getStartPosition() < nextPosition && nextPosition <= end) {
									simpleName.setSourceRange(nextPosition, end - nextPosition + 1);
									trimWhiteSpacesAndComments(simpleName);
								}
							}
							if (this.resolveBindings) {
								recordNodes(simpleName, typeReference);
								recordNodes(qualifiedType, typeReference);
							}
							currentType = qualifiedType;
							indexOfEnclosingType++;
							
							if (typeArguments != null && (arguments = typeArguments[i]) != null) {
								int arglen = arguments.length;
								qualifiedType.index = indexOfEnclosingType;
								ParameterizedType parameterizedType = new ParameterizedType(this.ast);
								parameterizedType.index = indexOfEnclosingType;
								parameterizedType.setType(currentType);
								if (this.resolveBindings) {
									recordNodes(parameterizedType, typeReference);
								}
								Type type2 = null; 
								for (int j = 0; j < arglen; ++j ) {
									type2 = convertType(arguments[j]);
									parameterizedType.typeArguments().add(type2);
								}
								end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
								end = retrieveClosingAngleBracketPosition(end + 1);
								parameterizedType.setSourceRange(start, end - start + 1);
								currentType = parameterizedType;
							} else {
								qualifiedType.index = indexOfEnclosingType;
							}
						}
						type = currentType;
				}
			} else if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) {			
				QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
				long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
				org.eclipse.jdt.internal.compiler.ast.Annotation [][] typeAnnotations = typeReference.annotations;
				char [][] tokens = qualifiedTypeReference.tokens;
				int lenth = tokens.length;
				int firstTypeIndex = lenth;
				
				if (typeAnnotations != null) {
					for (int i = 0; i < lenth; ++i) {
						if (typeAnnotations[i] != null) {
							firstTypeIndex = i;
							break;
						}
					}
				}  
//{ObjectTeams: revert anchored types like in MyTeam.this._OT$base.R => base.R
				org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBindingOT =
					((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).resolvedType;
				if (typeBindingOT != null) {
					typeBindingOT = typeBindingOT.leafComponentType();
					if (typeBindingOT instanceof RoleTypeBinding) {
						RoleTypeBinding rtb = (RoleTypeBinding)typeBindingOT;
						if (rtb.hasExplicitAnchor()) {
							char[][] newName = CharOperation.splitOn('.', rtb.optimalName());
							// refuse to use best name which is longer than source name.
							if (tokens.length >= newName.length)
								tokens = newName;
						}
					}
				}
// SH}
				Type currentType = createBaseType(typeReference, positions, typeAnnotations, tokens, lenth, firstTypeIndex, false);
				for (int i = firstTypeIndex + 1; i < lenth; ++i) {
					currentType = createQualifiedType(typeReference, positions,  typeAnnotations, tokens, i, currentType);
				}
				type = currentType;
			} else if (typeReference instanceof UnionTypeReference){
				TypeReference[] typeReferences = ((org.eclipse.jdt.internal.compiler.ast.UnionTypeReference) typeReference).typeReferences;
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
					case AST.JLS3_INTERNAL :
						// recovery
						type = this.convertType(typeReferences[0]);
						int start = typeReference.sourceStart;
						int endPosition = typeReference.sourceEnd;
						length = endPosition - start + 1;
						type.setSourceRange(start, length);
						type.setFlags(type.getFlags() | ASTNode.MALFORMED);
						break;
					default:
						// union type reference
						final UnionType unionType = new UnionType(this.ast);
						for (int i = 0, max = typeReferences.length; i < max; i++) {
							unionType.types().add(this.convertType(typeReferences[i]));
						}
						type = unionType;
						List types = unionType.types();
						int size = types.size();
						start = ((Type) types.get(0)).getStartPosition();
						Type lastType = (Type) types.get(size - 1);
						endPosition = lastType.getStartPosition() + lastType.getLength();
						length = endPosition - start; /* + 1 - 1 == 0 */
						type.setSourceRange(start, length);
				}
			} else if (typeReference instanceof IntersectionCastTypeReference) {
				TypeReference[] typeReferences = ((IntersectionCastTypeReference) typeReference).typeReferences;
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
					case AST.JLS3_INTERNAL :
					case AST.JLS4_INTERNAL :
						type = this.convertType(typeReferences[0]);
						int start = typeReference.sourceStart;
						int endPosition = typeReference.sourceEnd;
						length = endPosition - start + 1;
						type.setSourceRange(start, length);
						type.setFlags(type.getFlags() | ASTNode.MALFORMED);
						break;
					default:
						// intersection type reference
						final IntersectionType castType = new IntersectionType(this.ast);
						for (int i = 0, max = typeReferences.length; i < max; i++) {
							castType.types().add(this.convertType(typeReferences[i]));
						}
						type = castType;
						List types = castType.types();
						int size = types.size();
						start = ((Type) types.get(0)).getStartPosition();
						Type lastType = (Type) types.get(size - 1);
						endPosition = lastType.getStartPosition() + lastType.getLength();
						length = endPosition - start;
						type.setSourceRange(start, length);
				}
			}

			length = typeReference.sourceEnd - sourceStart + 1;
			if (dimensions != 0) {
				type = convertToArray(type, sourceStart, length, dimensions, typeReference.getAnnotationsOnDimensions(true));
				if (this.resolveBindings) {
					completeRecord((ArrayType) type, typeReference);
				}
			}
		}
		if (this.resolveBindings) {
			this.recordNodes(type, typeReference);
		}
		boolean sawDiamond = false;
		if (typeReference instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference pstr = (ParameterizedSingleTypeReference) typeReference;
			if (pstr.typeArguments == TypeReference.NO_TYPE_ARGUMENTS) {
				sawDiamond = true;
			}
		} else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
			ParameterizedQualifiedTypeReference pqtr = (ParameterizedQualifiedTypeReference) typeReference;
			for (int i = 0, len = pqtr.typeArguments.length; i < len; i++) {
				if (pqtr.typeArguments[i] == TypeReference.NO_TYPE_ARGUMENTS) {
					sawDiamond = true;
					break;
				}
			}
		} 
		if (sawDiamond) {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
				case AST.JLS3_INTERNAL :
					type.setFlags(type.getFlags() | ASTNode.MALFORMED);
			}
		}
		return type;
	}

	private Type createBaseType(TypeReference typeReference, long[] positions,
			org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, char[][] tokens, int lenth,
			int firstTypeIndex, boolean isTypeArgumentBased) {
		Type currentType;
		Name name = null;
		if (firstTypeIndex == 0) {
			name = createSimpleName(typeReference, positions, tokens, 0 );
			currentType = createSimpleType(name, typeReference, positions, 0, 0);
			setSourceRangeAnnotationsAndRecordNodes(typeReference, (SimpleType) currentType, positions, typeAnnotations, 0, 0, name.index > 0 ? name.index - 1 : 0);
		} else if (firstTypeIndex == lenth) {//Just a QualifiedName
			name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex - 1, typeReference);
			currentType = createSimpleType(name, typeReference, positions, 0, firstTypeIndex - 1);
		} else if (isTypeArgumentBased && (typeAnnotations == null || typeAnnotations[firstTypeIndex] == null)) {
			name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference);
			currentType = createSimpleType(name, typeReference, positions, 0, firstTypeIndex);
		} else {
			if (firstTypeIndex == 1) {
				name = createSimpleName(typeReference, positions, tokens, 0 );
			} else {
				name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex - 1, typeReference);
			}

			boolean createNameQualifiedType = typeAnnotations != null && typeAnnotations[firstTypeIndex] != null;
			if (createNameQualifiedType && this.ast.apiLevel >= AST.JLS8_INTERNAL) {
				NameQualifiedType nameQualifiedType = new NameQualifiedType(this.ast);
				nameQualifiedType.setQualifier(name);
				nameQualifiedType.setName(createSimpleName(typeReference, positions, tokens, firstTypeIndex));
				setSourceRangeAnnotationsAndRecordNodes(typeReference, nameQualifiedType, positions, typeAnnotations, firstTypeIndex, 0, firstTypeIndex);
				currentType = nameQualifiedType;																	
			} else {
				SimpleType simpleType = this.ast.newSimpleType(name);	
				setSourceRangeAnnotationsAndRecordNodes(typeReference, simpleType, positions, typeAnnotations, 0, 0, name.index > 0 ? name.index - 1 : 0);
				currentType = createQualifiedType(typeReference, positions,  typeAnnotations, tokens, firstTypeIndex, simpleType);
				if (createNameQualifiedType) 
					currentType.setFlags(currentType.getFlags() | ASTNode.MALFORMED);
			}
		}
		return currentType;
	}

	private QualifiedType createQualifiedType(TypeReference typeReference, long[] positions,
			org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, char[][] tokens, int index,
			Type qualifier) {
		SimpleName simpleName = createSimpleName(typeReference, positions, tokens, index);
		QualifiedType qualifiedType = new QualifiedType(this.ast);
		qualifiedType.setQualifier(qualifier);
		qualifiedType.setName(simpleName);
		int start = qualifier.getStartPosition();
		int end = simpleName.getStartPosition() + simpleName.getLength() - 1;
		setSourceRangeAnnotationsAndRecordNodes(typeReference, qualifiedType, typeAnnotations, index, start, end);
		return qualifiedType;
	}

	private SimpleType createSimpleType(Name name, TypeReference typeReference, long[] positions,
			int startIndex, int endIndex) {
		SimpleType simpleType = new SimpleType(this.ast);
		simpleType.setName(name);
		int start = (int)(positions[startIndex] >>> 32);
		int end = (int)positions[endIndex];
		simpleType.setSourceRange(start, end - start + 1);
		if (this.resolveBindings) {
			recordNodes(simpleType, typeReference);
		}
		return simpleType;
	}

	private void setSourceRangeAnnotationsAndRecordNodes(TypeReference typeReference, AnnotatableType annotatableType,
			org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, int index, int start, int end) {
		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations;
		int length = end - start + 1;
		annotatableType.setSourceRange(start, length);
		if (typeAnnotations != null && (annotations = typeAnnotations[index]) != null) {
			annotateType(annotatableType, annotations);
		}
		if (this.resolveBindings) {
			recordNodes(annotatableType, typeReference);
		}
	}

	private void setSourceRangeAnnotationsAndRecordNodes(TypeReference typeReference, AnnotatableType annotatableType, 
			long[] positions, org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, int index, int startIndex, int endIndex) {
		int start = (int) (positions[startIndex] >>> 32);
		int end = (int) positions[endIndex];
		setSourceRangeAnnotationsAndRecordNodes(typeReference, annotatableType, typeAnnotations, index, start, end);
	}

	private SimpleName createSimpleName(TypeReference typeReference, long[] positions, char[][] tokens, int index) {
		final SimpleName simpleName = new SimpleName(this.ast);
		simpleName.internalSetIdentifier(new String(tokens[index]));
		recordPendingNameScopeResolution(simpleName);
		int start = (int) (positions[index] >>> 32);
		int end = (int) positions[index];
		simpleName.setSourceRange(start, end - start + 1);
		simpleName.index = index + 1;
		if (this.resolveBindings) {
			recordNodes(simpleName, typeReference);
		}
		return simpleName;
	}

	protected Comment createComment(int[] positions) {
		// Create comment node
		Comment comment = null;
		int start = positions[0];
		int end = positions[1];
		if (positions[1]>0) { // Javadoc comments have positive end position
			Javadoc docComment = this.docParser.parse(positions);
			if (docComment == null) return null;
			comment = docComment;
		} else {
			end = -end;
			if (positions[0] == 0) { // we cannot know without testing chars again
				if (this.docParser.scanner.source[1] == '/') {
					comment = new LineComment(this.ast);
				} else {
					comment = new BlockComment(this.ast);
				}
			}
			else if (positions[0]>0) { // Block comment have positive start position
				comment = new BlockComment(this.ast);
			} else { // Line comment have negative start and end position
				start = -start;
				comment = new LineComment(this.ast);
			}
			comment.setSourceRange(start, end - start);
		}
		return comment;
	}

	protected Statement createFakeEmptyStatement(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
		if (statement == null) return null;
		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
		emptyStatement.setFlags(emptyStatement.getFlags() | ASTNode.MALFORMED);
		int start = statement.sourceStart;
		int end = statement.sourceEnd;
		emptyStatement.setSourceRange(start, end - start + 1);
		return emptyStatement;
	}

	/**
	 * Warning: Callers of this method must ensure that the fake literal node is not recorded in
	 * {@link #recordNodes(ASTNode, org.eclipse.jdt.internal.compiler.ast.ASTNode)}, see bug 403444!
	 */
	protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
		if (this.referenceContext != null) {
			this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED);
		}
		NullLiteral nullLiteral = new NullLiteral(this.ast);
		nullLiteral.setFlags(nullLiteral.getFlags() | ASTNode.MALFORMED);
		nullLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
		return nullLiteral;
	}

	/**
	 * @return a new modifier
	 */
	private Modifier createModifier(ModifierKeyword keyword) {
		final Modifier modifier = new Modifier(this.ast);
		modifier.setKeyword(keyword);
		int start = this.scanner.getCurrentTokenStartPosition();
		int end = this.scanner.getCurrentTokenEndPosition();
		modifier.setSourceRange(start, end - start + 1);
		return modifier;
	}

	/**
	 * @return a new module modifier
	 */
	private ModuleModifier createModuleModifier(ModuleModifierKeyword keyword) {
		final ModuleModifier modifier = new ModuleModifier(this.ast);
		modifier.setKeyword(keyword);
		int start = this.scanner.getCurrentTokenStartPosition();
		int end = this.scanner.getCurrentTokenEndPosition();
		modifier.setSourceRange(start, end - start + 1);
		return modifier;
	}

	protected InfixExpression.Operator getOperatorFor(int operatorID) {
		switch (operatorID) {
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
				return InfixExpression.Operator.EQUALS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
				return InfixExpression.Operator.LESS_EQUALS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
				return InfixExpression.Operator.GREATER_EQUALS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
				return InfixExpression.Operator.NOT_EQUALS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
				return InfixExpression.Operator.LEFT_SHIFT;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
				return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
				return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
				return InfixExpression.Operator.CONDITIONAL_OR;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
				return InfixExpression.Operator.CONDITIONAL_AND;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
				return InfixExpression.Operator.PLUS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
				return InfixExpression.Operator.MINUS;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
				return InfixExpression.Operator.REMAINDER;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
				return InfixExpression.Operator.XOR;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
				return InfixExpression.Operator.AND;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
				return InfixExpression.Operator.TIMES;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
				return InfixExpression.Operator.OR;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
				return InfixExpression.Operator.DIVIDE;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
				return InfixExpression.Operator.GREATER;
			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
				return InfixExpression.Operator.LESS;
		}
		return null;
	}

	protected PrimitiveType.Code getPrimitiveTypeCode(char[] name) {
		switch(name[0]) {
			case 'i' :
				if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
					return PrimitiveType.INT;
				}
				break;
			case 'l' :
				if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
					return PrimitiveType.LONG;
				}
				break;
			case 'd' :
				if (name.length == 6
					 && name[1] == 'o'
					 && name[2] == 'u'
					 && name[3] == 'b'
					 && name[4] == 'l'
					 && name[5] == 'e') {
					return PrimitiveType.DOUBLE;
				}
				break;
			case 'f' :
				if (name.length == 5
					 && name[1] == 'l'
					 && name[2] == 'o'
					 && name[3] == 'a'
					 && name[4] == 't') {
					return PrimitiveType.FLOAT;
				}
				break;
			case 'b' :
				if (name.length == 4
					 && name[1] == 'y'
					 && name[2] == 't'
					 && name[3] == 'e') {
					return PrimitiveType.BYTE;
				} else
					if (name.length == 7
						 && name[1] == 'o'
						 && name[2] == 'o'
						 && name[3] == 'l'
						 && name[4] == 'e'
						 && name[5] == 'a'
						 && name[6] == 'n') {
					return PrimitiveType.BOOLEAN;
				}
				break;
			case 'c' :
				if (name.length == 4
					 && name[1] == 'h'
					 && name[2] == 'a'
					 && name[3] == 'r') {
					return PrimitiveType.CHAR;
				}
				break;
			case 's' :
				if (name.length == 5
					 && name[1] == 'h'
					 && name[2] == 'o'
					 && name[3] == 'r'
					 && name[4] == 't') {
					return PrimitiveType.SHORT;
				}
				break;
			case 'v' :
				if (name.length == 4
					 && name[1] == 'o'
					 && name[2] == 'i'
					 && name[3] == 'd') {
					return PrimitiveType.VOID;
				}
		}
		return null; // cannot be reached
	}

	protected boolean isPrimitiveType(char[] name) {
		switch(name[0]) {
			case 'i' :
				if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
					return true;
				}
				return false;
			case 'l' :
				if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
					return true;
				}
				return false;
			case 'd' :
				if (name.length == 6
					 && name[1] == 'o'
					 && name[2] == 'u'
					 && name[3] == 'b'
					 && name[4] == 'l'
					 && name[5] == 'e') {
					return true;
				}
				return false;
			case 'f' :
				if (name.length == 5
					 && name[1] == 'l'
					 && name[2] == 'o'
					 && name[3] == 'a'
					 && name[4] == 't') {
					return true;
				}
				return false;
			case 'b' :
				if (name.length == 4
					 && name[1] == 'y'
					 && name[2] == 't'
					 && name[3] == 'e') {
					return true;
				} else
					if (name.length == 7
						 && name[1] == 'o'
						 && name[2] == 'o'
						 && name[3] == 'l'
						 && name[4] == 'e'
						 && name[5] == 'a'
						 && name[6] == 'n') {
					return true;
				}
				return false;
			case 'c' :
				if (name.length == 4
					 && name[1] == 'h'
					 && name[2] == 'a'
					 && name[3] == 'r') {
					return true;
				}
				return false;
			case 's' :
				if (name.length == 5
					 && name[1] == 'h'
					 && name[2] == 'o'
					 && name[3] == 'r'
					 && name[4] == 't') {
					return true;
				}
				return false;
			case 'v' :
				if (name.length == 4
					 && name[1] == 'o'
					 && name[2] == 'i'
					 && name[3] == 'd') {
					return true;
				}
				return false;
		}
		return false;
	}
	private void lookupForScopes() {
		if (this.pendingNameScopeResolution != null) {
			for (Iterator iterator = this.pendingNameScopeResolution.iterator(); iterator.hasNext(); ) {
				Name name = (Name) iterator.next();
				this.ast.getBindingResolver().recordScope(name, lookupScope(name));
			}
		}
		if (this.pendingThisExpressionScopeResolution != null) {
			for (Iterator iterator = this.pendingThisExpressionScopeResolution.iterator(); iterator.hasNext(); ) {
				ThisExpression thisExpression = (ThisExpression) iterator.next();
				this.ast.getBindingResolver().recordScope(thisExpression, lookupScope(thisExpression));
			}
		}

	}

	private BlockScope lookupScope(ASTNode node) {
		ASTNode currentNode = node;
		while(currentNode != null
			&&!(currentNode instanceof MethodDeclaration)
			&& !(currentNode instanceof Initializer)
			&& !(currentNode instanceof FieldDeclaration)
			&& !(currentNode instanceof AbstractTypeDeclaration)) {
			currentNode = currentNode.getParent();
		}
		if (currentNode == null) {
			return null;
		}
		if (currentNode instanceof Initializer) {
			Initializer initializer = (Initializer) currentNode;
			while(!(currentNode instanceof AbstractTypeDeclaration)) {
				currentNode = currentNode.getParent();
			}
			if (currentNode instanceof TypeDeclaration
				|| currentNode instanceof EnumDeclaration
				|| currentNode instanceof AnnotationTypeDeclaration) {
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
				if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
					return typeDecl.staticInitializerScope;
				} else {
					return typeDecl.initializerScope;
				}
			}
		} else if (currentNode instanceof FieldDeclaration) {
			FieldDeclaration fieldDeclaration = (FieldDeclaration) currentNode;
			while(!(currentNode instanceof AbstractTypeDeclaration)) {
				currentNode = currentNode.getParent();
			}
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
			if ((fieldDeclaration.getModifiers() & Modifier.STATIC) != 0) {
				return typeDecl.staticInitializerScope;
			} else {
				return typeDecl.initializerScope;
			}
		} else if (currentNode instanceof AbstractTypeDeclaration) {
			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
			return typeDecl.initializerScope;
		}
		AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
		return abstractMethodDeclaration.scope;
	}

	protected void recordName(Name name, org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode) {
		if (compilerNode != null) {
			recordNodes(name, compilerNode);
			if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
				org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) compilerNode;
				if (name.isQualifiedName()) {
					SimpleName simpleName = null;
					while (name.isQualifiedName()) {
						simpleName = ((QualifiedName) name).getName();
						recordNodes(simpleName, typeRef);
						name = ((QualifiedName) name).getQualifier();
						recordNodes(name, typeRef);
					}
				}
			}
		}
	}

	protected void recordNodes(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
		// Do not record the fake literal node created in lieu of functional expressions at JLS levels < 8, as it would lead to CCE down the road.
		if (oldASTNode instanceof org.eclipse.jdt.internal.compiler.ast.FunctionalExpression && node instanceof NullLiteral) {
			return;
		}
		this.ast.getBindingResolver().store(node, oldASTNode);
	}

	protected void recordNodes(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, TagElement tagElement) {
		Iterator fragments = tagElement.fragments().listIterator();
		while (fragments.hasNext()) {
			ASTNode node = (ASTNode) fragments.next();
			if (node.getNodeType() == ASTNode.MEMBER_REF) {
				MemberRef memberRef = (MemberRef) node;
				Name name = memberRef.getName();
				// get compiler node and record nodes
				int start = name.getStartPosition();
				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
				if (compilerNode!= null) {
					recordNodes(name, compilerNode);
					recordNodes(node, compilerNode);
				}
				// Replace qualifier to have all nodes recorded
				if (memberRef.getQualifier() != null) {
					org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
					if (compilerNode instanceof JavadocFieldReference) {
						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocFieldReference)compilerNode).receiver;
						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
						}
					}
					else if (compilerNode instanceof JavadocMessageSend) {
						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocMessageSend)compilerNode).receiver;
						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
						}
					}
					if (typeRef != null) {
						recordName(memberRef.getQualifier(), typeRef);
					}
				}
			} else if (node.getNodeType() == ASTNode.METHOD_REF) {
				MethodRef methodRef = (MethodRef) node;
				Name name = methodRef.getName();
				// get method name start position
				int start = methodRef.getStartPosition();
				this.scanner.resetTo(start, start + name.getStartPosition()+name.getLength());
				int token;
				try {
					nextToken: while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF && token != TerminalTokens.TokenNameLPAREN)  {
						if (token == TerminalTokens.TokenNameERROR && this.scanner.currentCharacter == '#') {
							start = this.scanner.getCurrentTokenEndPosition()+1;
							break nextToken;
						}
					}
				}
				catch(InvalidInputException e) {
					// ignore
				}
				// get compiler node and record nodes
				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
				// record nodes
				if (compilerNode != null) {
					recordNodes(methodRef, compilerNode);
					// get type ref
					org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
					if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression) {
						typeRef = ((org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
						if (typeRef != null) recordNodes(name, compilerNode);
					}
					else if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend) {
						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
						}
						recordNodes(name, compilerNode);
					}
					// record name and qualifier
					if (typeRef != null && methodRef.getQualifier() != null) {
						recordName(methodRef.getQualifier(), typeRef);
					}
				}
				// Resolve parameters
				Iterator parameters = methodRef.parameters().listIterator();
				while (parameters.hasNext()) {
					MethodRefParameter param = (MethodRefParameter) parameters.next();
					org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) javadoc.getNodeStartingAt(param.getStartPosition());
					if (expression != null) {
						recordNodes(param, expression);
						if (expression instanceof JavadocArgumentExpression) {
							JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
							org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
							if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
								param.setVarargs(argExpr.argument.isVarArgs());
							}
							recordNodes(param.getType(), typeRef);
							if (param.getType().isSimpleType()) {
								recordName(((SimpleType)param.getType()).getName(), typeRef);
							} else if (param.getType().isArrayType()) {
								Type type = ((ArrayType) param.getType()).getElementType();
								recordNodes(type, typeRef);
								if (type.isSimpleType()) {
									recordName(((SimpleType)type).getName(), typeRef);
								}
							}
						}
					}
				}
			} else if (node.getNodeType() == ASTNode.SIMPLE_NAME ||
					node.getNodeType() == ASTNode.QUALIFIED_NAME) {
				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(node.getStartPosition());
				recordName((Name) node, compilerNode);
			} else if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
				// resolve member and method references binding
				recordNodes(javadoc, (TagElement) node);
			}
		}
	}

	protected void recordPendingNameScopeResolution(Name name) {
		if (this.pendingNameScopeResolution == null) {
			this.pendingNameScopeResolution = new HashSet();
		}
		this.pendingNameScopeResolution.add(name);
	}

	protected void recordPendingThisExpressionScopeResolution(ThisExpression thisExpression) {
		if (this.pendingThisExpressionScopeResolution == null) {
			this.pendingThisExpressionScopeResolution = new HashSet();
		}
		this.pendingThisExpressionScopeResolution.add(thisExpression);
	}

	/**
	 * Remove whitespaces and comments before and after the expression.
	 */
	private void trimWhiteSpacesAndComments(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
		int[] positions = trimWhiteSpacesAndComments(expression.sourceStart, expression.sourceEnd);
		expression.sourceStart = positions[0];
		expression.sourceEnd = positions[1];
	}
	private void trimWhiteSpacesAndComments(ASTNode node) {
		int start = node.getStartPosition();
		int end = start + node.getLength() - 1;
		int[] positions = trimWhiteSpacesAndComments(start, end);
		start = positions[0];
		end = positions[1];
		node.setSourceRange(start, end - start + 1);
	}
	private int [] trimWhiteSpacesAndComments(int start, int end) {
		int [] positions = new int[]{start, end};
		int token;
		int trimLeftPosition = start;
		int trimRightPosition = end;
		boolean first = true;
		Scanner removeBlankScanner = this.ast.scanner;
		try {
			removeBlankScanner.setSource(this.compilationUnitSource);
			removeBlankScanner.resetTo(start, end);
			while (true) {
				token = removeBlankScanner.getNextToken();
				switch (token) {
					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
					case TerminalTokens.TokenNameCOMMENT_LINE :
					case TerminalTokens.TokenNameCOMMENT_BLOCK :
						if (first) {
							trimLeftPosition = removeBlankScanner.currentPosition;
						}
						break;
					case TerminalTokens.TokenNameWHITESPACE :
						if (first) {
							trimLeftPosition = removeBlankScanner.currentPosition;
						}
						break;
					case TerminalTokens.TokenNameEOF :
						positions[0] = trimLeftPosition;
						positions[1] = trimRightPosition;
						return positions;
					default :
						/*
						 * if we find something else than a whitespace or a comment,
						 * then we reset the trimRigthPosition to the expression
						 * source end.
						 */
						trimRightPosition = removeBlankScanner.currentPosition - 1;
						first = false;
				}
			}
		} catch (InvalidInputException e){
			// ignore
		}
		return positions;
	}

	/**
	 * Remove potential trailing comment by settings the source end on the closing parenthesis
	 */
	protected void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) {
		int start = node.getStartPosition();
		this.scanner.resetTo(start, start + node.getLength());
		int token;
		int startPosition = -1;
		try {
			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
				switch(token) {
					case TerminalTokens.TokenNameIntegerLiteral :
					case TerminalTokens.TokenNameFloatingPointLiteral :
					case TerminalTokens.TokenNameLongLiteral :
					case TerminalTokens.TokenNameDoubleLiteral :
					case TerminalTokens.TokenNameCharacterLiteral :
						if (startPosition == -1) {
							startPosition = this.scanner.startPosition;
						}
						int end = this.scanner.currentPosition;
						node.setSourceRange(startPosition, end - startPosition);
						return;
					case TerminalTokens.TokenNameMINUS :
						startPosition = this.scanner.startPosition;
						break;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}

	/**
	 * This method is used to retrieve the end position of the block.
	 * @return the dimension found, -1 if none
	 */
	protected int retrieveClosingAngleBracketPosition(int start) {
		this.scanner.resetTo(start, this.compilationUnitSourceLength);
		this.scanner.returnOnlyGreater = true;
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameGREATER:
						return this.scanner.currentPosition - 1;
					case TerminalTokens.TokenNameLESS:
						// TokenNameLESS can only be found if the current type has a diamond, start is located before the '<'
						continue;
					default:
						return start;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		this.scanner.returnOnlyGreater = false;
		return start;
	}

	/**
	 * This method is used to set the right end position for expression
	 * statement. The actual AST nodes don't include the trailing semicolon.
	 * This method fixes the length of the corresponding node.
	 */
	protected void retrieveColonPosition(ASTNode node) {
		setNodeSourceEndPosition(node, TerminalTokens.TokenNameCOLON);
	}
	/**
	 * This method is used to set the right end position for switch labeled rules ie with '->'
	 * The actual AST nodes don't include the trailing semicolon.
	 * This method fixes the length of the corresponding node.
	 */
	private void retrieveArrowPosition(ASTNode node) {
		setNodeSourceEndPosition(node, TerminalTokens.TokenNameARROW);
	}
	private void setNodeSourceEndPosition(ASTNode node, int expectedToken) {
		int start = node.getStartPosition();
		int length = node.getLength();
		int end = start + length;
		this.scanner.resetTo(end, this.compilationUnitSourceLength);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				if (token == expectedToken) {
						node.setSourceRange(start, this.scanner.currentPosition - start);
						return;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}
	/**
	 * This method is used to retrieve the start position of the Ellipsis
	 */
	protected int retrieveEllipsisStartPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameELLIPSIS:
						return this.scanner.startPosition - 1;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;

	}

	protected int retrieveSemiColonPosition(Expression node) {
		int start = node.getStartPosition();
		int length = node.getLength();
		int end = start + length;
		this.scanner.resetTo(end, this.compilationUnitSourceLength);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameSEMICOLON:
						return this.scanner.currentPosition - 1;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * This method is used to retrieve the start and end position of a name or primitive type token.
	 * 
	 * @return int[] a single dimensional array, with two elements, for the start and end positions of the name respectively
	 */
	protected int[] retrieveEndOfElementTypeNamePosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			int count = 0;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameLPAREN:
						++count;
						break;
					case TerminalTokens.TokenNameRPAREN:
						--count;
						break;
					case TerminalTokens.TokenNameIdentifier:
					case TerminalTokens.TokenNamebyte:
					case TerminalTokens.TokenNamechar:
					case TerminalTokens.TokenNamedouble:
					case TerminalTokens.TokenNamefloat:
					case TerminalTokens.TokenNameint:
					case TerminalTokens.TokenNamelong:
					case TerminalTokens.TokenNameshort:
					case TerminalTokens.TokenNameboolean:
						if (count > 0) break;
						return new int[]{this.scanner.startPosition, this.scanner.currentPosition - 1};
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return new int[]{-1, -1};
	}

	/**
	 * This method is used to retrieve the position after the right parenthesis.
	 * @return int the position found
	 */
	protected int retrieveEndOfRightParenthesisPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			int count = 0;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameRPAREN:
						count--;
						if (count <= 0) return this.scanner.currentPosition;
						 break;
					case TerminalTokens.TokenNameLPAREN:
						count++;
						//$FALL-THROUGH$
					default:
						break;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	protected void retrieveDimensionAndSetPositions(int start, int end, Dimension dim) {
		this.scanner.resetTo(start, end);
		int token;
		int count = 0, lParenCount = 0;
		boolean startSet = false;
		try {
			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
				if (token != TerminalTokens.TokenNameWHITESPACE) {
					if (!startSet) {
						start = this.scanner.startPosition;
						startSet = true;
					}
					switch(token) {
						case TerminalTokens.TokenNameRBRACKET:
							if (lParenCount > 0) break;
							--count;
							if (count > 0) break;
							int endDim = this.scanner.currentPosition - 1;
							dim.setSourceRange(start, endDim - start + 1);
							return;
						case TerminalTokens.TokenNameLBRACKET:
							if (lParenCount > 0) break;
							count++;
							break;
						case TerminalTokens.TokenNameLPAREN:
							lParenCount++;
							break;
						case TerminalTokens.TokenNameRPAREN:
							--lParenCount;
							break;
						default:
							break;
					}
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}
	protected void retrieveIdentifierAndSetPositions(int start, int end, Name name) {
		this.scanner.resetTo(start, end);
		int token;
		try {
			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
				if (token == TerminalTokens.TokenNameIdentifier) {
					int startName = this.scanner.startPosition;
					int endName = this.scanner.currentPosition - 1;
					name.setSourceRange(startName, endName - startName + 1);
					return;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}

	/**
	 * This method is used to retrieve the start position of the block.
	 * @return int the dimension found, -1 if none
	 */
	protected int retrieveIdentifierEndPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
//{ObjectTeams: treat like an Identifier:
				case TerminalTokens.TokenNamewhen:
//SH}
					case TerminalTokens.TokenNameIdentifier://110
						return this.scanner.getCurrentTokenEndPosition();
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * retrieves the start and and of new and set the positions of the name
	 * @param start position to start search
	 * @param end position to end search
	 * @param name object where these positions will be updated.
	 */
	protected void retrieveInitAndSetPositions(int start, int end, Name name) {
		this.scanner.resetTo(start, end);
		int token;
		try {
			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
				if (token == TerminalTokens.TokenNamenew) {
					int startName = this.scanner.startPosition;
					int endName = this.scanner.currentPosition;
					name.setSourceRange(startName, endName - startName);
					return;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}

	/**
	 * This method is used to retrieve position before the next comma or semi-colon.
	 * @param initializerEnd the given initializer end exclusive
	 * @return int the position found.
	 */
	protected int retrieveEndOfPotentialExtendedDimensions(int initializerEnd, int nameEnd, int end) {
		this.scanner.resetTo(initializerEnd, end);
		boolean hasTokens = false;
		int balance = 0;
		int pos = initializerEnd > nameEnd ? initializerEnd - 1 : nameEnd;
		try {
			int token, lParenCount = 0;
			boolean hasAnnotations = false;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				hasTokens = true;
				if (hasAnnotations) {
					if (token == TerminalTokens.TokenNameLPAREN) ++lParenCount;
					else if (token == TerminalTokens.TokenNameRPAREN) {
						--lParenCount; 
						continue;
					}
					if (lParenCount > 0) continue;
				}
				switch(token) {
					case TerminalTokens.TokenNameAT:
						hasAnnotations = true;
						break;
					case TerminalTokens.TokenNameLBRACE :
					case TerminalTokens.TokenNameLBRACKET :
						balance++;
						break;
					case TerminalTokens.TokenNameRBRACKET :
					case TerminalTokens.TokenNameRBRACE :
						balance --;
						pos = this.scanner.currentPosition - 1;
						break;
					case TerminalTokens.TokenNameCOMMA :
						if (balance == 0) return pos;
						// case where a missing closing brace doesn't close an array initializer
						pos = this.scanner.currentPosition - 1;
						break;
					case TerminalTokens.TokenNameSEMICOLON :
						if (balance == 0) return pos;
						return -pos;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		// no token, we simply return pos as the right position
		return hasTokens ? Integer.MIN_VALUE : pos;
	}

	protected int retrieveProperRightBracketPosition(int bracketNumber, int start, int end) {
		this.scanner.resetTo(start, this.compilationUnitSourceLength);
		try {
			int token, count = 0, lParentCount = 0, balance = 0;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameLPAREN:
						++lParentCount;
						break;
					case TerminalTokens.TokenNameRPAREN:
						--lParentCount;
						break;
					case TerminalTokens.TokenNameLBRACKET:
						++balance;
						break;
					case TerminalTokens.TokenNameELLIPSIS:
						++balance; // special case for varargs - simulate lbracket found
						//$FALL-THROUGH$
					case TerminalTokens.TokenNameRBRACKET:
						--balance;
						if (lParentCount > 0) break;
						if (balance > 0) break;
						count++;
						if (count == bracketNumber) {
							return this.scanner.currentPosition - 1;
						}
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}
	
	protected int retrieveProperRightBracketPosition(int bracketNumber, int start) {
		return retrieveProperRightBracketPosition(bracketNumber, start, this.compilationUnitSourceLength);
	}

	/**
	 * This method is used to retrieve position before the next right brace or semi-colon.
	 * @return int the position found.
	 */
	protected int retrieveRightBraceOrSemiColonPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameRBRACE :
						return this.scanner.currentPosition - 1;
					case TerminalTokens.TokenNameSEMICOLON :
						return this.scanner.currentPosition - 1;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * This method is used to retrieve position before the next right brace or semi-colon.
	 * @return int the position found.
	 */
	protected int retrieveRightBrace(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameRBRACE :
						return this.scanner.currentPosition - 1;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * This method is used to retrieve the start position of the block.
	 * @return int the dimension found, -1 if none
	 */
	protected int retrieveStartBlockPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameLBRACE://110
						return this.scanner.startPosition;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

	/**
	 * This method is used to retrieve the starting position of the catch keyword.
	 * @return int the dimension found, -1 if none
	 */
	protected int retrieveStartingCatchPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNamecatch://225
						return this.scanner.startPosition;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}

//{ObjectTeams:
	/**
	 * This method is used to retrieve the starting position of a  '<-' token
	 * @return int the position found, -1 if none
	 */
	protected int retrieveBINDINPosition(int start, int end) {
		this.scanner.resetTo(start, end);
		try {
			int token;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				switch(token) {
					case TerminalTokens.TokenNameBINDIN://225
						return this.scanner.startPosition;
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
		return -1;
	}
// SH}

	public void setAST(AST ast) {
//{ObjectTeams: transfer scanner mode
		if (ast.scanner != null && this.scanner != null)
			ast.scanner.copyOTFlags(this.scanner);
// SH}
		this.ast = ast;
		this.docParser = new DocCommentParser(this.ast, this.scanner, this.insideComments);
	}

	protected void setModifiers(AnnotationTypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
		this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
		this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
	}

	protected void setModifiers(AnnotationTypeMemberDeclaration annotationTypeMemberDecl, org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
		this.scanner.resetTo(annotationTypeMemberDeclaration.declarationSourceStart, annotationTypeMemberDeclaration.sourceStart);
		this.setModifiers(annotationTypeMemberDecl, annotationTypeMemberDeclaration.annotations, annotationTypeMemberDeclaration.sourceStart);
	}

	/**
	 * @param bodyDeclaration
	 */
	protected void setModifiers(BodyDeclaration bodyDeclaration, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations, int modifiersEnd) {
		setModifiers(bodyDeclaration.modifiers(), annotations, modifiersEnd);
	}
	protected void setModifiers(List modifiers, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations, int modifiersEnd) {
		this.scanner.tokenizeWhiteSpace = false;
		try {
			int token;
			int indexInAnnotations = 0;
			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
				IExtendedModifier modifier = null;
				switch(token) {
					case TerminalTokens.TokenNameabstract:
						modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
						break;
					case TerminalTokens.TokenNamepublic:
						modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
						break;
					case TerminalTokens.TokenNamestatic:
						modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
						break;
					case TerminalTokens.TokenNameprotected:
						modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
						break;
					case TerminalTokens.TokenNameprivate:
						modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
						break;
					case TerminalTokens.TokenNamefinal:
						modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
						break;
//{ObjectTeams: callin team
					case TerminalTokens.TokenNamecallin:
						modifier = createModifier(Modifier.ModifierKeyword.CALLIN_KEYWORD);
						break;
					case TerminalTokens.TokenNameteam:
						modifier = createModifier(Modifier.ModifierKeyword.TEAM_KEYWORD);
						break;
// SH}
					case TerminalTokens.TokenNamenative:
						modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
						break;
					case TerminalTokens.TokenNamesynchronized:
						modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
						break;
					case TerminalTokens.TokenNametransient:
						modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
						break;
					case TerminalTokens.TokenNamevolatile:
						modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
						break;
					case TerminalTokens.TokenNamestrictfp:
						modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
						break;
					case TerminalTokens.TokenNamedefault:
						modifier = createModifier(Modifier.ModifierKeyword.DEFAULT_KEYWORD);
						break;
					case TerminalTokens.TokenNameAT :
						// we have an annotation
						if (annotations != null && indexInAnnotations < annotations.length) {
							org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
							modifier = convert(annotation);
							this.scanner.resetTo(annotation.declarationSourceEnd + 1, modifiersEnd);
						}
						break;
					case TerminalTokens.TokenNameCOMMENT_BLOCK :
					case TerminalTokens.TokenNameCOMMENT_LINE :
					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
						break;
					default :
						// there is some syntax errors in source code
						break;
				}
				if (modifier != null) {
					modifiers.add(modifier);
				}
			}
		} catch(InvalidInputException e) {
			// ignore
		}
	}

	protected void setModifiers(EnumDeclaration enumDeclaration, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2) {
		this.scanner.resetTo(enumDeclaration2.declarationSourceStart, enumDeclaration2.sourceStart);
		this.setModifiers(enumDeclaration, enumDeclaration2.annotations, enumDeclaration2.sourceStart);
	}

	protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				enumConstantDeclaration.internalSetModifiers(fieldDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
				if (fieldDeclaration.annotations != null) {
					enumConstantDeclaration.setFlags(enumConstantDeclaration.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceStart);
				this.setModifiers(enumConstantDeclaration, fieldDeclaration.annotations, fieldDeclaration.sourceStart);
		}
	}

	/**
	 * @param fieldDeclaration
	 * @param fieldDecl
	 */
	protected void setModifiers(FieldDeclaration fieldDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				fieldDeclaration.internalSetModifiers(fieldDecl.modifiers & ExtraCompilerModifiers.AccJustFlag);
				if (fieldDecl.annotations != null) {
					fieldDeclaration.setFlags(fieldDeclaration.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(fieldDecl.declarationSourceStart, fieldDecl.sourceStart);
				this.setModifiers(fieldDeclaration, fieldDecl.annotations, fieldDecl.sourceStart);
		}
	}

	/**
	 * @param initializer
	 * @param oldInitializer
	 */
	protected void setModifiers(Initializer initializer, org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL:
				initializer.internalSetModifiers(oldInitializer.modifiers & ExtraCompilerModifiers.AccJustFlag);
				if (oldInitializer.annotations != null) {
					initializer.setFlags(initializer.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(oldInitializer.declarationSourceStart, oldInitializer.bodyStart);
				this.setModifiers(initializer, oldInitializer.annotations, oldInitializer.bodyStart);
		}
	}
	/**
	 * @param methodDecl
	 * @param methodDeclaration
	 */
	protected void setModifiers(MethodDeclaration methodDecl, AbstractMethodDeclaration methodDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				methodDecl.internalSetModifiers(methodDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
				if (methodDeclaration.annotations != null) {
					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(methodDeclaration.declarationSourceStart, methodDeclaration.sourceStart);
				this.setModifiers(methodDecl, methodDeclaration.annotations, methodDeclaration.sourceStart);
		}
	}

	protected void setAnnotations(ModuleDeclaration moduleDecl, org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration) {
		this.scanner.resetTo(moduleDeclaration.declarationSourceStart, moduleDeclaration.sourceStart);
		List<IExtendedModifier> modifiers = new ArrayList<>();
		this.setModifiers(modifiers, moduleDeclaration.annotations, moduleDeclaration.sourceStart);
		for (IExtendedModifier ie : modifiers) {
			if (!ie.isAnnotation()) {
				continue; // not setting to malformed.
			}
			moduleDecl.annotations().add(ie);
		}
	}
	/**
	 * @param variableDecl
	 * @param argument
	 */
	protected void setModifiers(SingleVariableDeclaration variableDecl, Argument argument) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				variableDecl.internalSetModifiers(argument.modifiers & ExtraCompilerModifiers.AccJustFlag);
				if (argument.annotations != null) {
					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(argument.declarationSourceStart, argument.sourceStart);
				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = argument.annotations;
				int indexInAnnotations = 0;
				try {
					int token;
					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
						IExtendedModifier modifier = null;
						switch(token) {
							case TerminalTokens.TokenNameabstract:
								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
								break;
							case TerminalTokens.TokenNamepublic:
								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
								break;
							case TerminalTokens.TokenNamestatic:
								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
								break;
							case TerminalTokens.TokenNameprotected:
								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
								break;
							case TerminalTokens.TokenNameprivate:
								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
								break;
							case TerminalTokens.TokenNamefinal:
								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
								break;
							case TerminalTokens.TokenNamenative:
								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
								break;
							case TerminalTokens.TokenNamesynchronized:
								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
								break;
							case TerminalTokens.TokenNametransient:
								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
								break;
							case TerminalTokens.TokenNamevolatile:
								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
								break;
							case TerminalTokens.TokenNamestrictfp:
								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
								break;
							case TerminalTokens.TokenNameAT :
								// we have an annotation
								if (annotations != null && indexInAnnotations < annotations.length) {
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
									modifier = convert(annotation);
									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
								}
								break;
							case TerminalTokens.TokenNameCOMMENT_BLOCK :
							case TerminalTokens.TokenNameCOMMENT_LINE :
							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
								break;
							default :
								return;
						}
						if (modifier != null) {
							variableDecl.modifiers().add(modifier);
						}
					}
				} catch(InvalidInputException e) {
					// ignore
				}
		}
	}

	protected void setModifiers(SingleVariableDeclaration variableDecl, LocalDeclaration localDeclaration) {
		switch(this.ast.apiLevel) {
		case AST.JLS2_INTERNAL :
			variableDecl.internalSetModifiers(localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
			if (localDeclaration.annotations != null) {
				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
			}
			break;
		default :
			this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
			org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
			int indexInAnnotations = 0;
			try {
				int token;
				while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
					IExtendedModifier modifier = null;
					switch(token) {
						case TerminalTokens.TokenNameabstract:
							modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
							break;
						case TerminalTokens.TokenNamepublic:
							modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
							break;
						case TerminalTokens.TokenNamestatic:
							modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
							break;
						case TerminalTokens.TokenNameprotected:
							modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
							break;
						case TerminalTokens.TokenNameprivate:
							modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
							break;
						case TerminalTokens.TokenNamefinal:
							modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
							break;
						case TerminalTokens.TokenNamenative:
							modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
							break;
						case TerminalTokens.TokenNamesynchronized:
							modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
							break;
						case TerminalTokens.TokenNametransient:
							modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
							break;
						case TerminalTokens.TokenNamevolatile:
							modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
							break;
						case TerminalTokens.TokenNamestrictfp:
							modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
							break;
						case TerminalTokens.TokenNameAT :
							// we have an annotation
							if (annotations != null && indexInAnnotations < annotations.length) {
								org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
								modifier = convert(annotation);
								this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
							}
							break;
						case TerminalTokens.TokenNameCOMMENT_BLOCK :
						case TerminalTokens.TokenNameCOMMENT_LINE :
						case TerminalTokens.TokenNameCOMMENT_JAVADOC :
							break;
						default :
							return;
					}
					if (modifier != null) {
						variableDecl.modifiers().add(modifier);
					}
				}
			} catch(InvalidInputException e) {
				// ignore
			}
		}
	}

	/**
	 * @param typeDecl
	 * @param typeDeclaration
	 */
	protected void setModifiers(TypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				int modifiers = typeDeclaration.modifiers;
				modifiers &= ~ClassFileConstants.AccInterface; // remove AccInterface flags
				modifiers &= ExtraCompilerModifiers.AccJustFlag;
				typeDecl.internalSetModifiers(modifiers);
				if (typeDeclaration.annotations != null) {
					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
				this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
		}
	}

	/**
	 * @param variableDeclarationExpression
	 * @param localDeclaration
	 */
	protected void setModifiers(VariableDeclarationExpression variableDeclarationExpression, LocalDeclaration localDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
				modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
				variableDeclarationExpression.internalSetModifiers(modifiers);
				if (localDeclaration.annotations != null) {
					variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
				int indexInAnnotations = 0;
				try {
					int token;
					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
						IExtendedModifier modifier = null;
						switch(token) {
							case TerminalTokens.TokenNameabstract:
								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
								break;
							case TerminalTokens.TokenNamepublic:
								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
								break;
							case TerminalTokens.TokenNamestatic:
								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
								break;
							case TerminalTokens.TokenNameprotected:
								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
								break;
							case TerminalTokens.TokenNameprivate:
								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
								break;
							case TerminalTokens.TokenNamefinal:
								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
								break;
							case TerminalTokens.TokenNamenative:
								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
								break;
							case TerminalTokens.TokenNamesynchronized:
								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
								break;
							case TerminalTokens.TokenNametransient:
								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
								break;
							case TerminalTokens.TokenNamevolatile:
								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
								break;
							case TerminalTokens.TokenNamestrictfp:
								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
								break;
							case TerminalTokens.TokenNameAT :
								// we have an annotation
								if (annotations != null && indexInAnnotations < annotations.length) {
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
									modifier = convert(annotation);
									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
								}
								break;
							case TerminalTokens.TokenNameCOMMENT_BLOCK :
							case TerminalTokens.TokenNameCOMMENT_LINE :
							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
								break;
							default :
								return;
						}
						if (modifier != null) {
							variableDeclarationExpression.modifiers().add(modifier);
						}
					}
				} catch(InvalidInputException e) {
					// ignore
				}
		}
	}

	/**
	 * @param variableDeclarationStatement
	 * @param localDeclaration
	 */
	protected void setModifiers(VariableDeclarationStatement variableDeclarationStatement, LocalDeclaration localDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
				modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
				variableDeclarationStatement.internalSetModifiers(modifiers);
				if (localDeclaration.annotations != null) {
					variableDeclarationStatement.setFlags(variableDeclarationStatement.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
				int indexInAnnotations = 0;
				try {
					int token;
					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
						IExtendedModifier modifier = null;
						switch(token) {
							case TerminalTokens.TokenNameabstract:
								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
								break;
							case TerminalTokens.TokenNamepublic:
								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
								break;
							case TerminalTokens.TokenNamestatic:
								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
								break;
							case TerminalTokens.TokenNameprotected:
								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
								break;
							case TerminalTokens.TokenNameprivate:
								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
								break;
							case TerminalTokens.TokenNamefinal:
								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
								break;
							case TerminalTokens.TokenNamenative:
								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
								break;
							case TerminalTokens.TokenNamesynchronized:
								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
								break;
							case TerminalTokens.TokenNametransient:
								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
								break;
							case TerminalTokens.TokenNamevolatile:
								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
								break;
							case TerminalTokens.TokenNamestrictfp:
								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
								break;
							case TerminalTokens.TokenNameAT :
								// we have an annotation
								if (annotations != null && indexInAnnotations < annotations.length) {
									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
									modifier = convert(annotation);
									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
								}
								break;
							case TerminalTokens.TokenNameCOMMENT_BLOCK :
							case TerminalTokens.TokenNameCOMMENT_LINE :
							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
								break;
							default :
								return;
						}
						if (modifier != null) {
							variableDeclarationStatement.modifiers().add(modifier);
						}
					}
				} catch(InvalidInputException e) {
					// ignore
				}
		}
	}

	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
	    int length = typeName.length;
		final SimpleName firstToken = new SimpleName(this.ast);
		firstToken.internalSetIdentifier(new String(typeName[0]));
		firstToken.index = 1;
		int start0 = (int)(positions[0]>>>32);
		int start = start0;
		int end = (int)(positions[0] & 0xFFFFFFFF);
		firstToken.setSourceRange(start, end - start + 1);
		final SimpleName secondToken = new SimpleName(this.ast);
		secondToken.internalSetIdentifier(new String(typeName[1]));
		secondToken.index = 2;
		start = (int)(positions[1]>>>32);
		end = (int)(positions[1] & 0xFFFFFFFF);
		secondToken.setSourceRange(start, end - start + 1);
		QualifiedName qualifiedName = new QualifiedName(this.ast);
		qualifiedName.setQualifier(firstToken);
		qualifiedName.setName(secondToken);
		if (this.resolveBindings) {
			recordNodes(qualifiedName, node);
			recordPendingNameScopeResolution(qualifiedName);
			recordNodes(firstToken, node);
			recordNodes(secondToken, node);
			recordPendingNameScopeResolution(firstToken);
			recordPendingNameScopeResolution(secondToken);
		}
		qualifiedName.index = 2;
		qualifiedName.setSourceRange(start0, end - start0 + 1);
		SimpleName newPart = null;
		for (int i = 2; i < length; i++) {
			newPart = new SimpleName(this.ast);
			newPart.internalSetIdentifier(new String(typeName[i]));
			newPart.index = i + 1;
			start = (int)(positions[i]>>>32);
			end = (int)(positions[i] & 0xFFFFFFFF);
			newPart.setSourceRange(start,  end - start + 1);
			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
			qualifiedName2.setQualifier(qualifiedName);
			qualifiedName2.setName(newPart);
			qualifiedName = qualifiedName2;
			qualifiedName.index = newPart.index;
			qualifiedName.setSourceRange(start0, end - start0 + 1);
			if (this.resolveBindings) {
				recordNodes(qualifiedName, node);
				recordNodes(newPart, node);
				recordPendingNameScopeResolution(qualifiedName);
				recordPendingNameScopeResolution(newPart);
			}
		}
		QualifiedName name = qualifiedName;
		if (this.resolveBindings) {
			recordNodes(name, node);
			recordPendingNameScopeResolution(name);
		}
		return name;
	}

	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, org.eclipse.jdt.internal.compiler.ast.TypeReference node) {
 		int length = endingIndex + 1;
		final SimpleName firstToken = new SimpleName(this.ast);
		firstToken.internalSetIdentifier(new String(typeName[0]));
		firstToken.index = 1;
		int start0 = (int)(positions[0]>>>32);
		int start = start0;
		int end = (int) positions[0];
		firstToken.setSourceRange(start, end - start + 1);
		final SimpleName secondToken = new SimpleName(this.ast);
		secondToken.internalSetIdentifier(new String(typeName[1]));
		secondToken.index = 2;
		start = (int)(positions[1]>>>32);
		end = (int) positions[1];
		secondToken.setSourceRange(start, end - start + 1);
		QualifiedName qualifiedName = new QualifiedName(this.ast);
		qualifiedName.setQualifier(firstToken);
		qualifiedName.setName(secondToken);
		if (this.resolveBindings) {
			recordNodes(qualifiedName, node);
			recordPendingNameScopeResolution(qualifiedName);
			recordNodes(firstToken, node);
			recordNodes(secondToken, node);
			recordPendingNameScopeResolution(firstToken);
			recordPendingNameScopeResolution(secondToken);
		}
		qualifiedName.index = 2;
		qualifiedName.setSourceRange(start0, end - start0 + 1);
		SimpleName newPart = null;
		for (int i = 2; i < length; i++) {
			newPart = new SimpleName(this.ast);
			newPart.internalSetIdentifier(new String(typeName[i]));
			newPart.index = i + 1;
			start = (int)(positions[i]>>>32);
			end = (int) positions[i];
			newPart.setSourceRange(start,  end - start + 1);
			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
			qualifiedName2.setQualifier(qualifiedName);
			qualifiedName2.setName(newPart);
			qualifiedName = qualifiedName2;
			qualifiedName.index = newPart.index;
			qualifiedName.setSourceRange(start0, end - start0 + 1);
			if (this.resolveBindings) {
				recordNodes(qualifiedName, node);
				recordNodes(newPart, node);
				recordPendingNameScopeResolution(qualifiedName);
				recordPendingNameScopeResolution(newPart);
			}
		}
        if (newPart == null && this.resolveBindings) {
            recordNodes(qualifiedName, node);
            recordPendingNameScopeResolution(qualifiedName);
        }
		return qualifiedName;
	}

	protected void setTypeNameForAnnotation(org.eclipse.jdt.internal.compiler.ast.Annotation compilerAnnotation, Annotation annotation) {
		TypeReference typeReference = compilerAnnotation.type;
		if (typeReference instanceof QualifiedTypeReference) {
			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
			char[][] tokens = qualifiedTypeReference.tokens;
			long[] positions = qualifiedTypeReference.sourcePositions;
			// QualifiedName
			annotation.setTypeName(setQualifiedNameNameAndSourceRanges(tokens, positions, typeReference));
		} else {
			SingleTypeReference singleTypeReference = (SingleTypeReference) typeReference;
			final SimpleName name = new SimpleName(this.ast);
			name.internalSetIdentifier(new String(singleTypeReference.token));
			int start = singleTypeReference.sourceStart;
			int end = singleTypeReference.sourceEnd;
			name.setSourceRange(start, end - start + 1);
			name.index = 1;
			annotation.setTypeName(name);
			if (this.resolveBindings) {
				recordNodes(name, typeReference);
			}
		}
	}

	protected void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
		if (extraDimension != 0) {
			if (type.isArrayType()) {
				ArrayType arrayType = (ArrayType) type;
				int remainingDimensions = arrayType.getDimensions() - extraDimension;
				if (remainingDimensions == 0)  {
					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
					Type elementType = arrayType.getElementType();
					// cut the child loose from its parent (without creating garbage)
					elementType.setParent(null, null);
					this.ast.getBindingResolver().updateKey(type, elementType);
					fieldDeclaration.setType(elementType);
				} else {
					ArrayType subarrayType = extractSubArrayType(arrayType, remainingDimensions, extraDimension);
					fieldDeclaration.setType(subarrayType);
					this.ast.getBindingResolver().updateKey(type, subarrayType);
				}
				checkAndSetMalformed(type, fieldDeclaration);
			} else {
				fieldDeclaration.setType(type);
			}
		} else {
			if (type.isArrayType() && (this.ast.apiLevel() < AST.JLS8_INTERNAL)) {
				// update positions of the component types of the array type
				int dimensions = ((ArrayType) type).getDimensions();
				updateInnerPositions(type, dimensions);
			}
			fieldDeclaration.setType(type);
		}
	}

	/** extracts the subArrayType for a given declaration for AST levels less
	 * @param arrayType parent type
	 * @param remainingDimensions 
	 * @param dimensionsToRemove
	 * @return an ArrayType
	 */
	private ArrayType extractSubArrayType(ArrayType arrayType, int remainingDimensions, int dimensionsToRemove) {
		ArrayType subArrayType = arrayType;
		int start = subArrayType.getStartPosition();
		if (this.ast.apiLevel() < AST.JLS8_INTERNAL) {
			while (dimensionsToRemove > 0 ) {
				subArrayType = (ArrayType) componentType(subArrayType);
				dimensionsToRemove--;
			}
			updateInnerPositions(subArrayType, remainingDimensions);
		} else {
			List dimensions = subArrayType.dimensions();
			while (dimensionsToRemove > 0 ) {
				dimensions.remove(dimensions.size() - 1);
				dimensionsToRemove--;
			}
		}
		int end = retrieveProperRightBracketPosition(remainingDimensions, start);
		subArrayType.setSourceRange(start, end - start + 1);
		// cut the child loose from its parent (without creating garbage)
		subArrayType.setParent(null, null);
		return subArrayType;
	}

	protected void setTypeForMethodDeclaration(MethodDeclaration methodDeclaration, Type type, int extraDimension) {
		if (extraDimension != 0) {
			if (type.isArrayType()) {
				ArrayType arrayType = (ArrayType) type;
				int remainingDimensions = arrayType.getDimensions() - extraDimension;
				if (remainingDimensions == 0)  {
					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
					Type elementType = arrayType.getElementType();
					// cut the child loose from its parent (without creating garbage)
					elementType.setParent(null, null);
					this.ast.getBindingResolver().updateKey(type, elementType);
					switch(this.ast.apiLevel) {
						case AST.JLS2_INTERNAL :
							methodDeclaration.internalSetReturnType(elementType);
							break;
						default :
							methodDeclaration.setReturnType2(elementType);
						break;
					}
				} else {
					ArrayType subarrayType = extractSubArrayType(arrayType, remainingDimensions, extraDimension);
					switch(this.ast.apiLevel) {
						case AST.JLS2_INTERNAL :
							methodDeclaration.internalSetReturnType(subarrayType);
							break;
						default :
							methodDeclaration.setReturnType2(subarrayType);
							break;
					}
					this.ast.getBindingResolver().updateKey(type, subarrayType);
				}
				checkAndSetMalformed(type, methodDeclaration);
			} else {
				switch(this.ast.apiLevel) {
					case AST.JLS2_INTERNAL :
						methodDeclaration.internalSetReturnType(type);
						break;
					default :
						methodDeclaration.setReturnType2(type);
					break;
				}
			}
		} else {
			switch(this.ast.apiLevel) {
				case AST.JLS2_INTERNAL :
					methodDeclaration.internalSetReturnType(type);
					break;
				default :
					methodDeclaration.setReturnType2(type);
				break;
			}
		}
	}

	protected void setTypeForMethodDeclaration(AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration, Type type, int extraDimension) {
		annotationTypeMemberDeclaration.setType(type);
	}

	protected void setTypeForSingleVariableDeclaration(SingleVariableDeclaration singleVariableDeclaration, Type type, int extraDimension) {
		if (extraDimension != 0) {
			if (type.isArrayType()) {
				ArrayType arrayType = (ArrayType) type;
				int remainingDimensions = arrayType.getDimensions() - extraDimension;
				if (remainingDimensions == 0)  {
					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
					Type elementType = arrayType.getElementType();
					// cut the child loose from its parent (without creating garbage)
					elementType.setParent(null, null);
					this.ast.getBindingResolver().updateKey(type, elementType);
					singleVariableDeclaration.setType(elementType);
				} else {
					ArrayType subarrayType = extractSubArrayType(arrayType, remainingDimensions, extraDimension);
					this.ast.getBindingResolver().updateKey(type, subarrayType);
					singleVariableDeclaration.setType(subarrayType);
				}
				checkAndSetMalformed(type, singleVariableDeclaration);
					
			} else {
				singleVariableDeclaration.setType(type);
			}
		} else {
			singleVariableDeclaration.setType(type);
		}
	}

	protected void setTypeForVariableDeclarationExpression(VariableDeclarationExpression variableDeclarationExpression, Type type, int extraDimension) {
		if (extraDimension != 0) {
			if (type.isArrayType()) {
				ArrayType arrayType = (ArrayType) type;
				int remainingDimensions = arrayType.getDimensions() - extraDimension;
				if (remainingDimensions == 0)  {
					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
					Type elementType = arrayType.getElementType();
					// cut the child loose from its parent (without creating garbage)
					elementType.setParent(null, null);
					this.ast.getBindingResolver().updateKey(type, elementType);
					variableDeclarationExpression.setType(elementType);
				} else {
					ArrayType subarrayType = extractSubArrayType(arrayType, remainingDimensions, extraDimension);
					variableDeclarationExpression.setType(subarrayType);
					this.ast.getBindingResolver().updateKey(type, subarrayType);
				}
				checkAndSetMalformed(type, variableDeclarationExpression);
			} else {
				variableDeclarationExpression.setType(type);
			}
		} else {
			variableDeclarationExpression.setType(type);
		}
	}

	protected void setTypeForVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, Type type, int extraDimension) {
		if (extraDimension != 0) {
			if (type.isArrayType()) {
				ArrayType arrayType = (ArrayType) type;
				int remainingDimensions = arrayType.getDimensions() - extraDimension;
				if (remainingDimensions == 0)  {
					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
					Type elementType = arrayType.getElementType();
					// cut the child loose from its parent (without creating garbage)
					elementType.setParent(null, null);
					this.ast.getBindingResolver().updateKey(type, elementType);
					variableDeclarationStatement.setType(elementType);
				} else {
					ArrayType subarrayType = extractSubArrayType(arrayType, remainingDimensions, extraDimension);
					variableDeclarationStatement.setType(subarrayType);
					this.ast.getBindingResolver().updateKey(type, subarrayType);
				}
				checkAndSetMalformed(type, variableDeclarationStatement);
			} else {
				variableDeclarationStatement.setType(type);
			}
		} else {
			variableDeclarationStatement.setType(type);
		}
	}

	protected void updateInnerPositions(Type type, int dimensions) {
		if (dimensions > 1) {
			// need to set positions for intermediate array type see 42839
			int start = type.getStartPosition();
			Type currentComponentType = componentType(((ArrayType) type));
			int searchedDimension = dimensions - 1;
			int rightBracketEndPosition = start;
			while (currentComponentType.isArrayType()) {
				rightBracketEndPosition = retrieveProperRightBracketPosition(searchedDimension, start);
				currentComponentType.setSourceRange(start, rightBracketEndPosition - start + 1);
				currentComponentType = componentType(((ArrayType) currentComponentType));
				searchedDimension--;
			}
		}
	}

//{ObjectTeams: build RoleTypeDeclaration with inforamtions from Compiler.TypeDeclaration
	private RoleTypeDeclaration buildRoleTypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration)
    {
		RoleTypeDeclaration roleTypeDecl = this.ast.newRoleTypeDeclaration();
		char[] oldSource = null;
		try {
			if (typeDeclaration.isRoleFile()) {
	    		if (typeDeclaration.isConverted)
	    			return null; // don't convert role files which may not have enough source information
				if (typeDeclaration.compilationResult.compilationUnit != null)
				{
					oldSource = this.scanner.source; // try again (see revert in 3857 but also change in 5472..)
					this.scanner.setSource(typeDeclaration.compilationResult);
					this.compilationUnitSource = this.scanner.source;
					this.compilationUnitSourceLength = this.scanner.source.length;
				}
				roleTypeDecl.setRoleFile(true);
			}

			//km: modifers are handled differently in JLS3
			switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL: {
					int modifiers = typeDeclaration.modifiers;
					modifiers &= ~ClassFileConstants.AccInterface; // remove AccInterface flags
					// also allow additional flag to be passed:  (how about deprecated?)
					modifiers &= ExtraCompilerModifiers.AccOTTypeJustFlag;
					roleTypeDecl.internalSetModifiers(modifiers);

					if (typeDeclaration.baseclass != null)
					    roleTypeDecl.internalSetBaseClass(convert(typeDeclaration.baseclass));

					// need to set the superclass and super interfaces here since we cannot distinguish them at
					// the type references level.
					if (typeDeclaration.superclass != null)
						roleTypeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));

				}
				break;
			default :
				this.setModifiers(roleTypeDecl, typeDeclaration);

				if (   typeDeclaration.baseclass != null
					&& !typeDeclaration.baseclass.isGenerated())
				    roleTypeDecl.setBaseClassType(convertType(typeDeclaration.baseclass));

				// need to set the superclass and super interfaces here since we cannot distinguish them at
				// the type references level.
				if (   typeDeclaration.superclass != null
					&& !typeDeclaration.superclass.isGenerated())
					roleTypeDecl.setSuperclassType(convertType(typeDeclaration.superclass));

				break;
			}

			roleTypeDecl.setInterface(typeDeclaration.isInterface());
			roleTypeDecl.setTeam(typeDeclaration.isTeam());
			roleTypeDecl.setRole(typeDeclaration.isSourceRole());

			SimpleName typeName = this.ast.newSimpleName(
					getRealName(typeDeclaration.name)
					);

			typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
			roleTypeDecl.setName(typeName);
			roleTypeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);

			// fetch superInterfaces from the interface part of the role:
			org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = null;
			RoleModel roleModel = typeDeclaration.getRoleModel();
			if (   !typeDeclaration.isInterface()												  // class?
				&& roleModel != null && roleModel.hasState(ITranslationStates.STATE_ROLES_SPLIT)) // has been split?
			{
				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration ifcDecl = roleModel.getInterfaceAst();
				if (ifcDecl != null)
					superInterfaces = ifcDecl.superInterfaces;
			} else {
				superInterfaces = typeDeclaration.superInterfaces;
			}
			if (superInterfaces != null)
				for (int index = 0, length = superInterfaces.length; index < length; index++)
					if (!superInterfaces[index].isGenerated())
						roleTypeDecl.superInterfaceTypes().add(convertType(superInterfaces[index]));

			org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration guard = typeDeclaration.predicate;
			if (guard != null)
				roleTypeDecl.setGuardPredicate(convertGuardPredicate(guard));

			buildBodyDeclarations(typeDeclaration, roleTypeDecl, typeDeclaration.isRegularInterface());

			SimpleName teamClassName = null;
			if (typeDeclaration.enclosingType!=null)
			{
			   org.eclipse.jdt.internal.compiler.ast.TypeDeclaration teamDecl
			   			= typeDeclaration.enclosingType;
			   teamClassName = this.ast.newSimpleName(new String(teamDecl.name));
			   teamClassName.setSourceRange(teamDecl.sourceStart, teamDecl.sourceEnd - teamDecl.sourceStart + 1);
			   if(this.ast.apiLevel >= AST.JLS3_INTERNAL){
				   SimpleType teamType = this.ast.newSimpleType(teamClassName);
				   teamType.setSourceRange(teamClassName.getStartPosition(), teamClassName.getLength());
				   roleTypeDecl.setTeamClassType(teamType);
			   }
			   else
				   roleTypeDecl.internalSetTeamClass(teamClassName);
			}

			if (this.resolveBindings)
	        {
				recordNodes(roleTypeDecl, typeDeclaration);
				recordNodes(typeName, typeDeclaration);
			    recordNodes(teamClassName, typeDeclaration.enclosingType);
    			roleTypeDecl.resolveBinding();
			}
			return roleTypeDecl;
		} finally {
			if (oldSource != null) {
				this.scanner.setSource(oldSource);
				this.compilationUnitSource = oldSource;
				this.compilationUnitSourceLength = oldSource.length;
			}
		}
	}

	private String getRealName(char[] name)
	{
		if (name == null || name.length == 0)
		{
			return ""; // //$NON-NLS-1$
		}
		String realName;
		String[] nameTokens = new String (name).split(IOTConstants.OT_DELIM);
		realName = nameTokens[nameTokens.length-1];
		return realName;
	}

	private PrecedenceDeclaration convertPrecedence(org.eclipse.objectteams.otdt.internal.core.compiler.ast.PrecedenceDeclaration aPrecedence)
	{
		PrecedenceDeclaration newPrecedence = this.ast.newPrecedenceDeclaration();
		newPrecedence.setSourceRange(aPrecedence.declarationSourceStart, aPrecedence.sourceEnd - aPrecedence.declarationSourceStart + 1);
		for (org.eclipse.jdt.internal.compiler.ast.NameReference nameRef: aPrecedence.bindingNames) {
			newPrecedence.elements().add(convert(nameRef));
		}
		if (aPrecedence.isAfter)
			newPrecedence.setAfter(true);
		return newPrecedence;
	}

	private GuardPredicateDeclaration convertGuardPredicate(org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration guard) {
		GuardPredicateDeclaration newGuard = this.ast.newGuardPredicateDeclaration();
		newGuard.setSourceRange(guard.declarationSourceStart, guard.declarationSourceEnd - guard.declarationSourceStart + 1);
		if (guard.hasParsedStatements) {
			org.eclipse.jdt.internal.compiler.ast.ReturnStatement returnStat = guard.returnStatement;
			newGuard.setExpression(convert(returnStat.expression));
		}
		newGuard.setBase(guard.isBasePredicate);
		return newGuard;
	}

//ike+SH}

//{ObjectTeams: convert method for OT-specific internal types
	// LiftingTypeReference
	public LiftingType convertType(LiftingTypeReference typeReference)
	{
	    Name name = convert(typeReference);
	    LiftingType result = this.ast.newLiftingType(name);
	    result.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);

	    // convert base type
	    org.eclipse.jdt.internal.compiler.ast.TypeReference baseTypeReference = typeReference.baseReference;
		if (baseTypeReference != null)
		{
			Type baseType = convertType(baseTypeReference);
			result.setBaseType(baseType);
		}

		// convert role type
	    org.eclipse.jdt.internal.compiler.ast.TypeReference roleTypeReference = typeReference.roleReference;
		if (roleTypeReference != null)
		{
			Type roleType = convertType(roleTypeReference);
			result.setRoleType(roleType);
		}

	    if (this.resolveBindings)
		{
			this.recordNodes(result, typeReference);
		}
	    return result;
	}
	// Type Anchor
	public TypeAnchor convertType(TypeAnchorReference anchorRef) {
		TypeAnchor result = new TypeAnchor(this.ast);
		if (anchorRef.anchor instanceof NameReference) {
			result.setPath(convert((NameReference)anchorRef.anchor));
		} else if (anchorRef.anchor instanceof FieldReference) {
			throw new InternalCompilerError("Unexpected type "+anchorRef.anchor.getClass()+" for anchor reference "+anchorRef.anchor); //$NON-NLS-1$ //$NON-NLS-2$
		}
		int start = anchorRef.sourceStart;
		int end = anchorRef.sourceEnd;
		result.setSourceRange(start, end-start+1);
		return result;
	}
	
	/**
	 * annotations for method mappings:
	 * @param mappingDecl
	 * @param mappingDeclaration
	 */
	protected void setModifiers(AbstractMethodMappingDeclaration mappingDecl,
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration mappingDeclaration) {
		switch(this.ast.apiLevel) {
			case AST.JLS2_INTERNAL :
				if (mappingDeclaration.annotations != null) {
					mappingDecl.setFlags(mappingDecl.getFlags() | ASTNode.MALFORMED);
				}
				break;
			default :
				this.scanner.resetTo(mappingDeclaration.declarationSourceStart, mappingDeclaration.sourceStart);
				this.setModifiers(mappingDecl, mappingDeclaration.annotations, mappingDeclaration.sourceStart);
		}
	}

//convert methods for OT-specific internal types
//  BaseAllocationExpression, BaseCallMessageSend,
//  QualifiedFakedBaseReference

public BaseConstructorInvocation convert(
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseAllocationExpression expr) {
		BaseConstructorInvocation result = this.ast
				.newBaseConstructorInvocation();
		result.setSourceRange(expr.sourceStart, expr.sourceEnd
				- expr.sourceStart + 1);
		if (this.resolveBindings) {
			recordNodes(result, expr);
		}

		// [SH]: expression is set during TransformStatements, will be null if
		// errors encountered
		if (expr.expression != null) {
			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments;
			org.eclipse.jdt.internal.compiler.ast.Expression call = expr.expression;
			if (call instanceof org.eclipse.jdt.internal.compiler.ast.CastExpression)
				call = ((org.eclipse.jdt.internal.compiler.ast.CastExpression)call).expression;
			if (call instanceof AllocationExpression)
				arguments = ((AllocationExpression) call).arguments;
			else if (call instanceof MessageSend)
				arguments = ((MessageSend) call).arguments; // creator call
			else
				throw new InternalCompilerError("Unexpected expression type in BaseAllocationExpression"); //$NON-NLS-1$
			if (arguments != null) {
				int argumentsLength = arguments.length;
				for (int idx = 0; idx < argumentsLength; idx++) {
					Expression argExpr = convert(arguments[idx]);
					if (this.resolveBindings) {
						recordNodes(argExpr, arguments[idx]);
					}
					result.getArguments().add(argExpr);
				}
			}
		}

		return result;
	}

	public org.eclipse.jdt.core.dom.BaseCallMessageSend convert(
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend expression) {
		org.eclipse.jdt.core.dom.BaseCallMessageSend result = this.ast
				.newBaseCallMessageSend();
		result.setSourceRange(expression.sourceStart, expression.sourceEnd
				- expression.sourceStart + 1);

		MessageSend msgSend = expression.getMessageSend();
		char[] srcSelector = expression.sourceSelector;
		SimpleName name = this.ast.newSimpleName(new String(srcSelector));
		int start = (int) (msgSend.nameSourcePosition >>> 32);
		int end = (int) (msgSend.nameSourcePosition & 0xFFFFFFFF);
		name.setSourceRange(start, end - start + 1);

		if (this.resolveBindings) {
			recordNodes(name, expression);
			recordNodes(result, expression);
		}
		result.setName(name);

		org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = msgSend.arguments;
		if (arguments != null) {
			int argumentsLength = arguments.length;
			// FIXME(SH): static?
			int startIdx = 0;
			if ((msgSend.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.HasBeenTransformed) != 0)
				startIdx = MethodSignatureEnhancer.getEnhancingArgLen(this.weavingScheme)+1; // +1: skip 'isSuperAccess'
			for (int idx = startIdx; idx < argumentsLength; idx++) {
				Expression argExpr = convert(arguments[idx]);
				if (this.resolveBindings) {
					recordNodes(argExpr, arguments[idx]);
				}
				result.getArguments().add(argExpr);
			}
		}
		return result;
	}

// convert method for OT-specific internal type WithinStatement
    /**
     * Converts internal compiler type WithinStatement to dom type WithinStatement.
     * The first two _OT$ Elements (for team activation) are left out. The body is
     * recovered from the try block, e.g.
     * <code>
     * within(new SimpleTeam())
     * {
     *     foo();
     * }
     * </code>
     * will be in the internal compiler ast
     * <code>
     * org.objectteams.Team _OT$team$206 = new SimpleTeam();
     * ...
     * int _OT$level206 = _OT$team$206.activate(3);
     * try
     * {
     *     foo();
     * }
     * finally
     * {
     *     _OT$team$206.deactivate(_OT$level206);
     * }
     * </code>
     */
	public org.eclipse.jdt.core.dom.WithinStatement convert(WithinStatement statement)
	{
        org.eclipse.jdt.core.dom.WithinStatement result = this.ast.newWithinStatement();

        if (statement.sourceEnd > 0)
		{
			result.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
		}

        result.setTeamExpression(convert(statement.getTeamExpression()));

        org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
		if (statements != null)
		{
		    // for within statements use statements inside try block
			for (int idx = 0; idx < statements.length; idx++) {
				if (statements[idx] instanceof org.eclipse.jdt.internal.compiler.ast.TryStatement)
				{
					org.eclipse.jdt.internal.compiler.ast.TryStatement tryStatement =
						(org.eclipse.jdt.internal.compiler.ast.TryStatement)statements[idx];
					Block tryBlock = convert(tryStatement.tryBlock);
					tryBlock.setParent(null, null);
					result.setBody(tryBlock);
					break;
				}
            }
        }

        return result;
	}

// convert method for OT-specific internal type AbstractMethodMappingDeclaration
	public AbstractMethodMappingDeclaration convert(
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration abstractMethodMapping)
	{
	    if (abstractMethodMapping instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration)
	    {
	        return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration)abstractMethodMapping);
	    }
	    if (abstractMethodMapping instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration)
	    {
	        return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration)abstractMethodMapping);
	    }
		throw new IllegalArgumentException("There does not exist a method binding of type" + abstractMethodMapping.getClass()); //$NON-NLS-1$
	}

// convert methods for OT-specific internal types CallinMappingDeclaration
//  and CalloutMappingDeclaration
	public CallinMappingDeclaration convert(
			org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration callinMapping) {
		org.eclipse.jdt.core.dom.CallinMappingDeclaration result = this.ast
				.newCallinMappingDeclaration();

		// annotations
		setModifiers(result, callinMapping);

		// name
		if (callinMapping.hasName()) {
			SimpleName labelName = this.ast.newSimpleName(String.valueOf(callinMapping.name));
			labelName.setSourceRange(callinMapping.sourceStart, callinMapping.sourceEnd - callinMapping.sourceStart + 1);
			result.setName(labelName);
		}

		// left side, role method
		if (callinMapping.roleMethodSpec != null)
			result.setRoleMappingElement(convert(callinMapping.roleMethodSpec));

		// right side, base methods
		org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec[] baseMethodSpecs = callinMapping.baseMethodSpecs;
		int len = (baseMethodSpecs != null) ? baseMethodSpecs.length : 0;
		for (int idx = 0; idx < len; idx++) {
			if (baseMethodSpecs[idx].selector.length > 0)
				result.getBaseMappingElements().add(convert(baseMethodSpecs[idx]));
		}
		org.eclipse.objectteams.otdt.internal.core.compiler.ast.GuardPredicateDeclaration guard = callinMapping.predicate;
		if (guard != null)
			result.setGuardPredicate(convertGuardPredicate(guard));


		// with { ... }, parameter mappings
		if (callinMapping.mappings != null) {
			int mappingsLength = callinMapping.mappings.length;
			for (int idx = 0; idx < mappingsLength; idx++) {
				result.getParameterMappings().add(
						convert(callinMapping.mappings[idx]));
			}
		}

		// callin modifier: after, before, replace
		ModifierKeyword keyword = null;
		int modifierStart = callinMapping.modifierStart;
		int modifierLength = callinMapping.modifierEnd- modifierStart + 1;
		switch (callinMapping.callinModifier) {
		case TerminalTokens.TokenNamebefore:
			keyword = ModifierKeyword.BEFORE_KEYWORD;
			break;
		case TerminalTokens.TokenNameafter:
			keyword = ModifierKeyword.AFTER_KEYWORD;
			break;
		case TerminalTokens.TokenNamereplace:
			keyword = ModifierKeyword.REPLACE_KEYWORD;
			break;
		default:
			keyword = ModifierKeyword.MISSING_KEYWORD;
			modifierStart= retrieveBINDINPosition(callinMapping.sourceEnd, callinMapping.declarationSourceEnd);
			if (modifierStart == -1)
				modifierStart= callinMapping.baseDeclarationSourceStart()-1;
			else
				modifierStart += 2; // skip "<-"
			modifierLength= 0;
			break;
		}
		MethodBindingOperator bindingOperator = this.ast.newMethodBindingOperator(keyword, MethodBindingOperator.KIND_CALLIN);
		bindingOperator.setSourceRange(callinMapping.bindingTokenStart, callinMapping.modifierEnd-callinMapping.bindingTokenStart+1);
		bindingOperator.bindingModifier().setSourceRange(modifierStart, modifierLength);
		result.setBindingOperator(bindingOperator);

		result.setSourceRange(callinMapping.declarationSourceStart,
				callinMapping.declarationSourceEnd - callinMapping.declarationSourceStart + 1);

		convert(callinMapping.javadoc, result);

		if (this.resolveBindings) {
			this.recordNodes(result, callinMapping);
		}
		return result;
	}

	public org.eclipse.jdt.core.dom.CalloutMappingDeclaration convert(
			CalloutMappingDeclaration calloutMapping)
	{
		org.eclipse.jdt.core.dom.CalloutMappingDeclaration result = this.ast
				.newCalloutMappingDeclaration();

		// annotations
		setModifiers(result, calloutMapping);

		org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec roleMethodSpec = calloutMapping.roleMethodSpec;
		if (roleMethodSpec != null) {
			org.eclipse.jdt.core.dom.MethodMappingElement leftMethodSpec = convert(roleMethodSpec);
			result.setRoleMappingElement(leftMethodSpec);
		}
		// possible types for calloutMapping.baseMethodSpec: MethodSpec,
		// FieldAccesSpec
		if (calloutMapping.baseMethodSpec != null && calloutMapping.baseMethodSpec.selector.length > 0) {
			result.setBaseMappingElement(convert(calloutMapping.baseMethodSpec));
			if (calloutMapping.isCalloutToField()) {
				FieldAccessSpec fieldAccessSpec = (FieldAccessSpec)calloutMapping.baseMethodSpec;
				result.bindingOperator().setBindingModifier(fieldAccessSpec.isSetter() ? Modifier.OT_SET_CALLOUT : Modifier.OT_GET_CALLOUT);
			}
		} else {
			result.setBaseMappingElement(null); // mark as initialized
		}

		// convert parameter mappings
		if (calloutMapping.mappings != null) {
			for (int idx = 0; idx < calloutMapping.mappings.length; idx++) {
				result.getParameterMappings().add(idx,
						convert(calloutMapping.mappings[idx]));
			}
		}

		result.setSourceRange(calloutMapping.declarationSourceStart,
				calloutMapping.declarationSourceEnd - calloutMapping.declarationSourceStart + 1);

		convert(calloutMapping.javadoc, result);

		if (this.resolveBindings) {
			this.recordNodes(result, calloutMapping);
			result.resolveBinding();
		}
		result.setSignatureFlag(calloutMapping.hasSignature);

		// binding operator (kind and modifier)
        ModifierKeyword keyword = null;
        int modifierStart = calloutMapping.modifierStart;
        int modifierLength = calloutMapping.modifierEnd - modifierStart + 1;
        if (calloutMapping.baseMethodSpec instanceof FieldAccessSpec) {
        	if (((FieldAccessSpec)calloutMapping.baseMethodSpec).isSetter())
        		keyword = ModifierKeyword.SET_KEYWORD;
        	else
        		keyword = ModifierKeyword.GET_KEYWORD;
        }
        int calloutKind = calloutMapping.isCalloutOverride() ? MethodBindingOperator.KIND_CALLOUT_OVERRIDE : MethodBindingOperator.KIND_CALLOUT;

		MethodBindingOperator bindingOperator = this.ast.newMethodBindingOperator(keyword, calloutKind);
		bindingOperator.setSourceRange(calloutMapping.bindingTokenStart, calloutMapping.modifierEnd-calloutMapping.bindingTokenStart+1);
		if (keyword != null)
			bindingOperator.bindingModifier().setSourceRange(modifierStart, modifierLength);
		result.setBindingOperator(bindingOperator);

		return result;
	}

// convert method for OT-specific internal type ParameterMapping
	@SuppressWarnings("nls")
	public org.eclipse.jdt.core.dom.ParameterMapping convert(
			ParameterMapping parameterMapping) {
		org.eclipse.jdt.core.dom.ParameterMapping result = this.ast
				.newParameterMapping();

		result
				.setSourceRange(
						parameterMapping.sourceStart,
						(parameterMapping.sourceEnd - parameterMapping.sourceStart) + 1);

		result.setExpression(convert(parameterMapping.expression));

		if (parameterMapping.direction == TerminalTokens.TokenNameBINDIN)
			result.setDirection("<-");

		if (parameterMapping.direction == TerminalTokens.TokenNameBINDOUT)
			result.setDirection("->");

		result.setIdentifier(convert(parameterMapping.ident));

		if (new String(parameterMapping.ident.token).equals("result"))
			result.setResultFlag(true);
		else
			result.setResultFlag(false);

		return result;
	}

// convert method for OT-specific internal type
	// ParameterMapping
	public org.eclipse.jdt.core.dom.FieldAccessSpec convert(
			FieldAccessSpec fieldAccessSpec) {
		org.eclipse.jdt.core.dom.FieldAccessSpec result = this.ast
				.newFieldAccessSpec();

		result.setSourceRange(fieldAccessSpec.declarationSourceStart,
				fieldAccessSpec.declarationSourceEnd - fieldAccessSpec.declarationSourceStart + 1);

		result.setSignatureFlag(fieldAccessSpec.hasSignature);

		String[] tokens = (new String(fieldAccessSpec.selector)).split("\\" //$NON-NLS-1$
				+ IOTConstants.JAVA_SEPARATOR);
		String realName = tokens[tokens.length - 1];
		SimpleName fieldName = this.ast.newSimpleName(realName);
		int start = fieldAccessSpec.sourceStart;
		int[] positions = retrieveEndOfElementTypeNamePosition(start,
				fieldAccessSpec.sourceEnd);
		if (positions[0] != -1)
			start = positions[0];
		int end = positions[1];

		fieldName.setSourceRange(start, end - start + 1);
		result.setName(fieldName);

		org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = fieldAccessSpec.declaredType();
		if (typeReference != null) {
			Type fieldType = convertType(typeReference);
			result.setFieldType(fieldType);
		}

		if (this.resolveBindings) {
			recordNodes(result, fieldAccessSpec);
			recordNodes(fieldName, fieldAccessSpec);
		}

		return result;
	}

// convert method for OT-specific internal type
	// MethodMappingElement
	public MethodMappingElement convert(MethodSpec methodSpec) {
		if (methodSpec instanceof org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec) {
			return convert((org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec) methodSpec);
		}

		org.eclipse.jdt.core.dom.MethodSpec result = this.ast.newMethodSpec();

		SimpleName methodName = this.ast.newSimpleName(new String(methodSpec.selector));
		int start = methodSpec.sourceStart;
		int[] positions = retrieveEndOfElementTypeNamePosition(start, methodSpec.sourceEnd);
		if (positions[0] != -1)
			start = positions[0];
		int end = positions[1];
		methodName.setSourceRange(start, end - start + 1);
		result.setName(methodName);

		if (methodSpec.hasSignature) {
			org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = methodSpec.returnType;
			if (typeReference != null) {
				Type returnType = convertType(typeReference);
				if(result.getAST().apiLevel() >= AST.JLS3_INTERNAL)
					result.setReturnType2(returnType);
				else
					result.setReturnType(returnType);
			}

			org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = methodSpec.arguments;
			if (parameters != null) {
				int parametersLength = parameters.length;
				for (int idx = 0; idx < parametersLength; idx++) {
					result.parameters().add(convert(parameters[idx]));
				}
			}

			org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = methodSpec.typeParameters;
			if (typeParameters != null)
				if (this.ast.apiLevel >= AST.JLS3_INTERNAL)
					for (int i = 0, max = typeParameters.length; i < max; i++)
						result.typeParameters().add(convert(typeParameters[i]));
		}

		result.setSourceRange(methodSpec.declarationSourceStart,
				methodSpec.declarationSourceEnd
						- methodSpec.declarationSourceStart + 1);

		result.setSignatureFlag(methodSpec.hasSignature);
		result.setCovariantReturnFlag(methodSpec.covariantReturn);

		if (this.resolveBindings) {
			recordNodes(result, methodSpec);
			recordNodes(methodName, methodSpec);
		}

		return result;
	}

// convert reused abstract methode declaration
	private boolean isReusedAbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration,
			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration)
	{
		return (methodDeclaration.isReusingSourceMethod && methodDeclaration.sourceStart > 0 );
	}

	public MethodDeclaration convertReusedAbstractMethodDeclaration(boolean isInterface,
			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration)
	{
		MethodDeclaration methodDecl = (MethodDeclaration) convert(isInterface, methodDeclaration);
		if(methodDecl.ast.apiLevel() == AST.JLS2_INTERNAL)
			methodDecl.internalSetModifiers(methodDecl.getModifiers() | Modifier.ABSTRACT);
		else
			methodDecl.modifiers().addAll(this.ast.newModifiers(methodDecl.getModifiers() | Modifier.ABSTRACT));
		return methodDecl;
	}
//SH+gbr+jsv+mkr}
}
