// ASPECTJ
/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Stephan Herrmann - Contributions for
 *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
 *								bug 186342 - [compiler][null] Using annotations for null checking
 *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
 *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
 *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
 *								bug 383368 - [compiler][null] syntactic null analysis for field references
 *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
 *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
 *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
 *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
 *								Bug 455723 - Nonnull argument not correctly inferred in loop
 *								Bug 415790 - [compiler][resource]Incorrect potential resource leak warning in for loop with close in try/catch
 *								Bug 446691 - [1.8][null][compiler] NullPointerException in SingleNameReference.analyseCode
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.flow;

import java.util.ArrayList;

import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NullAnnotationMatching;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Reference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;

/**
 * Reflects the context of code analysis, keeping track of enclosing
 *	try statements, exception handlers, etc...
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class FlowContext implements TypeConstants {

	// preempt marks looping contexts
	public final static FlowContext NotContinuableContext = new FlowContext(null, null, true);
	public ASTNode associatedNode;
	public FlowContext parent;
	public FlowInfo initsOnFinally;
		// only used within try blocks; remembers upstream flow info mergedWith
		// any null related operation happening within the try block
	/** 
	 * Used to record whether effects in a try block affect the finally-block
	 * conditionally or unconditionally.
	 * -1 means: no effect,
	 * 0 means: unconditional effect,
	 * > 0 means levels of nested conditional structures.
	 */
	public int conditionalLevel = -1;

	public int tagBits;

	// array to store the provided and expected types from the potential error location (for display in error messages):
	public TypeBinding[][] providedExpectedTypes = null;

	// record field references known to be non-null
	//   this array will never shrink, only grow. reset happens by nulling expired entries
	//   this array grows in lock step with timesToLiveForNullCheckInfo, which controls expiration
	private Reference[] nullCheckedFieldReferences = null;
	private int[] timesToLiveForNullCheckInfo = null;

	public static final int DEFER_NULL_DIAGNOSTIC = 0x1;
	public static final int PREEMPT_NULL_DIAGNOSTIC = 0x2;
	// inside an assertFalse or a not-expression checks for equality / inequality have reversed meaning for syntactic analysis for fields:
	public static final int INSIDE_NEGATION = 0x4;
	/**
	 * used to hide null comparison related warnings inside assert statements 
	 */
	public static final int HIDE_NULL_COMPARISON_WARNING = 0x1000;
	public static final int HIDE_NULL_COMPARISON_WARNING_MASK = 0xF000;

public static final int CAN_ONLY_NULL_NON_NULL = 0x0000;
//check against null and non null, with definite values -- comparisons
public static final int CAN_ONLY_NULL = 0x0001;
//check against null, with definite values -- comparisons
public static final int CAN_ONLY_NON_NULL = 0x0002;
//check against non null, with definite values -- comparisons
public static final int MAY_NULL = 0x0003;
//check binding a value to a @NonNull variable 
public final static int ASSIGN_TO_NONNULL = 0x0080;
//check against an unboxing conversion
public static final int IN_UNBOXING = 0x0010;
//check against unclosed resource at early exit:
public static final int EXIT_RESOURCE = 0x0800;
// check against null, with potential values -- NPE guard
public static final int CHECK_MASK = 0x00FF;
public static final int IN_COMPARISON_NULL = 0x0100;
public static final int IN_COMPARISON_NON_NULL = 0x0200;
// check happened in a comparison
public static final int IN_ASSIGNMENT = 0x0300;
// check happened in an assignment
public static final int IN_INSTANCEOF = 0x0400;
// check happened in an instanceof expression
public static final int CONTEXT_MASK = ~CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK;

public FlowContext(FlowContext parent, ASTNode associatedNode, boolean inheritNullFieldChecks) {
	this.parent = parent;
	this.associatedNode = associatedNode;
	if (parent != null) {
		if ((parent.tagBits & (FlowContext.DEFER_NULL_DIAGNOSTIC | FlowContext.PREEMPT_NULL_DIAGNOSTIC)) != 0) {
			this.tagBits |= FlowContext.DEFER_NULL_DIAGNOSTIC;
		}
		this.initsOnFinally = parent.initsOnFinally;
		this.conditionalLevel = parent.conditionalLevel;
		if (inheritNullFieldChecks)
			copyNullCheckedFieldsFrom(parent); // re-use list if there is one
	}
}

public void copyNullCheckedFieldsFrom(FlowContext other) {
	Reference[] fieldReferences = other.nullCheckedFieldReferences;
	if (fieldReferences != null && fieldReferences.length > 0 && fieldReferences[0] != null) {
		this.nullCheckedFieldReferences = other.nullCheckedFieldReferences;
		this.timesToLiveForNullCheckInfo = other.timesToLiveForNullCheckInfo;
	}
}

/**
 * Record that a reference to a field has been seen in a non-null state.
 *
 * @param reference Can be a SingleNameReference, a FieldReference or a QualifiedNameReference resolving to a field
 * @param timeToLive control how many expire events are needed to expire this information
 */
public void recordNullCheckedFieldReference(Reference reference, int timeToLive) {
	if (this.nullCheckedFieldReferences == null) {
		// first entry:
		this.nullCheckedFieldReferences = new Reference[] { reference, null };
		this.timesToLiveForNullCheckInfo = new int[] { timeToLive, -1 };
	} else {
		int len = this.nullCheckedFieldReferences.length;
		// insert into first empty slot:
		for (int i=0; i<len; i++) {
			if (this.nullCheckedFieldReferences[i] == null) {
				this.nullCheckedFieldReferences[i] = reference;
				this.timesToLiveForNullCheckInfo[i] = timeToLive;
				return;
			}
		}
		// grow arrays:
		System.arraycopy(this.nullCheckedFieldReferences, 0, this.nullCheckedFieldReferences=new Reference[len+2], 0, len);
		System.arraycopy(this.timesToLiveForNullCheckInfo, 0, this.timesToLiveForNullCheckInfo=new int[len+2], 0, len);
		this.nullCheckedFieldReferences[len] = reference;
		this.timesToLiveForNullCheckInfo[len] = timeToLive;
	}
}

/** If a null checked field has been recorded recently, increase its time to live. */
public void extendTimeToLiveForNullCheckedField(int t) {
	if (this.timesToLiveForNullCheckInfo != null) {
		for (int i = 0; i < this.timesToLiveForNullCheckInfo.length; i++)
			if (this.timesToLiveForNullCheckInfo[i] > 0)
				this.timesToLiveForNullCheckInfo[i] += t;
}
}

/**
 * Forget any information about fields that were previously known to be non-null.
 * 
 * Will only cause any effect if CompilerOptions.enableSyntacticNullAnalysisForFields
 * (implicitly by guards before calls to {@link #recordNullCheckedFieldReference(Reference, int)}).
 */	 
public void expireNullCheckedFieldInfo() {
	if (this.nullCheckedFieldReferences != null) {
		for (int i = 0; i < this.nullCheckedFieldReferences.length; i++) {
			if (--this.timesToLiveForNullCheckInfo[i] == 0)
				this.nullCheckedFieldReferences[i] = null;
		}
	}
}

/** 
 * Is the given field reference equivalent to a reference that is freshly known to be non-null?
 * Can only return true if CompilerOptions.enableSyntacticNullAnalysisForFields
 * (implicitly by guards before calls to {@link #recordNullCheckedFieldReference(Reference, int)}).
 */
public boolean isNullcheckedFieldAccess(Reference reference) {
	if (this.nullCheckedFieldReferences == null)  // always null unless CompilerOptions.enableSyntacticNullAnalysisForFields
		return false;
	int len = this.nullCheckedFieldReferences.length;
	for (int i=0; i<len; i++) {
		Reference checked = this.nullCheckedFieldReferences[i];
		if (checked == null) {
			continue;
		}
		if (checked.isEquivalent(reference)) {
			return true;
		}
	}
	return false;
}

public BranchLabel breakLabel() {
	return null;
}

public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
	checkExceptionHandlers(raisedException, location, flowInfo, scope, false);
}
/**
 * @param isExceptionOnAutoClose This is for checking exception handlers for exceptions raised during the
 * auto close of resources inside a try with resources statement. (Relevant for
 * source levels 1.7 and above only)
 */
public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope, boolean isExceptionOnAutoClose) {
	// LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS
	// check that all the argument exception types are handled
	// JDK Compatible implementation - when an exception type is thrown,
	// all related catch blocks are marked as reachable... instead of those only
	// until the point where it is safely handled (Smarter - see comment at the end)
	FlowContext traversedContext = this;
	ArrayList abruptlyExitedLoops = null;
	if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7 && location instanceof ThrowStatement) {
		Expression throwExpression = ((ThrowStatement)location).exception;
		LocalVariableBinding throwArgBinding = throwExpression.localVariableBinding();
		if (throwExpression instanceof SingleNameReference // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350361 
				&& throwArgBinding instanceof CatchParameterBinding && throwArgBinding.isEffectivelyFinal()) {
			CatchParameterBinding parameter = (CatchParameterBinding) throwArgBinding;
			checkExceptionHandlers(parameter.getPreciseTypes(), location, flowInfo, scope);
			return;
		}
	}
	while (traversedContext != null) {
		SubRoutineStatement sub;
		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
			// traversing a non-returning subroutine means that all unhandled
			// exceptions will actually never get sent...
			return;
		}

		// filter exceptions that are locally caught from the innermost enclosing
		// try statement to the outermost ones.
		if (traversedContext instanceof ExceptionHandlingFlowContext) {
			ExceptionHandlingFlowContext exceptionContext =
				(ExceptionHandlingFlowContext) traversedContext;
			ReferenceBinding[] caughtExceptions;
			if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
				boolean definitelyCaught = false;
				for (int caughtIndex = 0, caughtCount = caughtExceptions.length;
					caughtIndex < caughtCount;
					caughtIndex++) {
					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
					FlowInfo exceptionFlow = flowInfo;
				    int state = caughtException == null
				    	? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
				        : Scope.compareTypes(raisedException, caughtException);
				    if (abruptlyExitedLoops != null && caughtException != null && state != Scope.NOT_RELATED) {
				    	for (int i = 0, abruptlyExitedLoopsCount = abruptlyExitedLoops.size(); i < abruptlyExitedLoopsCount; i++) {
							LoopingFlowContext loop = (LoopingFlowContext) abruptlyExitedLoops.get(i);
							loop.recordCatchContextOfEscapingException(exceptionContext, caughtException, flowInfo);
						}
				    	exceptionFlow = FlowInfo.DEAD_END; // don't use flow info on first round, flow info will be evaluated during loopback simulation
					}
					switch (state) {
						case Scope.EQUAL_OR_MORE_SPECIFIC :
							exceptionContext.recordHandlingException(
								caughtException,
								exceptionFlow.unconditionalInits(),
								raisedException,
								raisedException, // precise exception that will be caught
								location,
								definitelyCaught);
							// was it already definitely caught ?
							definitelyCaught = true;
							break;
						case Scope.MORE_GENERIC :
							exceptionContext.recordHandlingException(
								caughtException,
								exceptionFlow.unconditionalInits(),
								raisedException,
								caughtException,
								location,
								false);
							// was not caught already per construction
					}
				}
				if (definitelyCaught)
					return;
			}
			// method treatment for unchecked exceptions
			if (exceptionContext.isMethodContext) {
				if (raisedException.isUncheckedException(false))
					return;
				boolean shouldMergeUnhandledExceptions = exceptionContext instanceof ExceptionInferenceFlowContext;

				// anonymous constructors are allowed to throw any exceptions (their thrown exceptions
				// clause will be fixed up later as per JLS 8.6).
				if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){
					AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode;
					if (method.isConstructor() && method.binding.declaringClass.isAnonymousType())
						shouldMergeUnhandledExceptions = true;
					}
				if (shouldMergeUnhandledExceptions) {
					exceptionContext.mergeUnhandledException(raisedException);
					return; // no need to complain, will fix up constructor/lambda exceptions
				}
				break; // not handled anywhere, thus jump to error handling
			}
		} else if (traversedContext instanceof LoopingFlowContext) {
			if (abruptlyExitedLoops == null) {
				abruptlyExitedLoops = new ArrayList(5);
			}
			abruptlyExitedLoops.add(traversedContext);
		}

		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());

		if (!isExceptionOnAutoClose) {
			if (traversedContext instanceof InsideSubRoutineFlowContext) {
				ASTNode node = traversedContext.associatedNode;
				if (node instanceof TryStatement) {
					TryStatement tryStatement = (TryStatement) node;
					flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
				}
			}
		}
		traversedContext = traversedContext.getLocalParent();
	}
	// if reaches this point, then there are some remaining unhandled exception types.
	if (isExceptionOnAutoClose) {
		scope.problemReporter().unhandledExceptionFromAutoClose(raisedException, location);
	} else {
		// New AspectJ Extension - see pr151772
		// old code:
		// scope.problemReporter().unhandledException(raisedException, location); 
		// new code:
		ProblemReporter problemReporter = scope.referenceCompilationUnit().problemReporter;
		problemReporter.referenceContext = scope.referenceContext();
		problemReporter.unhandledException(raisedException, location);
		// AspectJ Extension End
	}
}

public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
	// check that all the argument exception types are handled
	// JDK Compatible implementation - when an exception type is thrown,
	// all related catch blocks are marked as reachable... instead of those only
	// until the point where it is safely handled (Smarter - see comment at the end)
	int remainingCount; // counting the number of remaining unhandled exceptions
	int raisedCount; // total number of exceptions raised
	if ((raisedExceptions == null)
		|| ((raisedCount = raisedExceptions.length) == 0))
		return;
	remainingCount = raisedCount;

	// duplicate the array of raised exceptions since it will be updated
	// (null replaces any handled exception)
	System.arraycopy(
		raisedExceptions,
		0,
		(raisedExceptions = new TypeBinding[raisedCount]),
		0,
		raisedCount);
	FlowContext traversedContext = this;

	ArrayList abruptlyExitedLoops = null;
	while (traversedContext != null) {
		SubRoutineStatement sub;
		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
			// traversing a non-returning subroutine means that all unhandled
			// exceptions will actually never get sent...
			return;
		}
		// filter exceptions that are locally caught from the innermost enclosing
		// try statement to the outermost ones.
		if (traversedContext instanceof ExceptionHandlingFlowContext) {
			ExceptionHandlingFlowContext exceptionContext =
				(ExceptionHandlingFlowContext) traversedContext;
			ReferenceBinding[] caughtExceptions;
			if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
				int caughtCount = caughtExceptions.length;
				boolean[] locallyCaught = new boolean[raisedCount]; // at most

				for (int caughtIndex = 0; caughtIndex < caughtCount; caughtIndex++) {
					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
					for (int raisedIndex = 0; raisedIndex < raisedCount; raisedIndex++) {
						TypeBinding raisedException;
						if ((raisedException = raisedExceptions[raisedIndex]) != null) {
							FlowInfo exceptionFlow = flowInfo;
						    int state = caughtException == null
						    	? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
						        : Scope.compareTypes(raisedException, caughtException);
						    if (abruptlyExitedLoops != null && caughtException != null && state != Scope.NOT_RELATED) {
						    	for (int i = 0, abruptlyExitedLoopsCount = abruptlyExitedLoops.size(); i < abruptlyExitedLoopsCount; i++) {
									LoopingFlowContext loop = (LoopingFlowContext) abruptlyExitedLoops.get(i);
									loop.recordCatchContextOfEscapingException(exceptionContext, caughtException, flowInfo);
								}
						    	exceptionFlow = FlowInfo.DEAD_END; // don't use flow info on first round, flow info will be evaluated during loopback simulation
							}
							switch (state) {
								case Scope.EQUAL_OR_MORE_SPECIFIC :
									exceptionContext.recordHandlingException(
										caughtException,
										exceptionFlow.unconditionalInits(),
										raisedException,
										raisedException, // precise exception that will be caught
										location,
										locallyCaught[raisedIndex]);
									// was already definitely caught ?
									if (!locallyCaught[raisedIndex]) {
										locallyCaught[raisedIndex] = true;
										// remember that this exception has been definitely caught
										remainingCount--;
									}
									break;
								case Scope.MORE_GENERIC :
									exceptionContext.recordHandlingException(
										caughtException,
										exceptionFlow.unconditionalInits(),
										raisedException,
										caughtException, 
										location,
										false);
									// was not caught already per construction
							}
						}
					}
				}
				// remove locally caught exceptions from the remaining ones
				for (int i = 0; i < raisedCount; i++) {
					if (locallyCaught[i]) {
						raisedExceptions[i] = null; // removed from the remaining ones.
					}
				}
			}
			// method treatment for unchecked exceptions
			if (exceptionContext.isMethodContext) {
				for (int i = 0; i < raisedCount; i++) {
					TypeBinding raisedException;
					if ((raisedException = raisedExceptions[i]) != null) {
						if (raisedException.isUncheckedException(false)) {
							remainingCount--;
							raisedExceptions[i] = null;
						}
					}
				}
				boolean shouldMergeUnhandledException = exceptionContext instanceof ExceptionInferenceFlowContext;
				// anonymous constructors are allowed to throw any exceptions (their thrown exceptions
				// clause will be fixed up later as per JLS 8.6).
				if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){
					AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode;
					if (method.isConstructor() && method.binding.declaringClass.isAnonymousType())
						shouldMergeUnhandledException = true;
				}
				if (shouldMergeUnhandledException) {
						for (int i = 0; i < raisedCount; i++) {
							TypeBinding raisedException;
							if ((raisedException = raisedExceptions[i]) != null) {
								exceptionContext.mergeUnhandledException(raisedException);
							}
						}
					return; // no need to complain, will fix up constructor/lambda exceptions
				}
				break; // not handled anywhere, thus jump to error handling
			}
        } else if (traversedContext instanceof LoopingFlowContext) {
			if (abruptlyExitedLoops == null) {
				abruptlyExitedLoops = new ArrayList(5);
			}
			abruptlyExitedLoops.add(traversedContext);
		}
		if (remainingCount == 0)
			return;

		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());

		if (traversedContext instanceof InsideSubRoutineFlowContext) {
			ASTNode node = traversedContext.associatedNode;
			if (node instanceof TryStatement) {
				TryStatement tryStatement = (TryStatement) node;
				flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
			}
		}
		traversedContext = traversedContext.getLocalParent();
	}
	// if reaches this point, then there are some remaining unhandled exception types.
	nextReport: for (int i = 0; i < raisedCount; i++) {
		TypeBinding exception;
		if ((exception = raisedExceptions[i]) != null) {
			// only one complaint if same exception declared to be thrown more than once
			for (int j = 0; j < i; j++) {
				if (TypeBinding.equalsEquals(raisedExceptions[j], exception)) continue nextReport; // already reported
			}
			// AspectJ Extension Begin
			// was scope.problemReporter().unhandledException(exception, location); see pr151772
			ProblemReporter problemReporter = scope.referenceCompilationUnit().problemReporter;
			problemReporter.referenceContext = scope.referenceContext();
			problemReporter.unhandledException(exception, location);
			// AspectJ Extension End
		}
	}
}

public BranchLabel continueLabel() {
	return null;
}

public FlowInfo getInitsForFinalBlankInitializationCheck(TypeBinding declaringType, FlowInfo flowInfo) {
	FlowContext current = this;
	FlowInfo inits = flowInfo;
	do {
		if (current instanceof InitializationFlowContext) {
			InitializationFlowContext initializationContext = (InitializationFlowContext) current;
			if (TypeBinding.equalsEquals(((TypeDeclaration)initializationContext.associatedNode).binding, declaringType)) {
				return inits;
			}
			inits = initializationContext.initsBeforeContext;
			current = initializationContext.initializationParent;
		} else if (current instanceof ExceptionHandlingFlowContext) {
			if(current instanceof FieldInitsFakingFlowContext) {
				return FlowInfo.DEAD_END; // isDefinitelyAssigned will return true for all fields
			}
			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) current;
			current = exceptionContext.initializationParent == null ? exceptionContext.parent : exceptionContext.initializationParent;
		} else {
			current = current.getLocalParent();
		}
	} while (current != null);
	// not found
	throw new IllegalStateException(declaringType.debugName());
}

/*
 * lookup through break labels
 */
public FlowContext getTargetContextForBreakLabel(char[] labelName) {
	FlowContext current = this, lastNonReturningSubRoutine = null;
	while (current != null) {
		if (current.isNonReturningContext()) {
			lastNonReturningSubRoutine = current;
		}
		char[] currentLabelName;
		if (((currentLabelName = current.labelName()) != null)
			&& CharOperation.equals(currentLabelName, labelName)) {
			((LabeledStatement)current.associatedNode).bits |= ASTNode.LabelUsed;
			if (lastNonReturningSubRoutine == null)
				return current;
			return lastNonReturningSubRoutine;
		}
		current = current.getLocalParent();
	}
	// not found
	return null;
}

/*
 * lookup through continue labels
 */
public FlowContext getTargetContextForContinueLabel(char[] labelName) {
	FlowContext current = this;
	FlowContext lastContinuable = null;
	FlowContext lastNonReturningSubRoutine = null;

	while (current != null) {
		if (current.isNonReturningContext()) {
			lastNonReturningSubRoutine = current;
		} else {
			if (current.isContinuable()) {
				lastContinuable = current;
			}
		}

		char[] currentLabelName;
		if ((currentLabelName = current.labelName()) != null && CharOperation.equals(currentLabelName, labelName)) {
			((LabeledStatement)current.associatedNode).bits |= ASTNode.LabelUsed;

			// matching label found
			if ((lastContinuable != null)
					&& (current.associatedNode.concreteStatement()	== lastContinuable.associatedNode)) {

				if (lastNonReturningSubRoutine == null) return lastContinuable;
				return lastNonReturningSubRoutine;
			}
			// label is found, but not a continuable location
			return FlowContext.NotContinuableContext;
		}
		current = current.getLocalParent();
	}
	// not found
	return null;
}

/*
 * lookup a default break through breakable locations
 */
public FlowContext getTargetContextForDefaultBreak() {
	FlowContext current = this, lastNonReturningSubRoutine = null;
	while (current != null) {
		if (current.isNonReturningContext()) {
			lastNonReturningSubRoutine = current;
		}
		if (current.isBreakable() && current.labelName() == null) {
			if (lastNonReturningSubRoutine == null) return current;
			return lastNonReturningSubRoutine;
		}
		current = current.getLocalParent();
	}
	// not found
	return null;
}

/*
 * lookup a default continue amongst continuable locations
 */
public FlowContext getTargetContextForDefaultContinue() {
	FlowContext current = this, lastNonReturningSubRoutine = null;
	while (current != null) {
		if (current.isNonReturningContext()) {
			lastNonReturningSubRoutine = current;
		}
		if (current.isContinuable()) {
			if (lastNonReturningSubRoutine == null)
				return current;
			return lastNonReturningSubRoutine;
		}
		current = current.getLocalParent();
	}
	// not found
	return null;
}

/** 
 * Answer flow context that corresponds to initialization. Suitably override in subtypes.
 */
public FlowContext getInitializationContext() {
	return null;
}

/** 
 * Answer the parent flow context but be careful not to cross the boundary of a nested type,
 * or null if no such parent exists. 
 */
public FlowContext getLocalParent() {
	if (this.associatedNode instanceof AbstractMethodDeclaration || this.associatedNode instanceof TypeDeclaration || this.associatedNode instanceof LambdaExpression)
		return null;
	return this.parent;
}

public String individualToString() {
	return "Flow context"; //$NON-NLS-1$
}

public FlowInfo initsOnBreak() {
	return FlowInfo.DEAD_END;
}

public UnconditionalFlowInfo initsOnReturn() {
	return FlowInfo.DEAD_END;
}

public boolean isBreakable() {
	return false;
}

public boolean isContinuable() {
	return false;
}

public boolean isNonReturningContext() {
	return false;
}

public boolean isSubRoutine() {
	return false;
}

public char[] labelName() {
	return null;
}

/**
 * Record a given null status of a given local variable as it will be seen in the finally block.
 * @param local the local variable being observed
 * @param nullStatus the null status of local at the current point in the flow
 */
public void markFinallyNullStatus(LocalVariableBinding local, int nullStatus) {
	if (this.initsOnFinally == null) return;
	if (this.conditionalLevel == -1) return;
	if (this.conditionalLevel == 0) {
		// node is unconditionally reached, take nullStatus as is:
		this.initsOnFinally.markNullStatus(local, nullStatus);
		return;
	}
	// node is reached only conditionally, weaken status to potentially_ and merge with previous
	UnconditionalFlowInfo newInfo = this.initsOnFinally.unconditionalCopy();
	newInfo.markNullStatus(local, nullStatus);
	this.initsOnFinally = this.initsOnFinally.mergedWith(newInfo);
}

/**
 * Merge the effect of a statement presumably contained in a try-block,
 * i.e., record how the collected info will affect the corresponding finally-block.
 * Precondition: caller has checked that initsOnFinally != null.
 * @param flowInfo info after executing a statement of the try-block.
 */
public void mergeFinallyNullInfo(FlowInfo flowInfo) {
	if (this.initsOnFinally == null) return;
	if (this.conditionalLevel == -1) return;
	if (this.conditionalLevel == 0) {
		// node is unconditionally reached, take null info as is:
		this.initsOnFinally.addNullInfoFrom(flowInfo);
		return;
	}
	// node is reached only conditionally: merge flowInfo with existing since both paths are possible
	this.initsOnFinally = this.initsOnFinally.mergedWith(flowInfo.unconditionalCopy());
}

/**
 * Record the fact that an abrupt exit has been observed, one of:
 * - potential exception (incl. unchecked exceptions)
 * - break
 * - continue
 * - return
 */
public void recordAbruptExit() {
	if (this.conditionalLevel > -1) {
		this.conditionalLevel++;
		// delegate up up-to the enclosing try-finally:
		if (!(this instanceof ExceptionHandlingFlowContext) && this.parent != null) {
			this.parent.recordAbruptExit();
		}
	}
}

public void recordBreakFrom(FlowInfo flowInfo) {
	// default implementation: do nothing
}

public void recordBreakTo(FlowContext targetContext) {
	// default implementation: do nothing
}

public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) {
	// default implementation: do nothing
}

/** 
 * Record that we found an early exit from a method while a resource is in scope.
 * @param scope enclosing scope
 * @param flowInfo flowInfo at the point of the early exit
 * @param trackingVar representation of the resource
 * @param reference the return or throw statement marking the early exit
 * @return true if the situation has been handled by this flow context.
 */
public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) {
	return false; // not handled
}

protected void recordProvidedExpectedTypes(TypeBinding providedType, TypeBinding expectedType, int nullCount) {
	if (nullCount == 0) {
		this.providedExpectedTypes = new TypeBinding[5][];
	} else if (this.providedExpectedTypes == null) {
		int size = 5;
		while (size <= nullCount) size *= 2;
		this.providedExpectedTypes = new TypeBinding[size][];
	}
	else if (nullCount >= this.providedExpectedTypes.length) {
		int oldLen = this.providedExpectedTypes.length;
		System.arraycopy(this.providedExpectedTypes, 0,
			this.providedExpectedTypes = new TypeBinding[nullCount * 2][], 0, oldLen);
	}
	this.providedExpectedTypes[nullCount] = new TypeBinding[]{providedType, expectedType};
}

protected boolean recordFinalAssignment(VariableBinding variable, Reference finalReference) {
	return true; // keep going
}

/**
 * Record a null reference for use by deferred checks. Only looping or
 * finally contexts really record that information. Other contexts
 * immediately check for unboxing.
 * @param local the local variable involved in the check
 * @param location the location triggering the analysis, for normal null dereference
 *      this is an expression resolving to 'local', for resource leaks it is an
 *      early exit statement.
 * @param checkType the checkType against which the check must be performed; one of
 * 		{@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
 * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL},
 *      {@link #CAN_ONLY_NON_NULL CAN_ONLY_NON_NULL}, potentially
 *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
 *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF}).
 *      <br>
 *      Alternatively, a {@link #IN_UNBOXING} check can e requested.
 * @param nullInfo the null flow info observed at this first visit of location.
 */
protected void recordNullReference(LocalVariableBinding local,
	ASTNode location, int checkType, FlowInfo nullInfo) {
	// default implementation: do nothing
}

/**
 * Either AST analysis or checking of a child flow context has encountered an unboxing situation.
 * Record this fact for handling at an appropriate point in time.
 * @param nullStatus the status as we know it so far.
 */
public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
	// default: handle immediately:
	checkUnboxing(scope, expression, flowInfo);
}
/** During deferred checking re-visit a previously recording unboxing situation. */
protected void checkUnboxing(Scope scope, Expression expression, FlowInfo flowInfo) {
	int status = expression.nullStatus(flowInfo, this);
	if ((status & FlowInfo.NULL) != 0) {
		scope.problemReporter().nullUnboxing(expression, expression.resolvedType);
		return;
	} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) {
		scope.problemReporter().potentialNullUnboxing(expression, expression.resolvedType);
		return;
	} else if ((status & FlowInfo.NON_NULL) != 0) {
		return;
	}
	// not handled, perhaps our parent will eventually have something to say?
	if (this.parent != null) {
		this.parent.recordUnboxing(scope, expression, FlowInfo.UNKNOWN, flowInfo);
	}
}

public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
	// default implementation: do nothing
}

public void recordSettingFinal(VariableBinding variable, Reference finalReference, FlowInfo flowInfo) {
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
	// for initialization inside looping statement that effectively loops
	FlowContext context = this;
	while (context != null) {
		if (!context.recordFinalAssignment(variable, finalReference)) {
			break; // no need to keep going
		}
		context = context.getLocalParent();
	}
	}
}

/**
 * Record a null reference for use by deferred checks. Only looping or
 * finally contexts really record that information. The context may
 * emit an error immediately depending on the status of local against
 * flowInfo and its nature (only looping of finally contexts defer part
 * of the checks; nonetheless, contexts that are nested into a looping or a
 * finally context get affected and delegate some checks to their enclosing
 * context).
 * @param scope the scope into which the check is performed
 * @param local the local variable involved in the check
 * @param location the location triggering the analysis, for normal null dereference
 *      this is an expression resolving to 'local', for resource leaks it is an
 *      early exit statement.
 * @param checkType the status against which the check must be performed; one
 * 		of {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
 * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, potentially
 *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
 *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF})
 *      and a bit to indicate whether the reference is being recorded inside an assert, 
 *      {@link #HIDE_NULL_COMPARISON_WARNING}
 * @param flowInfo the flow info at the check point; deferring contexts will
 *  	perform supplementary checks against flow info instances that cannot
 *  	be known at the time of calling this method (they are influenced by
 * 		code that follows the current point)
 */
public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
		ASTNode location, int checkType, FlowInfo flowInfo) {
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 ||
			flowInfo.isDefinitelyUnknown(local)) {
		return;
	}
	// if reference is being recorded inside an assert, we will not raise redundant null check warnings
	checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
	int checkTypeWithoutHideNullWarning = checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
	switch (checkTypeWithoutHideNullWarning) {
		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
			if (flowInfo.isDefinitelyNonNull(local)) {
				if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
					if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
						scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
					}
					flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
				} else {
					scope.problemReporter().localVariableNonNullComparedToNull(local, location);
					flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
				}
				return;
			}
			else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
				return;
			}
			//$FALL-THROUGH$
		case CAN_ONLY_NULL | IN_COMPARISON_NULL:
		case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
		case CAN_ONLY_NULL | IN_ASSIGNMENT:
		case CAN_ONLY_NULL | IN_INSTANCEOF:
			Expression reference = (Expression)location;
			if (flowInfo.isDefinitelyNull(local)) {
				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
					case FlowContext.IN_COMPARISON_NULL:
						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
							scope.problemReporter().localVariableNullReference(local, reference);
							return;
						}
						if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
							scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
						}
						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
						return;
					case FlowContext.IN_COMPARISON_NON_NULL:
						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
							scope.problemReporter().localVariableNullReference(local, reference);
							return;
						}
						scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
						return;
					case FlowContext.IN_ASSIGNMENT:
						scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
						return;
					case FlowContext.IN_INSTANCEOF:
						scope.problemReporter().localVariableNullInstanceof(local, reference);
						return;
				}
			} else if (flowInfo.isPotentiallyNull(local)) {
				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
					case FlowContext.IN_COMPARISON_NULL:
						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
							scope.problemReporter().localVariablePotentialNullReference(local, reference);
							return;
						}
						break;
					case FlowContext.IN_COMPARISON_NON_NULL:
						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
							scope.problemReporter().localVariablePotentialNullReference(local, reference);
							return;
						}
						break;
				}
			} else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
				return;
			}
			break;
		case MAY_NULL :
			if (flowInfo.isDefinitelyNull(local)) {
				scope.problemReporter().localVariableNullReference(local, location);
				return;
			}
			if (flowInfo.isPotentiallyNull(local)) {
				if(local.type.isFreeTypeVariable()) {
					scope.problemReporter().localVariableFreeTypeVariableReference(local, location);
					return;
				}
				scope.problemReporter().localVariablePotentialNullReference(local, location);
				return;
			}
			break;
		default:
			// never happens
	}
	if (this.parent != null) {
		this.parent.recordUsingNullReference(scope, local, location, checkType,
				flowInfo);
	}
}

void removeFinalAssignmentIfAny(Reference reference) {
	// default implementation: do nothing
}

public SubRoutineStatement subroutine() {
	return null;
}

@Override
public String toString() {
	StringBuffer buffer = new StringBuffer();
	FlowContext current = this;
	int parentsCount = 0;
	while ((current = current.parent) != null) {
		parentsCount++;
	}
	FlowContext[] parents = new FlowContext[parentsCount + 1];
	current = this;
	int index = parentsCount;
	while (index >= 0) {
		parents[index--] = current;
		current = current.parent;
	}
	for (int i = 0; i < parentsCount; i++) {
		for (int j = 0; j < i; j++)
			buffer.append('\t');
		buffer.append(parents[i].individualToString()).append('\n');
	}
	buffer.append('*');
	for (int j = 0; j < parentsCount + 1; j++)
		buffer.append('\t');
	buffer.append(individualToString()).append('\n');
	return buffer.toString();
}

/**
 * Record that a nullity mismatch was detected against an annotated type reference.
 * @param currentScope scope for error reporting
 * @param expression the expression violating the specification
 * @param providedType the type of the provided value, i.e., either expression or an element thereof (in ForeachStatements)
 * @param expectedType the declared type of the spec'ed variable, for error reporting.
 * @param flowInfo the flowInfo observed when visiting expression
 * @param nullStatus the null status of expression at the current location
 * @param annotationStatus status from type annotation analysis, or null
 */
public void recordNullityMismatch(BlockScope currentScope, Expression expression, TypeBinding providedType, TypeBinding expectedType, FlowInfo flowInfo, int nullStatus, NullAnnotationMatching annotationStatus) {
	if (providedType == null) {
		return; // assume type error was already reported
	}
	if (expression.localVariableBinding() != null) { // flowContext cannot yet handle non-localvar expressions (e.g., fields)
		// find the inner-most flowContext that might need deferred handling:
		FlowContext currentContext = this;
		while (currentContext != null) {
			// some flow contexts implement deferred checking, should we participate in that?
			int isInsideAssert = 0x0;
			if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
				isInsideAssert = FlowContext.HIDE_NULL_COMPARISON_WARNING;
			}
			if (currentContext.internalRecordNullityMismatch(expression, providedType, flowInfo, nullStatus, expectedType, ASSIGN_TO_NONNULL | isInsideAssert))
				return;
			currentContext = currentContext.parent;
		}
	}
	// no reason to defer, so report now:
	if (annotationStatus != null)
		currentScope.problemReporter().nullityMismatchingTypeAnnotation(expression, providedType, expectedType, annotationStatus);
	else
		currentScope.problemReporter().nullityMismatch(expression, providedType, expectedType, nullStatus,
														currentScope.environment().getNonNullAnnotationName());
}
protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, FlowInfo flowInfo, int nullStatus, TypeBinding expectedType, int checkType) {
	// nop, to be overridden in subclasses
	return false; // not recorded
}
}
