/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
 *			     				bug 292478 - Report potentially null across variable assignment
 *     							bug 332637 - Dead Code detection removing code that isn't dead
 *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
 *								Bug 411964 - [1.8][null] leverage null type annotation in foreach statement
 *								Bug 421035 - [resource] False alarm of resource leak warning when casting a closeable in its assignment
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;

import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallTrackingVariable;

/**
 * OTDT changes
 *
 * What: Allow public query isDefinitelyAssigned() for base-call tracking variables.
 * Why:  Prepare for overriding by UnconditionalFlowInfo
 *
 * @version $Id: FlowInfo.java 23404 2010-02-03 14:10:22Z stephan $
 */
public abstract class FlowInfo {

	public int tagBits; // REACHABLE by default
	public final static int REACHABLE = 0;
	/* unreachable code 
	 * eg. while (true);
	 *     i++;  --> unreachable code 
	 */
	public final static int UNREACHABLE_OR_DEAD = 1;
	/* unreachable code as inferred by null analysis
	 * eg. str = null;
	 *     if (str != null) {
	 *        // dead code
	 *     }
	 */
	public final static int UNREACHABLE_BY_NULLANALYSIS = 2;
	/*
	 * code unreachable in any fashion
	 */
	public final static int UNREACHABLE = UNREACHABLE_OR_DEAD | UNREACHABLE_BY_NULLANALYSIS;
	public final static int NULL_FLAG_MASK = 4;
	
	public final static int UNKNOWN = 1;
	public final static int NULL = 2;
	public final static int NON_NULL = 4;
	public final static int POTENTIALLY_UNKNOWN = 8;
	public final static int POTENTIALLY_NULL = 16;
	public final static int POTENTIALLY_NON_NULL = 32;

	public final static int UNROOTED = 64; // marks a flowInfo that may be appended to another flowInfo (accepting incoming nulls/nonnulls, see UFI.iNBit/iNNBit).
	
	public static final int FREE_TYPEVARIABLE = FlowInfo.POTENTIALLY_NULL | FlowInfo.POTENTIALLY_NON_NULL;

	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
	static {
		DEAD_END = new UnconditionalFlowInfo();
		DEAD_END.tagBits = UNREACHABLE;
	}

/**
 * Add other inits to this flow info, then return this. The operation semantics
 * are to match as closely as possible the application to this flow info of all
 * the operations that resulted into otherInits.
 * @param otherInits other inits to add to this
 * @return this, modified according to otherInits information
 */
abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);

/**
 * Add all null information from otherInits to this flow info and return this.
 * The operation models the effect of an unconditional sequence of this flow info
 * and otherInits.
 */
abstract public FlowInfo addNullInfoFrom(FlowInfo otherInits);


/**
 * Compose other inits over this flow info, then return this. The operation
 * semantics are to wave into this flow info the consequences of a possible
 * path into the operations that resulted into otherInits. The fact that this
 * path may be left unexecuted under peculiar conditions results into less
 * specific results than {@link #addInitializationsFrom(FlowInfo)
 * addInitializationsFrom}.
 * @param otherInits other inits to compose over this
 * @return this, modified according to otherInits information
 */
abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);

	public FlowInfo asNegatedCondition() {

		return this;
	}

	public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
		if (initsWhenTrue == initsWhenFalse) return initsWhenTrue;
		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
	}

/**
 * Check whether a given local variable is known to be unable to gain a definite
 * non null or definite null status by the use of an enclosing flow info. The
 * semantics are that if the current flow info marks the variable as potentially
 * unknown or else as being both potentially null and potentially non null,
 * then it won't ever be promoted as definitely null or definitely non null. (It
 * could still get promoted to definite unknown).
 * @param local the variable to check
 * @return true iff this flow info prevents local from being promoted to
 *         definite non null or definite null against an enclosing flow info
 */
public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
	return isPotentiallyUnknown(local) ||
		isPotentiallyNonNull(local) && isPotentiallyNull(local);
}

/**
 * Check whether a given local variable is known to be non null, either because
 * it is definitely non null, or because is has been tested against non null.
 * @param local the variable to ckeck
 * @return true iff local cannot be null for this flow info
 */
public boolean cannotBeNull(LocalVariableBinding local) {
	return isDefinitelyNonNull(local) || isProtectedNonNull(local);
}

/**
 * Check whether a given local variable is known to be null, either because it
 * is definitely null, or because is has been tested against null.
 * @param local the variable to ckeck
 * @return true iff local can only be null for this flow info
 */
public boolean canOnlyBeNull(LocalVariableBinding local) {
	return isDefinitelyNull(local) || isProtectedNull(local);
}

/**
 * Return a deep copy of the current instance.
 * @return a deep copy of this flow info
 */
	abstract public FlowInfo copy();

	public static UnconditionalFlowInfo initial(int maxFieldCount) {
		UnconditionalFlowInfo info = new UnconditionalFlowInfo();
		info.maxFieldCount = maxFieldCount;
		return info;
	}

/**
 * Return the flow info that would result from the path associated to the
 * value false for the condition expression that generated this flow info.
 * May be this flow info if it is not an instance of {@link
 * ConditionalFlowInfo}. May have a side effect on subparts of this flow
 * info (subtrees get merged).
 * @return the flow info associated to the false branch of the condition
 * 			that generated this flow info
 */
abstract public FlowInfo initsWhenFalse();

/**
 * Return the flow info that would result from the path associated to the
 * value true for the condition expression that generated this flow info.
 * May be this flow info if it is not an instance of {@link
 * ConditionalFlowInfo}. May have a side effect on subparts of this flow
 * info (subtrees get merged).
 * @return the flow info associated to the true branch of the condition
 * 			that generated this flow info
 */
	abstract public FlowInfo initsWhenTrue();

	/**
	 * Check status of definite assignment for a field.
	 */
	 abstract public boolean isDefinitelyAssigned(FieldBinding field);

	/**
	 * Check status of definite assignment for a local.
	 */
	public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);

/**
 * Check status of definite non-null value for a given local variable.
 * @param local the variable to ckeck
 * @return true iff local is definitely non null for this flow info
 */
	public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);

/**
 * Check status of definite null value for a given local variable.
 * @param local the variable to ckeck
 * @return true iff local is definitely null for this flow info
 */
public abstract boolean isDefinitelyNull(LocalVariableBinding local);

/**
 * Check status of definite unknown value for a given local variable.
 * @param local the variable to ckeck
 * @return true iff local is definitely unknown for this flow info
 */
public abstract boolean isDefinitelyUnknown(LocalVariableBinding local);

/**
 * Check if any null info has been recorded for a given local variable.
 * Here even recording of 'UNKNOWN' is considered as null info.
 */
public abstract boolean hasNullInfoFor(LocalVariableBinding local);

	/**
	 * Check status of potential assignment for a field.
	 */
	 abstract public boolean isPotentiallyAssigned(FieldBinding field);

	/**
	 * Check status of potential assignment for a local variable.
	 */

	 abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);

/**
 * Check status of potential null assignment for a local. Return true if there
 * is a reasonable expectation that the variable be non null at this point.
 * @param local LocalVariableBinding - the binding for the checked local
 * @return true if there is a reasonable expectation that local be non null at
 * this point
 */
public abstract boolean isPotentiallyNonNull(LocalVariableBinding local);

/**
 * Check status of potential null assignment for a local. Return true if there
 * is a reasonable expectation that the variable be null at this point. This
 * includes the protected null case, so as to augment diagnostics, but does not
 * really check that someone deliberately assigned to null on any specific
 * path
 * @param local LocalVariableBinding - the binding for the checked local
 * @return true if there is a reasonable expectation that local be null at
 * this point
 */
public abstract boolean isPotentiallyNull(LocalVariableBinding local);

/**
 * Return true if the given local may have been assigned to an unknown value.
 * @param local the local to check
 * @return true if the given local may have been assigned to an unknown value
 */
public abstract boolean isPotentiallyUnknown(LocalVariableBinding local);

/**
 * Return true if the given local is protected by a test against a non null
 * value.
 * @param local the local to check
 * @return true if the given local is protected by a test against a non null
 */
public abstract boolean isProtectedNonNull(LocalVariableBinding local);

/**
 * Return true if the given local is protected by a test against null.
 * @param local the local to check
 * @return true if the given local is protected by a test against null
 */
public abstract boolean isProtectedNull(LocalVariableBinding local);

/**
 * Record that a local variable got checked to be non null.
 * @param local the checked local variable
 */
abstract public void markAsComparedEqualToNonNull(LocalVariableBinding local);

/**
 * Record that a local variable got checked to be null.
 * @param local the checked local variable
 */
abstract public void markAsComparedEqualToNull(LocalVariableBinding local);

	/**
	 * Record a field got definitely assigned.
	 */
	abstract public void markAsDefinitelyAssigned(FieldBinding field);

	/**
	 * Record a local got definitely assigned to a non-null value.
	 */
	abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);

	/**
	 * Record a local got definitely assigned to null.
	 */
	abstract public void markAsDefinitelyNull(LocalVariableBinding local);

	/**
	 * Reset all null-information about a given local.
	 */
	abstract public void resetNullInfo(LocalVariableBinding local);

	/**
	 * Record a local may have got assigned to unknown (set the bit on existing info).
	 */
	abstract public void markPotentiallyUnknownBit(LocalVariableBinding local);

	/**
	 * Record a local may have got assigned to null (set the bit on existing info).
	 */
	abstract public void markPotentiallyNullBit(LocalVariableBinding local);

	/**
	 * Record a local may have got assigned to non-null (set the bit on existing info).
	 */
	abstract public void markPotentiallyNonNullBit(LocalVariableBinding local);

	/**
	 * Record a local got definitely assigned.
	 */
	abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);

/**
 * Record a local got definitely assigned to an unknown value.
 */
abstract public void markAsDefinitelyUnknown(LocalVariableBinding local);

/**
 * Mark the null status of the given local according to the given status
 * @param local
 * @param nullStatus bitset of FLowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
 */
public void markNullStatus(LocalVariableBinding local, int nullStatus) {
	switch(nullStatus) {
		// definite status?
		case FlowInfo.UNKNOWN :
			markAsDefinitelyUnknown(local);
			break;
		case FlowInfo.NULL :
			markAsDefinitelyNull(local);
			break;
		case FlowInfo.NON_NULL :
			markAsDefinitelyNonNull(local);
			break;
		default:
			// collect potential status:
			resetNullInfo(local);
			if ((nullStatus & FlowInfo.POTENTIALLY_UNKNOWN) != 0)
				markPotentiallyUnknownBit(local);
			if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
				markPotentiallyNullBit(local);
			if ((nullStatus & FlowInfo.POTENTIALLY_NON_NULL) != 0)
				markPotentiallyNonNullBit(local);
			if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL|FlowInfo.POTENTIALLY_UNKNOWN)) == 0)
				markAsDefinitelyUnknown(local);
	}
}

/**
 * Answer the null status of the given local
 * @param local
 * @return bitset of FlowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
 */
public int nullStatus(LocalVariableBinding local) {
	if (isDefinitelyUnknown(local))
		return FlowInfo.UNKNOWN;
	if (isDefinitelyNull(local))
		return FlowInfo.NULL;
	if (isDefinitelyNonNull(local))
		return FlowInfo.NON_NULL;
	int status = 0;
	if (isPotentiallyUnknown(local))
		status |= FlowInfo.POTENTIALLY_UNKNOWN;
	if (isPotentiallyNull(local))
		status |= FlowInfo.POTENTIALLY_NULL;
	if (isPotentiallyNonNull(local))
		status |= FlowInfo.POTENTIALLY_NON_NULL;
	if (status > 0)
		return status;
	return FlowInfo.UNKNOWN;
}

/**
 * Merge two single bits (NULL, NON_NULL, POTENTIALLY*..) into one.
 * This method implements a simpler logic than the 4-bit encoding used in FlowInfo instances.
 */
public static int mergeNullStatus(int nullStatus1, int nullStatus2) {
	boolean canBeNull = false;
	boolean canBeNonNull = false;
	switch (nullStatus1) {
		case POTENTIALLY_NULL:
			canBeNonNull = true;
			//$FALL-THROUGH$
		case NULL:
			canBeNull = true;
			break;
		case POTENTIALLY_NON_NULL:
			canBeNull = true;
			//$FALL-THROUGH$
		case NON_NULL:
			canBeNonNull = true;
			break;
	}
	switch (nullStatus2) {
		case POTENTIALLY_NULL:
			canBeNonNull = true;
			//$FALL-THROUGH$
		case NULL:
			canBeNull = true;
			break;
		case POTENTIALLY_NON_NULL:
			canBeNull = true;
			//$FALL-THROUGH$
		case NON_NULL:
			canBeNonNull = true;
			break;
	}
	if (canBeNull) {
		if (canBeNonNull)
			return POTENTIALLY_NULL;
		else
			return NULL;
	} else {
		if (canBeNonNull)
			return NON_NULL;
		else
			return UNKNOWN;
	}
}

/**
 * Merge branches using optimized boolean conditions
 */
public static UnconditionalFlowInfo mergedOptimizedBranches(
		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
		boolean allowFakeDeadBranch) {
	UnconditionalFlowInfo mergedInfo;
	if (isOptimizedTrue){
		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
				unconditionalInits();
		}
		else {
			mergedInfo =
				initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
					nullInfoLessUnconditionalCopy()).
				unconditionalInits();
		}
	}
	else if (isOptimizedFalse) {
		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
				unconditionalInits();
		}
		else {
			mergedInfo =
				initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
					nullInfoLessUnconditionalCopy()).
				unconditionalInits();
		}
	}
	else {
		mergedInfo = initsWhenTrue.
			mergedWith(initsWhenFalse.unconditionalInits());
	}
	return mergedInfo;
}

/**
 * Merge if-else branches using optimized boolean conditions
 */
public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
		boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement,
		boolean reportDeadCodeInKnownPattern) {
	UnconditionalFlowInfo mergedInfo;
	if (isOptimizedTrue){
		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
			if (!reportDeadCodeInKnownPattern) {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
				if (ifStatement.elseStatement == null) {
					mergedInfo = flowInfo.unconditionalInits();
				} else {
					mergedInfo = initsWhenFalse.unconditionalInits();
					if (initsWhenFalse != FlowInfo.DEAD_END) {
						// let the definitely true status of known dead code pattern not affect the reachability
						mergedInfo.setReachMode(flowInfo.reachMode());
					}
				}
			} else {
				mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
					unconditionalInits();
			}
		}
		else {
			mergedInfo =
				initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
					nullInfoLessUnconditionalCopy()).
				unconditionalInits();
		}
	}
	else if (isOptimizedFalse) {
		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
			if (!reportDeadCodeInKnownPattern) {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
				if (ifStatement.thenStatement == null) {
					mergedInfo = flowInfo.unconditionalInits();
				} else {
					mergedInfo = initsWhenTrue.unconditionalInits();
					if (initsWhenTrue != FlowInfo.DEAD_END) {
						// let the definitely false status of known dead code pattern not affect the reachability
						mergedInfo.setReachMode(flowInfo.reachMode());
					}
				}
			} else {
				mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
					unconditionalInits();
			}
		}
		else {
			mergedInfo =
				initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
					nullInfoLessUnconditionalCopy()).
				unconditionalInits();
		}
	}
	else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
				(ifStatement.bits & ASTNode.IsElseStatementUnreachable) != 0 &&
				initsWhenTrue != FlowInfo.DEAD_END &&
				initsWhenFalse != FlowInfo.DEAD_END) {
		// Done when the then branch will always be executed but the condition does not have a boolean
		// true or false (i.e if(true), etc) for sure
		// We don't do this if both if and else branches themselves are in an unreachable code
		// or if any of them is a DEAD_END (e.g. contains 'return' or 'throws')
		mergedInfo =
			initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
				nullInfoLessUnconditionalCopy()).
			unconditionalInits();
		// if a variable is only initialized in one branch and not initialized in the other,
		// then we need to cast a doubt on its initialization in the merged info
		mergedInfo.mergeDefiniteInitsWith(initsWhenFalse.unconditionalCopy());
		
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsElseStatementUnreachable could be due to null analysis
		if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenFalse.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) {
			mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD;
			mergedInfo.tagBits |= UNREACHABLE_BY_NULLANALYSIS;
		}
	}
	else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
			(ifStatement.bits & ASTNode.IsThenStatementUnreachable) != 0 && initsWhenTrue != FlowInfo.DEAD_END
			&& initsWhenFalse != FlowInfo.DEAD_END) {
		// Done when the else branch will always be executed but the condition does not have a boolean
		// true or false (i.e if(true), etc) for sure
		// We don't do this if both if and else branches themselves are in an unreachable code
		// or if any of them is a DEAD_END (e.g. contains 'return' or 'throws')
		mergedInfo = 
			initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
				nullInfoLessUnconditionalCopy()).
			unconditionalInits();
		// if a variable is only initialized in one branch and not initialized in the other,
		// then we need to cast a doubt on its initialization in the merged info
		mergedInfo.mergeDefiniteInitsWith(initsWhenTrue.unconditionalCopy());
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=415997, classify unreachability precisely, IsThenStatementUnreachable could be due to null analysis
		if ((mergedInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 && (initsWhenTrue.tagBits & FlowInfo.UNREACHABLE) == FlowInfo.UNREACHABLE_BY_NULLANALYSIS) {
			mergedInfo.tagBits &= ~UNREACHABLE_OR_DEAD;
			mergedInfo.tagBits |= UNREACHABLE_BY_NULLANALYSIS;
		}
	}
	else {
		mergedInfo = initsWhenTrue.
			mergedWith(initsWhenFalse.unconditionalInits());
	}
	return mergedInfo;
}

/**
 * Find out the reachability mode of this flowInfo.
 * @return REACHABLE if this flow info is reachable, otherwise
 *         either UNREACHABLE_OR_DEAD or UNREACHABLE_BY_NULLANALYSIS.
 */
public int reachMode() {
	return this.tagBits & UNREACHABLE;
}

/**
 * Return a flow info that carries the same information as the result of
 * {@link #initsWhenTrue() initsWhenTrue}, but warrantied to be different
 * from this.<br>
 * Caveat: side effects on the result may affect components of this.
 * @return the result of initsWhenTrue or a copy of it
 */
abstract public FlowInfo safeInitsWhenTrue();

/**
 * Set this flow info reach mode and return this.
 * @param reachMode one of {@link #REACHABLE REACHABLE}, {@link #UNREACHABLE_OR_DEAD UNREACHABLE_OR_DEAD},
 * {@link #UNREACHABLE_BY_NULLANALYSIS UNREACHABLE_BY_NULLANALYSIS} or {@link #UNREACHABLE UNREACHABLE}
 * @return this, with the reach mode set to reachMode
 */
abstract public FlowInfo setReachMode(int reachMode);

/**
 * Return the intersection of this and otherInits, that is
 * one of:<ul>
 *   <li>the receiver updated in the following way:<ul>
 *     <li>intersection of definitely assigned variables,
 *     <li>union of potentially assigned variables,
 *     <li>similar operations for null,</ul>
 *   <li>or the receiver or otherInits if the other one is non
 *       reachable.</ul>
 * otherInits is not affected, and is not returned either (no
 * need to protect the result).
 * @param otherInits the flow info to merge with this
 * @return the intersection of this and otherInits.
 */
abstract public UnconditionalFlowInfo mergedWith(
		UnconditionalFlowInfo otherInits);

abstract public UnconditionalFlowInfo mergeDefiniteInitsWith(UnconditionalFlowInfo otherInits);

/**
 * Return a copy of this unconditional flow info, deprived from its null
 * info. {@link #DEAD_END DEAD_END} is returned unmodified.
 * @return a copy of this unconditional flow info deprived from its null info
 */
abstract public UnconditionalFlowInfo nullInfoLessUnconditionalCopy();

	public String toString(){

		if (this == DEAD_END){
			return "FlowInfo.DEAD_END"; //$NON-NLS-1$
		}
		return super.toString();
	}

/**
 * Return a new flow info that holds the same information as this would after
 * a call to unconditionalInits, but leaving this info unaffected. Moreover,
 * the result can be modified without affecting this.
 * @return a new flow info carrying this unconditional flow info
 */
abstract public UnconditionalFlowInfo unconditionalCopy();

/**
 * Return a new flow info that holds the same information as this would after
 * a call to {@link #unconditionalInits() unconditionalInits} followed by the
 * erasure of fields specific information, but leaving this flow info unaffected.
 * @return a new flow info carrying the unconditional flow info for local variables
 */
abstract public UnconditionalFlowInfo unconditionalFieldLessCopy();

/**
 * Return a flow info that merges the possible paths of execution described by
 * this flow info. In case of an unconditional flow info, return this. In case
 * of a conditional flow info, merge branches recursively. Caveat: this may
 * be affected, and modifying the result may affect this.
 * @return a flow info that merges the possible paths of execution described by
 * 			this
 */
abstract public UnconditionalFlowInfo unconditionalInits();

/**
 * Return a new flow info that holds the same information as this would after
 * a call to {@link #unconditionalInits() unconditionalInits}, but leaving
 * this info unaffected. Side effects on the result might affect this though
 * (consider it as read only).
 * @return a flow info carrying this unconditional flow info
 */
abstract public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect();

/**
 * Resets the definite and potential initialization info for the given local variable
 * @param local
 */
abstract public void resetAssignmentInfo(LocalVariableBinding local);

/**
 * Check whether 'tagBits' contains either {@link TagBits#AnnotationNonNull} or {@link TagBits#AnnotationNullable},
 * and answer the corresponding null status ({@link #NON_NULL} etc.).
 */
public static int tagBitsToNullStatus(long tagBits) {
	if ((tagBits & TagBits.AnnotationNonNull) != 0)
		return NON_NULL;
	if ((tagBits & TagBits.AnnotationNullable) != 0)
		return POTENTIALLY_NULL | POTENTIALLY_NON_NULL;
	return UNKNOWN;
}

//{ObjectTeams:
public boolean isDefinitelyAssigned(BaseCallTrackingVariable baseCallTrackingVariable)
{
	return isDefinitelyAssigned(baseCallTrackingVariable.binding);
}
// SH}
}
