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

import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;

/**
 * Record initialization status during definite assignment analysis
 *
 * No caching of pre-allocated instances.
 */
public class UnconditionalFlowInfo extends FlowInfo {
	// Coverage tests
	/**
	 * Exception raised when unexpected behavior is detected during coverage
	 * tests. 
	 */
	public static class AssertionFailedException extends RuntimeException {
		private static final long serialVersionUID = 1827352841030089703L;
		
	public AssertionFailedException(String message) {
		super(message);
	}
	}
	
	// Coverage tests need that the code be instrumented. The following flag
	// controls whether the instrumented code is compiled in or not, and whether
	// the coverage tests methods run or not.
	public final static boolean coverageTestFlag = false;
	// never release with the coverageTestFlag set to true
	public static int coverageTestId;

	// assignment bits - first segment
	public long definiteInits;
	public long potentialInits;
	
	// null bits - first segment
	public long 
		nullBit1,
		nullBit2,
		nullBit3,
		nullBit4;
/*
		nullBit1
		 nullBit2...
		0000	start
		0001	pot. unknown
		0010	pot. non null
		0011	pot. nn & pot. un
		0100	pot. null
		0101	pot. n & pot. un
		0110	pot. n & pot. nn
		1001	def. unknown
		1010	def. non null
		1011	pot. nn & prot. nn
		1100	def. null
		1101	pot. n & prot. n
		1110	prot. null
		1111	prot. non null
 */	
		
	// extra segments
	public static final int extraLength = 6;
	public long extra[][];
		// extra bit fields for larger numbers of fields/variables
		// extra[0] holds definiteInits values, extra[1] potentialInits, etc.
		// lifecycle is extra == null or else all extra[]'s are allocated
		// arrays which have the same size

	public int maxFieldCount; // limit between fields and locals

	// Constants
	public static final int BitCacheSize = 64; // 64 bits in a long.

public FlowInfo addInitializationsFrom(FlowInfo inits) {
	if (this == DEAD_END)
		return this;
	if (inits == DEAD_END)
		return this;
	UnconditionalFlowInfo otherInits = inits.unconditionalInits();		

	// union of definitely assigned variables, 
	this.definiteInits |= otherInits.definiteInits;
	// union of potentially set ones
	this.potentialInits |= otherInits.potentialInits;
	// combine null information
	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
	long 
		a1, a2, a3, a4, 
		na1, na2, na3, na4, 
		b1, b2, b3, b4,
		nb1, nb2, nb3, nb4;
	if (otherHasNulls) {
		if (!thisHadNulls) {
			this.nullBit1 = otherInits.nullBit1;
			this.nullBit2 = otherInits.nullBit2;
			this.nullBit3 = otherInits.nullBit3;
			this.nullBit4 = otherInits.nullBit4;
			if (coverageTestFlag && coverageTestId == 1) {
			  this.nullBit4 = ~0;
			}
		}
		else {
			this.nullBit1 = (b1 = otherInits.nullBit1)
                				| (a1 = this.nullBit1) & ((a3 = this.nullBit3) 
                					& (a4 = this.nullBit4) & (nb2 = ~(b2 = otherInits.nullBit2)) 
                					& (nb4 = ~(b4 = otherInits.nullBit4))
                        		| ((na4 = ~a4) | (na3 = ~a3)) 
                        			& ((na2 = ~(a2 = this.nullBit2)) & nb2 
                        				| a2 & (nb3 = ~(b3 = otherInits.nullBit3)) & nb4));
			this.nullBit2  = b2 & (nb4 | nb3)
                    			| na3 & na4 & b2
                    			| a2 & (nb3 & nb4
                                			| (nb1 = ~b1) & (na3 | (na1 = ~a1))
                                			| a1 & b2);
			this.nullBit3 = b3 & (nb1 & (b2 | a2 | na1)
                        			| b1 & (b4 | nb2 | a1 & a3)
                         			| na1 & na2 & na4)
                    			| a3 & nb2 & nb4
                    			| nb1 & ((na2 & a4 | na1) & a3
                                			| a1 & na2 & na4 & b2);
			this.nullBit4 = nb1 & (a4 & (na3 & nb3	| (a3 | na2) & nb2)
                      			| a1 & (a3 & nb2 & b4
                              			| a2 & b2 & (b4	| a3 & na4 & nb3)))
                      			| b1 & (a3 & a4 & b4
                          			| na2 & na4 & nb3 & b4
                          			| a2 & ((b3 | a4) & b4
                                  				| na3 & a4 & b2 & b3)
                          			| na1 & (b4	| (a4 | a2) & b2 & b3))
                      			| (na1 & (na3 & nb3 | na2 & nb2)
                      				| a1 & (nb2 & nb3 | a2 & a3)) & b4;	
			if (coverageTestFlag && coverageTestId == 2) {
			  this.nullBit4 = ~0;
			}
		}
		this.tagBits |= NULL_FLAG_MASK; // in all cases - avoid forgetting extras
	}
	// treating extra storage
	if (this.extra != null || otherInits.extra != null) {
		int mergeLimit = 0, copyLimit = 0;
		if (this.extra != null) {
			if (otherInits.extra != null) {
				// both sides have extra storage
				int length, otherLength;
				if ((length = this.extra[0].length) < 
						(otherLength = otherInits.extra[0].length)) {
					// current storage is shorter -> grow current
					for (int j = 0; j < extraLength; j++) {
						System.arraycopy(this.extra[j], 0, 
							(this.extra[j] = new long[otherLength]), 0, length);
					}
					mergeLimit = length;
					copyLimit = otherLength;
					if (coverageTestFlag && coverageTestId == 3) {
						throw new AssertionFailedException("COVERAGE 3"); //$NON-NLS-1$
					}
				} else {
					// current storage is longer
					mergeLimit = otherLength;
					if (coverageTestFlag && coverageTestId == 4) {
						throw new AssertionFailedException("COVERAGE 4"); //$NON-NLS-1$
					}
				}
			} 
		} else if (otherInits.extra != null) {
			// no storage here, but other has extra storage.
			// shortcut regular copy because array copy is better
			int otherLength;
			this.extra = new long[extraLength][];
			System.arraycopy(otherInits.extra[0], 0, 
				(this.extra[0] = new long[otherLength = 
					otherInits.extra[0].length]), 0, otherLength);			
			System.arraycopy(otherInits.extra[1], 0, 
				(this.extra[1] = new long[otherLength]), 0, otherLength);
			if (otherHasNulls) {
				for (int j = 2; j < extraLength; j++) {
					System.arraycopy(otherInits.extra[j], 0, 
						(this.extra[j] = new long[otherLength]), 0, otherLength);
				}
				if (coverageTestFlag && coverageTestId == 5) {
					this.extra[5][otherLength - 1] = ~0;
				}
			}
			else {
				for (int j = 2; j < extraLength; j++) {
					this.extra[j] = new long[otherLength];			
				}
				if (coverageTestFlag && coverageTestId == 6) {
					throw new AssertionFailedException("COVERAGE 6"); //$NON-NLS-1$
				}
			}
		}
		int i;
		// manage definite assignment info
		for (i = 0; i < mergeLimit; i++) {
			this.extra[0][i] |= otherInits.extra[0][i];
			this.extra[1][i] |= otherInits.extra[1][i];
		}
		for (; i < copyLimit; i++) {
			this.extra[0][i] = otherInits.extra[0][i];
			this.extra[1][i] = otherInits.extra[1][i];
		}
		// tweak limits for nulls
		if (!thisHadNulls) {
		    if (copyLimit < mergeLimit) {
		      	copyLimit = mergeLimit;
		    }
		  	mergeLimit = 0;
		}
		if (!otherHasNulls) {
		  	copyLimit = 0;
		  	mergeLimit = 0;
		}
		for (i = 0; i < mergeLimit; i++) {
			this.extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i])
                				| (a1 = this.extra[1 + 1][i]) & ((a3 = this.extra[3 + 1][i]) 
                					& (a4 = this.extra[4 + 1][i]) & (nb2 = ~(b2 = otherInits.extra[2 + 1][i])) 
                					& (nb4 = ~(b4 = otherInits.extra[4 + 1][i]))
                        		| ((na4 = ~a4) | (na3 = ~a3)) 
                        			& ((na2 = ~(a2 = this.extra[2 + 1][i])) & nb2 
                        				| a2 & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])) & nb4));
			this.extra[2 + 1][i]  = b2 & (nb4 | nb3)
                    			| na3 & na4 & b2
                    			| a2 & (nb3 & nb4
                                			| (nb1 = ~b1) & (na3 | (na1 = ~a1))
                                			| a1 & b2);
			this.extra[3 + 1][i] = b3 & (nb1 & (b2 | a2 | na1)
                        			| b1 & (b4 | nb2 | a1 & a3)
                         			| na1 & na2 & na4)
                    			| a3 & nb2 & nb4
                    			| nb1 & ((na2 & a4 | na1) & a3
                                			| a1 & na2 & na4 & b2);
			this.extra[4 + 1][i] = nb1 & (a4 & (na3 & nb3	| (a3 | na2) & nb2)
                      			| a1 & (a3 & nb2 & b4
                              			| a2 & b2 & (b4	| a3 & na4 & nb3)))
                      			| b1 & (a3 & a4 & b4
                          			| na2 & na4 & nb3 & b4
                          			| a2 & ((b3 | a4) & b4
                                  				| na3 & a4 & b2 & b3)
                          			| na1 & (b4	| (a4 | a2) & b2 & b3))
                      			| (na1 & (na3 & nb3 | na2 & nb2)
                      				| a1 & (nb2 & nb3 | a2 & a3)) & b4;	
			if (coverageTestFlag && coverageTestId == 7) {
			  this.extra[5][i] = ~0;
			}
		}
		for (; i < copyLimit; i++) {
			for (int j = 2; j < extraLength; j++) {
				this.extra[j][i] = otherInits.extra[j][i];
			}
			if (coverageTestFlag && coverageTestId == 8) {
			  this.extra[5][i] = ~0;
			}
		}
	}
	return this;
}

public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) {
	if (this == DEAD_END){
		return this;
	}
	if (inits == DEAD_END){
		return this;
	}
	UnconditionalFlowInfo otherInits = inits.unconditionalInits();
	// union of potentially set ones
	this.potentialInits |= otherInits.potentialInits;
	// treating extra storage
	if (this.extra != null) {
		if (otherInits.extra != null) {
			// both sides have extra storage
			int i = 0, length, otherLength;
			if ((length = this.extra[0].length) < (otherLength = otherInits.extra[0].length)) {
				// current storage is shorter -> grow current
				for (int j = 0; j < extraLength; j++) {
					System.arraycopy(this.extra[j], 0, 
						(this.extra[j] = new long[otherLength]), 0, length);
				}
				for (; i < length; i++) {
					this.extra[1][i] |= otherInits.extra[1][i];
				}
				for (; i < otherLength; i++) {
					this.extra[1][i] = otherInits.extra[1][i];
				}
			} 
			else {
				// current storage is longer
				for (; i < otherLength; i++) {
					this.extra[1][i] |= otherInits.extra[1][i];
				}
			}
		}
	} 
	else if (otherInits.extra != null) {
		// no storage here, but other has extra storage.
		int otherLength = otherInits.extra[0].length;
		this.extra = new long[extraLength][];
		for (int j = 0; j < extraLength; j++) {
			this.extra[j] = new long[otherLength];			
		}
		System.arraycopy(otherInits.extra[1], 0, this.extra[1], 0, 
			otherLength);
	}
	this.addPotentialNullInfoFrom(otherInits);
	return this;
}

/**
 * Compose other inits over this flow info, then return this. The operation
 * semantics are to wave into this flow info the consequences upon null 
 * information 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}; moreover,
 * only the null information is affected.
 * @param otherInits other null inits to compose over this
 * @return this, modified according to otherInits information
 */
public UnconditionalFlowInfo addPotentialNullInfoFrom(
		UnconditionalFlowInfo otherInits) {
	if ((this.tagBits & UNREACHABLE) != 0 ||
			(otherInits.tagBits & UNREACHABLE) != 0 ||
			(otherInits.tagBits & NULL_FLAG_MASK) == 0) {
		return this;
	}
	// if we get here, otherInits has some null info
	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
		thisHasNulls = false;
	long a1, a2, a3, a4,  
		na1, na2, na3, na4, 
		b1, b2, b3, b4,
		nb1, nb2, nb3, nb4;
	if (thisHadNulls) {
		this.nullBit1  = (a1 = this.nullBit1) 
								& ((a3 = this.nullBit3) & (a4 = this.nullBit4) 
									& ((nb2 = ~(b2 = otherInits.nullBit2)) 
										& (nb4 = ~(b4 = otherInits.nullBit4)) 
											| (b1 = otherInits.nullBit1) & (b3 = otherInits.nullBit3))
                			| (na2 = ~(a2 = this.nullBit2)) 
                				& (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2)
                			| a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2)));
		this.nullBit2 = b2 & (nb3 | (nb1 = ~b1))
    			| a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
		this.nullBit3 = b3 & (nb1 & b2
            		| a2 & (nb2	| a3)
            		| na1 & nb2
            		| a1 & na2 & na4 & b1)
    			| a3 & (nb2 & nb4 | na2 & a4 | na1)
    			| a1 & na2 & na4 & b2;
		this.nullBit4 = na3 & (nb1 & nb3 & b4
    				| a4 & (nb3 | b1 & b2))
    			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
    			| a3 & (a4 & (nb2 | b1 & b3)
            			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
		if (coverageTestFlag && coverageTestId == 9) {
		  this.nullBit4 = ~0;
		}
		if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { //  bit1 is redundant
		  	thisHasNulls = true;
		}
	} else {
  		this.nullBit1 = 0;
  		this.nullBit2 = (b2 = otherInits.nullBit2) 
  							& ((nb3 = ~(b3 = otherInits.nullBit3)) | 
  								(nb1 = ~(b1 = otherInits.nullBit1)));
  		this.nullBit3 = b3 & (nb1 | (nb2 = ~b2));
  		this.nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4) | ~b2 & (b1 & ~b3 | ~b1 & b4);
		if (coverageTestFlag && coverageTestId == 10) {
		  this.nullBit4 = ~0;
		}
		if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { //  bit1 is redundant
		  	thisHasNulls = true;
		}
	}
	// extra storage management
	if (otherInits.extra != null) {
		int mergeLimit = 0, copyLimit = otherInits.extra[0].length;
		if (this.extra == null) {
			this.extra = new long[extraLength][];
			for (int j = 0; j < extraLength; j++) {
				this.extra[j] = new long[copyLimit];
			}
			if (coverageTestFlag && coverageTestId == 11) {
				throw new AssertionFailedException("COVERAGE 11"); //$NON-NLS-1$
			}
		} else {
			mergeLimit = copyLimit;
			if (mergeLimit > this.extra[0].length) {
				mergeLimit = this.extra[0].length;
				for (int j = 0; j < extraLength; j++) {
					System.arraycopy(this.extra[j], 0,
							this.extra[j] = new long[copyLimit], 0,
							mergeLimit);
				}
				if (! thisHadNulls) {
    				mergeLimit = 0; 
    				// will do with a copy -- caveat: only valid because definite assignment bits copied above
        			if (coverageTestFlag && coverageTestId == 12) {
						throw new AssertionFailedException("COVERAGE 12"); //$NON-NLS-1$
        			}
				}
			}
		}
		// PREMATURE skip operations for fields
		int i;
		for (i = 0 ; i < mergeLimit ; i++) {
    		this.extra[1 + 1][i]  = (a1 = this.extra[1 + 1][i]) 
    								& ((a3 = this.extra[3 + 1][i]) & (a4 = this.extra[4 + 1][i]) 
    									& ((nb2 = ~(b2 = otherInits.extra[2 + 1][i])) 
    										& (nb4 = ~(b4 = otherInits.extra[4 + 1][i])) 
    											| (b1 = otherInits.extra[1 + 1][i]) & (b3 = otherInits.extra[3 + 1][i]))
                    			| (na2 = ~(a2 = this.extra[2 + 1][i])) 
                    				& (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2)
                    			| a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2)));
    		this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1))
        			| a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
    		this.extra[3 + 1][i] = b3 & (nb1 & b2
                		| a2 & (nb2	| a3)
                		| na1 & nb2
                		| a1 & na2 & na4 & b1)
        			| a3 & (nb2 & nb4 | na2 & a4 | na1)
        			| a1 & na2 & na4 & b2;
    		this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
        				| a4 & (nb3 | b1 & b2))
        			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
        			| a3 & (a4 & (nb2 | b1 & b3)
                			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
    		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
    		  	thisHasNulls = true;
    		}
			if (coverageTestFlag && coverageTestId == 13) {
			  this.nullBit4 = ~0;
			}
		}
		for (; i < copyLimit; i++) {
    		this.extra[1 + 1][i] = 0;
    		this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) 
    							& ((nb3 = ~(b3 = otherInits.extra[3 + 1][i])) | 
    								(nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
    		this.extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2));
    		this.extra[4 + 1][i] = ~b1 & ~b3 & (b4 = otherInits.extra[4 + 1][i]) | ~b2 & (b1 & ~b3 | ~b1 & b4);
    		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
    		  	thisHasNulls = true;
    		}
			if (coverageTestFlag && coverageTestId == 14) {
			  this.extra[5][i] = ~0;
			}
		}
	}
	if (thisHasNulls) {
		this.tagBits |= NULL_FLAG_MASK; 
	}
	else {
		this.tagBits &= NULL_FLAG_MASK; 
	}
	return this;
}

final public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return (
			(~this.nullBit1 
					& (this.nullBit2 & this.nullBit3 | this.nullBit4)
				| ~this.nullBit2 & ~this.nullBit3 & this.nullBit4)
			& (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	long a2, a3, a4;
	return (
			(~this.extra[2][vectorIndex] 
					& ((a2 = this.extra[3][vectorIndex]) & (a3 = this.extra[4][vectorIndex]) | (a4 = this.extra[5][vectorIndex]))
				| ~a2 & ~a3 & a4)
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean cannotBeNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return (this.nullBit1 & this.nullBit3
			& ((this.nullBit2 & this.nullBit4) | ~this.nullBit2)
			& (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return (this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
	        & ((this.extra[3][vectorIndex] & this.extra[5][vectorIndex]) |
	        		~this.extra[3][vectorIndex])
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean canOnlyBeNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return (this.nullBit1 & this.nullBit2
			& (~this.nullBit3 | ~this.nullBit4)
			& (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
	        & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex])
		    & (1L << (position % BitCacheSize))) != 0;
}

public FlowInfo copy() {
	// do not clone the DeadEnd
	if (this == DEAD_END) {
		return this;
	}
	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
	// copy slots
	copy.definiteInits = this.definiteInits;
	copy.potentialInits = this.potentialInits;
	boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0;
	if (hasNullInfo) { 
		copy.nullBit1 = this.nullBit1;
		copy.nullBit2 = this.nullBit2;
		copy.nullBit3 = this.nullBit3;
		copy.nullBit4 = this.nullBit4;
	}
	copy.tagBits = this.tagBits;
	copy.maxFieldCount = this.maxFieldCount;
	if (this.extra != null) {
		int length;
		copy.extra = new long[extraLength][];
		System.arraycopy(this.extra[0], 0, 
			(copy.extra[0] = new long[length = this.extra[0].length]), 0, 
			length);
		System.arraycopy(this.extra[1], 0, 
			(copy.extra[1] = new long[length]), 0, length);
		if (hasNullInfo) {
			for (int j = 2; j < extraLength; j++) {
				System.arraycopy(this.extra[j], 0, 
					(copy.extra[j] = new long[length]), 0, length);
			}
		}
		else {
			for (int j = 2; j < extraLength; j++) {
				copy.extra[j] = new long[length];
			}
		}
	}
	return copy;
}

/**
 * Discard definite inits and potential inits from this, then return this.
 * The returned flow info only holds null related information. 
 * @return this flow info, minus definite inits and potential inits
 */
public UnconditionalFlowInfo discardInitializationInfo() {
	if (this == DEAD_END) {
		return this;
	}
	this.definiteInits =
		this.potentialInits = 0;
	if (this.extra != null) {
		for (int i = 0, length = this.extra[0].length; i < length; i++) {
			this.extra[0][i] = this.extra[1][i] = 0;
		}
	}
	return this;
}

/**
 * Remove local variables information from this flow info and return this.
 * @return this, deprived from any local variable information
 */
public UnconditionalFlowInfo discardNonFieldInitializations() {
	int limit = this.maxFieldCount;
	if (limit < BitCacheSize) {
		long mask = (1L << limit)-1;
		this.definiteInits &= mask;
		this.potentialInits &= mask;
		this.nullBit1 &= mask;
		this.nullBit2 &= mask;
		this.nullBit3 &= mask;
		this.nullBit4 &= mask;
	} 
	// use extra vector
	if (this.extra == null) {
		return this; // if vector not yet allocated, then not initialized
	}
	int vectorIndex, length = this.extra[0].length;
	if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) {
		return this; // not enough room yet
	}
	if (vectorIndex >= 0) { 
		// else we only have complete non field array items left
		long mask = (1L << (limit % BitCacheSize))-1;
		for (int j = 0; j < extraLength; j++) {
			this.extra[j][vectorIndex] &= mask;
		}
	}
	for (int i = vectorIndex + 1; i < length; i++) {
		for (int j = 0; j < extraLength; j++) {
			this.extra[j][i] = 0;
		}
	}
	return this;
}

public FlowInfo initsWhenFalse() {
	return this;
}

public FlowInfo initsWhenTrue() {
	return this;
}

/**
 * Check status of definite assignment at a given position.
 * It deals with the dual representation of the InitializationInfo2:
 * bits for the first 64 entries, then an array of booleans.
 */
final private boolean isDefinitelyAssigned(int position) {
	if (position < BitCacheSize) {
		// use bits
		return (this.definiteInits & (1L << position)) != 0; 
	}
	// use extra vector
	if (this.extra == null)
		return false; // if vector not yet allocated, then not initialized
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) 
			>= this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[0][vectorIndex]) & 
				(1L << (position % BitCacheSize))) != 0;
}

final public boolean isDefinitelyAssigned(FieldBinding field) {
	// Mirrored in CodeStream.isDefinitelyAssigned(..) 
	// do not want to complain in unreachable code
	if ((this.tagBits & UNREACHABLE) != 0) { 
		return true;
	}
	return isDefinitelyAssigned(field.id); 
}

final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
	// do not want to complain in unreachable code if local declared in reachable code
	if ((this.tagBits & UNREACHABLE) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
		return true;
	}
	return isDefinitelyAssigned(local.id + this.maxFieldCount);
}

final public boolean isDefinitelyNonNull(LocalVariableBinding local) {
	// do not want to complain in unreachable code
	if ((this.tagBits & UNREACHABLE) != 0 || 
			(this.tagBits & NULL_FLAG_MASK) == 0) {
		return false;
	}
	if ((local.type.tagBits & TagBits.IsBaseType) != 0 || 
			local.constant() != Constant.NotAConstant) { // String instances
		return true;
	}
	int position = local.id + this.maxFieldCount;
	if (position < BitCacheSize) { // use bits
		return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4))
			    & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1)  
			>= this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
		        & (~this.extra[3][vectorIndex] | this.extra[5][vectorIndex]))
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isDefinitelyNull(LocalVariableBinding local) {
	// do not want to complain in unreachable code
	if ((this.tagBits & UNREACHABLE) != 0 || 
			(this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position = local.id + this.maxFieldCount;
	if (position < BitCacheSize) { // use bits
		return ((this.nullBit1 & this.nullBit2
			        & (~this.nullBit3 | ~this.nullBit4))
			    & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
		        & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex]))
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isDefinitelyUnknown(LocalVariableBinding local) {
	// do not want to complain in unreachable code
	if ((this.tagBits & UNREACHABLE) != 0 || 
			(this.tagBits & NULL_FLAG_MASK) == 0) {
		return false;
	}
	int position = local.id + this.maxFieldCount;
	if (position < BitCacheSize) { // use bits
		return ((this.nullBit1 & this.nullBit4
				& ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex]
	    & ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex])
		    & (1L << (position % BitCacheSize))) != 0;
}

/**
 * Check status of potential assignment at a given position.
 */
final private boolean isPotentiallyAssigned(int position) {
	// id is zero-based
	if (position < BitCacheSize) {
		// use bits
		return (this.potentialInits & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) 
			>= this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[1][vectorIndex]) & 
			(1L << (position % BitCacheSize))) != 0;
}

final public boolean isPotentiallyAssigned(FieldBinding field) {
	return isPotentiallyAssigned(field.id); 
}

final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
	// final constants are inlined, and thus considered as always initialized
	if (local.constant() != Constant.NotAConstant) {
		return true;
	}
	return isPotentiallyAssigned(local.id + this.maxFieldCount);
}

final public boolean isPotentiallyNonNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2))
			    & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[4][vectorIndex]
		        & (~this.extra[2][vectorIndex] | ~this.extra[3][vectorIndex]))
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isPotentiallyNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3))
			    & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return ((this.extra[3][vectorIndex]
		        & (~this.extra[2][vectorIndex] | ~this.extra[4][vectorIndex]))
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isPotentiallyUnknown(LocalVariableBinding local) {
	// do not want to complain in unreachable code
	if ((this.tagBits & UNREACHABLE) != 0 || 
			(this.tagBits & NULL_FLAG_MASK) == 0) {
		return false;
	}
	int position = local.id + this.maxFieldCount;
	if (position < BitCacheSize) { // use bits
		return (this.nullBit4 
			& (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3)
			& (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return (this.extra[5][vectorIndex]
	        & (~this.extra[2][vectorIndex] 
	            | ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex]) 
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isProtectedNonNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
		this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return (this.extra[2][vectorIndex] 
	            & this.extra[4][vectorIndex]
	            & this.extra[5][vectorIndex]
		    & (1L << (position % BitCacheSize))) != 0;
}

final public boolean isProtectedNull(LocalVariableBinding local) {
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
		return false;
	}
	int position;
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
		// use bits
		return (this.nullBit1 & this.nullBit2
			& (this.nullBit3 ^ this.nullBit4)
			& (1L << position)) != 0;
	}
	// use extra vector
	if (this.extra == null) {
		return false; // if vector not yet allocated, then not initialized
	}
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
			this.extra[0].length) {
		return false; // if not enough room in vector, then not initialized
	}
	return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
	        & (this.extra[4][vectorIndex] ^ this.extra[5][vectorIndex])
		    & (1L << (position % BitCacheSize))) != 0;
}

public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
	// protected from non-object locals in calling methods
	if (this != DEAD_END) {
		this.tagBits |= NULL_FLAG_MASK;
		int position;
		long mask;
		long a1, a2, a3, a4, na2;
		// position is zero-based
		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
			// use bits
			if (((mask = 1L << position) 
				& (a1 = this.nullBit1)
				& (na2 = ~(a2 = this.nullBit2))
				& ~(a3 = this.nullBit3)
				& (a4 = this.nullBit4))
					!= 0) {
			  	this.nullBit4 &= ~mask;
			} else if ((mask & a1 & na2 & a3) == 0) {
			  	this.nullBit4 |= mask;
			  	if ((mask & a1) == 0) {
			  	  	if ((mask & a2 & (a3 ^ a4)) != 0) {
			  	  	  	this.nullBit2 &= ~mask;
			  	  	}
			  	  	else if ((mask & (a2 | a3 | a4)) == 0) {
			  	  	  	this.nullBit2 |= mask;
			  	  	}
			  	}
			}
			this.nullBit1 |= mask;
			this.nullBit3 |= mask; 
			if (coverageTestFlag && coverageTestId == 15) {
			  	this.nullBit4 = ~0;
			}
		} 
		else {
			// use extra vector
			int vectorIndex = (position / BitCacheSize) - 1;
			if (this.extra == null) {
				int length = vectorIndex + 1;
				this.extra = new long[extraLength][];
				for (int j = 0; j < extraLength; j++) {
					this.extra[j] = new long[length];
				}
				if (coverageTestFlag && coverageTestId == 16) {
					throw new AssertionFailedException("COVERAGE 16"); //$NON-NLS-1$
				}
			}
			else {
				int oldLength;
				if (vectorIndex >= (oldLength = this.extra[0].length)) {
					int newLength = vectorIndex + 1;
					for (int j = 0; j < extraLength; j++) {
						System.arraycopy(this.extra[j], 0, 
							(this.extra[j] = new long[newLength]), 0, 
							oldLength);
					}
					if (coverageTestFlag && coverageTestId == 17) {
						throw new AssertionFailedException("COVERAGE 17"); //$NON-NLS-1$
					}
				}
			}
			// MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][vectorIndex]/gc
			if (((mask = 1L << (position % BitCacheSize)) 
  				& (a1 = this.extra[1 + 1][vectorIndex])
  				& (na2 = ~(a2 = this.extra[2 + 1][vectorIndex]))
  				& ~(a3 = this.extra[3 + 1][vectorIndex])
  				& (a4 = this.extra[4 + 1][vectorIndex]))
  					!= 0) {
  			  	this.extra[4 + 1][vectorIndex] &= ~mask;
  			} else if ((mask & a1 & na2 & a3) == 0) {
  			  	this.extra[4 + 1][vectorIndex] |= mask;
  			  	if ((mask & a1) == 0) {
  			  	  	if ((mask & a2 & (a3 ^ a4)) != 0) {
  			  	  	  	this.extra[2 + 1][vectorIndex] &= ~mask;
  			  	  	}
  			  	  	else if ((mask & (a2 | a3 | a4)) == 0) {
  			  	  	  	this.extra[2 + 1][vectorIndex] |= mask;
  			  	  	}
  			  	}
  			}
  			this.extra[1 + 1][vectorIndex] |= mask;
  			this.extra[3 + 1][vectorIndex] |= mask; 
			if (coverageTestFlag && coverageTestId == 18) {
			  	this.extra[5][vectorIndex] = ~0;
			}
		}
	}
}

public void markAsComparedEqualToNull(LocalVariableBinding local) {
	// protected from non-object locals in calling methods
	if (this != DEAD_END) {
		this.tagBits |= NULL_FLAG_MASK;
		int position;
		long mask;
		// position is zero-based
		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
			// use bits
			if (((mask = 1L << position) & this.nullBit1) != 0) {
  			  	if ((mask  
  			  		& (~this.nullBit2 | this.nullBit3
  			  			| ~this.nullBit4)) != 0) {
  			  	  	this.nullBit4 &= ~mask;
  			  	}
			} else if ((mask & this.nullBit4) != 0) {
			  	  this.nullBit3 &= ~mask;
			} else {
    			if ((mask & this.nullBit2) != 0) {
    			  	this.nullBit3 &= ~mask;
      			  	this.nullBit4 |= mask;
    			} else {
    			  	this.nullBit3 |= mask;
    			}
			}
			this.nullBit1 |= mask;
			this.nullBit2 |= mask; 
			if (coverageTestFlag && coverageTestId == 19) {
			  	this.nullBit4 = ~0;
			}
		} 
		else {
			// use extra vector
			int vectorIndex = (position / BitCacheSize) - 1;
			mask = 1L << (position % BitCacheSize);
			if (this.extra == null) {
				int length = vectorIndex + 1;
				this.extra = new long[extraLength][];
				for (int j = 0; j < extraLength; j++) {
					this.extra[j] = new long[length ];
				}
				if (coverageTestFlag && coverageTestId == 20) {
					throw new AssertionFailedException("COVERAGE 20"); //$NON-NLS-1$
				}
			}
			else {
				int oldLength;
				if (vectorIndex >= (oldLength = this.extra[0].length)) {
					int newLength = vectorIndex + 1;
					for (int j = 0; j < extraLength; j++) {
						System.arraycopy(this.extra[j], 0, 
							(this.extra[j] = new long[newLength]), 0,
							oldLength);
					}
					if (coverageTestFlag && coverageTestId == 21) {
						throw new AssertionFailedException("COVERAGE 21"); //$NON-NLS-1$
					}
				}
			}
			if ((mask & this.extra[1 + 1][vectorIndex]) != 0) {
  			  	if ((mask  
  			  		& (~this.extra[2 + 1][vectorIndex] | this.extra[3 + 1][vectorIndex]
  			  			| ~this.extra[4 + 1][vectorIndex])) != 0) {
  			  	  	this.extra[4 + 1][vectorIndex] &= ~mask;
  			  	}
			} else if ((mask & this.extra[4 + 1][vectorIndex]) != 0) {
			  	  this.extra[3 + 1][vectorIndex] &= ~mask;
			} else {
    			if ((mask & this.extra[2 + 1][vectorIndex]) != 0) {
    			  	this.extra[3 + 1][vectorIndex] &= ~mask;
      			  	this.extra[4 + 1][vectorIndex] |= mask;
    			} else {
    			  	this.extra[3 + 1][vectorIndex] |= mask;
    			}
			}
			this.extra[1 + 1][vectorIndex] |= mask;
			this.extra[2 + 1][vectorIndex] |= mask; 
		}
	}
}

/**
 * Record a definite assignment at a given position.
 */
final private void markAsDefinitelyAssigned(int position) {
	
	if (this != DEAD_END) {
		// position is zero-based
		if (position < BitCacheSize) {
			// use bits
			long mask;
			this.definiteInits |= (mask = 1L << position);
			this.potentialInits |= mask;
		} 
		else {
			// use extra vector
			int vectorIndex = (position / BitCacheSize) - 1;
			if (this.extra == null) {
				int length = vectorIndex + 1;
				this.extra = new long[extraLength][];
				for (int j = 0; j < extraLength; j++) {
					this.extra[j] = new long[length];
				}
			} 
			else {
				int oldLength; // might need to grow the arrays
				if (vectorIndex >= (oldLength = this.extra[0].length)) {
					for (int j = 0; j < extraLength; j++) {
						System.arraycopy(this.extra[j], 0, 
							(this.extra[j] = new long[vectorIndex + 1]), 0, 
							oldLength);
					}
				}
			}
			long mask;
			this.extra[0][vectorIndex] |= 
				(mask = 1L << (position % BitCacheSize));
			this.extra[1][vectorIndex] |= mask;
		}
	}
}

public void markAsDefinitelyAssigned(FieldBinding field) {
	if (this != DEAD_END)
		markAsDefinitelyAssigned(field.id);
}

public void markAsDefinitelyAssigned(LocalVariableBinding local) {
	if (this != DEAD_END)
		markAsDefinitelyAssigned(local.id + this.maxFieldCount);
}

public void markAsDefinitelyNonNull(LocalVariableBinding local) {
	// protected from non-object locals in calling methods
	if (this != DEAD_END) {
    	this.tagBits |= NULL_FLAG_MASK;
    	long mask;
    	int position;
    	// position is zero-based
    	if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
    		// set assigned non null
    		this.nullBit1 |= (mask = 1L << position);
    		this.nullBit3 |= mask;
    		// clear others
    		this.nullBit2 &= (mask = ~mask);
    		this.nullBit4 &= mask;
    		if (coverageTestFlag && coverageTestId == 22) {
    		  	this.nullBit1 = 0;
    		}
    	} 
    	else {
    		// use extra vector
    		int vectorIndex ;
    		this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 
    		    |= (mask = 1L << (position % BitCacheSize));
    		this.extra[4][vectorIndex] |= mask;
    		this.extra[3][vectorIndex] &= (mask = ~mask);
    		this.extra[5][vectorIndex] &= mask;
    		if (coverageTestFlag && coverageTestId == 23) {
    			this.extra[2][vectorIndex] = 0;
    		}
    	}
	}
}

public void markAsDefinitelyNull(LocalVariableBinding local) {
	// protected from non-object locals in calling methods
	if (this != DEAD_END) {
    	this.tagBits |= NULL_FLAG_MASK;
    	long mask;
    	int position;
    	// position is zero-based
    	if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
    		// mark assigned null
    		this.nullBit1 |= (mask = 1L << position);
    		this.nullBit2 |= mask;
    		// clear others
    		this.nullBit3 &= (mask = ~mask);
    		this.nullBit4 &= mask;
    		if (coverageTestFlag && coverageTestId == 24) {
    		  	this.nullBit4 = ~0;
    		}
    	} 
    	else {
    		// use extra vector
    		int vectorIndex ;
    		this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 
    		    |= (mask = 1L << (position % BitCacheSize));
    		this.extra[3][vectorIndex] |= mask;
    		this.extra[4][vectorIndex] &= (mask = ~mask);
    		this.extra[5][vectorIndex] &= mask;
    		if (coverageTestFlag && coverageTestId == 25) {
    			this.extra[5][vectorIndex] = ~0;
    		}
    	}
	}
}

/**
 * Mark a local as having been assigned to an unknown value.
 * @param local the local to mark
 */
// PREMATURE may try to get closer to markAsDefinitelyAssigned, but not
//			 obvious
public void markAsDefinitelyUnknown(LocalVariableBinding local) {
	// protected from non-object locals in calling methods
	if (this != DEAD_END) {
		this.tagBits |= NULL_FLAG_MASK;
		long mask;
		int position;
		// position is zero-based
		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
			// use bits
			// mark assigned null
			this.nullBit1 |= (mask = 1L << position);
			this.nullBit4 |= mask;
			// clear others
			this.nullBit2 &= (mask = ~mask);
			this.nullBit3 &= mask;
			if (coverageTestFlag && coverageTestId == 26) {
			  	this.nullBit4 = 0;
			}
		} 
		else {
			// use extra vector
			int vectorIndex ;
			this.extra[2][vectorIndex = (position / BitCacheSize) - 1] 
			    |= (mask = 1L << (position % BitCacheSize));
			this.extra[5][vectorIndex] |= mask;
			this.extra[3][vectorIndex] &= (mask = ~mask);
			this.extra[4][vectorIndex] &= mask;
			if (coverageTestFlag && coverageTestId == 27) {
				this.extra[5][vectorIndex] = 0;
			}
		}
	}
}

public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
	if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) {
		if (coverageTestFlag && coverageTestId == 28) {
			throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$
		}
		return this;
	}
	if ((this.tagBits & UNREACHABLE) != 0) {
		if (coverageTestFlag && coverageTestId == 29) {
			throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$
		}
		return (UnconditionalFlowInfo) otherInits.copy(); // make sure otherInits won't be affected
	} 
	
	// intersection of definitely assigned variables, 
	this.definiteInits &= otherInits.definiteInits;
	// union of potentially set ones
	this.potentialInits |= otherInits.potentialInits;

	// null combinations
	boolean
		thisHasNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0,
		thisHadNulls = thisHasNulls;
	long 
		a1, a2, a3, a4,  
		na1, na2, na3, na4, 
		nb1, nb2, nb3, nb4,
		b1, b2, b3, b4;
	if (thisHadNulls) {
    	if (otherHasNulls) {
    		this.nullBit1 = (a2 = this.nullBit2) & (a3 = this.nullBit3) 
    							& (a4 = this.nullBit4) & (b1 = otherInits.nullBit1) 
    							& (nb2 = ~(b2 = otherInits.nullBit2))
                  			| (a1 = this.nullBit1) & (b1 & (a3 & a4 & (b3 = otherInits.nullBit3) 
                  													& (b4 = otherInits.nullBit4)
                  												| (na2 = ~a2) & nb2 
                  													& ((nb4 = ~b4) | (na4 = ~a4) 
                  															| (na3 = ~a3) & (nb3 = ~b3))
                  												| a2 & b2 & ((na4 | na3) & (nb4	| nb3)))
                  											| na2 & b2 & b3 & b4);
    		this.nullBit2 = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4)
        			| a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1);
    		this.nullBit3 = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4))
        			| a3 & (na2 & a4 | na1)
        			| (a2 | na1) & b1 & nb2 & nb4
        			| a1 & na2 & na4 & (b2 | nb1);
    		this.nullBit4 = na3 & (nb1 & nb3 & b4
              			| b1 & (nb2 & nb3 | a4 & b2 & nb4)
              			| na1 & a4 & (nb3 | b1 & b2))
        			| a3 & a4 & (b3 & b4 | b1 & nb2)
        			| na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
        			| a1 & (na3 & (nb3 & b4
                        			| b1 & b2 & b3 & nb4
                        			| na2 & (nb3 | nb2))
                			| na2 & b3 & b4
                			| a2 & (nb1 & b4 | a3 & na4 & b1) & nb3);
    		if (coverageTestFlag && coverageTestId == 30) {
    		  	this.nullBit4 = ~0;
    		}
    	} else { // other has no null info 
    		a1 = this.nullBit1;
      		this.nullBit1 = 0;
      		this.nullBit2 = (a2 = this.nullBit2) & (na3 = ~(a3 = this.nullBit3) | (na1 = ~a1));
      		this.nullBit3 = a3 & ((na2 = ~a2) & (a4 = this.nullBit4) | na1) | a1 & na2 & ~a4;
      		this.nullBit4 = (na3 | na2) & na1 & a4	| a1 & na3 & na2;
    		if (coverageTestFlag && coverageTestId == 31) {
    		  	this.nullBit4 = ~0;
    		}
    	}
	} else if (otherHasNulls) { // only other had nulls
  		this.nullBit1 = 0;
  		this.nullBit2 = (b2 = otherInits.nullBit2) & (nb3 = ~(b3 = otherInits.nullBit3) | (nb1 = ~(b1 = otherInits.nullBit1)));
  		this.nullBit3 = b3 & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1) | b1 & nb2 & ~b4;
  		this.nullBit4 = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
  		if (coverageTestFlag && coverageTestId == 32) {
  		  	this.nullBit4 = ~0;
  		}
    	thisHasNulls =
    		// redundant with the three following ones
    		this.nullBit2 != 0 ||
    		this.nullBit3 != 0 ||
    		this.nullBit4 != 0;
	}

	// treating extra storage
	if (this.extra != null || otherInits.extra != null) {
		int mergeLimit = 0, copyLimit = 0, resetLimit = 0;
		int i;
		if (this.extra != null) {
			if (otherInits.extra != null) {
				// both sides have extra storage
				int length, otherLength;
				if ((length = this.extra[0].length) < 
						(otherLength = otherInits.extra[0].length)) {
					// current storage is shorter -> grow current 
					for (int j = 0; j < extraLength; j++) {
						System.arraycopy(this.extra[j], 0, 
							(this.extra[j] = new long[otherLength]), 0, length);
					}
					mergeLimit = length;
					copyLimit = otherLength;
					if (coverageTestFlag && coverageTestId == 33) {
						throw new AssertionFailedException("COVERAGE 33"); //$NON-NLS-1$
					}
				} 
				else {
					// current storage is longer
					mergeLimit = otherLength;
					resetLimit = length;
					if (coverageTestFlag && coverageTestId == 34) {
						throw new AssertionFailedException("COVERAGE 34"); //$NON-NLS-1$
					}
				}
			} 
			else {
				resetLimit = this.extra[0].length;
				if (coverageTestFlag && coverageTestId == 35) {
					throw new AssertionFailedException("COVERAGE 35"); //$NON-NLS-1$
				}
			}
		} 
		else if (otherInits.extra != null) {
			// no storage here, but other has extra storage.
			int otherLength = otherInits.extra[0].length;
			this.extra = new long[extraLength][];
			for (int j = 0; j < extraLength; j++) {
				this.extra[j] = new long[otherLength];
			}
			System.arraycopy(otherInits.extra[1], 0, 
				this.extra[1], 0, otherLength);
			copyLimit = otherLength;
			if (coverageTestFlag && coverageTestId == 36) {
				throw new AssertionFailedException("COVERAGE 36"); //$NON-NLS-1$
			}
		}
        // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][i]/g
		// manage definite assignment
		for (i = 0; i < mergeLimit; i++) {
	  		this.extra[0][i] &= otherInits.extra[0][i];
	  		this.extra[1][i] |= otherInits.extra[1][i];
		}
		for (; i < copyLimit; i++) {
		  	this.extra[1][i] = otherInits.extra[1][i];
		}
		for (; i < resetLimit; i++) {
		  	this.extra[0][i] = 0;
		}
		// refine null bits requirements
		if (!otherHasNulls) {
		  if (resetLimit < mergeLimit) {
			resetLimit = mergeLimit;
		  }
		  copyLimit = 0; // no need to carry inexisting nulls
		  mergeLimit = 0;
		}
		if (!thisHadNulls) {
		  resetLimit = 0; // no need to reset anything
		}
		// compose nulls
		for (i = 0; i < mergeLimit; i++) {
    		this.extra[1 + 1][i] = (a2 = this.extra[2 + 1][i]) & (a3 = this.extra[3 + 1][i]) 
    							& (a4 = this.extra[4 + 1][i]) & (b1 = otherInits.extra[1 + 1][i]) 
    							& (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
                  			| (a1 = this.extra[1 + 1][i]) & (b1 & (a3 & a4 & (b3 = otherInits.extra[3 + 1][i]) 
                  													& (b4 = otherInits.extra[4 + 1][i])
                  												| (na2 = ~a2) & nb2 
                  													& ((nb4 = ~b4) | (na4 = ~a4) 
                  															| (na3 = ~a3) & (nb3 = ~b3))
                  												| a2 & b2 & ((na4 | na3) & (nb4	| nb3)))
                  											| na2 & b2 & b3 & b4);
    		this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & nb4)
        			| a2 & (b2 | na4 & b3 & (b4 | nb1) | na3 | na1);
    		this.extra[3 + 1][i] = b3 & (nb2 & b4 | nb1 | a3 & (na4 & nb4 | a4 & b4))
        			| a3 & (na2 & a4 | na1)
        			| (a2 | na1) & b1 & nb2 & nb4
        			| a1 & na2 & na4 & (b2 | nb1);
    		this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
              			| b1 & (nb2 & nb3 | a4 & b2 & nb4)
              			| na1 & a4 & (nb3 | b1 & b2))
        			| a3 & a4 & (b3 & b4 | b1 & nb2)
        			| na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
        			| a1 & (na3 & (nb3 & b4
                        			| b1 & b2 & b3 & nb4
                        			| na2 & (nb3 | nb2))
                			| na2 & b3 & b4
                			| a2 & (nb1 & b4 | a3 & na4 & b1) & nb3);
			thisHasNulls = thisHasNulls ||
				this.extra[3][i] != 0 ||
				this.extra[4][i] != 0 ||
				this.extra[5][i] != 0 ;
			if (coverageTestFlag && coverageTestId == 37) {
				this.extra[5][i] = ~0;
			}
		}
		for (; i < copyLimit; i++) {
    		this.extra[1 + 1][i] = 0;
    		this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
    		this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4;
    		this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
			thisHasNulls = thisHasNulls ||
				this.extra[3][i] != 0 ||
				this.extra[4][i] != 0 ||
				this.extra[5][i] != 0;
			if (coverageTestFlag && coverageTestId == 38) {
				this.extra[5][i] = ~0;
			}
		}
		for (; i < resetLimit; i++) {
    		a1 = this.extra[1 + 1][i];
      		this.extra[1 + 1][i] = 0;
      		this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1));
      		this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4;
      		this.extra[4 + 1][i] = (na3 | na2) & na1 & a4	| a1 & na3 & na2;
			thisHasNulls = thisHasNulls ||
				this.extra[3][i] != 0 ||
				this.extra[4][i] != 0 ||
				this.extra[5][i] != 0;
			if (coverageTestFlag && coverageTestId == 39) {
				this.extra[5][i] = ~0;
			}
		}
	}
	if (thisHasNulls) {
		this.tagBits |= NULL_FLAG_MASK;
	}
	else {
		this.tagBits &= ~NULL_FLAG_MASK;
	}
	return this;
}

/*
 * Answer the total number of fields in enclosing types of a given type
 */
static int numberOfEnclosingFields(ReferenceBinding type){
	int count = 0;
	type = type.enclosingType();
	while(type != null) {
		count += type.fieldCount();
		type = type.enclosingType();
	}
	return count;
}

public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
	if (this == DEAD_END) {
		return this;
	}
	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
	copy.definiteInits = this.definiteInits;
	copy.potentialInits = this.potentialInits;
	copy.tagBits = this.tagBits & ~NULL_FLAG_MASK;
	copy.maxFieldCount = this.maxFieldCount;
	if (this.extra != null) {
		int length;
		copy.extra = new long[extraLength][];
		System.arraycopy(this.extra[0], 0, 
			(copy.extra[0] = 
				new long[length = this.extra[0].length]), 0, length);
		System.arraycopy(this.extra[1], 0, 
			(copy.extra[1] = new long[length]), 0, length);
		for (int j = 2; j < extraLength; j++) {
			copy.extra[j] = new long[length];
		}
	}
	return copy;
}

public FlowInfo safeInitsWhenTrue() {
	return copy();
}

public FlowInfo setReachMode(int reachMode) {
	if (reachMode == REACHABLE && this != DEAD_END) { // cannot modify DEAD_END
		this.tagBits &= ~UNREACHABLE;
	}
	else {
		if ((this.tagBits & UNREACHABLE) == 0) {
			// reset optional inits when becoming unreachable
			// see InitializationTest#test090 (and others)
			this.potentialInits = 0;
			if (this.extra != null) {
				for (int i = 0, length = this.extra[0].length; 
						i < length; i++) {
					this.extra[1][i] = 0;
				}
			}
		}				
		this.tagBits |= UNREACHABLE;
	}
	return this;
}

public String toString(){
	// PREMATURE consider printing bit fields as 0001 0001 1000 0001...
	if (this == DEAD_END){
		return "FlowInfo.DEAD_END"; //$NON-NLS-1$
	}
	if ((this.tagBits & NULL_FLAG_MASK) != 0) {
		if (this.extra == null) {
			return "FlowInfo<def: " + this.definiteInits //$NON-NLS-1$
				+", pot: " + this.potentialInits  //$NON-NLS-1$
				+ ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
				+", null: " + this.nullBit1 //$NON-NLS-1$
					+ this.nullBit2 + this.nullBit3 + this.nullBit4
				+">"; //$NON-NLS-1$
		}
		else {
			String def = "FlowInfo<def:[" + this.definiteInits, //$NON-NLS-1$
				pot = "], pot:[" + this.potentialInits, //$NON-NLS-1$
				nullS = ", null:[" + this.nullBit1 //$NON-NLS-1$
					+ this.nullBit2 + this.nullBit3 + this.nullBit4;
			int i, ceil;
			for (i = 0, ceil = this.extra[0].length > 3 ? 
								3 : 
								this.extra[0].length;
				i < ceil; i++) {
				def += "," + this.extra[0][i]; //$NON-NLS-1$
				pot += "," + this.extra[1][i]; //$NON-NLS-1$
				nullS += "," + this.extra[2][i] //$NON-NLS-1$
				    + this.extra[3][i] + this.extra[4][i] + this.extra[5][i];
			}
			if (ceil < this.extra[0].length) {
				def += ",..."; //$NON-NLS-1$
				pot += ",..."; //$NON-NLS-1$
				nullS += ",..."; //$NON-NLS-1$
			}
			return def + pot 
				+ "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
				+ nullS
				+ "]>"; //$NON-NLS-1$
		}
	}
	else {
		if (this.extra == null) {
			return "FlowInfo<def: " + this.definiteInits //$NON-NLS-1$
				+", pot: " + this.potentialInits  //$NON-NLS-1$
				+ ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
				+", no null info>"; //$NON-NLS-1$
		}
		else {
			String def = "FlowInfo<def:[" + this.definiteInits, //$NON-NLS-1$
				pot = "], pot:[" + this.potentialInits; //$NON-NLS-1$
			int i, ceil;
			for (i = 0, ceil = this.extra[0].length > 3 ? 
								3 : 
								this.extra[0].length;
				i < ceil; i++) {
				def += "," + this.extra[0][i]; //$NON-NLS-1$
				pot += "," + this.extra[1][i]; //$NON-NLS-1$
			}
			if (ceil < this.extra[0].length) {
				def += ",..."; //$NON-NLS-1$
				pot += ",..."; //$NON-NLS-1$
			}
			return def + pot 
				+ "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
				+ ", no null info>"; //$NON-NLS-1$
		}
	}
}

public UnconditionalFlowInfo unconditionalCopy() {
	return (UnconditionalFlowInfo) copy();
}
	
public UnconditionalFlowInfo unconditionalFieldLessCopy() {
	// TODO (maxime) may consider leveraging null contribution verification as it is done in copy
	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
	copy.tagBits = this.tagBits;
	copy.maxFieldCount = this.maxFieldCount;
	int limit = this.maxFieldCount;
	if (limit < BitCacheSize) {
		long mask;
		copy.definiteInits = this.definiteInits & (mask = ~((1L << limit)-1));
		copy.potentialInits = this.potentialInits & mask;
		copy.nullBit1 = this.nullBit1 & mask;
		copy.nullBit2 = this.nullBit2 & mask;
		copy.nullBit3 = this.nullBit3 & mask;
		copy.nullBit4 = this.nullBit4 & mask;
	} 
	// use extra vector
	if (this.extra == null) {
		return copy; // if vector not yet allocated, then not initialized
	}
	int vectorIndex, length, copyStart;
	if ((vectorIndex = (limit / BitCacheSize) - 1) >= 
			(length = this.extra[0].length)) {
		return copy; // not enough room yet
	}
	long mask;
	copy.extra = new long[extraLength][];
	if ((copyStart = vectorIndex + 1) < length) {
		int copyLength = length - copyStart;
		for (int j = 0; j < extraLength; j++) {
			System.arraycopy(this.extra[j], copyStart, 
				(copy.extra[j] = new long[length]), copyStart, 
				copyLength);
		}
	}
	else if (vectorIndex >= 0) {
		for (int j = 0; j < extraLength; j++) {
			copy.extra[j] = new long[length];
		}
	}
	if (vectorIndex >= 0) {
		mask = ~((1L << (limit % BitCacheSize))-1);
		for (int j = 0; j < extraLength; j++) {
			copy.extra[j][vectorIndex] = 
				this.extra[j][vectorIndex] & mask;
		}
	}
	return copy;
}

public UnconditionalFlowInfo unconditionalInits() {
	// also see conditional inits, where it requests them to merge
	return this;
}

public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() {
	return this;
}
}

