gt: 	if (this.localTypes == null) {
context: /*******************************************************************************
   * Copyright (c) 2000, 2013 IBM Corporation and others.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     IBM Corporation - initial API and implementation
   *     Jesper S Moller - Bug 392671
   *          NPE with a method with explicit this and a following incomplete parameter
   *******************************************************************************/
  package org.eclipse.jdt.internal.compiler.parser;
  
  import java.util.HashSet;
  import java.util.Set;
  
  import org.eclipse.jdt.core.compiler.*;
  import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.Annotation;
  import org.eclipse.jdt.internal.compiler.ast.Argument;
  import org.eclipse.jdt.internal.compiler.ast.ASTNode;
  import org.eclipse.jdt.internal.compiler.ast.Block;
  import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
  import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
  import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.Statement;
  import org.eclipse.jdt.internal.compiler.ast.SuperReference;
  import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
  import org.eclipse.jdt.internal.compiler.ast.TypeReference;
  import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
  import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  import org.eclipse.jdt.internal.compiler.util.Util;
  
  /**
   * Internal method structure for parsing recovery
   */
  
  @SuppressWarnings("rawtypes")
  public class RecoveredMethod extends RecoveredElement implements TerminalTokens {
  
  	public AbstractMethodDeclaration methodDeclaration;
  
  	public RecoveredAnnotation[] annotations;
  	public int annotationCount;
  
  	public int modifiers;
  	public int modifiersStart;
  
  	public RecoveredType[] localTypes;
  	public int localTypeCount;
  
  	public RecoveredBlock methodBody;
  	public boolean discardBody = true;
  
  	int pendingModifiers;
  	int pendingModifersSourceStart = -1;
  	RecoveredAnnotation[] pendingAnnotations;
  	int pendingAnnotationCount;
  
  public RecoveredMethod(AbstractMethodDeclaration methodDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
  	super(parent, bracketBalance, parser);
  	this.methodDeclaration = methodDeclaration;
  	this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
  	if(this.foundOpeningBrace) {
  		this.bracketBalance++;
  	}
  }
  /*
   * Record a nested block declaration
   */
  public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
  	/* default behavior is to delegate recording to parent if any,
  	do not consider elements passed the known end (if set)
  	it must be belonging to an enclosing element
  	*/
  	if (this.methodDeclaration.declarationSourceEnd > 0
  		&& nestedBlockDeclaration.sourceStart
  			> this.methodDeclaration.declarationSourceEnd){
  				resetPendingModifiers();
  				if (this.parent == null){
  					return this; // ignore
  				} else {
  					return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
  				}
  	}
  	/* consider that if the opening brace was not found, it is there */
  	if (!this.foundOpeningBrace){
  		this.foundOpeningBrace = true;
  		this.bracketBalance++;
  	}
  
  	this.methodBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
  	if (nestedBlockDeclaration.sourceEnd == 0) return this.methodBody;
  	return this;
  }
  /*
   * Record a field declaration
   */
  public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
  	resetPendingModifiers();
  
  	/* local variables inside method can only be final and non void */
  	char[][] fieldTypeName;
  	if ((fieldDeclaration.modifiers & ~ClassFileConstants.AccFinal) != 0 // local var can only be final
  		|| (fieldDeclaration.type == null) // initializer
  		|| ((fieldTypeName = fieldDeclaration.type.getTypeName()).length == 1 // non void
  			&& CharOperation.equals(fieldTypeName[0], TypeBinding.VOID.sourceName()))){
  		if (this.parent == null){
  			return this; // ignore
  		} else {
  			this.updateSourceEndIfNecessary(previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
  			return this.parent.add(fieldDeclaration, bracketBalanceValue);
  		}
  	}
  	/* default behavior is to delegate recording to parent if any,
  	do not consider elements passed the known end (if set)
  	it must be belonging to an enclosing element
  	*/
  	if (this.methodDeclaration.declarationSourceEnd > 0
  		&& fieldDeclaration.declarationSourceStart
  			> this.methodDeclaration.declarationSourceEnd){
  		if (this.parent == null){
  			return this; // ignore
  		} else {
  			return this.parent.add(fieldDeclaration, bracketBalanceValue);
  		}
  	}
  	/* consider that if the opening brace was not found, it is there */
  	if (!this.foundOpeningBrace){
  		this.foundOpeningBrace = true;
  		this.bracketBalance++;
  	}
  	// still inside method, treat as local variable
  	return this; // ignore
  }
  /*
   * Record a local declaration - regular method should have been created a block body
   */
  public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
  	resetPendingModifiers();
  
  	/* local variables inside method can only be final and non void */
  /*
  	char[][] localTypeName;
  	if ((localDeclaration.modifiers & ~AccFinal) != 0 // local var can only be final
  		|| (localDeclaration.type == null) // initializer
  		|| ((localTypeName = localDeclaration.type.getTypeName()).length == 1 // non void
  			&& CharOperation.equals(localTypeName[0], VoidBinding.sourceName()))){
  
  		if (this.parent == null){
  			return this; // ignore
  		} else {
  			this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
  			return this.parent.add(localDeclaration, bracketBalance);
  		}
  	}
  */
  	/* do not consider a type starting passed the type end (if set)
  		it must be belonging to an enclosing type */
  	if (this.methodDeclaration.declarationSourceEnd != 0
  		&& localDeclaration.declarationSourceStart > this.methodDeclaration.declarationSourceEnd){
  
  		if (this.parent == null) {
  			return this; // ignore
  		} else {
  			return this.parent.add(localDeclaration, bracketBalanceValue);
  		}
  	}
  	if (this.methodBody == null){
  		Block block = new Block(0);
  		block.sourceStart = this.methodDeclaration.bodyStart;
  		RecoveredElement currentBlock = this.add(block, 1);
  		if (this.bracketBalance > 0){
  			for (int i = 0; i < this.bracketBalance - 1; i++){
  				currentBlock = currentBlock.add(new Block(0), 1);
  			}
  			this.bracketBalance = 1;
  		}
  		return currentBlock.add(localDeclaration, bracketBalanceValue);
  	}
  	return this.methodBody.add(localDeclaration, bracketBalanceValue, true);
  }
  /*
   * Record a statement - regular method should have been created a block body
   */
  public RecoveredElement add(Statement statement, int bracketBalanceValue) {
  	resetPendingModifiers();
  
  	/* do not consider a type starting passed the type end (if set)
  		it must be belonging to an enclosing type */
  	if (this.methodDeclaration.declarationSourceEnd != 0
  		&& statement.sourceStart > this.methodDeclaration.declarationSourceEnd){
  
  		if (this.parent == null) {
  			return this; // ignore
  		} else {
  			return this.parent.add(statement, bracketBalanceValue);
  		}
  	}
  	if (this.methodBody == null){
  		Block block = new Block(0);
  		block.sourceStart = this.methodDeclaration.bodyStart;
  		RecoveredElement currentBlock = this.add(block, 1);
  		if (this.bracketBalance > 0){
  			for (int i = 0; i < this.bracketBalance - 1; i++){
  				currentBlock = currentBlock.add(new Block(0), 1);
  			}
  			this.bracketBalance = 1;
  		}
  		return currentBlock.add(statement, bracketBalanceValue);
  	}
  	return this.methodBody.add(statement, bracketBalanceValue, true);
  }
  public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
  
  	/* do not consider a type starting passed the type end (if set)
  		it must be belonging to an enclosing type */
  	if (this.methodDeclaration.declarationSourceEnd != 0
  		&& typeDeclaration.declarationSourceStart > this.methodDeclaration.declarationSourceEnd){
  
  		if (this.parent == null) {
  			return this; // ignore
  		}
  		return this.parent.add(typeDeclaration, bracketBalanceValue);
  	}
  	if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0 || parser().methodRecoveryActivated || parser().statementRecoveryActivated){
  		if (this.methodBody == null){
  			Block block = new Block(0);
  			block.sourceStart = this.methodDeclaration.bodyStart;
  			this.add(block, 1);
  		}
  		this.methodBody.attachPendingModifiers(
  				this.pendingAnnotations,
  				this.pendingAnnotationCount,
  				this.pendingModifiers,
  				this.pendingModifersSourceStart);
  		resetPendingModifiers();
  		return this.methodBody.add(typeDeclaration, bracketBalanceValue, true);
  	}
  	switch (TypeDeclaration.kind(typeDeclaration.modifiers)) {
  		case TypeDeclaration.INTERFACE_DECL :
  		case TypeDeclaration.ANNOTATION_TYPE_DECL :
  			resetPendingModifiers();
  			this.updateSourceEndIfNecessary(previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));
  			if (this.parent == null) {
  				return this; // ignore
  			}
  			// close the constructor
  			return this.parent.add(typeDeclaration, bracketBalanceValue);
  	}
  