diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index a8ff9ec..d6f9ab0 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -1,149 +1,148 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.parser.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public class Clinit extends AbstractMethodDeclaration {
-	public final static char[] ConstantPoolName = "<clinit>"/*nonNLS*/.toCharArray();
-public Clinit() {
-	modifiers = 0;
-	selector = ConstantPoolName;
-}
-public void analyseCode(ClassScope classScope, InitializationFlowContext staticInitializerFlowContext, FlowInfo flowInfo){
-	
-	if (ignoreFurtherInvestigation)
-		return;
-	try {
-		ExceptionHandlingFlowContext clinitContext = new ExceptionHandlingFlowContext(
-			staticInitializerFlowContext.parent, 
-			this, 
-			NoExceptions, 
-			scope,
-			FlowInfo.DeadEnd);
-
-		// check for missing returning path
-		needFreeReturn = !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
-
-		// check missing blank final field initializations
-		flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
-		FieldBinding[] fields = scope.enclosingSourceType().fields();
-		for (int i = 0, count = fields.length; i < count; i++) {
-			FieldBinding field;
-			if ((field = fields[i]).isStatic()
-				&& field.isFinal()
-				&& (!flowInfo.isDefinitelyAssigned(fields[i]))) {
-				scope.problemReporter().uninitializedBlankFinalField(field, scope.referenceType().declarationOf(field)); // can complain against the field decl, since only one <clinit>
-			}
-		}
-		// check static initializers thrown exceptions
-		staticInitializerFlowContext.checkInitializerExceptions(scope, clinitContext, flowInfo);
-	} catch (AbortMethod e) {
-		this.ignoreFurtherInvestigation = true;		
-	}
-}
-/**
- * Bytecode generation for a <clinit> method
- *
- * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
- * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
- */
-public void generateCode(ClassScope classScope, ClassFile classFile) {
-	int clinitOffset = 0;
-	if (ignoreFurtherInvestigation) {
-		// should never have to add any <clinit> problem method
-		return;
-	}
-	try {
-		clinitOffset = classFile.contentsOffset;
-		ConstantPool constantPool = classFile.constantPool;
-		int constantPoolOffset = constantPool.currentOffset;
-		int constantPoolIndex = constantPool.currentIndex;
-		classFile.generateMethodInfoHeaderForClinit();
-		int codeAttributeOffset = classFile.contentsOffset;
-		classFile.generateCodeAttributeHeader();
-		CodeStream codeStream = classFile.codeStream;
-		codeStream.reset(this, classFile);
-		TypeDeclaration declaringType = classScope.referenceContext;
-
-		// initialize local positions - including initializer scope.
-		scope.computeLocalVariablePositions(0, codeStream); // should not be necessary
-		MethodScope staticInitializerScope = declaringType.staticInitializerScope;
-		staticInitializerScope.computeLocalVariablePositions(0, codeStream); // offset by the argument size
-
-		// generate initializers
-		if (declaringType.fields != null) {
-			for (int i = 0, max = declaringType.fields.length; i < max; i++) {
-				FieldDeclaration fieldDecl;
-				if ((fieldDecl = declaringType.fields[i]).isStatic()) {
-					fieldDecl.generateCode(staticInitializerScope, codeStream);
-				}
-			}
-		}
-		if (codeStream.position == 0) {
-			// do not need to output a Clinit if no bytecodes
-			// so we reset the offset inside the byte array contents.
-			classFile.contentsOffset = clinitOffset;
-			// like we don't addd a method we need to undo the increment on the method count
-			classFile.methodCount--;
-			// reset the constant pool to its state before the clinit
-			constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
-		} else {
-			if (needFreeReturn) {
-				int oldPosition = codeStream.position;
-				codeStream.return_();
-				codeStream.updateLocalVariablesAttribute(oldPosition);
-			}
-			// Record the end of the clinit: point to the declaration of the class
-			codeStream.recordPositionsFrom(0, declaringType);
-			classFile.completeCodeAttributeForClinit(codeAttributeOffset);
-		}
-	} catch (AbortMethod e) {
-		// should never occur
-		// the clinit referenceContext is the type declaration
-		// All clinit problems will be reported against the type: AbortType instead of AbortMethod
-		// reset the contentsOffset to the value before generating the clinit code
-		// decrement the number of method info as well.
-		// This is done in the addProblemMethod and addProblemConstructor for other
-		// cases.
-		classFile.contentsOffset = clinitOffset;
-		classFile.methodCount--;	
-	}
-}
-public boolean isClinit() {
-	return true;
-}
-public boolean isInitializationMethod(){
-	return true;
-}
-public boolean isStatic() {
-	return true;
-}
-public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
-	//the clinit is filled by hand .... 
-}
-public void resolve(ClassScope scope) {
-	this.scope = new MethodScope(scope, scope.referenceContext, true);
-}
-public String toString(int tab){
-	/* slow code */
-
-	String s = ""/*nonNLS*/ ;
-	s = s + tabString(tab);
-	s = s + "<clinit>()"/*nonNLS*/ ;
-	s = s + toStringStatements(tab + 1);
-	return s ;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
-	visitor.visit(this, classScope);
-	visitor.endVisit(this, classScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+
+public class Clinit extends AbstractMethodDeclaration {
+	public final static char[] ConstantPoolName = "<clinit>"/*nonNLS*/.toCharArray();
+public Clinit() {
+	modifiers = 0;
+	selector = ConstantPoolName;
+}
+public void analyseCode(ClassScope classScope, InitializationFlowContext staticInitializerFlowContext, FlowInfo flowInfo){
+	
+	if (ignoreFurtherInvestigation)
+		return;
+	try {
+		ExceptionHandlingFlowContext clinitContext = new ExceptionHandlingFlowContext(
+			staticInitializerFlowContext.parent, 
+			this, 
+			NoExceptions, 
+			scope,
+			FlowInfo.DeadEnd);
+
+		// check for missing returning path
+		needFreeReturn = !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
+
+		// check missing blank final field initializations
+		flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
+		FieldBinding[] fields = scope.enclosingSourceType().fields();
+		for (int i = 0, count = fields.length; i < count; i++) {
+			FieldBinding field;
+			if ((field = fields[i]).isStatic()
+				&& field.isFinal()
+				&& (!flowInfo.isDefinitelyAssigned(fields[i]))) {
+				scope.problemReporter().uninitializedBlankFinalField(field, scope.referenceType().declarationOf(field)); // can complain against the field decl, since only one <clinit>
+			}
+		}
+		// check static initializers thrown exceptions
+		staticInitializerFlowContext.checkInitializerExceptions(scope, clinitContext, flowInfo);
+	} catch (AbortMethod e) {
+		this.ignoreFurtherInvestigation = true;		
+	}
+}
+/**
+ * Bytecode generation for a <clinit> method
+ *
+ * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
+ * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+ */
+public void generateCode(ClassScope classScope, ClassFile classFile) {
+	int clinitOffset = 0;
+	if (ignoreFurtherInvestigation) {
+		// should never have to add any <clinit> problem method
+		return;
+	}
+	try {
+		clinitOffset = classFile.contentsOffset;
+		ConstantPool constantPool = classFile.constantPool;
+		int constantPoolOffset = constantPool.currentOffset;
+		int constantPoolIndex = constantPool.currentIndex;
+		classFile.generateMethodInfoHeaderForClinit();
+		int codeAttributeOffset = classFile.contentsOffset;
+		classFile.generateCodeAttributeHeader();
+		CodeStream codeStream = classFile.codeStream;
+		codeStream.reset(this, classFile);
+		TypeDeclaration declaringType = classScope.referenceContext;
+
+		// initialize local positions - including initializer scope.
+		scope.computeLocalVariablePositions(0, codeStream); // should not be necessary
+		MethodScope staticInitializerScope = declaringType.staticInitializerScope;
+		staticInitializerScope.computeLocalVariablePositions(0, codeStream); // offset by the argument size
+
+		// generate initializers
+		if (declaringType.fields != null) {
+			for (int i = 0, max = declaringType.fields.length; i < max; i++) {
+				FieldDeclaration fieldDecl;
+				if ((fieldDecl = declaringType.fields[i]).isStatic()) {
+					fieldDecl.generateCode(staticInitializerScope, codeStream);
+				}
+			}
+		}
+		if (codeStream.position == 0) {
+			// do not need to output a Clinit if no bytecodes
+			// so we reset the offset inside the byte array contents.
+			classFile.contentsOffset = clinitOffset;
+			// like we don't addd a method we need to undo the increment on the method count
+			classFile.methodCount--;
+			// reset the constant pool to its state before the clinit
+			constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
+		} else {
+			if (needFreeReturn) {
+				int oldPosition = codeStream.position;
+				codeStream.return_();
+				codeStream.updateLocalVariablesAttribute(oldPosition);
+			}
+			// Record the end of the clinit: point to the declaration of the class
+			codeStream.recordPositionsFrom(0, declaringType);
+			classFile.completeCodeAttributeForClinit(codeAttributeOffset);
+		}
+	} catch (AbortMethod e) {
+		// should never occur
+		// the clinit referenceContext is the type declaration
+		// All clinit problems will be reported against the type: AbortType instead of AbortMethod
+		// reset the contentsOffset to the value before generating the clinit code
+		// decrement the number of method info as well.
+		// This is done in the addProblemMethod and addProblemConstructor for other
+		// cases.
+		classFile.contentsOffset = clinitOffset;
+		classFile.methodCount--;	
+	}
+}
+public boolean isClinit() {
+	return true;
+}
+public boolean isInitializationMethod(){
+	return true;
+}
+public boolean isStatic() {
+	return true;
+}
+public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
+	//the clinit is filled by hand .... 
+}
+public void resolve(ClassScope scope) {
+	this.scope = new MethodScope(scope, scope.referenceContext, true);
+}
+public String toString(int tab){
+	/* slow code */
+
+	String s = ""/*nonNLS*/ ;
+	s = s + tabString(tab);
+	s = s + "<clinit>()"/*nonNLS*/ ;
+	s = s + toStringStatements(tab + 1);
+	return s ;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
+	visitor.visit(this, classScope);
+	visitor.endVisit(this, classScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 5fe113f..6e4b189 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -1,234 +1,233 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class CompilationUnitDeclaration extends AstNode implements ProblemSeverities, ReferenceContext {
-	public ImportReference currentPackage;
-	public ImportReference[] imports;
-	public TypeDeclaration[] types;
-	//public char[][] name;
-	
-	public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors
-	public boolean ignoreMethodBodies = false;
-	/*
-	lookup is done first in the CompilationUnit then 
-	on the explicit import types then in the current
-	pakage and finaly into the on demand imports.
-	*/
-	public CompilationUnitScope scope;
-	public ProblemReporter problemReporter;
-	public CompilationResult compilationResult;
-	//public ProblemHandler.Policy handlingPolicy;
-
-	private LocalTypeBinding[] allLocalTypes;
-	public boolean isPropagatingInnerClassEmulation;
-public CompilationUnitDeclaration(ProblemReporter problemReporter, CompilationResult compilationResult, int sourceLength) {
-
-	this.problemReporter = problemReporter;
-	this.compilationResult = compilationResult;
-	
-	//by definition of a compilation unit....
-	sourceStart = 0;
-	sourceEnd = sourceLength - 1;
-	
-}
-/*
- *	We cause the compilation task to abort to a given extent.
- */
-public void abort(int abortLevel) {
-
-	switch (abortLevel) {
-		case AbortType :
-			throw new AbortType(compilationResult);
-		case AbortMethod :
-			throw new AbortMethod(compilationResult);
-		default :
-			throw new AbortCompilationUnit(compilationResult);
-	}
-}
-/*
- * Dispatch code analysis AND request saturation of inner emulation
- */
-public void analyseCode() {
-	if (ignoreFurtherInvestigation)
-		return;
-	try {
-		if (types != null) {
-			for (int i = 0, count = types.length; i < count; i++) {
-				types[i].analyseCode(scope);
-			}
-		}
-		// request inner emulation propagation
-		propagateInnerEmulationForAllLocalTypes();
-	} catch (AbortCompilationUnit e) {
-		this.ignoreFurtherInvestigation = true;		
-		return;
-	}
-}
-/*
- * When unit result is about to be accepted, removed back pointers
- * to compiler structures.
- */
-public void cleanUp() {
-
-	ClassFile[] classFiles = compilationResult.getClassFiles();
-	for (int i = 0, max = classFiles.length; i < max; i++){
-		// clear the classFile back pointer to the bindings
-		ClassFile classFile = classFiles[i];
-		// null out the type's scope backpointers
-	 	((SourceTypeBinding) classFile.referenceBinding).scope = null;
-		// null out the classfile backpointer to a type binding
-		classFile.referenceBinding = null;
-		classFile.codeStream = null; // codeStream holds onto ast and scopes
-		classFile.innerClassesBindings = null;
-	}
-}
-public CompilationResult compilationResult(){
-	return compilationResult;
-}
-/*
- * Finds the matching type amoung this compilation unit types.
- * Returns null if no type with this name is found.
- * The type name is a compound name
- * eg. if we're looking for X.A.B then a type name would be {X, A, B}
- */
-public TypeDeclaration declarationOfType(char[][] typeName) {
-	for (int i = 0; i < this.types.length; i++) {
-		TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
-		if (typeDecl != null) {
-			return typeDecl;
-		}
-	}
-	return null;
-}
-/**
- * Bytecode generation
- */
-public void generateCode() {
-	if (ignoreFurtherInvestigation) {
-		if (types != null) {
-			for (int i = 0, count = types.length; i < count; i++){
-				types[i].ignoreFurtherInvestigation = true; // propagate the flag to request problem type creation
-				types[i].generateCode(scope);
-			}
-		}
-		return;
-	}
-	try {
-		if (types != null) {
-			for (int i = 0, count = types.length; i < count; i++)
-				types[i].generateCode(scope);
-		}
-	} catch (AbortCompilationUnit e) {
-	}
-}
-public char[] getFileName() {
-	return compilationResult.getFileName();
-}
-public char[] getMainTypeName() {
-	if (compilationResult.compilationUnit == null) {
-		char[] fileName = compilationResult.getFileName();
-
-		int start = CharOperation.lastIndexOf('/', fileName) + 1;
-		if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
-			start = CharOperation.lastIndexOf('\\', fileName) + 1;
-
-		int end = CharOperation.lastIndexOf('.', fileName);
-		if (end == -1)
-			end = fileName.length;
-
-		return CharOperation.subarray(fileName, start, end);
-	} else {
-		return compilationResult.compilationUnit.getMainTypeName();
-	}
-}
-public boolean isEmpty() {
-	
-	return 	(currentPackage == null) 
-			&& (imports == null)
-			&& (types == null);}
-/*
- * Force inner local types to update their innerclass emulation
- */
-public void propagateInnerEmulationForAllLocalTypes() {
-
-	isPropagatingInnerClassEmulation = true;
-	if (allLocalTypes != null) {
-		for (int i = 0, max = allLocalTypes.length; i < max; i++) {
-			allLocalTypes[i].updateInnerEmulationDependents();
-		}
-	}
-}
-/*
- * Keep track of all local types, so as to update their innerclass
- * emulation later on.
- */ 
-public void record(LocalTypeBinding localType){
-	if (allLocalTypes == null){
-		allLocalTypes = new LocalTypeBinding[]{ localType };
-	} else {
-		int length = allLocalTypes.length;
-		System.arraycopy(allLocalTypes, 0, (allLocalTypes = new LocalTypeBinding[length+1]), 0, length);
-		allLocalTypes[length] = localType; 
-	}
-}
-public void resolve() {
-	try {
-		if (types != null)
-			for (int i = 0, count = types.length; i < count; i++)
-				types[i].resolve(scope);
-	} catch (AbortCompilationUnit e) {
-		this.ignoreFurtherInvestigation = true;
-		return;
-	}
-}
-public void tagAsHavingErrors(){
-	ignoreFurtherInvestigation = true;
-}
-public String toString(int tab) {
-	/*very slow code*/
-
-	String s = ""/*nonNLS*/;
-	if (currentPackage != null)
-		s = tabString(tab) + "package "/*nonNLS*/ + currentPackage.toString(0, false) + ";\n"/*nonNLS*/;
-
-	if (imports != null)
-		for (int i = 0; i < imports.length; i++) {
-			s += tabString(tab) + "import "/*nonNLS*/ + imports[i].toString() + ";\n"/*nonNLS*/;
-		};
-
-	if (types != null)
-		for (int i = 0; i < types.length; i++) {
-			s +=  types[i].toString(tab) + "\n"/*nonNLS*/;
-		}
-	return s;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) {
-	if (ignoreFurtherInvestigation)
-		return;
-	try {
-		if (visitor.visit(this, scope)) {
-			if (imports != null) {
-				int importLength = imports.length;
-				for (int i = 0; i < importLength; i++)
-					imports[i].traverse(visitor, scope);
-			}
-			if (types != null) {
-				int typesLength = types.length;
-				for (int i = 0; i < typesLength; i++)
-					types[i].traverse(visitor, scope);
-			}
-		}
-	} catch (AbortCompilationUnit e) {
-	}
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class CompilationUnitDeclaration extends AstNode implements ProblemSeverities, ReferenceContext {
+	public ImportReference currentPackage;
+	public ImportReference[] imports;
+	public TypeDeclaration[] types;
+	//public char[][] name;
+	
+	public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors
+	public boolean ignoreMethodBodies = false;
+	/*
+	lookup is done first in the CompilationUnit then 
+	on the explicit import types then in the current
+	pakage and finaly into the on demand imports.
+	*/
+	public CompilationUnitScope scope;
+	public ProblemReporter problemReporter;
+	public CompilationResult compilationResult;
+	//public ProblemHandler.Policy handlingPolicy;
+
+	private LocalTypeBinding[] allLocalTypes;
+	public boolean isPropagatingInnerClassEmulation;
+public CompilationUnitDeclaration(ProblemReporter problemReporter, CompilationResult compilationResult, int sourceLength) {
+
+	this.problemReporter = problemReporter;
+	this.compilationResult = compilationResult;
+	
+	//by definition of a compilation unit....
+	sourceStart = 0;
+	sourceEnd = sourceLength - 1;
+	
+}
+/*
+ *	We cause the compilation task to abort to a given extent.
+ */
+public void abort(int abortLevel) {
+
+	switch (abortLevel) {
+		case AbortType :
+			throw new AbortType(compilationResult);
+		case AbortMethod :
+			throw new AbortMethod(compilationResult);
+		default :
+			throw new AbortCompilationUnit(compilationResult);
+	}
+}
+/*
+ * Dispatch code analysis AND request saturation of inner emulation
+ */
+public void analyseCode() {
+	if (ignoreFurtherInvestigation)
+		return;
+	try {
+		if (types != null) {
+			for (int i = 0, count = types.length; i < count; i++) {
+				types[i].analyseCode(scope);
+			}
+		}
+		// request inner emulation propagation
+		propagateInnerEmulationForAllLocalTypes();
+	} catch (AbortCompilationUnit e) {
+		this.ignoreFurtherInvestigation = true;		
+		return;
+	}
+}
+/*
+ * When unit result is about to be accepted, removed back pointers
+ * to compiler structures.
+ */
+public void cleanUp() {
+
+	ClassFile[] classFiles = compilationResult.getClassFiles();
+	for (int i = 0, max = classFiles.length; i < max; i++){
+		// clear the classFile back pointer to the bindings
+		ClassFile classFile = classFiles[i];
+		// null out the type's scope backpointers
+	 	((SourceTypeBinding) classFile.referenceBinding).scope = null;
+		// null out the classfile backpointer to a type binding
+		classFile.referenceBinding = null;
+		classFile.codeStream = null; // codeStream holds onto ast and scopes
+		classFile.innerClassesBindings = null;
+	}
+}
+public CompilationResult compilationResult(){
+	return compilationResult;
+}
+/*
+ * Finds the matching type amoung this compilation unit types.
+ * Returns null if no type with this name is found.
+ * The type name is a compound name
+ * eg. if we're looking for X.A.B then a type name would be {X, A, B}
+ */
+public TypeDeclaration declarationOfType(char[][] typeName) {
+	for (int i = 0; i < this.types.length; i++) {
+		TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
+		if (typeDecl != null) {
+			return typeDecl;
+		}
+	}
+	return null;
+}
+/**
+ * Bytecode generation
+ */
+public void generateCode() {
+	if (ignoreFurtherInvestigation) {
+		if (types != null) {
+			for (int i = 0, count = types.length; i < count; i++){
+				types[i].ignoreFurtherInvestigation = true; // propagate the flag to request problem type creation
+				types[i].generateCode(scope);
+			}
+		}
+		return;
+	}
+	try {
+		if (types != null) {
+			for (int i = 0, count = types.length; i < count; i++)
+				types[i].generateCode(scope);
+		}
+	} catch (AbortCompilationUnit e) {
+	}
+}
+public char[] getFileName() {
+	return compilationResult.getFileName();
+}
+public char[] getMainTypeName() {
+	if (compilationResult.compilationUnit == null) {
+		char[] fileName = compilationResult.getFileName();
+
+		int start = CharOperation.lastIndexOf('/', fileName) + 1;
+		if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
+			start = CharOperation.lastIndexOf('\\', fileName) + 1;
+
+		int end = CharOperation.lastIndexOf('.', fileName);
+		if (end == -1)
+			end = fileName.length;
+
+		return CharOperation.subarray(fileName, start, end);
+	} else {
+		return compilationResult.compilationUnit.getMainTypeName();
+	}
+}
+public boolean isEmpty() {
+	
+	return 	(currentPackage == null) 
+			&& (imports == null)
+			&& (types == null);}
+/*
+ * Force inner local types to update their innerclass emulation
+ */
+public void propagateInnerEmulationForAllLocalTypes() {
+
+	isPropagatingInnerClassEmulation = true;
+	if (allLocalTypes != null) {
+		for (int i = 0, max = allLocalTypes.length; i < max; i++) {
+			allLocalTypes[i].updateInnerEmulationDependents();
+		}
+	}
+}
+/*
+ * Keep track of all local types, so as to update their innerclass
+ * emulation later on.
+ */ 
+public void record(LocalTypeBinding localType){
+	if (allLocalTypes == null){
+		allLocalTypes = new LocalTypeBinding[]{ localType };
+	} else {
+		int length = allLocalTypes.length;
+		System.arraycopy(allLocalTypes, 0, (allLocalTypes = new LocalTypeBinding[length+1]), 0, length);
+		allLocalTypes[length] = localType; 
+	}
+}
+public void resolve() {
+	try {
+		if (types != null)
+			for (int i = 0, count = types.length; i < count; i++)
+				types[i].resolve(scope);
+	} catch (AbortCompilationUnit e) {
+		this.ignoreFurtherInvestigation = true;
+		return;
+	}
+}
+public void tagAsHavingErrors(){
+	ignoreFurtherInvestigation = true;
+}
+public String toString(int tab) {
+	/*very slow code*/
+
+	String s = ""/*nonNLS*/;
+	if (currentPackage != null)
+		s = tabString(tab) + "package "/*nonNLS*/ + currentPackage.toString(0, false) + ";\n"/*nonNLS*/;
+
+	if (imports != null)
+		for (int i = 0; i < imports.length; i++) {
+			s += tabString(tab) + "import "/*nonNLS*/ + imports[i].toString() + ";\n"/*nonNLS*/;
+		};
+
+	if (types != null)
+		for (int i = 0; i < types.length; i++) {
+			s +=  types[i].toString(tab) + "\n"/*nonNLS*/;
+		}
+	return s;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) {
+	if (ignoreFurtherInvestigation)
+		return;
+	try {
+		if (visitor.visit(this, scope)) {
+			if (imports != null) {
+				int importLength = imports.length;
+				for (int i = 0; i < importLength; i++)
+					imports[i].traverse(visitor, scope);
+			}
+			if (types != null) {
+				int typesLength = types.length;
+				for (int i = 0; i < typesLength; i++)
+					types[i].traverse(visitor, scope);
+			}
+		}
+	} catch (AbortCompilationUnit e) {
+	}
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index 8f3df73..299db39 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -1,132 +1,131 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class CompoundAssignment extends Assignment implements OperatorIds {
-	public int operator;
-	public int assignmentImplicitConversion;
-
-	//  var op exp is equivalent to var = (varType) var op exp
-	// assignmentImplicitConversion stores the cast needed for the assignment
-
-public CompoundAssignment(Expression lhs, Expression expression,int operator) {
-	//lhs is always a reference by construction ,
-	//but is build as an expression ==> the checkcast cannot fail
-
-	super(lhs, expression);
-	this.operator = operator ;
-	
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	// record setting a variable: various scenarii are possible, setting an array reference, 
-	// a field reference, a blank final field reference, a field of an enclosing instance or 
-	// just a local variable.
-
-	return lhs.analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
-}
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	// various scenarii are possible, setting an array reference, 
-	// a field reference, a blank final field reference, a field of an enclosing instance or 
-	// just a local variable.
-
-	int pc = codeStream.position;
-	lhs.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
-	if (valueRequired) {
-		codeStream.generateImplicitConversion(implicitConversion);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public String operatorToString() {
-	switch (operator) {
-		case PLUS :
-			return "+="/*nonNLS*/;
-		case MINUS :
-			return "-="/*nonNLS*/;
-		case MULTIPLY :
-			return "*="/*nonNLS*/;
-		case DIVIDE :
-			return "/="/*nonNLS*/;
-		case AND :
-			return "&="/*nonNLS*/;
-		case OR :
-			return "|="/*nonNLS*/;
-		case XOR :
-			return "^="/*nonNLS*/;
-		case REMAINDER :
-			return "%="/*nonNLS*/;
-		case LEFT_SHIFT :
-			return "<<="/*nonNLS*/;
-		case RIGHT_SHIFT :
-			return ">>="/*nonNLS*/;
-		case UNSIGNED_RIGHT_SHIFT :
-			return ">>>="/*nonNLS*/;
-	};
-	return "unknown operator"/*nonNLS*/;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	constant = NotAConstant;
-	TypeBinding lhsTb = lhs.resolveType(scope);
-	TypeBinding expressionTb = expression.resolveType(scope);
-	if (lhsTb == null || expressionTb == null)
-		return null;
-
-	int lhsId = lhsTb.id;
-	int expressionId = expressionTb.id;
-	if (restrainUsageToNumericTypes() && !lhsTb.isNumericType()) {
-		scope.problemReporter().operatorOnlyValidOnNumericType(this, lhsTb, expressionTb);
-		return null;
-	}
-	if (lhsId > 15 || expressionId > 15) {
-		if (lhsId != T_String) { // String += Object is valid wheraas Object -= String is not
-			scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
-			return null;
-		}
-		expressionId = T_Object; // use the Object has tag table
-	}
-
-	// the code is an int
-	// (cast)  left   Op (cast)  rigth --> result 
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8     <<4        <<0
-
-	// the conversion is stored INTO the reference (info needed for the code gen)
-	int result = OperatorExpression.ResolveTypeTables[operator][ (lhsId << 4) + expressionId];
-	if (result == T_undefined) {
-		scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
-		return null;
-	}
-	if (operator == PLUS && scope.isJavaLangObject(lhsTb)) {
-		// Object o = "hello"; 
-		// o += " world"  // <--illegal
-		scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
-		return null;
-	}
-	lhs.implicitConversion = result >>> 12;
-	expression.implicitConversion = (result >>> 4) & 0x000FF;
-	assignmentImplicitConversion = (lhsId << 4) + (result & 0x0000F);
-	return lhsTb;
-}
-public boolean restrainUsageToNumericTypes(){
-	return false ;}
-public String toStringExpressionNoParenthesis() {
-
-	return 	lhs.toStringExpression() + " "/*nonNLS*/ +
-			operatorToString() + " "/*nonNLS*/ +
-			expression.toStringExpression() ; }
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		lhs.traverse(visitor, scope);
-		expression.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompoundAssignment extends Assignment implements OperatorIds {
+	public int operator;
+	public int assignmentImplicitConversion;
+
+	//  var op exp is equivalent to var = (varType) var op exp
+	// assignmentImplicitConversion stores the cast needed for the assignment
+
+public CompoundAssignment(Expression lhs, Expression expression,int operator) {
+	//lhs is always a reference by construction ,
+	//but is build as an expression ==> the checkcast cannot fail
+
+	super(lhs, expression);
+	this.operator = operator ;
+	
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// record setting a variable: various scenarii are possible, setting an array reference, 
+	// a field reference, a blank final field reference, a field of an enclosing instance or 
+	// just a local variable.
+
+	return lhs.analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	// various scenarii are possible, setting an array reference, 
+	// a field reference, a blank final field reference, a field of an enclosing instance or 
+	// just a local variable.
+
+	int pc = codeStream.position;
+	lhs.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public String operatorToString() {
+	switch (operator) {
+		case PLUS :
+			return "+="/*nonNLS*/;
+		case MINUS :
+			return "-="/*nonNLS*/;
+		case MULTIPLY :
+			return "*="/*nonNLS*/;
+		case DIVIDE :
+			return "/="/*nonNLS*/;
+		case AND :
+			return "&="/*nonNLS*/;
+		case OR :
+			return "|="/*nonNLS*/;
+		case XOR :
+			return "^="/*nonNLS*/;
+		case REMAINDER :
+			return "%="/*nonNLS*/;
+		case LEFT_SHIFT :
+			return "<<="/*nonNLS*/;
+		case RIGHT_SHIFT :
+			return ">>="/*nonNLS*/;
+		case UNSIGNED_RIGHT_SHIFT :
+			return ">>>="/*nonNLS*/;
+	};
+	return "unknown operator"/*nonNLS*/;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	constant = NotAConstant;
+	TypeBinding lhsTb = lhs.resolveType(scope);
+	TypeBinding expressionTb = expression.resolveType(scope);
+	if (lhsTb == null || expressionTb == null)
+		return null;
+
+	int lhsId = lhsTb.id;
+	int expressionId = expressionTb.id;
+	if (restrainUsageToNumericTypes() && !lhsTb.isNumericType()) {
+		scope.problemReporter().operatorOnlyValidOnNumericType(this, lhsTb, expressionTb);
+		return null;
+	}
+	if (lhsId > 15 || expressionId > 15) {
+		if (lhsId != T_String) { // String += Object is valid wheraas Object -= String is not
+			scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
+			return null;
+		}
+		expressionId = T_Object; // use the Object has tag table
+	}
+
+	// the code is an int
+	// (cast)  left   Op (cast)  rigth --> result 
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8     <<4        <<0
+
+	// the conversion is stored INTO the reference (info needed for the code gen)
+	int result = OperatorExpression.ResolveTypeTables[operator][ (lhsId << 4) + expressionId];
+	if (result == T_undefined) {
+		scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
+		return null;
+	}
+	if (operator == PLUS && scope.isJavaLangObject(lhsTb)) {
+		// Object o = "hello"; 
+		// o += " world"  // <--illegal
+		scope.problemReporter().invalidOperator(this, lhsTb, expressionTb);
+		return null;
+	}
+	lhs.implicitConversion = result >>> 12;
+	expression.implicitConversion = (result >>> 4) & 0x000FF;
+	assignmentImplicitConversion = (lhsId << 4) + (result & 0x0000F);
+	return lhsTb;
+}
+public boolean restrainUsageToNumericTypes(){
+	return false ;}
+public String toStringExpressionNoParenthesis() {
+
+	return 	lhs.toStringExpression() + " "/*nonNLS*/ +
+			operatorToString() + " "/*nonNLS*/ +
+			expression.toStringExpression() ; }
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		lhs.traverse(visitor, scope);
+		expression.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 78f8785..df91fb9 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -1,297 +1,296 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.parser.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class ConstructorDeclaration extends AbstractMethodDeclaration {
-	public ExplicitConstructorCall constructorCall;
-	public final static char[] ConstantPoolName = "<init>"/*nonNLS*/.toCharArray();
-	public boolean isDefaultConstructor = false;
-
-	public int referenceCount = 0; // count how many times this constructor is referenced from other local constructors
-public void analyseCode(ClassScope classScope, InitializationFlowContext initializerFlowContext, FlowInfo flowInfo) {
-	if (ignoreFurtherInvestigation)
-		return;
-	try {
-		ExceptionHandlingFlowContext constructorContext = new ExceptionHandlingFlowContext(
-			initializerFlowContext.parent, 
-			this, 
-			binding.thrownExceptions, 
-			scope,
-			FlowInfo.DeadEnd);
-		initializerFlowContext.checkInitializerExceptions(scope, constructorContext, flowInfo);
-		
-		// propagate to constructor call
-		if (constructorCall != null) {
-			// if calling 'this(...)', then flag all non-static fields as definitely
-			// set since they are supposed to be set inside other local constructor
-			if (constructorCall.accessMode == ExplicitConstructorCall.This) {
-				FieldBinding[] fields = binding.declaringClass.fields();
-				for (int i = 0, count = fields.length; i < count; i++) {
-					FieldBinding field;
-					if (!(field = fields[i]).isStatic()) {
-						flowInfo.markAsDefinitelyAssigned(field);
-					}
-				}
-			}
-			flowInfo = constructorCall.analyseCode(scope, constructorContext, flowInfo);
-		}
-		// propagate to statements
-		if (statements != null){
-			for (int i = 0, count = statements.length; i < count; i++) {
-				Statement stat;
-				if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope)) {
-					flowInfo = stat.analyseCode(scope, constructorContext, flowInfo);
-				}
-			}
-		}
-		// check for missing returning path
-		needFreeReturn = !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
-
-		// check missing blank final field initializations
-		if ((constructorCall != null) && (constructorCall.accessMode != ExplicitConstructorCall.This)){
-			flowInfo = flowInfo.mergedWith(initializerFlowContext.initsOnReturn);
-			FieldBinding[] fields = binding.declaringClass.fields();
-			for (int i = 0, count = fields.length; i < count; i++) {
-				FieldBinding field;
-				if ((!(field = fields[i]).isStatic())
-					&& field.isFinal()
-					&& (!flowInfo.isDefinitelyAssigned(fields[i]))) {
-					scope.problemReporter().uninitializedBlankFinalField(field, isDefaultConstructor ? (AstNode)scope.referenceType() : this);
-				}
-			}
-		}
-	} catch (AbortMethod e) {
-		this.ignoreFurtherInvestigation = true;		
-	}
-}
-public void checkName() {
-	//look if the name of the method is correct
-	//and proceed with the resolution of the special constructor statement 
-
-	if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector))
-		scope.problemReporter().missingReturnType(this);
-
-	// if null ==> an error has occurs at parsing time ....
-	if (constructorCall != null){
-		// e.g. using super() in java.lang.Object
-		if ((binding.declaringClass.id == T_Object) 
-			&& (constructorCall.accessMode != ExplicitConstructorCall.This)){
-			if (constructorCall.accessMode == ExplicitConstructorCall.Super){
-				scope.problemReporter().cannotUseSuperInJavaLangObject(constructorCall);
-			}
-			constructorCall = null;
-			return;
-		}
-		constructorCall.resolve(scope);
-	}
-}
-/**
- * Bytecode generation for a constructor
- *
- * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
- * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
- */
-public void generateCode(ClassScope classScope, ClassFile classFile) {
-	int problemResetPC = 0;
-	if (ignoreFurtherInvestigation) {
-		if (this.binding == null)
-			return; // Handle methods with invalid signature or duplicates
-		int problemsLength;
-		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
-		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
-		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
-		classFile.addProblemConstructor(this, binding, problemsCopy);
-		return;
-	}
-	try {
-		problemResetPC = classFile.contentsOffset;
-		classFile.generateMethodInfoHeader(binding);
-		int methodAttributeOffset = classFile.contentsOffset;
-		int attributeNumber = classFile.generateMethodInfoAttribute(binding);
-		if ((!binding.isNative()) && (!binding.isAbstract())) {
-			TypeDeclaration declaringType = classScope.referenceContext;
-			int codeAttributeOffset = classFile.contentsOffset;
-			classFile.generateCodeAttributeHeader();
-			CodeStream codeStream = classFile.codeStream;
-			codeStream.reset(this, classFile);
-			// initialize local positions - including initializer scope.
-			ReferenceBinding declaringClass = binding.declaringClass;
-			int argSize = 0;
-			scope.computeLocalVariablePositions(// consider synthetic arguments if any
-			argSize = declaringClass.isNestedType() ? ((NestedTypeBinding) declaringClass).syntheticArgumentsOffset : 1, codeStream);
-			if (arguments != null) {
-				for (int i = 0, max = arguments.length; i < max; i++) {
-					// arguments initialization for local variable debug attributes
-					LocalVariableBinding argBinding;
-					codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding);
-					argBinding.recordInitializationStartPC(0);
-					TypeBinding argType;
-					if ((argType = argBinding.type) == LongBinding || (argType == DoubleBinding)) {
-						argSize += 2;
-					} else {
-						argSize++;
-					}
-				}
-			}
-			MethodScope initializerScope = declaringType.initializerScope;
-			initializerScope.computeLocalVariablePositions(argSize, codeStream); // offset by the argument size (since not linked to method scope)
-
-			// generate constructor call
-			if (constructorCall != null) {
-				constructorCall.generateCode(scope, codeStream);
-			}
-			// generate field initialization - only if not invoking another constructor call of the same class
-			if ((constructorCall != null) && (constructorCall.accessMode != ExplicitConstructorCall.This)) {
-				// generate synthetic fields initialization
-				if (declaringClass.isNestedType()) {
-					NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
-					SyntheticArgumentBinding[] syntheticArgs = nestedType.syntheticEnclosingInstances();
-					for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
-						if (syntheticArgs[i].matchingField != null) {
-							codeStream.aload_0();
-							codeStream.load(syntheticArgs[i]);
-							codeStream.putfield(syntheticArgs[i].matchingField);
-						}
-					}
-					syntheticArgs = nestedType.syntheticOuterLocalVariables();
-					for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
-						if (syntheticArgs[i].matchingField != null) {
-							codeStream.aload_0();
-							codeStream.load(syntheticArgs[i]);
-							codeStream.putfield(syntheticArgs[i].matchingField);
-						}
-					}
-				}
-				// generate user field initialization
-				if (declaringType.fields != null) {
-					for (int i = 0, max = declaringType.fields.length; i < max; i++) {
-						FieldDeclaration fieldDecl;
-						if (!(fieldDecl = declaringType.fields[i]).isStatic()) {
-							fieldDecl.generateCode(initializerScope, codeStream);
-						}
-					}
-				}
-			}
-			// generate statements
-			if (statements != null) {
-				for (int i = 0, max = statements.length; i < max; i++) {
-					statements[i].generateCode(scope, codeStream);
-				}
-			}
-			if (needFreeReturn) {
-				codeStream.return_();
-			}
-			// local variable attributes
-			codeStream.exitUserScope(scope);
-			codeStream.recordPositionsFrom(0, this);
-			classFile.completeCodeAttribute(codeAttributeOffset);
-			attributeNumber++;
-		}
-		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
-
-		// if a problem got reported during code gen, then trigger problem method creation
-		if (ignoreFurtherInvestigation){
-			throw new AbortMethod(scope.referenceCompilationUnit().compilationResult);
-		}
-	} catch (AbortMethod e) {
-		int problemsLength;
-		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
-		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
-		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
-		classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC);
-	}
-}
-public boolean isConstructor() {
-	return true;
-}
-public boolean isDefaultConstructor() {
-	return isDefaultConstructor;
-}
-public boolean isInitializationMethod() {
-	return true;
-}
-public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
-	//fill up the constructor body with its statements
-
-	if (ignoreFurtherInvestigation) return;
-	if (isDefaultConstructor ) return ;
-	parser.parse(this, unit);
-	
-}
-/*
- * Type checking for constructor, just another method, except for special check
- * for recursive constructor invocations.
- */
-public void resolve(ClassScope upperScope) {
-	
-	if (binding == null) {
-		ignoreFurtherInvestigation = true;
-		return;
-	}
-
-	super.resolve(upperScope);
-
-	try {
-		// checking for recursive constructor call
-		if (constructorCall != null) {
-			// indirect reference: increment target constructor reference count
-			if (constructorCall.binding != null && !constructorCall.isSuperAccess() && constructorCall.binding.isValidBinding()) {
-				((ConstructorDeclaration) (upperScope.referenceContext.declarationOf(constructorCall.binding))).referenceCount++;
-			}		
-		}
-	} catch (AbortMethod e) {
-		this.ignoreFurtherInvestigation = true;		
-	}
-}
-public String toStringStatements(int tab) {
-	/* slow code */
-
-	String s = " {"/*nonNLS*/;
-	if (constructorCall != null) {
-		s = s + "\n"/*nonNLS*/ + constructorCall.toString(tab) + ";"/*nonNLS*/;
-	}
-	if (statements != null){
-		for (int i = 0; i < statements.length; i++){
-			s = s + "\n"/*nonNLS*/ + statements[i].toString(tab);
-			if (!(statements[i] instanceof Block)){
-				s += ";"/*nonNLS*/;
-			}
-		}
-	}
-	s+="\n"/*nonNLS*/+tabString(tab == 0 ? 0 : tab - 1)+"}"/*nonNLS*/;
-	return s;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
-	if (visitor.visit(this, classScope)) {
-		if (arguments != null) {
-			int argumentLength = arguments.length;
-			for (int i = 0; i < argumentLength; i++)
-				arguments[i].traverse(visitor, scope);
-		}
-		if (thrownExceptions != null) {
-			int thrownExceptionsLength = thrownExceptions.length;
-			for (int i = 0; i < thrownExceptionsLength; i++)
-				thrownExceptions[i].traverse(visitor, scope);
-		}
-		if (constructorCall != null)
-			constructorCall.traverse(visitor, scope);
-		if (statements != null) {
-			int statementsLength = statements.length;
-			for (int i = 0; i < statementsLength; i++)
-				statements[i].traverse(visitor, scope);
-		}
-	}
-	visitor.endVisit(this, classScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class ConstructorDeclaration extends AbstractMethodDeclaration {
+	public ExplicitConstructorCall constructorCall;
+	public final static char[] ConstantPoolName = "<init>"/*nonNLS*/.toCharArray();
+	public boolean isDefaultConstructor = false;
+
+	public int referenceCount = 0; // count how many times this constructor is referenced from other local constructors
+public void analyseCode(ClassScope classScope, InitializationFlowContext initializerFlowContext, FlowInfo flowInfo) {
+	if (ignoreFurtherInvestigation)
+		return;
+	try {
+		ExceptionHandlingFlowContext constructorContext = new ExceptionHandlingFlowContext(
+			initializerFlowContext.parent, 
+			this, 
+			binding.thrownExceptions, 
+			scope,
+			FlowInfo.DeadEnd);
+		initializerFlowContext.checkInitializerExceptions(scope, constructorContext, flowInfo);
+		
+		// propagate to constructor call
+		if (constructorCall != null) {
+			// if calling 'this(...)', then flag all non-static fields as definitely
+			// set since they are supposed to be set inside other local constructor
+			if (constructorCall.accessMode == ExplicitConstructorCall.This) {
+				FieldBinding[] fields = binding.declaringClass.fields();
+				for (int i = 0, count = fields.length; i < count; i++) {
+					FieldBinding field;
+					if (!(field = fields[i]).isStatic()) {
+						flowInfo.markAsDefinitelyAssigned(field);
+					}
+				}
+			}
+			flowInfo = constructorCall.analyseCode(scope, constructorContext, flowInfo);
+		}
+		// propagate to statements
+		if (statements != null){
+			for (int i = 0, count = statements.length; i < count; i++) {
+				Statement stat;
+				if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope)) {
+					flowInfo = stat.analyseCode(scope, constructorContext, flowInfo);
+				}
+			}
+		}
+		// check for missing returning path
+		needFreeReturn = !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
+
+		// check missing blank final field initializations
+		if ((constructorCall != null) && (constructorCall.accessMode != ExplicitConstructorCall.This)){
+			flowInfo = flowInfo.mergedWith(initializerFlowContext.initsOnReturn);
+			FieldBinding[] fields = binding.declaringClass.fields();
+			for (int i = 0, count = fields.length; i < count; i++) {
+				FieldBinding field;
+				if ((!(field = fields[i]).isStatic())
+					&& field.isFinal()
+					&& (!flowInfo.isDefinitelyAssigned(fields[i]))) {
+					scope.problemReporter().uninitializedBlankFinalField(field, isDefaultConstructor ? (AstNode)scope.referenceType() : this);
+				}
+			}
+		}
+	} catch (AbortMethod e) {
+		this.ignoreFurtherInvestigation = true;		
+	}
+}
+public void checkName() {
+	//look if the name of the method is correct
+	//and proceed with the resolution of the special constructor statement 
+
+	if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector))
+		scope.problemReporter().missingReturnType(this);
+
+	// if null ==> an error has occurs at parsing time ....
+	if (constructorCall != null){
+		// e.g. using super() in java.lang.Object
+		if ((binding.declaringClass.id == T_Object) 
+			&& (constructorCall.accessMode != ExplicitConstructorCall.This)){
+			if (constructorCall.accessMode == ExplicitConstructorCall.Super){
+				scope.problemReporter().cannotUseSuperInJavaLangObject(constructorCall);
+			}
+			constructorCall = null;
+			return;
+		}
+		constructorCall.resolve(scope);
+	}
+}
+/**
+ * Bytecode generation for a constructor
+ *
+ * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
+ * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+ */
+public void generateCode(ClassScope classScope, ClassFile classFile) {
+	int problemResetPC = 0;
+	if (ignoreFurtherInvestigation) {
+		if (this.binding == null)
+			return; // Handle methods with invalid signature or duplicates
+		int problemsLength;
+		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
+		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
+		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+		classFile.addProblemConstructor(this, binding, problemsCopy);
+		return;
+	}
+	try {
+		problemResetPC = classFile.contentsOffset;
+		classFile.generateMethodInfoHeader(binding);
+		int methodAttributeOffset = classFile.contentsOffset;
+		int attributeNumber = classFile.generateMethodInfoAttribute(binding);
+		if ((!binding.isNative()) && (!binding.isAbstract())) {
+			TypeDeclaration declaringType = classScope.referenceContext;
+			int codeAttributeOffset = classFile.contentsOffset;
+			classFile.generateCodeAttributeHeader();
+			CodeStream codeStream = classFile.codeStream;
+			codeStream.reset(this, classFile);
+			// initialize local positions - including initializer scope.
+			ReferenceBinding declaringClass = binding.declaringClass;
+			int argSize = 0;
+			scope.computeLocalVariablePositions(// consider synthetic arguments if any
+			argSize = declaringClass.isNestedType() ? ((NestedTypeBinding) declaringClass).syntheticArgumentsOffset : 1, codeStream);
+			if (arguments != null) {
+				for (int i = 0, max = arguments.length; i < max; i++) {
+					// arguments initialization for local variable debug attributes
+					LocalVariableBinding argBinding;
+					codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding);
+					argBinding.recordInitializationStartPC(0);
+					TypeBinding argType;
+					if ((argType = argBinding.type) == LongBinding || (argType == DoubleBinding)) {
+						argSize += 2;
+					} else {
+						argSize++;
+					}
+				}
+			}
+			MethodScope initializerScope = declaringType.initializerScope;
+			initializerScope.computeLocalVariablePositions(argSize, codeStream); // offset by the argument size (since not linked to method scope)
+
+			// generate constructor call
+			if (constructorCall != null) {
+				constructorCall.generateCode(scope, codeStream);
+			}
+			// generate field initialization - only if not invoking another constructor call of the same class
+			if ((constructorCall != null) && (constructorCall.accessMode != ExplicitConstructorCall.This)) {
+				// generate synthetic fields initialization
+				if (declaringClass.isNestedType()) {
+					NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
+					SyntheticArgumentBinding[] syntheticArgs = nestedType.syntheticEnclosingInstances();
+					for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
+						if (syntheticArgs[i].matchingField != null) {
+							codeStream.aload_0();
+							codeStream.load(syntheticArgs[i]);
+							codeStream.putfield(syntheticArgs[i].matchingField);
+						}
+					}
+					syntheticArgs = nestedType.syntheticOuterLocalVariables();
+					for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
+						if (syntheticArgs[i].matchingField != null) {
+							codeStream.aload_0();
+							codeStream.load(syntheticArgs[i]);
+							codeStream.putfield(syntheticArgs[i].matchingField);
+						}
+					}
+				}
+				// generate user field initialization
+				if (declaringType.fields != null) {
+					for (int i = 0, max = declaringType.fields.length; i < max; i++) {
+						FieldDeclaration fieldDecl;
+						if (!(fieldDecl = declaringType.fields[i]).isStatic()) {
+							fieldDecl.generateCode(initializerScope, codeStream);
+						}
+					}
+				}
+			}
+			// generate statements
+			if (statements != null) {
+				for (int i = 0, max = statements.length; i < max; i++) {
+					statements[i].generateCode(scope, codeStream);
+				}
+			}
+			if (needFreeReturn) {
+				codeStream.return_();
+			}
+			// local variable attributes
+			codeStream.exitUserScope(scope);
+			codeStream.recordPositionsFrom(0, this);
+			classFile.completeCodeAttribute(codeAttributeOffset);
+			attributeNumber++;
+		}
+		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+
+		// if a problem got reported during code gen, then trigger problem method creation
+		if (ignoreFurtherInvestigation){
+			throw new AbortMethod(scope.referenceCompilationUnit().compilationResult);
+		}
+	} catch (AbortMethod e) {
+		int problemsLength;
+		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
+		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
+		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+		classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC);
+	}
+}
+public boolean isConstructor() {
+	return true;
+}
+public boolean isDefaultConstructor() {
+	return isDefaultConstructor;
+}
+public boolean isInitializationMethod() {
+	return true;
+}
+public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
+	//fill up the constructor body with its statements
+
+	if (ignoreFurtherInvestigation) return;
+	if (isDefaultConstructor ) return ;
+	parser.parse(this, unit);
+	
+}
+/*
+ * Type checking for constructor, just another method, except for special check
+ * for recursive constructor invocations.
+ */
+public void resolve(ClassScope upperScope) {
+	
+	if (binding == null) {
+		ignoreFurtherInvestigation = true;
+		return;
+	}
+
+	super.resolve(upperScope);
+
+	try {
+		// checking for recursive constructor call
+		if (constructorCall != null) {
+			// indirect reference: increment target constructor reference count
+			if (constructorCall.binding != null && !constructorCall.isSuperAccess() && constructorCall.binding.isValidBinding()) {
+				((ConstructorDeclaration) (upperScope.referenceContext.declarationOf(constructorCall.binding))).referenceCount++;
+			}		
+		}
+	} catch (AbortMethod e) {
+		this.ignoreFurtherInvestigation = true;		
+	}
+}
+public String toStringStatements(int tab) {
+	/* slow code */
+
+	String s = " {"/*nonNLS*/;
+	if (constructorCall != null) {
+		s = s + "\n"/*nonNLS*/ + constructorCall.toString(tab) + ";"/*nonNLS*/;
+	}
+	if (statements != null){
+		for (int i = 0; i < statements.length; i++){
+			s = s + "\n"/*nonNLS*/ + statements[i].toString(tab);
+			if (!(statements[i] instanceof Block)){
+				s += ";"/*nonNLS*/;
+			}
+		}
+	}
+	s+="\n"/*nonNLS*/+tabString(tab == 0 ? 0 : tab - 1)+"}"/*nonNLS*/;
+	return s;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
+	if (visitor.visit(this, classScope)) {
+		if (arguments != null) {
+			int argumentLength = arguments.length;
+			for (int i = 0; i < argumentLength; i++)
+				arguments[i].traverse(visitor, scope);
+		}
+		if (thrownExceptions != null) {
+			int thrownExceptionsLength = thrownExceptions.length;
+			for (int i = 0; i < thrownExceptionsLength; i++)
+				thrownExceptions[i].traverse(visitor, scope);
+		}
+		if (constructorCall != null)
+			constructorCall.traverse(visitor, scope);
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++)
+				statements[i].traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, classScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 29f43f2..bc1c248 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -1,545 +1,543 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class EqualExpression extends BinaryExpression {
-
-public EqualExpression(Expression left, Expression right,int operator) {
-	super(left,right,operator);
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
-		if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) {
-			if (left.constant.booleanValue()) { //  true == anything
-				//  this is equivalent to the right argument inits 
-				return right.analyseCode(currentScope, flowContext, flowInfo);
-			} else { // false == anything
-				//  this is equivalent to the right argument inits negated
-				return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
-			}
-		}
-		if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) {
-			if (right.constant.booleanValue()) { //  anything == true
-				//  this is equivalent to the right argument inits 
-				return left.analyseCode(currentScope, flowContext, flowInfo);
-			} else { // anything == false
-				//  this is equivalent to the right argument inits negated
-				return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
-			}
-		}
-		return right.analyseCode(
-			currentScope, flowContext, 
-			left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).unconditionalInits();
-	} else { //NOT_EQUAL :
-		if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) {
-			if (!left.constant.booleanValue()) { //  false != anything
-				//  this is equivalent to the right argument inits 
-				return right.analyseCode(currentScope, flowContext, flowInfo);
-			} else { // true != anything
-				//  this is equivalent to the right argument inits negated
-				return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
-			}
-		}
-		if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) {
-			if (!right.constant.booleanValue()) { //  anything != false
-				//  this is equivalent to the right argument inits 
-				return left.analyseCode(currentScope, flowContext, flowInfo);
-			} else { // anything != true
-				//  this is equivalent to the right argument inits negated
-				return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
-			}
-		}
-		return right.analyseCode(
-			currentScope, flowContext, 
-			left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).asNegatedCondition().unconditionalInits();
-	}
-}
-public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb, TypeBinding expressionTb) {
-	//see specifications p.68
-	//A more complete version of this method is provided on
-	//CastExpression (it deals with constant and need runtime checkcast)
-
-
-	//========ARRAY===============
-	if (expressionTb.isArrayType()) {
-		if (castTb.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
-			TypeBinding expressionEltTb = ((ArrayBinding) expressionTb).elementsType(scope);
-			if (expressionEltTb.isBaseType())
-				// <---stop the recursion------- 
-				return ((ArrayBinding) castTb).elementsType(scope) == expressionEltTb;
-			//recursivly on the elts...
-			return areTypesCastCompatible(scope, ((ArrayBinding) castTb).elementsType(scope), expressionEltTb);
-		}
-		if (castTb.isBaseType()) {
-			return false;
-		}
-		if (castTb.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------	
-			if (scope.isJavaLangObject(castTb))
-				return true;
-			return false;
-		}
-		if (castTb.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
-			if (scope.isJavaLangCloneable(castTb) || scope.isJavaIoSerializable(castTb)) {
-				return true;
-			}
-			return false;
-		}
-
-		//===houps=====
-		return false;
-	}
-
-
-	//------------(castType) null--------------
-	if (expressionTb == NullBinding) {
-		return !castTb.isBaseType();
-	}
-
-	//========BASETYPE==============
-	if (expressionTb.isBaseType()) {
-		return false;
-	}
-
-
-	//========REFERENCE TYPE===================
-
-	if (expressionTb.isClass()) {
-		if (castTb.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
-			if (scope.isJavaLangObject(expressionTb))
-				return true;
-		}
-		if (castTb.isBaseType()) {
-			return false;
-		}
-		if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ 
-			if (scope.areTypesCompatible(expressionTb, castTb))
-				return true;
-			else {
-				if (scope.areTypesCompatible(castTb, expressionTb)) {
-					return true;
-				}
-				return false;
-			}
-		}
-		if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------  
-			if (((ReferenceBinding) expressionTb).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
-				if (scope.areTypesCompatible(expressionTb, castTb))
-					return true;
-				return false;
-			} else {
-				return true;
-			}
-		}
-
-		//=========houps=============
-		return false;
-	}
-	if (expressionTb.isInterface()) {
-		if (castTb.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
-			if (scope.isJavaLangCloneable(expressionTb) || scope.isJavaIoSerializable(expressionTb))
-				//potential runtime error
-				{
-				return true;
-			}
-			return false;
-		}
-		if (castTb.isBaseType()) {
-			return false;
-		}
-		if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
-			if (scope.isJavaLangObject(castTb))
-				return true;
-			if (((ReferenceBinding) castTb).isFinal()) { //no subclass for castTb, thus compile-time check is valid
-				if (scope.areTypesCompatible(castTb, expressionTb)) {
-					return true;
-				}
-				return false;
-			}
-			return true;
-		}
-		if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
-			if (castTb != expressionTb && (scope.compareTypes(castTb, expressionTb) == NotRelated)) {
-				MethodBinding[] castTbMethods = ((ReferenceBinding) castTb).methods();
-				int castTbMethodsLength = castTbMethods.length;
-				MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionTb).methods();
-				int expressionTbMethodsLength = expressionTbMethods.length;
-				for (int i = 0; i < castTbMethodsLength; i++) {
-					for (int j = 0; j < expressionTbMethodsLength; j++) {
-						if (castTbMethods[i].selector == expressionTbMethods[j].selector) {
-							if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) {
-								if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) {
-									return false;
-								}
-							}
-						}
-					}
-				}
-			}
-			return true;
-		}
-
-
-		//=========hoops===========	
-		return false;
-	}
-
-	//==========HOUPS==========
-	return false;
-}
-public final void computeConstant(TypeBinding leftTb, TypeBinding rightTb){
-	if ((left.constant != NotAConstant) && (right.constant != NotAConstant)) {
-		constant =
-			Constant.computeConstantOperationEQUAL_EQUAL(
-				left.constant,
-				rightTb.id,
-				EQUAL_EQUAL,
-				right.constant,
-				rightTb.id);
-		if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL)
-			constant = Constant.fromValue(!constant.booleanValue());
-	} else {
-		constant = NotAConstant;
-	}
-}
-/**
- * Normal == or != code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	if (constant != NotAConstant) {
-		int pc = codeStream.position;
-		if (valueRequired) 
-			codeStream.generateConstant(constant, implicitConversion);
-		codeStream.recordPositionsFrom(pc, this);
-		return;
-	}
-	Label falseLabel = new Label(codeStream);
-	generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
-	if (valueRequired){
-		// comparison is TRUE 
-		codeStream.iconst_1();
-		if ((bits & ValueForReturnMASK) != 0){
-			codeStream.ireturn();
-			// comparison is FALSE
-			falseLabel.place();
-			codeStream.iconst_0();
-		} else {
-			Label endLabel = new Label(codeStream);
-			codeStream.goto_(endLabel);
-			codeStream.decrStackSize(1);
-			// comparison is FALSE
-			falseLabel.place();
-			codeStream.iconst_0();
-			endLabel.place();
-		}
-	}
-}
-/**
- * Boolean operator code generation
- *	Optimized operations are: == and !=
- */
-public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
-	int pc = codeStream.position;
-	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
-		if (constant.booleanValue() == true) {
-			// constant == true
-			if (valueRequired) {
-				if (falseLabel == null) {
-					// implicit falling through the FALSE case
-					if (trueLabel != null) {
-						codeStream.goto_(trueLabel);
-					}
-				}
-			}
-		} else {
-			// constant == false
-			if (valueRequired) {
-				if (falseLabel != null) {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.goto_(falseLabel);
-					}
-				}
-			}
-		}
-		codeStream.recordPositionsFrom(pc, this);
-		return;
-	}
-	if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
-		if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
-			generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
-		} else {
-			generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
-		}
-	} else {
-		if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
-			generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
-		} else {
-			generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-/**
- * Boolean generation for == with boolean operands
- *
- * Note this code does not optimize conditional constants !!!!
- */
-public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
-	int pc = codeStream.position;
-	// optimized cases: true == x, false == x
-	if (left.constant != NotAConstant) {
-		boolean inline = left.constant.booleanValue();
-		right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
-		codeStream.recordPositionsFrom(pc, this);
-		return;
-	} // optimized cases: x == true, x == false
-	if (right.constant != NotAConstant) {
-		boolean inline = right.constant.booleanValue();
-		left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
-		codeStream.recordPositionsFrom(pc, this);
-		return;
-	}
-	// default case
-	left.generateCode(currentScope, codeStream, valueRequired);
-	right.generateCode(currentScope, codeStream, valueRequired);
-	if (valueRequired) {
-		if (falseLabel == null) {
-			if (trueLabel != null) {
-				// implicit falling through the FALSE case
-				codeStream.if_icmpeq(trueLabel);
-			}
-		} else {
-			// implicit falling through the TRUE case
-			if (trueLabel == null) {
-				codeStream.if_icmpne(falseLabel);
-			} else {
-				// no implicit fall through TRUE/FALSE --> should never occur
-			}
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-/**
- * Boolean generation for == with non-boolean operands
- *
- */
-public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
-	int pc = codeStream.position;
-	Constant inline;
-	if ((inline = right.constant) != NotAConstant) {
-		// optimized case: x == null
-		if (right.constant == NullConstant.Default) {
-			left.generateCode(currentScope, codeStream, valueRequired);
-			if (valueRequired) {
-				if (falseLabel == null) {
-					if (trueLabel != null) {
-						// implicit falling through the FALSE case
-						codeStream.ifnull(trueLabel);
-					}
-				} else {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.ifnonnull(falseLabel);
-					} else {
-						// no implicit fall through TRUE/FALSE --> should never occur
-					}
-				}
-			}
-			codeStream.recordPositionsFrom(pc, this);
-			return;
-		}
-		// optimized case: x == 0
-		if (((left.implicitConversion >> 4) == T_int) && (inline.intValue() == 0)) {
-			left.generateCode(currentScope, codeStream, valueRequired);
-			if (valueRequired) {
-				if (falseLabel == null) {
-					if (trueLabel != null) {
-						// implicit falling through the FALSE case
-						codeStream.ifeq(trueLabel);
-					}
-				} else {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.ifne(falseLabel);
-					} else {
-						// no implicit fall through TRUE/FALSE --> should never occur
-					}
-				}
-			}
-			codeStream.recordPositionsFrom(pc, this);
-			return;
-		}
-	}
-	if ((inline = left.constant) != NotAConstant) {
-		// optimized case: null == x
-		if (left.constant == NullConstant.Default) {
-			right.generateCode(currentScope, codeStream, valueRequired);
-			if (valueRequired) {
-				if (falseLabel == null) {
-					if (trueLabel != null) {
-						// implicit falling through the FALSE case
-						codeStream.ifnull(trueLabel);
-					}
-				} else {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.ifnonnull(falseLabel);
-					} else {
-						// no implicit fall through TRUE/FALSE --> should never occur
-					}
-				}
-			}
-			codeStream.recordPositionsFrom(pc, this);
-			return;
-		}
-		// optimized case: 0 == x
-		if (((left.implicitConversion >> 4) == T_int)
-			&& (inline.intValue() == 0)) {
-			right.generateCode(currentScope, codeStream, valueRequired);
-			if (valueRequired) {
-				if (falseLabel == null) {
-					if (trueLabel != null) {
-						// implicit falling through the FALSE case
-						codeStream.ifeq(trueLabel);
-					}
-				} else {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.ifne(falseLabel);
-					} else {
-						// no implicit fall through TRUE/FALSE --> should never occur
-					}
-				}
-			}
-			codeStream.recordPositionsFrom(pc, this);
-			return;
-		}
-	}
-	// default case
-	left.generateCode(currentScope, codeStream, valueRequired);
-	right.generateCode(currentScope, codeStream, valueRequired);
-	if (valueRequired) {
-		if (falseLabel == null) {
-			if (trueLabel != null) {
-				// implicit falling through the FALSE case
-				switch (left.implicitConversion >> 4) { // operand runtime type
-					case T_int :
-						codeStream.if_icmpeq(trueLabel);
-						break;
-					case T_float :
-						codeStream.fcmpl();
-						codeStream.ifeq(trueLabel);
-						break;
-					case T_long :
-						codeStream.lcmp();
-						codeStream.ifeq(trueLabel);
-						break;
-					case T_double :
-						codeStream.dcmpl();
-						codeStream.ifeq(trueLabel);
-						break;
-					default :
-						codeStream.if_acmpeq(trueLabel);
-				}
-			}
-		} else {
-			// implicit falling through the TRUE case
-			if (trueLabel == null) {
-				switch (left.implicitConversion >> 4) { // operand runtime type
-					case T_int :
-						codeStream.if_icmpne(falseLabel);
-						break;
-					case T_float :
-						codeStream.fcmpl();
-						codeStream.ifne(falseLabel);
-						break;
-					case T_long :
-						codeStream.lcmp();
-						codeStream.ifne(falseLabel);
-						break;
-					case T_double :
-						codeStream.dcmpl();
-						codeStream.ifne(falseLabel);
-						break;
-					default :
-						codeStream.if_acmpne(falseLabel);
-				}
-			} else {
-				// no implicit fall through TRUE/FALSE --> should never occur
-			}
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public boolean isCompactableOperation() {
-	return false;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// always return BooleanBinding
-	TypeBinding leftTb = left.resolveType(scope);
-	TypeBinding rightTb = right.resolveType(scope);
-	if (leftTb == null || rightTb == null){
-		constant = NotAConstant;		
-		return null;
-	}
-
-	// both base type
-	if (leftTb.isBaseType() && rightTb.isBaseType()) {
-		// the code is an int
-		// (cast)  left   == (cast)  rigth --> result
-		//  0000   0000       0000   0000      0000
-		//  <<16   <<12       <<8    <<4       <<0
-		int result = ResolveTypeTables[EQUAL_EQUAL][ (leftTb.id << 4) + rightTb.id];
-		left.implicitConversion = result >>> 12;
-		right.implicitConversion = (result >>> 4) & 0x000FF;
-		bits |= result & 0xF;		
-		if ((result & 0x0000F) == T_undefined) {
-			constant = Constant.NotAConstant;
-			scope.problemReporter().invalidOperator(this, leftTb, rightTb);
-			return null;
-		}
-		computeConstant(leftTb, rightTb);
-		return BooleanBinding;
-	}
-
-	// Object references 
-	// spec 15.20.3
-	if (areTypesCastCompatible(scope, rightTb, leftTb) || areTypesCastCompatible(scope, leftTb, rightTb)) {
-		// (special case for String)
-		if ((rightTb.id == T_String) && (leftTb.id == T_String))
-			computeConstant(leftTb, rightTb);
-		else
-			constant = NotAConstant;
-		if (rightTb.id == T_String)
-			right.implicitConversion = String2String;
-		if (leftTb.id == T_String)
-			left.implicitConversion = String2String;
-		return BooleanBinding;
-	}
-	constant = NotAConstant;
-	scope.problemReporter().notCompatibleTypesError(this, leftTb, rightTb);
-	return null;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		left.traverse(visitor, scope);
-		right.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class EqualExpression extends BinaryExpression {
+
+public EqualExpression(Expression left, Expression right,int operator) {
+	super(left,right,operator);
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+		if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) {
+			if (left.constant.booleanValue()) { //  true == anything
+				//  this is equivalent to the right argument inits 
+				return right.analyseCode(currentScope, flowContext, flowInfo);
+			} else { // false == anything
+				//  this is equivalent to the right argument inits negated
+				return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+			}
+		}
+		if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) {
+			if (right.constant.booleanValue()) { //  anything == true
+				//  this is equivalent to the right argument inits 
+				return left.analyseCode(currentScope, flowContext, flowInfo);
+			} else { // anything == false
+				//  this is equivalent to the right argument inits negated
+				return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+			}
+		}
+		return right.analyseCode(
+			currentScope, flowContext, 
+			left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).unconditionalInits();
+	} else { //NOT_EQUAL :
+		if ((left.constant != NotAConstant) && (left.constant.typeID() == T_boolean)) {
+			if (!left.constant.booleanValue()) { //  false != anything
+				//  this is equivalent to the right argument inits 
+				return right.analyseCode(currentScope, flowContext, flowInfo);
+			} else { // true != anything
+				//  this is equivalent to the right argument inits negated
+				return right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+			}
+		}
+		if ((right.constant != NotAConstant) && (right.constant.typeID() == T_boolean)) {
+			if (!right.constant.booleanValue()) { //  anything != false
+				//  this is equivalent to the right argument inits 
+				return left.analyseCode(currentScope, flowContext, flowInfo);
+			} else { // anything != true
+				//  this is equivalent to the right argument inits negated
+				return left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+			}
+		}
+		return right.analyseCode(
+			currentScope, flowContext, 
+			left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).asNegatedCondition().unconditionalInits();
+	}
+}
+public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb, TypeBinding expressionTb) {
+	//see specifications p.68
+	//A more complete version of this method is provided on
+	//CastExpression (it deals with constant and need runtime checkcast)
+
+
+	//========ARRAY===============
+	if (expressionTb.isArrayType()) {
+		if (castTb.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
+			TypeBinding expressionEltTb = ((ArrayBinding) expressionTb).elementsType(scope);
+			if (expressionEltTb.isBaseType())
+				// <---stop the recursion------- 
+				return ((ArrayBinding) castTb).elementsType(scope) == expressionEltTb;
+			//recursivly on the elts...
+			return areTypesCastCompatible(scope, ((ArrayBinding) castTb).elementsType(scope), expressionEltTb);
+		}
+		if (castTb.isBaseType()) {
+			return false;
+		}
+		if (castTb.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------	
+			if (scope.isJavaLangObject(castTb))
+				return true;
+			return false;
+		}
+		if (castTb.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
+			if (scope.isJavaLangCloneable(castTb) || scope.isJavaIoSerializable(castTb)) {
+				return true;
+			}
+			return false;
+		}
+
+		//===houps=====
+		return false;
+	}
+
+
+	//------------(castType) null--------------
+	if (expressionTb == NullBinding) {
+		return !castTb.isBaseType();
+	}
+
+	//========BASETYPE==============
+	if (expressionTb.isBaseType()) {
+		return false;
+	}
+
+
+	//========REFERENCE TYPE===================
+
+	if (expressionTb.isClass()) {
+		if (castTb.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
+			if (scope.isJavaLangObject(expressionTb))
+				return true;
+		}
+		if (castTb.isBaseType()) {
+			return false;
+		}
+		if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ 
+			if (scope.areTypesCompatible(expressionTb, castTb))
+				return true;
+			else {
+				if (scope.areTypesCompatible(castTb, expressionTb)) {
+					return true;
+				}
+				return false;
+			}
+		}
+		if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------  
+			if (((ReferenceBinding) expressionTb).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
+				if (scope.areTypesCompatible(expressionTb, castTb))
+					return true;
+				return false;
+			} else {
+				return true;
+			}
+		}
+
+		//=========houps=============
+		return false;
+	}
+	if (expressionTb.isInterface()) {
+		if (castTb.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
+			if (scope.isJavaLangCloneable(expressionTb) || scope.isJavaIoSerializable(expressionTb))
+				//potential runtime error
+				{
+				return true;
+			}
+			return false;
+		}
+		if (castTb.isBaseType()) {
+			return false;
+		}
+		if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
+			if (scope.isJavaLangObject(castTb))
+				return true;
+			if (((ReferenceBinding) castTb).isFinal()) { //no subclass for castTb, thus compile-time check is valid
+				if (scope.areTypesCompatible(castTb, expressionTb)) {
+					return true;
+				}
+				return false;
+			}
+			return true;
+		}
+		if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
+			if (castTb != expressionTb && (scope.compareTypes(castTb, expressionTb) == NotRelated)) {
+				MethodBinding[] castTbMethods = ((ReferenceBinding) castTb).methods();
+				int castTbMethodsLength = castTbMethods.length;
+				MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionTb).methods();
+				int expressionTbMethodsLength = expressionTbMethods.length;
+				for (int i = 0; i < castTbMethodsLength; i++) {
+					for (int j = 0; j < expressionTbMethodsLength; j++) {
+						if (castTbMethods[i].selector == expressionTbMethods[j].selector) {
+							if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) {
+								if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) {
+									return false;
+								}
+							}
+						}
+					}
+				}
+			}
+			return true;
+		}
+
+
+		//=========hoops===========	
+		return false;
+	}
+
+	//==========HOUPS==========
+	return false;
+}
+public final void computeConstant(TypeBinding leftTb, TypeBinding rightTb){
+	if ((left.constant != NotAConstant) && (right.constant != NotAConstant)) {
+		constant =
+			Constant.computeConstantOperationEQUAL_EQUAL(
+				left.constant,
+				rightTb.id,
+				EQUAL_EQUAL,
+				right.constant,
+				rightTb.id);
+		if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL)
+			constant = Constant.fromValue(!constant.booleanValue());
+	} else {
+		constant = NotAConstant;
+	}
+}
+/**
+ * Normal == or != code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	if (constant != NotAConstant) {
+		int pc = codeStream.position;
+		if (valueRequired) 
+			codeStream.generateConstant(constant, implicitConversion);
+		codeStream.recordPositionsFrom(pc, this);
+		return;
+	}
+	Label falseLabel = new Label(codeStream);
+	generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
+	if (valueRequired){
+		// comparison is TRUE 
+		codeStream.iconst_1();
+		if ((bits & ValueForReturnMASK) != 0){
+			codeStream.ireturn();
+			// comparison is FALSE
+			falseLabel.place();
+			codeStream.iconst_0();
+		} else {
+			Label endLabel = new Label(codeStream);
+			codeStream.goto_(endLabel);
+			codeStream.decrStackSize(1);
+			// comparison is FALSE
+			falseLabel.place();
+			codeStream.iconst_0();
+			endLabel.place();
+		}
+	}
+}
+/**
+ * Boolean operator code generation
+ *	Optimized operations are: == and !=
+ */
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+	int pc = codeStream.position;
+	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
+		if (constant.booleanValue() == true) {
+			// constant == true
+			if (valueRequired) {
+				if (falseLabel == null) {
+					// implicit falling through the FALSE case
+					if (trueLabel != null) {
+						codeStream.goto_(trueLabel);
+					}
+				}
+			}
+		} else {
+			// constant == false
+			if (valueRequired) {
+				if (falseLabel != null) {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.goto_(falseLabel);
+					}
+				}
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this);
+		return;
+	}
+	if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+		if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
+			generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+		} else {
+			generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+		}
+	} else {
+		if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
+			generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+		} else {
+			generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+/**
+ * Boolean generation for == with boolean operands
+ *
+ * Note this code does not optimize conditional constants !!!!
+ */
+public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+	int pc = codeStream.position;
+	// optimized cases: true == x, false == x
+	if (left.constant != NotAConstant) {
+		boolean inline = left.constant.booleanValue();
+		right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+		codeStream.recordPositionsFrom(pc, this);
+		return;
+	} // optimized cases: x == true, x == false
+	if (right.constant != NotAConstant) {
+		boolean inline = right.constant.booleanValue();
+		left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+		codeStream.recordPositionsFrom(pc, this);
+		return;
+	}
+	// default case
+	left.generateCode(currentScope, codeStream, valueRequired);
+	right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				codeStream.if_icmpeq(trueLabel);
+			}
+		} else {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				codeStream.if_icmpne(falseLabel);
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+/**
+ * Boolean generation for == with non-boolean operands
+ *
+ */
+public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+	int pc = codeStream.position;
+	Constant inline;
+	if ((inline = right.constant) != NotAConstant) {
+		// optimized case: x == null
+		if (right.constant == NullConstant.Default) {
+			left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicit falling through the FALSE case
+						codeStream.ifnull(trueLabel);
+					}
+				} else {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.ifnonnull(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this);
+			return;
+		}
+		// optimized case: x == 0
+		if (((left.implicitConversion >> 4) == T_int) && (inline.intValue() == 0)) {
+			left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicit falling through the FALSE case
+						codeStream.ifeq(trueLabel);
+					}
+				} else {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.ifne(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this);
+			return;
+		}
+	}
+	if ((inline = left.constant) != NotAConstant) {
+		// optimized case: null == x
+		if (left.constant == NullConstant.Default) {
+			right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicit falling through the FALSE case
+						codeStream.ifnull(trueLabel);
+					}
+				} else {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.ifnonnull(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this);
+			return;
+		}
+		// optimized case: 0 == x
+		if (((left.implicitConversion >> 4) == T_int)
+			&& (inline.intValue() == 0)) {
+			right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicit falling through the FALSE case
+						codeStream.ifeq(trueLabel);
+					}
+				} else {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.ifne(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this);
+			return;
+		}
+	}
+	// default case
+	left.generateCode(currentScope, codeStream, valueRequired);
+	right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				switch (left.implicitConversion >> 4) { // operand runtime type
+					case T_int :
+						codeStream.if_icmpeq(trueLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifeq(trueLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifeq(trueLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifeq(trueLabel);
+						break;
+					default :
+						codeStream.if_acmpeq(trueLabel);
+				}
+			}
+		} else {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				switch (left.implicitConversion >> 4) { // operand runtime type
+					case T_int :
+						codeStream.if_icmpne(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifne(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifne(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifne(falseLabel);
+						break;
+					default :
+						codeStream.if_acmpne(falseLabel);
+				}
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public boolean isCompactableOperation() {
+	return false;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// always return BooleanBinding
+	TypeBinding leftTb = left.resolveType(scope);
+	TypeBinding rightTb = right.resolveType(scope);
+	if (leftTb == null || rightTb == null){
+		constant = NotAConstant;		
+		return null;
+	}
+
+	// both base type
+	if (leftTb.isBaseType() && rightTb.isBaseType()) {
+		// the code is an int
+		// (cast)  left   == (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4       <<0
+		int result = ResolveTypeTables[EQUAL_EQUAL][ (leftTb.id << 4) + rightTb.id];
+		left.implicitConversion = result >>> 12;
+		right.implicitConversion = (result >>> 4) & 0x000FF;
+		bits |= result & 0xF;		
+		if ((result & 0x0000F) == T_undefined) {
+			constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, leftTb, rightTb);
+			return null;
+		}
+		computeConstant(leftTb, rightTb);
+		return BooleanBinding;
+	}
+
+	// Object references 
+	// spec 15.20.3
+	if (areTypesCastCompatible(scope, rightTb, leftTb) || areTypesCastCompatible(scope, leftTb, rightTb)) {
+		// (special case for String)
+		if ((rightTb.id == T_String) && (leftTb.id == T_String))
+			computeConstant(leftTb, rightTb);
+		else
+			constant = NotAConstant;
+		if (rightTb.id == T_String)
+			right.implicitConversion = String2String;
+		if (leftTb.id == T_String)
+			left.implicitConversion = String2String;
+		return BooleanBinding;
+	}
+	constant = NotAConstant;
+	scope.problemReporter().notCompatibleTypesError(this, leftTb, rightTb);
+	return null;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		left.traverse(visitor, scope);
+		right.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 8df5881..0b869db 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -1,252 +1,251 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class ExplicitConstructorCall extends Statement implements InvocationSite {
-	public Expression[] arguments;
-	public Expression qualification;
-	public MethodBinding binding;
-
-	public int accessMode;
-
-	public final static int ImplicitSuper = 1;
-	public final static int Super = 2;
-	public final static int This = 3;
-
-	public VariableBinding[][] implicitArguments;
-	boolean discardEnclosingInstance;
-
-	MethodBinding syntheticAccessor;
-
-public ExplicitConstructorCall(int accessMode) {
-	this.accessMode = accessMode;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	// must verify that exceptions potentially thrown by this expression are caught in the method.
-
-	try {
-		((MethodScope) currentScope).isConstructorCall = true;
-		
-		// process enclosing instance
-		if (qualification != null){
-			flowInfo = qualification.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-		}
-		// process arguments
-		if (arguments != null){
-			for (int i = 0, max = arguments.length; i < max; i++) {
-				flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-			}
-		}
-
-		ReferenceBinding[] thrownExceptions;
-		if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) {
-			// check exceptions
-			flowContext.checkExceptionHandlers(
-				thrownExceptions, 
-				(accessMode == ImplicitSuper) ? (AstNode)currentScope.methodScope().referenceContext : (AstNode)this, 
-				flowInfo, 
-				currentScope);
-		}
-		manageEnclosingInstanceAccessIfNecessary(currentScope);
-		manageSyntheticAccessIfNecessary(currentScope);
-		return flowInfo;
-	} finally {
-		((MethodScope) currentScope).isConstructorCall = false;
-	}
-}
-/**
- * Constructor call code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	try {
-		((MethodScope) currentScope).isConstructorCall = true;
-	
-		int pc = codeStream.position;
-		codeStream.aload_0();
-
-		// handling innerclass constructor invocation
-		ReferenceBinding targetType;
-		if ((targetType = binding.declaringClass).isNestedType()){
-			codeStream.generateSyntheticArgumentValues(currentScope, targetType, discardEnclosingInstance ? null : qualification, this);
-		}	
-		// regular code gen
-		if (arguments != null){
-			for (int i = 0, max = arguments.length; i < max; i++) {
-				arguments[i].generateCode(currentScope, codeStream, true);
-			}
-		}
-		if (syntheticAccessor != null){
-			// synthetic accessor got some extra arguments appended to its signature, which need values
-			for (int i = 0, max = syntheticAccessor.parameters.length - binding.parameters.length; i < max; i++){
-				codeStream.aconst_null();
-			}
-			codeStream.invokespecial(syntheticAccessor);			
-		} else {
-			codeStream.invokespecial(binding);
-		}
-		codeStream.recordPositionsFrom(pc, this);
-	} finally {
-		((MethodScope) currentScope).isConstructorCall = false;
-	}
-}
-public boolean isImplicitSuper(){
-	//return true if I'm of these compiler added statement super();
-
-	return (accessMode == ImplicitSuper) ;}
-public boolean isSuperAccess(){
-	return accessMode != This;
-}
-public boolean isTypeAccess(){
-	return true;
-}
-/* Inner emulation consists in either recording a dependency 
- * link only, or performing one level of propagation.
- *
- * Dependency mechanism is used whenever dealing with source target
- * types, since by the time we reach them, we might not yet know their
- * exact need.
- */
-void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-	ReferenceBinding invocationType, superType;
-
-	// perform some emulation work in case there is some and we are inside a local type only
-	if ((superType = binding.declaringClass).isNestedType() 
-		&& currentScope.enclosingSourceType().isLocalType()) {
-
-		if (superType.isLocalType()){
-			((LocalTypeBinding)superType).addInnerEmulationDependent(currentScope, qualification != null, true); // request direct access
-		} else {
-			// locally propagate, since we already now the desired shape for sure
-			currentScope.propagateInnerEmulation(superType, qualification != null, true); // request direct access
-			
-		}
-	}
-}
-public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
-
-	// perform some emulation work in case there is some and we are inside a local type only
-	if (binding.isPrivate() && (accessMode != This)) {
-
-		if (currentScope.environment().options.isPrivateConstructorAccessChangingVisibility){
-			binding.tagForClearingPrivateModifier(); // constructor will not be dumped as private, no emulation required thus
-		} else {
-			syntheticAccessor = ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding);
-			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
-		}
-	}
-}
-public void resolve(BlockScope scope) {
-	// the return type should be void for a constructor.
-	// the test is made into getConstructor
-
-	// mark the fact that we are in a constructor call.....
-	// unmark at all returns
-	try {
-		((MethodScope) scope).isConstructorCall = true;
-		ReferenceBinding receiverType = scope.enclosingSourceType();
-		if (accessMode != This)
-			receiverType = receiverType.superclass();
-
-		if (receiverType == null) { 
-			return;
-		}
-
-		// qualification should be from the type of the enclosingType
-		if (qualification != null) {
-			if (accessMode != Super){
-				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(qualification, receiverType);
-			}
-			ReferenceBinding enclosingType = receiverType.enclosingType();
-			if (enclosingType == null) {
-				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(qualification, receiverType);
-				discardEnclosingInstance = true;
-			} else {
-				TypeBinding qTb = qualification.resolveTypeExpecting(scope, enclosingType);
-				qualification.implicitWidening(qTb, qTb);
-			}
-		}
-
-		// arguments buffering for the method lookup
-		TypeBinding[] argTypes = NoParameters;
-		if (arguments != null) {
-			boolean argHasError = false; // typeChecks all arguments
-			int length = arguments.length;
-			argTypes = new TypeBinding[length];
-			for (int i = 0; i < length; i++)
-				if ((argTypes[i] = arguments[i].resolveType(scope)) == null)
-					argHasError = true;
-			if (argHasError)
-				return;
-		}
-		if ((binding = scope.getConstructor(receiverType, argTypes, this)).isValidBinding()) {
-			if (isMethodUseDeprecated(binding, scope))
-				scope.problemReporter().deprecatedMethod(binding, this);
-			
-			// see for user-implicit widening conversion 
-			if (arguments != null) {
-				int length = arguments.length;
-				TypeBinding[] paramTypes = binding.parameters;
-				for (int i = 0; i < length; i++)
-					arguments[i].implicitWidening(paramTypes[i], argTypes[i]);
-			}
-		} else {
-			if (binding.declaringClass == null)
-				binding.declaringClass = receiverType;
-			scope.problemReporter().invalidConstructor(this, binding);
-		}
-	} finally {
-		((MethodScope) scope).isConstructorCall = false;
-	}
-}
-public void setDepth(int depth){
-	// ignore for here
-}
-public void setFieldIndex(int depth){
-	// ignore for here
-}
-public String toString(int tab){
-	/* slow code */
-
-	String s = tabString(tab);
-	if (qualification != null) 
-		s = s + qualification.toStringExpression() + "."/*nonNLS*/ ;
-	if (accessMode == This){
-		s = s + "this("/*nonNLS*/;
-	} else {
-		s = s + "super("/*nonNLS*/;
-	}
-	if (arguments != null)
-		for (int i=0 ; i < arguments.length ; i++)
-		{	s = s + arguments[i].toStringExpression();
-			if (i != arguments.length-1) s = s + ", "/*nonNLS*/;};;
-	s = s+")"/*nonNLS*/ ;
-	return s;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		if (qualification != null) {
-			qualification.traverse(visitor, scope);
-		}
-		if (arguments != null) {
-			int argumentLength = arguments.length;
-			for (int i = 0; i < argumentLength; i++)
-				arguments[i].traverse(visitor, scope);
-		}
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ExplicitConstructorCall extends Statement implements InvocationSite {
+	public Expression[] arguments;
+	public Expression qualification;
+	public MethodBinding binding;
+
+	public int accessMode;
+
+	public final static int ImplicitSuper = 1;
+	public final static int Super = 2;
+	public final static int This = 3;
+
+	public VariableBinding[][] implicitArguments;
+	boolean discardEnclosingInstance;
+
+	MethodBinding syntheticAccessor;
+
+public ExplicitConstructorCall(int accessMode) {
+	this.accessMode = accessMode;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// must verify that exceptions potentially thrown by this expression are caught in the method.
+
+	try {
+		((MethodScope) currentScope).isConstructorCall = true;
+		
+		// process enclosing instance
+		if (qualification != null){
+			flowInfo = qualification.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+		}
+		// process arguments
+		if (arguments != null){
+			for (int i = 0, max = arguments.length; i < max; i++) {
+				flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+			}
+		}
+
+		ReferenceBinding[] thrownExceptions;
+		if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) {
+			// check exceptions
+			flowContext.checkExceptionHandlers(
+				thrownExceptions, 
+				(accessMode == ImplicitSuper) ? (AstNode)currentScope.methodScope().referenceContext : (AstNode)this, 
+				flowInfo, 
+				currentScope);
+		}
+		manageEnclosingInstanceAccessIfNecessary(currentScope);
+		manageSyntheticAccessIfNecessary(currentScope);
+		return flowInfo;
+	} finally {
+		((MethodScope) currentScope).isConstructorCall = false;
+	}
+}
+/**
+ * Constructor call code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	try {
+		((MethodScope) currentScope).isConstructorCall = true;
+	
+		int pc = codeStream.position;
+		codeStream.aload_0();
+
+		// handling innerclass constructor invocation
+		ReferenceBinding targetType;
+		if ((targetType = binding.declaringClass).isNestedType()){
+			codeStream.generateSyntheticArgumentValues(currentScope, targetType, discardEnclosingInstance ? null : qualification, this);
+		}	
+		// regular code gen
+		if (arguments != null){
+			for (int i = 0, max = arguments.length; i < max; i++) {
+				arguments[i].generateCode(currentScope, codeStream, true);
+			}
+		}
+		if (syntheticAccessor != null){
+			// synthetic accessor got some extra arguments appended to its signature, which need values
+			for (int i = 0, max = syntheticAccessor.parameters.length - binding.parameters.length; i < max; i++){
+				codeStream.aconst_null();
+			}
+			codeStream.invokespecial(syntheticAccessor);			
+		} else {
+			codeStream.invokespecial(binding);
+		}
+		codeStream.recordPositionsFrom(pc, this);
+	} finally {
+		((MethodScope) currentScope).isConstructorCall = false;
+	}
+}
+public boolean isImplicitSuper(){
+	//return true if I'm of these compiler added statement super();
+
+	return (accessMode == ImplicitSuper) ;}
+public boolean isSuperAccess(){
+	return accessMode != This;
+}
+public boolean isTypeAccess(){
+	return true;
+}
+/* Inner emulation consists in either recording a dependency 
+ * link only, or performing one level of propagation.
+ *
+ * Dependency mechanism is used whenever dealing with source target
+ * types, since by the time we reach them, we might not yet know their
+ * exact need.
+ */
+void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+	ReferenceBinding invocationType, superType;
+
+	// perform some emulation work in case there is some and we are inside a local type only
+	if ((superType = binding.declaringClass).isNestedType() 
+		&& currentScope.enclosingSourceType().isLocalType()) {
+
+		if (superType.isLocalType()){
+			((LocalTypeBinding)superType).addInnerEmulationDependent(currentScope, qualification != null, true); // request direct access
+		} else {
+			// locally propagate, since we already now the desired shape for sure
+			currentScope.propagateInnerEmulation(superType, qualification != null, true); // request direct access
+			
+		}
+	}
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
+
+	// perform some emulation work in case there is some and we are inside a local type only
+	if (binding.isPrivate() && (accessMode != This)) {
+
+		if (currentScope.environment().options.isPrivateConstructorAccessChangingVisibility){
+			binding.tagForClearingPrivateModifier(); // constructor will not be dumped as private, no emulation required thus
+		} else {
+			syntheticAccessor = ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding);
+			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
+		}
+	}
+}
+public void resolve(BlockScope scope) {
+	// the return type should be void for a constructor.
+	// the test is made into getConstructor
+
+	// mark the fact that we are in a constructor call.....
+	// unmark at all returns
+	try {
+		((MethodScope) scope).isConstructorCall = true;
+		ReferenceBinding receiverType = scope.enclosingSourceType();
+		if (accessMode != This)
+			receiverType = receiverType.superclass();
+
+		if (receiverType == null) { 
+			return;
+		}
+
+		// qualification should be from the type of the enclosingType
+		if (qualification != null) {
+			if (accessMode != Super){
+				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(qualification, receiverType);
+			}
+			ReferenceBinding enclosingType = receiverType.enclosingType();
+			if (enclosingType == null) {
+				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(qualification, receiverType);
+				discardEnclosingInstance = true;
+			} else {
+				TypeBinding qTb = qualification.resolveTypeExpecting(scope, enclosingType);
+				qualification.implicitWidening(qTb, qTb);
+			}
+		}
+
+		// arguments buffering for the method lookup
+		TypeBinding[] argTypes = NoParameters;
+		if (arguments != null) {
+			boolean argHasError = false; // typeChecks all arguments
+			int length = arguments.length;
+			argTypes = new TypeBinding[length];
+			for (int i = 0; i < length; i++)
+				if ((argTypes[i] = arguments[i].resolveType(scope)) == null)
+					argHasError = true;
+			if (argHasError)
+				return;
+		}
+		if ((binding = scope.getConstructor(receiverType, argTypes, this)).isValidBinding()) {
+			if (isMethodUseDeprecated(binding, scope))
+				scope.problemReporter().deprecatedMethod(binding, this);
+			
+			// see for user-implicit widening conversion 
+			if (arguments != null) {
+				int length = arguments.length;
+				TypeBinding[] paramTypes = binding.parameters;
+				for (int i = 0; i < length; i++)
+					arguments[i].implicitWidening(paramTypes[i], argTypes[i]);
+			}
+		} else {
+			if (binding.declaringClass == null)
+				binding.declaringClass = receiverType;
+			scope.problemReporter().invalidConstructor(this, binding);
+		}
+	} finally {
+		((MethodScope) scope).isConstructorCall = false;
+	}
+}
+public void setDepth(int depth){
+	// ignore for here
+}
+public void setFieldIndex(int depth){
+	// ignore for here
+}
+public String toString(int tab){
+	/* slow code */
+
+	String s = tabString(tab);
+	if (qualification != null) 
+		s = s + qualification.toStringExpression() + "."/*nonNLS*/ ;
+	if (accessMode == This){
+		s = s + "this("/*nonNLS*/;
+	} else {
+		s = s + "super("/*nonNLS*/;
+	}
+	if (arguments != null)
+		for (int i=0 ; i < arguments.length ; i++)
+		{	s = s + arguments[i].toStringExpression();
+			if (i != arguments.length-1) s = s + ", "/*nonNLS*/;};;
+	s = s+")"/*nonNLS*/ ;
+	return s;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (qualification != null) {
+			qualification.traverse(visitor, scope);
+		}
+		if (arguments != null) {
+			int argumentLength = arguments.length;
+			for (int i = 0; i < argumentLength; i++)
+				arguments[i].traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 8595400..e8993e1 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1,371 +1,370 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-public abstract class Expression extends Statement {
-	//some expression may not be used - from a java semantic point
-	//of view only - as statements. Other may. In order to avoid the creation
-	//of wrappers around expression in order to tune them as expression
-	//Expression is a subclass of Statement. See the message isValidJavaStatement()
-	
-	public int implicitConversion;
-	public Constant constant;
-
-public Expression() {
-	super();
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
-	return analyseCode(currentScope, flowContext, flowInfo);
-}
-public Constant conditionalConstant(){
-
-		return constant;
-}
-/* Dislike this name
-*/
-
-public static final boolean convertToTypeFromTypeValue(int left , int right, Constant cst){
-	//true if there is no loose of information while casting.
-	//right is constant's type.id
-
-	//a faster solution would be to use combinaison of 
-	//some range.........????
-
-
-	/*
-	org.eclipse.jdt.internal.compiler.util.Constant cst ;
-	cst = org.eclipse.jdt.internal.compiler.util.Constant.fromValue((float)898565456.0) ;
-	org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding.convertToTypeFromTypeValue(
-	org.eclipse.jdt.internal.compiler.ast.TypeReference.T_int,
-	org.eclipse.jdt.internal.compiler.ast.TypeReference.T_float,
-	cst)
-	*/
-	
-	if (left == right) return true ;
-	switch(left){
-		case T_char 	:	
-				switch (right) {
-					case T_char	: return true ;
-					case T_double : return cst.doubleValue() 	== cst.charValue() ;
-					case T_float  : return cst.floatValue() 	== cst.charValue() ;
-					case T_int    : return cst.intValue() 	== cst.charValue() ;
-					case T_short  : return cst.shortValue() 	== cst.charValue() ;
-					case T_byte   : return cst.byteValue() 	== cst.charValue() ;
-					case T_long   : return cst.longValue() 	== cst.charValue() ;
-					default : return false ;} //boolean
-
-		case T_float 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.floatValue() ;
-					case T_double : return cst.doubleValue() 	== cst.floatValue() ;
-					case T_float  : return true;
-					case T_int    : return cst.intValue() 	== cst.floatValue() ;
-					case T_short  : return cst.shortValue() 	== cst.floatValue() ;
-					case T_byte   : return cst.byteValue() 	== cst.floatValue() ;
-					case T_long   : return cst.longValue() 	== cst.floatValue() ;
-					default : return false ;} //boolean
-	case T_double 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.doubleValue() ;
-					case T_double : return true ;
-					case T_float  : return cst.floatValue() 	== cst.doubleValue() ;
-					case T_int    : return cst.intValue() 	== cst.doubleValue() ;
-					case T_short  : return cst.shortValue() 	== cst.doubleValue() ;
-					case T_byte   : return cst.byteValue() 	== cst.doubleValue() ;
-					case T_long   : return cst.longValue() 	== cst.doubleValue() ;
-					default : return false ;} //boolean
-	case T_byte 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.byteValue() ;
-					case T_double : return cst.doubleValue() 	== cst.byteValue() ;
-					case T_float  : return cst.floatValue() 	== cst.byteValue() ;
-					case T_int    : return cst.intValue() 	== cst.byteValue() ;
-					case T_short  : return cst.shortValue() 	== cst.byteValue() ;
-					case T_byte   : return true ; 
-					case T_long   : return cst.longValue() 	== cst.byteValue() ;
-					default : return false ;} //boolean
-	case T_short 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.shortValue() ;
-					case T_double : return cst.doubleValue() 	== cst.shortValue() ;
-					case T_float  : return cst.floatValue() 	== cst.shortValue() ;
-					case T_int    : return cst.intValue() 	== cst.shortValue() ;
-					case T_short  : return true ;
-					case T_byte   : return cst.byteValue() 	== cst.shortValue() ;
-					case T_long   : return cst.longValue() 	== cst.shortValue() ;
-					default : return false ;} //boolean
-	case T_int 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.intValue() ;
-					case T_double : return cst.doubleValue() 	== cst.intValue() ;
-					case T_float  : return cst.floatValue() 	== cst.intValue() ;
-					case T_int    : return true ; 
-					case T_short  : return cst.shortValue() 	== cst.intValue() ;
-					case T_byte   : return cst.byteValue() 	== cst.intValue() ;
-					case T_long   : return cst.longValue() 	== cst.intValue() ;
-					default : return false ;} //boolean
-	case T_long 	:	
-				switch (right) {
-					case T_char	: return cst.charValue() 	== cst.longValue() ;
-					case T_double : return cst.doubleValue() 	== cst.longValue() ;
-					case T_float  : return cst.floatValue() 	== cst.longValue() ;
-					case T_int    : return cst.intValue() 	== cst.longValue() ;
-					case T_short  : return cst.shortValue() 	== cst.longValue() ;
-					case T_byte   : return cst.byteValue() 	== cst.longValue() ;
-					case T_long   : return true ;
-					default : return false ;} //boolean
-	default : return false ; } //boolean
-}
-/**
- * Expression statements are plain expressions, however they generate like
- * normal expressions with no value required.
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream 
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	generateCode(currentScope, codeStream, false);
-}
-/**
- * Every expression is responsible for generating its implicit conversion when necessary.
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	if (constant != NotAConstant) {
-		// generate a constant expression
-		int pc = codeStream.position;
-		codeStream.generateConstant(constant, implicitConversion);
-		codeStream.recordPositionsFrom(pc, this);
-	} else {
-		// actual non-constant code generation
-		throw new ShouldNotImplement(Util.bind("ast.missingCode"/*nonNLS*/));
-	}
-}
-/**
- * Default generation of a boolean value
- */
-public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
-
-	// a label valued to nil means: by default we fall through the case... 
-	// both nil means we leave the value on the stack
-
-	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
-		int pc = codeStream.position;
-		if (constant.booleanValue() == true) {
-			// constant == true
-			if (valueRequired) {
-				if (falseLabel == null) {
-					// implicit falling through the FALSE case
-					if (trueLabel != null) {
-						codeStream.goto_(trueLabel);
-					}
-				}
-			}
-		} else {
-			if (valueRequired) {
-				if (falseLabel != null) {
-					// implicit falling through the TRUE case
-					if (trueLabel == null) {
-						codeStream.goto_(falseLabel);
-					}
-				}
-			}
-		}
-		codeStream.recordPositionsFrom(pc, this);
-		return;
-	}
-	generateCode(currentScope, codeStream, valueRequired);
-	// branching
-	int position = codeStream.position;
-	if (valueRequired) {
-		if (falseLabel == null) {
-			if (trueLabel != null) {
-				// Implicit falling through the FALSE case
-				codeStream.ifne(trueLabel);
-			}
-		} else {
-			if (trueLabel == null) {
-				// Implicit falling through the TRUE case
-				codeStream.ifeq(falseLabel);
-			} else {
-				// No implicit fall through TRUE/FALSE --> should never occur
-			}
-		}
-	}
-	// reposition the endPC
-	codeStream.updateLastRecordedEndPC(position);
-}
-public void generateOptimizedStringBuffer(BlockScope blockScope, org.eclipse.jdt.internal.compiler.codegen.CodeStream codeStream, int typeID) {
-	/* Optimized (java) code generation for string concatenations that involve StringBuffer
-	 * creation: going through this path means that there is no need for a new StringBuffer
-	 * creation, further operands should rather be only appended to the current one.
-	 * By default: no optimization.
-	 */
-
-	generateCode(blockScope, codeStream, true);
-	codeStream.invokeStringBufferAppendForType(typeID);
-}
-public void generateOptimizedStringBufferCreation(BlockScope blockScope, CodeStream codeStream, int typeID) {
-	/* Optimized (java) code generation for string concatenations that involve StringBuffer
-	 * creation: going through this path means that there is no need for a new StringBuffer
-	 * creation, further operands should rather be only appended to the current one.
-	 */
-
-	// Optimization only for integers and strings
-
-	if (typeID == T_Object) {
-		// in the case the runtime value of valueOf(Object) returns null, we have to use append(Object) instead of directly valueOf(Object)
-		// append(Object) returns append(valueOf(Object)), which means that the null case is handled by append(String).
-		codeStream.newStringBuffer();
-		codeStream.dup();
-		codeStream.invokeStringBufferDefaultConstructor();
-		generateCode(blockScope, codeStream, true);
-		codeStream.invokeStringBufferAppendForType(T_Object);	
-		return;
-	}
-	codeStream.newStringBuffer();
-	codeStream.dup();
-	if ((typeID == T_String) || (typeID == T_null)) {
-		if (constant != NotAConstant) {
-			codeStream.ldc(constant.stringValue());
-		} else {
-			generateCode(blockScope, codeStream, true);
-			codeStream.invokeStringValueOf(T_Object);
-		}
-	} else {
-		generateCode(blockScope, codeStream, true);
-		codeStream.invokeStringValueOf(typeID);
-	}
-	codeStream.invokeStringBufferStringConstructor();
-}
-public void implicitWidening(TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
-	// Base types need that the widening is explicitly done by the compiler using some bytecode like i2f
-
-	if (runtimeTimeType == null || compileTimeType == null)
-		return;
-
-	if (compileTimeType.id == T_null) {
-		// this case is possible only for constant null
-		// The type of runtime is a reference type
-		// The code gen use the constant id thus any value
-		// for the runtime id (akak the <<4) could be used.
-		// T_Object is used as some general T_reference
-		implicitConversion = (T_Object << 4) + T_null;
-		return;
-	}
-
-	switch (runtimeTimeType.id) {
-		case T_byte :
-		case T_short :
-		case T_char :
-			implicitConversion = (T_int << 4) + compileTimeType.id;
-			break;
-		case T_String :
-		case T_float :
-		case T_boolean :
-		case T_double :
-		case T_int : //implicitConversion may result in i2i which will result in NO code gen
-		case T_long :
-			implicitConversion = (runtimeTimeType.id << 4) + compileTimeType.id;
-			break;
-		default : //nothing on regular object ref
-	}
-}
-public boolean isCompactableOperation() {
-	return false;
-}
-public boolean isConstantValueOfTypeAssignableToType(TypeBinding constantType, TypeBinding targetType) {
-	//Return true if the conversion is done AUTOMATICALLY by the vm
-	//while the javaVM is an int based-machine, thus for example pushing
-	//a byte onto the stack , will automatically creates a int on the stack
-	//(this request some work d be done by the VM on signed numbers)
-
-	if (constant == Constant.NotAConstant)
-		return false;
-	if (constantType == targetType)
-		return true;
-	if (constantType.isBaseType() && targetType.isBaseType()) {
-		//No free assignment conversion from anything but to integral ones.
-		if ((constantType == IntBinding || BaseTypeBinding.isWidening(T_int, constantType.id))
-			&& (BaseTypeBinding.isNarrowing(targetType.id, T_int))) {
-				//use current explicit conversion in order to get some new value to compare with current one
-				return convertToTypeFromTypeValue(targetType.id, constantType.id, constant);
-		}
-	}
-	return false;
-}
-public boolean isTypeReference() {
-	return false;
-}
-public void resolve(BlockScope scope) {
-	// drops the returning expression's type whatever the type is.
-
-	this.resolveType(scope);
-	return;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// by default... subclasses should implement a better TC if required.
-
-	return null;
-}
-public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedTb) {
-	TypeBinding thisTb = this.resolveType(scope);
-	if (thisTb == null)
-		return null;
-	if (!scope.areTypesCompatible(thisTb, expectedTb)) {
-		scope.problemReporter().typeMismatchError(thisTb, expectedTb, this);
-		return null;
-	}
-	return thisTb;
-}
-public String toString(int tab) {
-
-	//Subclass re-define toStringExpression
-
-	String s = tabString(tab);
-	if (constant != null)
-		//before TC has runned
-		if (constant != NotAConstant)
-			//after the TC has runned
-			s += " /*cst:"/*nonNLS*/ + constant.toString() + "*/ "/*nonNLS*/;
-	return s + toStringExpression(tab);
-}
-public String toStringExpression() {
-
-	//Subclass re-define toStringExpression
-	//This method is abstract and should never be called
-	//but we provide some code that is running.....just in case
-	//of developpement time (while every  thing is not built)
-	
-	return super.toString(0);}
-public String toStringExpression(int tab) {
-	// default is regular toString expression (qualified allocation expressions redifine this method)
-	return this.toStringExpression();
-}
-public Expression toTypeReference(){
-	//by default undefined
-
-	//this method is meanly used by the parser in order to transform
-	//an expression that is used as a type reference in a cast ....
-	//--appreciate the fact that castExpression and ExpressionWithParenthesis
-	//--starts with the same pattern.....
-	
-	return this; }
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public abstract class Expression extends Statement {
+	//some expression may not be used - from a java semantic point
+	//of view only - as statements. Other may. In order to avoid the creation
+	//of wrappers around expression in order to tune them as expression
+	//Expression is a subclass of Statement. See the message isValidJavaStatement()
+	
+	public int implicitConversion;
+	public Constant constant;
+
+public Expression() {
+	super();
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	return analyseCode(currentScope, flowContext, flowInfo);
+}
+public Constant conditionalConstant(){
+
+		return constant;
+}
+/* Dislike this name
+*/
+
+public static final boolean convertToTypeFromTypeValue(int left , int right, Constant cst){
+	//true if there is no loose of information while casting.
+	//right is constant's type.id
+
+	//a faster solution would be to use combinaison of 
+	//some range.........????
+
+
+	/*
+	org.eclipse.jdt.internal.compiler.util.Constant cst ;
+	cst = org.eclipse.jdt.internal.compiler.util.Constant.fromValue((float)898565456.0) ;
+	org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding.convertToTypeFromTypeValue(
+	org.eclipse.jdt.internal.compiler.ast.TypeReference.T_int,
+	org.eclipse.jdt.internal.compiler.ast.TypeReference.T_float,
+	cst)
+	*/
+	
+	if (left == right) return true ;
+	switch(left){
+		case T_char 	:	
+				switch (right) {
+					case T_char	: return true ;
+					case T_double : return cst.doubleValue() 	== cst.charValue() ;
+					case T_float  : return cst.floatValue() 	== cst.charValue() ;
+					case T_int    : return cst.intValue() 	== cst.charValue() ;
+					case T_short  : return cst.shortValue() 	== cst.charValue() ;
+					case T_byte   : return cst.byteValue() 	== cst.charValue() ;
+					case T_long   : return cst.longValue() 	== cst.charValue() ;
+					default : return false ;} //boolean
+
+		case T_float 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.floatValue() ;
+					case T_double : return cst.doubleValue() 	== cst.floatValue() ;
+					case T_float  : return true;
+					case T_int    : return cst.intValue() 	== cst.floatValue() ;
+					case T_short  : return cst.shortValue() 	== cst.floatValue() ;
+					case T_byte   : return cst.byteValue() 	== cst.floatValue() ;
+					case T_long   : return cst.longValue() 	== cst.floatValue() ;
+					default : return false ;} //boolean
+	case T_double 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.doubleValue() ;
+					case T_double : return true ;
+					case T_float  : return cst.floatValue() 	== cst.doubleValue() ;
+					case T_int    : return cst.intValue() 	== cst.doubleValue() ;
+					case T_short  : return cst.shortValue() 	== cst.doubleValue() ;
+					case T_byte   : return cst.byteValue() 	== cst.doubleValue() ;
+					case T_long   : return cst.longValue() 	== cst.doubleValue() ;
+					default : return false ;} //boolean
+	case T_byte 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.byteValue() ;
+					case T_double : return cst.doubleValue() 	== cst.byteValue() ;
+					case T_float  : return cst.floatValue() 	== cst.byteValue() ;
+					case T_int    : return cst.intValue() 	== cst.byteValue() ;
+					case T_short  : return cst.shortValue() 	== cst.byteValue() ;
+					case T_byte   : return true ; 
+					case T_long   : return cst.longValue() 	== cst.byteValue() ;
+					default : return false ;} //boolean
+	case T_short 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.shortValue() ;
+					case T_double : return cst.doubleValue() 	== cst.shortValue() ;
+					case T_float  : return cst.floatValue() 	== cst.shortValue() ;
+					case T_int    : return cst.intValue() 	== cst.shortValue() ;
+					case T_short  : return true ;
+					case T_byte   : return cst.byteValue() 	== cst.shortValue() ;
+					case T_long   : return cst.longValue() 	== cst.shortValue() ;
+					default : return false ;} //boolean
+	case T_int 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.intValue() ;
+					case T_double : return cst.doubleValue() 	== cst.intValue() ;
+					case T_float  : return cst.floatValue() 	== cst.intValue() ;
+					case T_int    : return true ; 
+					case T_short  : return cst.shortValue() 	== cst.intValue() ;
+					case T_byte   : return cst.byteValue() 	== cst.intValue() ;
+					case T_long   : return cst.longValue() 	== cst.intValue() ;
+					default : return false ;} //boolean
+	case T_long 	:	
+				switch (right) {
+					case T_char	: return cst.charValue() 	== cst.longValue() ;
+					case T_double : return cst.doubleValue() 	== cst.longValue() ;
+					case T_float  : return cst.floatValue() 	== cst.longValue() ;
+					case T_int    : return cst.intValue() 	== cst.longValue() ;
+					case T_short  : return cst.shortValue() 	== cst.longValue() ;
+					case T_byte   : return cst.byteValue() 	== cst.longValue() ;
+					case T_long   : return true ;
+					default : return false ;} //boolean
+	default : return false ; } //boolean
+}
+/**
+ * Expression statements are plain expressions, however they generate like
+ * normal expressions with no value required.
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream 
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	generateCode(currentScope, codeStream, false);
+}
+/**
+ * Every expression is responsible for generating its implicit conversion when necessary.
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	if (constant != NotAConstant) {
+		// generate a constant expression
+		int pc = codeStream.position;
+		codeStream.generateConstant(constant, implicitConversion);
+		codeStream.recordPositionsFrom(pc, this);
+	} else {
+		// actual non-constant code generation
+		throw new ShouldNotImplement(Util.bind("ast.missingCode"/*nonNLS*/));
+	}
+}
+/**
+ * Default generation of a boolean value
+ */
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+
+	// a label valued to nil means: by default we fall through the case... 
+	// both nil means we leave the value on the stack
+
+	if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
+		int pc = codeStream.position;
+		if (constant.booleanValue() == true) {
+			// constant == true
+			if (valueRequired) {
+				if (falseLabel == null) {
+					// implicit falling through the FALSE case
+					if (trueLabel != null) {
+						codeStream.goto_(trueLabel);
+					}
+				}
+			}
+		} else {
+			if (valueRequired) {
+				if (falseLabel != null) {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.goto_(falseLabel);
+					}
+				}
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this);
+		return;
+	}
+	generateCode(currentScope, codeStream, valueRequired);
+	// branching
+	int position = codeStream.position;
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// Implicit falling through the FALSE case
+				codeStream.ifne(trueLabel);
+			}
+		} else {
+			if (trueLabel == null) {
+				// Implicit falling through the TRUE case
+				codeStream.ifeq(falseLabel);
+			} else {
+				// No implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	// reposition the endPC
+	codeStream.updateLastRecordedEndPC(position);
+}
+public void generateOptimizedStringBuffer(BlockScope blockScope, org.eclipse.jdt.internal.compiler.codegen.CodeStream codeStream, int typeID) {
+	/* Optimized (java) code generation for string concatenations that involve StringBuffer
+	 * creation: going through this path means that there is no need for a new StringBuffer
+	 * creation, further operands should rather be only appended to the current one.
+	 * By default: no optimization.
+	 */
+
+	generateCode(blockScope, codeStream, true);
+	codeStream.invokeStringBufferAppendForType(typeID);
+}
+public void generateOptimizedStringBufferCreation(BlockScope blockScope, CodeStream codeStream, int typeID) {
+	/* Optimized (java) code generation for string concatenations that involve StringBuffer
+	 * creation: going through this path means that there is no need for a new StringBuffer
+	 * creation, further operands should rather be only appended to the current one.
+	 */
+
+	// Optimization only for integers and strings
+
+	if (typeID == T_Object) {
+		// in the case the runtime value of valueOf(Object) returns null, we have to use append(Object) instead of directly valueOf(Object)
+		// append(Object) returns append(valueOf(Object)), which means that the null case is handled by append(String).
+		codeStream.newStringBuffer();
+		codeStream.dup();
+		codeStream.invokeStringBufferDefaultConstructor();
+		generateCode(blockScope, codeStream, true);
+		codeStream.invokeStringBufferAppendForType(T_Object);	
+		return;
+	}
+	codeStream.newStringBuffer();
+	codeStream.dup();
+	if ((typeID == T_String) || (typeID == T_null)) {
+		if (constant != NotAConstant) {
+			codeStream.ldc(constant.stringValue());
+		} else {
+			generateCode(blockScope, codeStream, true);
+			codeStream.invokeStringValueOf(T_Object);
+		}
+	} else {
+		generateCode(blockScope, codeStream, true);
+		codeStream.invokeStringValueOf(typeID);
+	}
+	codeStream.invokeStringBufferStringConstructor();
+}
+public void implicitWidening(TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+	// Base types need that the widening is explicitly done by the compiler using some bytecode like i2f
+
+	if (runtimeTimeType == null || compileTimeType == null)
+		return;
+
+	if (compileTimeType.id == T_null) {
+		// this case is possible only for constant null
+		// The type of runtime is a reference type
+		// The code gen use the constant id thus any value
+		// for the runtime id (akak the <<4) could be used.
+		// T_Object is used as some general T_reference
+		implicitConversion = (T_Object << 4) + T_null;
+		return;
+	}
+
+	switch (runtimeTimeType.id) {
+		case T_byte :
+		case T_short :
+		case T_char :
+			implicitConversion = (T_int << 4) + compileTimeType.id;
+			break;
+		case T_String :
+		case T_float :
+		case T_boolean :
+		case T_double :
+		case T_int : //implicitConversion may result in i2i which will result in NO code gen
+		case T_long :
+			implicitConversion = (runtimeTimeType.id << 4) + compileTimeType.id;
+			break;
+		default : //nothing on regular object ref
+	}
+}
+public boolean isCompactableOperation() {
+	return false;
+}
+public boolean isConstantValueOfTypeAssignableToType(TypeBinding constantType, TypeBinding targetType) {
+	//Return true if the conversion is done AUTOMATICALLY by the vm
+	//while the javaVM is an int based-machine, thus for example pushing
+	//a byte onto the stack , will automatically creates a int on the stack
+	//(this request some work d be done by the VM on signed numbers)
+
+	if (constant == Constant.NotAConstant)
+		return false;
+	if (constantType == targetType)
+		return true;
+	if (constantType.isBaseType() && targetType.isBaseType()) {
+		//No free assignment conversion from anything but to integral ones.
+		if ((constantType == IntBinding || BaseTypeBinding.isWidening(T_int, constantType.id))
+			&& (BaseTypeBinding.isNarrowing(targetType.id, T_int))) {
+				//use current explicit conversion in order to get some new value to compare with current one
+				return convertToTypeFromTypeValue(targetType.id, constantType.id, constant);
+		}
+	}
+	return false;
+}
+public boolean isTypeReference() {
+	return false;
+}
+public void resolve(BlockScope scope) {
+	// drops the returning expression's type whatever the type is.
+
+	this.resolveType(scope);
+	return;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// by default... subclasses should implement a better TC if required.
+
+	return null;
+}
+public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedTb) {
+	TypeBinding thisTb = this.resolveType(scope);
+	if (thisTb == null)
+		return null;
+	if (!scope.areTypesCompatible(thisTb, expectedTb)) {
+		scope.problemReporter().typeMismatchError(thisTb, expectedTb, this);
+		return null;
+	}
+	return thisTb;
+}
+public String toString(int tab) {
+
+	//Subclass re-define toStringExpression
+
+	String s = tabString(tab);
+	if (constant != null)
+		//before TC has runned
+		if (constant != NotAConstant)
+			//after the TC has runned
+			s += " /*cst:"/*nonNLS*/ + constant.toString() + "*/ "/*nonNLS*/;
+	return s + toStringExpression(tab);
+}
+public String toStringExpression() {
+
+	//Subclass re-define toStringExpression
+	//This method is abstract and should never be called
+	//but we provide some code that is running.....just in case
+	//of developpement time (while every  thing is not built)
+	
+	return super.toString(0);}
+public String toStringExpression(int tab) {
+	// default is regular toString expression (qualified allocation expressions redifine this method)
+	return this.toStringExpression();
+}
+public Expression toTypeReference(){
+	//by default undefined
+
+	//this method is meanly used by the parser in order to transform
+	//an expression that is used as a type reference in a cast ....
+	//--appreciate the fact that castExpression and ExpressionWithParenthesis
+	//--starts with the same pattern.....
+	
+	return this; }
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
index be9c90d..c745ffb 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
@@ -1,56 +1,56 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-
-public class ExtendedStringLiteral extends StringLiteral {
-	private static final int INIT_SIZE = 30;
-public ExtendedStringLiteral(StringLiteral str, CharLiteral character) {
-	//build a string+char literal
-
-	super(str.source, str.sourceStart, str.sourceEnd);
-	extendWith(character);
-}
-public ExtendedStringLiteral(StringLiteral str1, StringLiteral str2) {
-	//build a two-strings literal
-
-	super(str1.source, str1.sourceStart, str1.sourceEnd);
-	extendWith(str2);
-}
-public ExtendedStringLiteral extendWith(CharLiteral lit){
-	//add the lit source to mine, just as if it was mine
-
-	//uddate the source
-	int length = source.length;
-	System.arraycopy(source,0,(source=new char[length+1]),0,length);
-	source[length] = lit.value;
-	//position at the end of all literals
-	sourceEnd = lit.sourceEnd ;
-	return this;
-}
-public ExtendedStringLiteral extendWith(StringLiteral lit){
-	//add the lit source to mine, just as if it was mine
-
-	//uddate the source
-	int length = source.length;
-	System.arraycopy(source,0,source=new char[length+lit.source.length],0,length);
-	System.arraycopy(lit.source,0,source,length,lit.source.length);
-	//position at the end of all literals
-	sourceEnd = lit.sourceEnd ;
-	return this;
-}
-public String toStringExpression() {
-	/* slow code */
-
-	String str = "ExtendedStringLiteral{"/*nonNLS*/+ new String(source) +"}"/*nonNLS*/;
-	return str;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+public class ExtendedStringLiteral extends StringLiteral {
+	
+public ExtendedStringLiteral(StringLiteral str, CharLiteral character) {
+	//build a string+char literal
+
+	super(str.source, str.sourceStart, str.sourceEnd);
+	extendWith(character);
+}
+public ExtendedStringLiteral(StringLiteral str1, StringLiteral str2) {
+	//build a two-strings literal
+
+	super(str1.source, str1.sourceStart, str1.sourceEnd);
+	extendWith(str2);
+}
+public ExtendedStringLiteral extendWith(CharLiteral lit){
+	//add the lit source to mine, just as if it was mine
+
+	//uddate the source
+	int length = source.length;
+	System.arraycopy(source,0,(source=new char[length+1]),0,length);
+	source[length] = lit.value;
+	//position at the end of all literals
+	sourceEnd = lit.sourceEnd ;
+	return this;
+}
+public ExtendedStringLiteral extendWith(StringLiteral lit){
+	//add the lit source to mine, just as if it was mine
+
+	//uddate the source
+	int length = source.length;
+	System.arraycopy(source,0,source=new char[length+lit.source.length],0,length);
+	System.arraycopy(lit.source,0,source,length,lit.source.length);
+	//position at the end of all literals
+	sourceEnd = lit.sourceEnd ;
+	return this;
+}
+public String toStringExpression() {
+	/* slow code */
+
+	String str = "ExtendedStringLiteral{"/*nonNLS*/+ new String(source) +"}"/*nonNLS*/;
+	return str;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index fce4cee..fb727f9 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -1,150 +1,149 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*; 
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public class FieldDeclaration extends AbstractVariableDeclaration {
-	public FieldBinding binding;
-	boolean hasBeenResolved = false;
-
-	//allows to retrieve both the "type" part of the declaration (part1)
-	//and also the part that decribe the name and the init and optionally
-	//some other dimension ! .... 
-	//public int[] a, b[] = X, c ;
-	//for b that would give for 
-	// - part1 : public int[]
-	// - part2 : b[] = X,
-	
-	public int endPart1Position; 
-	public int endPart2Position;
-public FieldDeclaration(){}
-public FieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
-	
-	this.initialization = initialization;
-	this.name = name;
-
-	//due to some declaration like 
-	// int x, y = 3, z , x ;
-	//the sourceStart and the sourceEnd is ONLY on  the name
-
-	this.sourceStart = sourceStart;
-	this.sourceEnd = sourceEnd;
-}
-public FlowInfo analyseCode(MethodScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	if (initialization != null) {
-		flowInfo = initialization.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-		flowInfo.markAsDefinitelyAssigned(binding);
-	} else {
-		flowInfo.markAsDefinitelyNotAssigned(binding); // clear the bit in case it was already set (from enclosing info)
-	}
-	return flowInfo;
-}
-/**
- * Code generation for a field declaration
- *	i.e. normal assignment to a field 
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	// do not generate initialization code if final and static (constant is then
-	// recorded inside the field itself).
-	int pc = codeStream.position;
-	boolean isStatic;
-	if (initialization != null 
-		&& !((isStatic = binding.isStatic()) && binding.constant != NotAConstant)){
-		// non-static field, need receiver
-		if (!isStatic) codeStream.aload_0(); 
-		// generate initialization value
-		initialization.generateCode(currentScope, codeStream, true);
-		// store into field
-		if (isStatic) {
-			codeStream.putstatic(binding);
-		} else {
-			codeStream.putfield(binding);
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public TypeBinding getTypeBinding(Scope scope) {
-	return type.getTypeBinding(scope);
-}
-public boolean isField() {
-	return true;
-}
-public boolean isStatic() {
-	if (binding != null) return binding.isStatic();	
-	return (modifiers & AccStatic) != 0;
-}
-public String name(){
-
-	return String.valueOf(name) ;}
-public void resolve(MethodScope initializationScope) {
-	// the two <constant = Constant.NotAConstant> could be regrouped into
-	// a single line but it is clearer to have two lines while the reason of their
-	// existence is not at all the same. See comment for the second one.
-
-	//--------------------------------------------------------
-	if (!hasBeenResolved && binding != null && binding.isValidBinding()) {
-		hasBeenResolved = true;
-		if (isTypeUseDeprecated(binding.type, initializationScope))
-			initializationScope.problemReporter().deprecatedType(binding.type, type);
-
-		this.type.binding = this.binding.type; // update binding for type reference
-		
-		// the resolution of the initialization hasn't been done
-		if (initialization == null) {
-			binding.constant = Constant.NotAConstant;
-		} else {
-			// break dead-lock cycles by forcing constant to NotAConstant
-			int previous = initializationScope.fieldDeclarationIndex;
-			try {
-				initializationScope.fieldDeclarationIndex = binding.id;
-				binding.constant = Constant.NotAConstant;
-				TypeBinding tb = binding.type;
-				TypeBinding initTb;
-				if (initialization instanceof ArrayInitializer) {
-					if ((initTb = initialization.resolveTypeExpecting(initializationScope, tb)) != null) {
-						((ArrayInitializer) initialization).binding = (ArrayBinding) initTb;
-						initialization.implicitWidening(tb, initTb);
-					}
-				} else if ((initTb = initialization.resolveType(initializationScope)) != null) {
-					if (initialization.isConstantValueOfTypeAssignableToType(initTb, tb) || (tb.isBaseType() && BaseTypeBinding.isWidening(tb.id, initTb.id)))
-						initialization.implicitWidening(tb, initTb);
-					else if (initializationScope.areTypesCompatible(initTb, tb))
-						initialization.implicitWidening(tb, initTb);
-					else
-						initializationScope.problemReporter().typeMismatchError(initTb, tb, this);
-					if (binding.isFinal())  // cast from constant actual type to variable type
-						binding.constant = initialization.constant.castTo((binding.type.id << 4) + initialization.constant.typeID());
-				} else {
-					binding.constant = NotAConstant;
-				}
-			} finally {
-				initializationScope.fieldDeclarationIndex = previous;
-				if (binding.constant == null) binding.constant = Constant.NotAConstant;
-			}
-		}
-		// cannot define static non-constant field inside nested class
-		if (binding.isStatic() && binding.constant == NotAConstant)
-			if (binding.declaringClass.isNestedType() && binding.declaringClass.isClass() && !binding.declaringClass.isStatic())
-				initializationScope.problemReporter().unexpectedStaticModifierForField((SourceTypeBinding)binding.declaringClass, this);		
-	} 
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) {
-	visitor.visit(this, scope);
-	type.traverse(visitor, scope);
-	if (initialization != null) initialization.traverse(visitor, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*; 
+
+public class FieldDeclaration extends AbstractVariableDeclaration {
+	public FieldBinding binding;
+	boolean hasBeenResolved = false;
+
+	//allows to retrieve both the "type" part of the declaration (part1)
+	//and also the part that decribe the name and the init and optionally
+	//some other dimension ! .... 
+	//public int[] a, b[] = X, c ;
+	//for b that would give for 
+	// - part1 : public int[]
+	// - part2 : b[] = X,
+	
+	public int endPart1Position; 
+	public int endPart2Position;
+public FieldDeclaration(){}
+public FieldDeclaration(Expression initialization, char[] name, int sourceStart, int sourceEnd) {
+	
+	this.initialization = initialization;
+	this.name = name;
+
+	//due to some declaration like 
+	// int x, y = 3, z , x ;
+	//the sourceStart and the sourceEnd is ONLY on  the name
+
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+public FlowInfo analyseCode(MethodScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (initialization != null) {
+		flowInfo = initialization.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+		flowInfo.markAsDefinitelyAssigned(binding);
+	} else {
+		flowInfo.markAsDefinitelyNotAssigned(binding); // clear the bit in case it was already set (from enclosing info)
+	}
+	return flowInfo;
+}
+/**
+ * Code generation for a field declaration
+ *	i.e. normal assignment to a field 
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	// do not generate initialization code if final and static (constant is then
+	// recorded inside the field itself).
+	int pc = codeStream.position;
+	boolean isStatic;
+	if (initialization != null 
+		&& !((isStatic = binding.isStatic()) && binding.constant != NotAConstant)){
+		// non-static field, need receiver
+		if (!isStatic) codeStream.aload_0(); 
+		// generate initialization value
+		initialization.generateCode(currentScope, codeStream, true);
+		// store into field
+		if (isStatic) {
+			codeStream.putstatic(binding);
+		} else {
+			codeStream.putfield(binding);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public TypeBinding getTypeBinding(Scope scope) {
+	return type.getTypeBinding(scope);
+}
+public boolean isField() {
+	return true;
+}
+public boolean isStatic() {
+	if (binding != null) return binding.isStatic();	
+	return (modifiers & AccStatic) != 0;
+}
+public String name(){
+
+	return String.valueOf(name) ;}
+public void resolve(MethodScope initializationScope) {
+	// the two <constant = Constant.NotAConstant> could be regrouped into
+	// a single line but it is clearer to have two lines while the reason of their
+	// existence is not at all the same. See comment for the second one.
+
+	//--------------------------------------------------------
+	if (!hasBeenResolved && binding != null && binding.isValidBinding()) {
+		hasBeenResolved = true;
+		if (isTypeUseDeprecated(binding.type, initializationScope))
+			initializationScope.problemReporter().deprecatedType(binding.type, type);
+
+		this.type.binding = this.binding.type; // update binding for type reference
+		
+		// the resolution of the initialization hasn't been done
+		if (initialization == null) {
+			binding.constant = Constant.NotAConstant;
+		} else {
+			// break dead-lock cycles by forcing constant to NotAConstant
+			int previous = initializationScope.fieldDeclarationIndex;
+			try {
+				initializationScope.fieldDeclarationIndex = binding.id;
+				binding.constant = Constant.NotAConstant;
+				TypeBinding tb = binding.type;
+				TypeBinding initTb;
+				if (initialization instanceof ArrayInitializer) {
+					if ((initTb = initialization.resolveTypeExpecting(initializationScope, tb)) != null) {
+						((ArrayInitializer) initialization).binding = (ArrayBinding) initTb;
+						initialization.implicitWidening(tb, initTb);
+					}
+				} else if ((initTb = initialization.resolveType(initializationScope)) != null) {
+					if (initialization.isConstantValueOfTypeAssignableToType(initTb, tb) || (tb.isBaseType() && BaseTypeBinding.isWidening(tb.id, initTb.id)))
+						initialization.implicitWidening(tb, initTb);
+					else if (initializationScope.areTypesCompatible(initTb, tb))
+						initialization.implicitWidening(tb, initTb);
+					else
+						initializationScope.problemReporter().typeMismatchError(initTb, tb, this);
+					if (binding.isFinal())  // cast from constant actual type to variable type
+						binding.constant = initialization.constant.castTo((binding.type.id << 4) + initialization.constant.typeID());
+				} else {
+					binding.constant = NotAConstant;
+				}
+			} finally {
+				initializationScope.fieldDeclarationIndex = previous;
+				if (binding.constant == null) binding.constant = Constant.NotAConstant;
+			}
+		}
+		// cannot define static non-constant field inside nested class
+		if (binding.isStatic() && binding.constant == NotAConstant)
+			if (binding.declaringClass.isNestedType() && binding.declaringClass.isClass() && !binding.declaringClass.isStatic())
+				initializationScope.problemReporter().unexpectedStaticModifierForField((SourceTypeBinding)binding.declaringClass, this);		
+	} 
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) {
+	visitor.visit(this, scope);
+	type.traverse(visitor, scope);
+	if (initialization != null) initialization.traverse(visitor, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index e733ac9..97019d4 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,373 +1,372 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class FieldReference extends Reference implements InvocationSite {
-	public Expression receiver;
-	public char[] token;
-	public FieldBinding binding;
-
-	public long nameSourcePosition ; //(start<<32)+end
-	
-
-	MethodBinding syntheticReadAccessor, syntheticWriteAccessor;
-	public TypeBinding receiverType;
-
-public FieldReference(char[] source , long pos) {
-		token = source ;
-		nameSourcePosition = pos;
-		//by default the position are the one of the field (not true for super access)
-		sourceStart = (int) (pos>>>32) ;
-		sourceEnd = (int) (pos & 0x00000000FFFFFFFFL);
-		bits |= BindingIds.FIELD;
-	
-}
-public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
-
-	// compound assignment extra work
-	if (isCompound) { // check the variable part is initialized if blank final
-		if (binding.isFinal() && receiver.isThis() && currentScope.allowBlankFinalFieldAssignment(binding) && (!flowInfo.isDefinitelyAssigned(binding))) {
-			currentScope.problemReporter().uninitializedBlankFinalField(binding, this);
-			// we could improve error msg here telling "cannot use compound assignment on final blank field"
-		}
-		manageSyntheticReadAccessIfNecessary(currentScope);
-	}
-	if (assignment.expression != null) {
-		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-	}
-	flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()).unconditionalInits();
-	manageSyntheticWriteAccessIfNecessary(currentScope);
-
-	// check if assigning a final field 
-	if (binding.isFinal()) {
-		// in a context where it can be assigned?
-		if (receiver.isThis() && currentScope.allowBlankFinalFieldAssignment(binding)) {
-			if (flowInfo.isPotentiallyAssigned(binding)) {
-				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(binding, this);
-			}
-			flowInfo.markAsDefinitelyAssigned(binding);
-			flowContext.recordSettingFinal(binding, this);
-		} else {
-			// assigning a final field outside an initializer or constructor
-			currentScope.problemReporter().cannotAssignToFinalField(binding, this);
-		}
-	}
-	return flowInfo;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return analyseCode(currentScope, flowContext, flowInfo, true);
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
-	receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic());
-	if (valueRequired) {
-		manageSyntheticReadAccessIfNecessary(currentScope);
-	}
-	return flowInfo;
-}
-public FieldBinding fieldBinding() {
-	//FLOW ANALYSIS
-	
-	return binding ; }
-public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
-
-	receiver.generateCode(currentScope, codeStream, !binding.isStatic());
-	assignment.expression.generateCode(currentScope, codeStream, true);
-	fieldStore(codeStream, binding, syntheticWriteAccessor, valueRequired);
-	if (valueRequired){
-		codeStream.generateImplicitConversion(assignment.implicitConversion);
-	}
-}
-/**
- * Field reference code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	if (constant != NotAConstant) {
-		if (valueRequired) {
-			codeStream.generateConstant(constant, implicitConversion);
-		}
-	} else {
-		boolean isStatic = binding.isStatic();
-		receiver.generateCode(currentScope, codeStream, valueRequired && (!isStatic) && (binding.constant == NotAConstant));
-		if (valueRequired) {
-			if (binding.constant == NotAConstant) {
-				if (binding.declaringClass == null) { // array length
-					codeStream.arraylength();
-				} else {
-					if (syntheticReadAccessor == null) {
-						if (isStatic) {
-							codeStream.getstatic(binding);
-						} else {
-							codeStream.getfield(binding);
-						}
-					} else {
-						codeStream.invokestatic(syntheticReadAccessor);
-					}
-				}
-				codeStream.generateImplicitConversion(implicitConversion);
-			} else {
-				codeStream.generateConstant(binding.constant, implicitConversion);
-			}
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
-	boolean isStatic;
-	receiver.generateCode(currentScope, codeStream, !(isStatic = binding.isStatic()));
-	if (isStatic) {
-		if (syntheticReadAccessor == null) {
-			codeStream.getstatic(binding);
-		} else {
-			codeStream.invokestatic(syntheticReadAccessor);
-		}
-	} else {
-		codeStream.dup();
-		if (syntheticReadAccessor == null) {
-			codeStream.getfield(binding);
-		} else {
-			codeStream.invokestatic(syntheticReadAccessor);
-		}
-	}
-	int operationTypeID;
-	if ((operationTypeID = implicitConversion >> 4) == T_String) {
-		codeStream.generateStringAppend(currentScope, null, expression);
-	} else {
-		// promote the array reference to the suitable operation type
-		codeStream.generateImplicitConversion(implicitConversion);
-		// generate the increment value (will by itself  be promoted to the operation value)
-		if (expression == IntLiteral.One){ // prefix operation
-			codeStream.generateConstant(expression.constant, implicitConversion);			
-		} else {
-			expression.generateCode(currentScope, codeStream, true);
-		}		
-		// perform the operation
-		codeStream.sendOperator(operator, operationTypeID);
-		// cast the value back to the array reference type
-		codeStream.generateImplicitConversion(assignmentImplicitConversion);
-	}
-		fieldStore(codeStream, binding, syntheticWriteAccessor, valueRequired);
-}
-public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
-	boolean isStatic;
-	receiver.generateCode(currentScope, codeStream, !(isStatic = binding.isStatic()));
-	if (isStatic) {
-		if (syntheticReadAccessor == null) {
-			codeStream.getstatic(binding);
-		} else {
-			codeStream.invokestatic(syntheticReadAccessor);
-		}
-	} else {
-		codeStream.dup();
-		if (syntheticReadAccessor == null) {
-			codeStream.getfield(binding);
-		} else {
-			codeStream.invokestatic(syntheticReadAccessor);
-		}
-	}
-	if (valueRequired) {
-		if (isStatic) {
-			if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) {
-				codeStream.dup2();
-			} else {
-				codeStream.dup();
-			}
-		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
-			if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) {
-				codeStream.dup2_x1();
-			} else {
-				codeStream.dup_x1();
-			}
-		}
-	}
-	codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
-	codeStream.sendOperator(postIncrement.operator, binding.type.id);
-	codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
-	fieldStore(codeStream, binding, syntheticWriteAccessor, false);
-}
-public static final Constant getConstantFor(
-	FieldBinding binding, 
-	boolean implicitReceiver, 
-	Reference ref, 
-	int indexInQualification) {
-	//propagation of the constant.
-
-	//ref can be a FieldReference, a SingleNameReference or a QualifiedNameReference
-	//indexInQualification may have a value greater than zero only for QualifiednameReference
-	//if ref==null then indexInQualification==0 AND implicitReceiver == false. This case is a 
-	//degenerated case where a fake reference field (null) 
-	//is associted to a real FieldBinding in order 
-	//to allow its constant computation using the regular path (i.e. find the fieldDeclaration
-	//and proceed to its type resolution). As implicitReceiver is false, no error reporting
-	//against ref will be used ==> no nullPointerException risk .... 
-
-	//special treatment for langage-built-in  field (their declaring class is null)
-	if (binding.declaringClass == null) {
-		//currently only one field "length" : the constant computation is never done
-		return NotAConstant;
-	}
-	if (!binding.isFinal()) {
-		return binding.constant = NotAConstant;
-	}
-	if (binding.constant != null) {
-		if (indexInQualification == 0) {
-			return binding.constant;
-		}
-		//see previous comment for the (sould-always-be) valid cast
-		QualifiedNameReference qnr = (QualifiedNameReference) ref;
-		if (indexInQualification == (qnr.indexOfFirstFieldBinding - 1)) {
-			return binding.constant;
-		}
-		return NotAConstant;
-	}
-	//The field has not been yet type checked.
-	//It also means that the field is not coming from a class that
-	//has already been compiled. It can only be from a class within
-	//compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
-
-	SourceTypeBinding tb = (SourceTypeBinding) binding.declaringClass;
-	TypeDeclaration typeDecl = tb.scope.referenceContext;
-
-	//fetch the field declaration
-	FieldDeclaration fieldDecl = null;
-	int index = 0;
-	FieldDeclaration[] fields = typeDecl.fields;
-	while (fieldDecl == null) {
-		if ((fields[index].isField())
-			&& (CharOperation.equals(fields[index].name, binding.name)))
-			fieldDecl = fields[index];
-		else
-			index++;
-	}
-	//what scope to use (depend on the staticness of the field binding)
-	MethodScope fieldScope = 
-		binding.isStatic()
-			? typeDecl.staticInitializerScope
-			: typeDecl.initializerScope; 
-	if (implicitReceiver) { //Determine if the ref is legal in the current class of the field
-		//i.e. not a forward reference .... (they are allowed when the receiver is explicit ! ... Please don't ask me why !...yet another java mystery...)
-		if (fieldScope.fieldDeclarationIndex == MethodScope.NotInFieldDecl) {
-			// no field is currently being analysed in typeDecl
-			fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
-			return binding.constant;
-		}
-		//We are re-entering the same class fields analysing
-		if (((ref == null) || ((ref.bits & DepthMASK) == 0)) // not implicit ref to enclosing field
-			&& (binding.id > fieldScope.fieldDeclarationIndex)) {
-			//forward reference. The declaration remains unresolved.
-			tb.scope.problemReporter().forwardReference(ref, indexInQualification, tb);
-			return NotAConstant;
-		}
-		fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
-		return binding.constant;
-	}
-	//the field reference is explicity. It has to be a "simple" like field reference to get the
-	//constant propagation. For example in Packahe.Type.field1.field2 , field1 may have its
-	//constant having a propagation where field2 is always not propagating its
-	if (indexInQualification == 0) {
-		fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
-		return binding.constant;
-	}
-	// Side-effect on the field binding may not be propagated out for the qualified reference
-	// unless it occurs in first place of the name sequence
-	fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
-	//see previous comment for the cast that should always be valid
-	QualifiedNameReference qnr = (QualifiedNameReference) ref;
-	if (indexInQualification == (qnr.indexOfFirstFieldBinding - 1)) {
-		return binding.constant;
-	} else {
-		return NotAConstant;
-	}
-}
-
-public boolean isSuperAccess() {
-
-	return receiver.isSuper();
-}
-public boolean isTypeAccess() {	
-	return receiver != null && receiver.isTypeReference();
-}
-/*
- * No need to emulate access to protected fields since not implicitly accessed
- */
-public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope){
-	if (binding.isPrivate() 
-		&& (currentScope.enclosingSourceType() != binding.declaringClass)
-		&& (binding.constant == NotAConstant)) {
-		syntheticReadAccessor = binding.getSyntheticReadAccess();
-	}
-}
-/*
- * No need to emulate access to protected fields since not implicitly accessed
- */
-public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope){
-	if (binding.isPrivate() && (currentScope.enclosingSourceType() != binding.declaringClass)) {
-		syntheticWriteAccessor = binding.getSyntheticWriteAccess();
-	}
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// Answer the signature type of the field.
-	// constants are propaged when the field is final
-	// and initialized with a (compile time) constant 
-
-	// regular receiver reference 
-	this.receiverType = receiver.resolveType(scope);
-	if (this.receiverType == null){
-		constant = NotAConstant;
-		return null;
-	}
-	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
-	binding = scope.getField(this.receiverType, token, this);
-	if (!binding.isValidBinding()) {
-		constant = NotAConstant;
-		scope.problemReporter().invalidField(this, this.receiverType);
-		return null;
-	}
-
-	if (isFieldUseDeprecated(binding, scope))
-		scope.problemReporter().deprecatedField(binding, this);
-
-	// check for this.x in static is done in the resolution of the receiver
-	constant = FieldReference.getConstantFor(binding, receiver == ThisReference.ThisImplicit, this, 0);
-	if (!receiver.isThis())
-		constant = NotAConstant;
-
-	// if the binding declaring class is not visible, need special action
-	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
-	if (binding.declaringClass != this.receiverType
-		&& binding.declaringClass != null // array.length
-		&& binding.constant == NotAConstant
-		&& !binding.declaringClass.canBeSeenBy(scope))
-			binding = new FieldBinding(binding, (ReferenceBinding) this.receiverType);
-	return binding.type;
-}
-public void setDepth(int d) {
-}
-public void setFieldIndex(int index){}
-public String toStringExpression(){
-	/* slow code */
-	
-	return 	receiver.toString()
-			+ "."/*nonNLS*/ 
-			+ new String(token);}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		receiver.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class FieldReference extends Reference implements InvocationSite {
+	public Expression receiver;
+	public char[] token;
+	public FieldBinding binding;
+
+	public long nameSourcePosition ; //(start<<32)+end
+	
+
+	MethodBinding syntheticReadAccessor, syntheticWriteAccessor;
+	public TypeBinding receiverType;
+
+public FieldReference(char[] source , long pos) {
+		token = source ;
+		nameSourcePosition = pos;
+		//by default the position are the one of the field (not true for super access)
+		sourceStart = (int) (pos>>>32) ;
+		sourceEnd = (int) (pos & 0x00000000FFFFFFFFL);
+		bits |= BindingIds.FIELD;
+	
+}
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+
+	// compound assignment extra work
+	if (isCompound) { // check the variable part is initialized if blank final
+		if (binding.isFinal() && receiver.isThis() && currentScope.allowBlankFinalFieldAssignment(binding) && (!flowInfo.isDefinitelyAssigned(binding))) {
+			currentScope.problemReporter().uninitializedBlankFinalField(binding, this);
+			// we could improve error msg here telling "cannot use compound assignment on final blank field"
+		}
+		manageSyntheticReadAccessIfNecessary(currentScope);
+	}
+	if (assignment.expression != null) {
+		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+	}
+	flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()).unconditionalInits();
+	manageSyntheticWriteAccessIfNecessary(currentScope);
+
+	// check if assigning a final field 
+	if (binding.isFinal()) {
+		// in a context where it can be assigned?
+		if (receiver.isThis() && currentScope.allowBlankFinalFieldAssignment(binding)) {
+			if (flowInfo.isPotentiallyAssigned(binding)) {
+				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(binding, this);
+			}
+			flowInfo.markAsDefinitelyAssigned(binding);
+			flowContext.recordSettingFinal(binding, this);
+		} else {
+			// assigning a final field outside an initializer or constructor
+			currentScope.problemReporter().cannotAssignToFinalField(binding, this);
+		}
+	}
+	return flowInfo;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic());
+	if (valueRequired) {
+		manageSyntheticReadAccessIfNecessary(currentScope);
+	}
+	return flowInfo;
+}
+public FieldBinding fieldBinding() {
+	//FLOW ANALYSIS
+	
+	return binding ; }
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+
+	receiver.generateCode(currentScope, codeStream, !binding.isStatic());
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	fieldStore(codeStream, binding, syntheticWriteAccessor, valueRequired);
+	if (valueRequired){
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+/**
+ * Field reference code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (constant != NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(constant, implicitConversion);
+		}
+	} else {
+		boolean isStatic = binding.isStatic();
+		receiver.generateCode(currentScope, codeStream, valueRequired && (!isStatic) && (binding.constant == NotAConstant));
+		if (valueRequired) {
+			if (binding.constant == NotAConstant) {
+				if (binding.declaringClass == null) { // array length
+					codeStream.arraylength();
+				} else {
+					if (syntheticReadAccessor == null) {
+						if (isStatic) {
+							codeStream.getstatic(binding);
+						} else {
+							codeStream.getfield(binding);
+						}
+					} else {
+						codeStream.invokestatic(syntheticReadAccessor);
+					}
+				}
+				codeStream.generateImplicitConversion(implicitConversion);
+			} else {
+				codeStream.generateConstant(binding.constant, implicitConversion);
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	boolean isStatic;
+	receiver.generateCode(currentScope, codeStream, !(isStatic = binding.isStatic()));
+	if (isStatic) {
+		if (syntheticReadAccessor == null) {
+			codeStream.getstatic(binding);
+		} else {
+			codeStream.invokestatic(syntheticReadAccessor);
+		}
+	} else {
+		codeStream.dup();
+		if (syntheticReadAccessor == null) {
+			codeStream.getfield(binding);
+		} else {
+			codeStream.invokestatic(syntheticReadAccessor);
+		}
+	}
+	int operationTypeID;
+	if ((operationTypeID = implicitConversion >> 4) == T_String) {
+		codeStream.generateStringAppend(currentScope, null, expression);
+	} else {
+		// promote the array reference to the suitable operation type
+		codeStream.generateImplicitConversion(implicitConversion);
+		// generate the increment value (will by itself  be promoted to the operation value)
+		if (expression == IntLiteral.One){ // prefix operation
+			codeStream.generateConstant(expression.constant, implicitConversion);			
+		} else {
+			expression.generateCode(currentScope, codeStream, true);
+		}		
+		// perform the operation
+		codeStream.sendOperator(operator, operationTypeID);
+		// cast the value back to the array reference type
+		codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+		fieldStore(codeStream, binding, syntheticWriteAccessor, valueRequired);
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	boolean isStatic;
+	receiver.generateCode(currentScope, codeStream, !(isStatic = binding.isStatic()));
+	if (isStatic) {
+		if (syntheticReadAccessor == null) {
+			codeStream.getstatic(binding);
+		} else {
+			codeStream.invokestatic(syntheticReadAccessor);
+		}
+	} else {
+		codeStream.dup();
+		if (syntheticReadAccessor == null) {
+			codeStream.getfield(binding);
+		} else {
+			codeStream.invokestatic(syntheticReadAccessor);
+		}
+	}
+	if (valueRequired) {
+		if (isStatic) {
+			if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) {
+				codeStream.dup2();
+			} else {
+				codeStream.dup();
+			}
+		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+			if ((binding.type == LongBinding) || (binding.type == DoubleBinding)) {
+				codeStream.dup2_x1();
+			} else {
+				codeStream.dup_x1();
+			}
+		}
+	}
+	codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, binding.type.id);
+	codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+	fieldStore(codeStream, binding, syntheticWriteAccessor, false);
+}
+public static final Constant getConstantFor(
+	FieldBinding binding, 
+	boolean implicitReceiver, 
+	Reference ref, 
+	int indexInQualification) {
+	//propagation of the constant.
+
+	//ref can be a FieldReference, a SingleNameReference or a QualifiedNameReference
+	//indexInQualification may have a value greater than zero only for QualifiednameReference
+	//if ref==null then indexInQualification==0 AND implicitReceiver == false. This case is a 
+	//degenerated case where a fake reference field (null) 
+	//is associted to a real FieldBinding in order 
+	//to allow its constant computation using the regular path (i.e. find the fieldDeclaration
+	//and proceed to its type resolution). As implicitReceiver is false, no error reporting
+	//against ref will be used ==> no nullPointerException risk .... 
+
+	//special treatment for langage-built-in  field (their declaring class is null)
+	if (binding.declaringClass == null) {
+		//currently only one field "length" : the constant computation is never done
+		return NotAConstant;
+	}
+	if (!binding.isFinal()) {
+		return binding.constant = NotAConstant;
+	}
+	if (binding.constant != null) {
+		if (indexInQualification == 0) {
+			return binding.constant;
+		}
+		//see previous comment for the (sould-always-be) valid cast
+		QualifiedNameReference qnr = (QualifiedNameReference) ref;
+		if (indexInQualification == (qnr.indexOfFirstFieldBinding - 1)) {
+			return binding.constant;
+		}
+		return NotAConstant;
+	}
+	//The field has not been yet type checked.
+	//It also means that the field is not coming from a class that
+	//has already been compiled. It can only be from a class within
+	//compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
+
+	SourceTypeBinding tb = (SourceTypeBinding) binding.declaringClass;
+	TypeDeclaration typeDecl = tb.scope.referenceContext;
+
+	//fetch the field declaration
+	FieldDeclaration fieldDecl = null;
+	int index = 0;
+	FieldDeclaration[] fields = typeDecl.fields;
+	while (fieldDecl == null) {
+		if ((fields[index].isField())
+			&& (CharOperation.equals(fields[index].name, binding.name)))
+			fieldDecl = fields[index];
+		else
+			index++;
+	}
+	//what scope to use (depend on the staticness of the field binding)
+	MethodScope fieldScope = 
+		binding.isStatic()
+			? typeDecl.staticInitializerScope
+			: typeDecl.initializerScope; 
+	if (implicitReceiver) { //Determine if the ref is legal in the current class of the field
+		//i.e. not a forward reference .... (they are allowed when the receiver is explicit ! ... Please don't ask me why !...yet another java mystery...)
+		if (fieldScope.fieldDeclarationIndex == MethodScope.NotInFieldDecl) {
+			// no field is currently being analysed in typeDecl
+			fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
+			return binding.constant;
+		}
+		//We are re-entering the same class fields analysing
+		if (((ref == null) || ((ref.bits & DepthMASK) == 0)) // not implicit ref to enclosing field
+			&& (binding.id > fieldScope.fieldDeclarationIndex)) {
+			//forward reference. The declaration remains unresolved.
+			tb.scope.problemReporter().forwardReference(ref, indexInQualification, tb);
+			return NotAConstant;
+		}
+		fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
+		return binding.constant;
+	}
+	//the field reference is explicity. It has to be a "simple" like field reference to get the
+	//constant propagation. For example in Packahe.Type.field1.field2 , field1 may have its
+	//constant having a propagation where field2 is always not propagating its
+	if (indexInQualification == 0) {
+		fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
+		return binding.constant;
+	}
+	// Side-effect on the field binding may not be propagated out for the qualified reference
+	// unless it occurs in first place of the name sequence
+	fieldDecl.resolve(fieldScope); //side effect on binding :-) ... 
+	//see previous comment for the cast that should always be valid
+	QualifiedNameReference qnr = (QualifiedNameReference) ref;
+	if (indexInQualification == (qnr.indexOfFirstFieldBinding - 1)) {
+		return binding.constant;
+	} else {
+		return NotAConstant;
+	}
+}
+
+public boolean isSuperAccess() {
+
+	return receiver.isSuper();
+}
+public boolean isTypeAccess() {	
+	return receiver != null && receiver.isTypeReference();
+}
+/*
+ * No need to emulate access to protected fields since not implicitly accessed
+ */
+public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope){
+	if (binding.isPrivate() 
+		&& (currentScope.enclosingSourceType() != binding.declaringClass)
+		&& (binding.constant == NotAConstant)) {
+		syntheticReadAccessor = binding.getSyntheticReadAccess();
+	}
+}
+/*
+ * No need to emulate access to protected fields since not implicitly accessed
+ */
+public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope){
+	if (binding.isPrivate() && (currentScope.enclosingSourceType() != binding.declaringClass)) {
+		syntheticWriteAccessor = binding.getSyntheticWriteAccess();
+	}
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature type of the field.
+	// constants are propaged when the field is final
+	// and initialized with a (compile time) constant 
+
+	// regular receiver reference 
+	this.receiverType = receiver.resolveType(scope);
+	if (this.receiverType == null){
+		constant = NotAConstant;
+		return null;
+	}
+	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
+	binding = scope.getField(this.receiverType, token, this);
+	if (!binding.isValidBinding()) {
+		constant = NotAConstant;
+		scope.problemReporter().invalidField(this, this.receiverType);
+		return null;
+	}
+
+	if (isFieldUseDeprecated(binding, scope))
+		scope.problemReporter().deprecatedField(binding, this);
+
+	// check for this.x in static is done in the resolution of the receiver
+	constant = FieldReference.getConstantFor(binding, receiver == ThisReference.ThisImplicit, this, 0);
+	if (!receiver.isThis())
+		constant = NotAConstant;
+
+	// if the binding declaring class is not visible, need special action
+	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+	if (binding.declaringClass != this.receiverType
+		&& binding.declaringClass != null // array.length
+		&& binding.constant == NotAConstant
+		&& !binding.declaringClass.canBeSeenBy(scope))
+			binding = new FieldBinding(binding, (ReferenceBinding) this.receiverType);
+	return binding.type;
+}
+public void setDepth(int d) {
+}
+public void setFieldIndex(int index){}
+public String toStringExpression(){
+	/* slow code */
+	
+	return 	receiver.toString()
+			+ "."/*nonNLS*/ 
+			+ new String(token);}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		receiver.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index 37e6887..3e1ad0b 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -1,260 +1,259 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class ForStatement extends Statement {
-	public Statement[] initializations ;
-	public Expression condition ;
-	public Statement[] increments ;
-	public Statement action ;
-
-	//when there is no local declaration, there is no need of a new scope
-	//scope is positionned either to a new scope, or to the "upper"scope (see resolveType)
-	public boolean neededScope;
-	public BlockScope scope;
-	
-	private Label breakLabel, continueLabel;
-
-	// for local variables table attributes
-	int preCondInitStateIndex = -1;
-	int condIfTrueInitStateIndex = -1;
-	int mergedInitStateIndex = -1;
-public ForStatement(Statement[] initializations, Expression condition, Statement[] increments, Statement action, boolean neededScope, int s, int e) {
-	this.sourceStart = s;
-	this.sourceEnd = e;
-	this.initializations = initializations;
-	this.condition = condition;
-	this.increments = increments;
-	this.action = action;
-	this.neededScope = neededScope;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	breakLabel = new Label();
-	continueLabel = new Label();
-
-	// process the initializations
-	if (initializations != null) {
-		int count = initializations.length, i = 0;
-		while (i < count) {
-			flowInfo = initializations[i++].analyseCode(scope, flowContext, flowInfo);
-		}
-	}
-	preCondInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
-	
-	// process the condition
-	LoopingFlowContext condLoopContext = null;
-	if (condition != null) {
-		if ((condition.constant == NotAConstant) || (condition.constant.booleanValue() != true)) {
-			flowInfo = condition.analyseCode(scope, (condLoopContext = new LoopingFlowContext(flowContext, this, null, null, scope)), flowInfo);
-		}
-	}
-
-	// process the action
-	LoopingFlowContext loopingContext;
-	FlowInfo actionInfo;
-	if ((action == null) || action.isEmptyBlock()) {
-		if (condLoopContext != null) condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
-		if ((condition == null) || ((condition.constant != NotAConstant) && (condition.constant.booleanValue() == true))) {
-			return FlowInfo.DeadEnd;
-		} else {
-			actionInfo = flowInfo.initsWhenTrue().copy();
-			loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope);
-		}
-	} else {
-		loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope);
-		FlowInfo initsWhenTrue = flowInfo.initsWhenTrue();
-		condIfTrueInitStateIndex = currentScope.methodScope().recordInitializationStates(initsWhenTrue);
-		actionInfo = action.analyseCode(
-			scope, 
-			loopingContext, 
-			((condition != null) && (condition.constant != NotAConstant) && (condition.constant.booleanValue() == false)) ? // unreachable when condition inlined to false
-				FlowInfo.DeadEnd : 
-				initsWhenTrue.copy());
-
-		// code generation can be optimized when no need to continue in the loop
-		if (((actionInfo == FlowInfo.DeadEnd) || actionInfo.isFakeReachable())
-			&& ((loopingContext.initsOnContinue == FlowInfo.DeadEnd) || loopingContext.initsOnContinue.isFakeReachable())){
-				continueLabel = null;
-		} else {
-			if (condLoopContext != null) condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
-			loopingContext.complainOnFinalAssignmentsInLoop(scope, actionInfo);
-			actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue.unconditionalInits()); // for increments
-		}
-	}
-	if ((continueLabel != null) && (increments != null)) {
-		LoopingFlowContext loopContext = new LoopingFlowContext(flowContext, this, null, null, scope);
-		int i = 0, count = increments.length;
-		while (i < count)
-			actionInfo = increments[i++].analyseCode(scope, loopContext, actionInfo);
-		loopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
-	}
-
-	// infinite loop
-	FlowInfo mergedInfo;
-	if ((condition == null) || ((condition.constant != NotAConstant) && (condition.constant.booleanValue() == true))) {
-		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo = loopingContext.initsOnBreak);
-		return mergedInfo;
-	}
-
-	//end of loop: either condition false or break
-	mergedInfo = flowInfo.initsWhenFalse().unconditionalInits().mergedWith(loopingContext.initsOnBreak.unconditionalInits());
-	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
-	return mergedInfo;
-}
-/**
- * For statement code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	int pc = codeStream.position;
-
-	// generate the initializations
-	if (initializations != null){
-		for (int i = 0, max = initializations.length; i < max; i++){
-			initializations[i].generateCode(scope, codeStream);
-		}
-	}
-
-	// label management
-	Label actionLabel = new Label(codeStream);
-	Label conditionLabel = new Label(codeStream);
-	breakLabel.codeStream = codeStream;
-	if (continueLabel != null) {
-		continueLabel.codeStream = codeStream;
-	}
-	// jump over the actionBlock
-	if ((condition != null) 
-		&& (condition.constant == NotAConstant) 
-		&& !((action == null || action.isEmptyBlock()) && (increments == null))) {
-		int jumpPC = codeStream.position;
-		codeStream.goto_(conditionLabel);
-		codeStream.recordPositionsFrom(jumpPC, condition);
-	}
-	// generate the loop action
-	actionLabel.place();
-	if (action != null) {
-		// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
-		if (condIfTrueInitStateIndex != -1){ // insert all locals initialized inside the condition into the action generated prior to the condition
-			codeStream.addDefinitelyAssignedVariables(currentScope, condIfTrueInitStateIndex);
-		}
-		action.generateCode(scope, codeStream);
-	}
-	// continuation point
-	if (continueLabel != null) {
-		continueLabel.place();
-		// generate the increments for next iteration
-		if (increments != null) {
-			for (int i = 0, max = increments.length; i < max; i++) {
-				increments[i].generateCode(scope, codeStream);
-			}
-		}
-	}
-	
-	// May loose some local variable initializations : affecting the local variable attributes
-	if (preCondInitStateIndex != -1) {
-		codeStream.removeNotDefinitelyAssignedVariables(currentScope, preCondInitStateIndex);
-	}	
-	
-	// generate the condition
-	conditionLabel.place();
-	if ((condition != null) && (condition.constant == NotAConstant)) {
-		condition.generateOptimizedBoolean(scope, codeStream, actionLabel, null, true);
-	} else {
-		if (continueLabel != null) {
-			codeStream.goto_(actionLabel);
-		}
-	}
-	breakLabel.place();
-	
-	// May loose some local variable initializations : affecting the local variable attributes
-	if (neededScope) {
-		codeStream.exitUserScope(scope);		
-	}
-	if (mergedInitStateIndex != -1) {
-		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void resolve(BlockScope upperScope) {
-	// use the scope that will hold the init declarations
-
-	scope = neededScope ? new BlockScope(upperScope) : upperScope;
-	if (initializations != null)
-		for (int i = 0, length = initializations.length; i < length; i++)
-			initializations[i].resolve(scope);
-	if (condition != null) {
-		TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding);
-		condition.implicitWidening(type, type);
-	}
-	if (increments != null)
-		for (int i = 0, length = increments.length; i < length; i++)
-			increments[i].resolve(scope);
-	if (action != null)
-		action.resolve(scope);
-}
-public String toString(int tab ){
-	/* slow code */
-	
-	String s = tabString(tab) + "for ("/*nonNLS*/;
-	if (!neededScope)
-		s = s + " //--NO upperscope scope needed\n"/*nonNLS*/ + tabString(tab) + "     "/*nonNLS*/ ;
-	//inits
-	if (initializations != null)
-	{	for (int i = 0 ; i < initializations.length ; i++){
-			//nice only with expressions
-			s = s + initializations[i].toString(0);
-			if (i != (initializations.length -1)) s = s + " , "/*nonNLS*/ ;}};
-	s = s + "; "/*nonNLS*/ ;
-	//cond
-	if (condition != null)
-		s = s + condition.toStringExpression() ;
-	s = s + "; "/*nonNLS*/ ;
-	//updates
-	if (increments != null)
-	{	for (int i = 0 ; i < increments.length ; i++){
-			//nice only with expressions
-			s = s + increments[i].toString(0);
-			if (i != (increments.length -1)) s = s + " , "/*nonNLS*/ ;}};
-	s = s + ") "/*nonNLS*/ ;
-	//block
-	if (action == null)
-		s = s + "{}"/*nonNLS*/ ;
-	else
-		s = s + "\n"/*nonNLS*/+ action.toString(tab+1) ;
-	return s;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		if (initializations != null) {
-			int initializationsLength = initializations.length;
-			for (int i = 0; i < initializationsLength; i++)
-				initializations[i].traverse(visitor, scope);
-		}
-
-		if (condition != null)
-			condition.traverse(visitor, scope);
-
-		if (increments != null) {
-			int incrementsLength = increments.length;
-			for (int i = 0; i < incrementsLength; i++)
-				increments[i].traverse(visitor, scope);
-		}
-
-		if (action != null)
-			action.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ForStatement extends Statement {
+	public Statement[] initializations ;
+	public Expression condition ;
+	public Statement[] increments ;
+	public Statement action ;
+
+	//when there is no local declaration, there is no need of a new scope
+	//scope is positionned either to a new scope, or to the "upper"scope (see resolveType)
+	public boolean neededScope;
+	public BlockScope scope;
+	
+	private Label breakLabel, continueLabel;
+
+	// for local variables table attributes
+	int preCondInitStateIndex = -1;
+	int condIfTrueInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+public ForStatement(Statement[] initializations, Expression condition, Statement[] increments, Statement action, boolean neededScope, int s, int e) {
+	this.sourceStart = s;
+	this.sourceEnd = e;
+	this.initializations = initializations;
+	this.condition = condition;
+	this.increments = increments;
+	this.action = action;
+	this.neededScope = neededScope;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	breakLabel = new Label();
+	continueLabel = new Label();
+
+	// process the initializations
+	if (initializations != null) {
+		int count = initializations.length, i = 0;
+		while (i < count) {
+			flowInfo = initializations[i++].analyseCode(scope, flowContext, flowInfo);
+		}
+	}
+	preCondInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+	
+	// process the condition
+	LoopingFlowContext condLoopContext = null;
+	if (condition != null) {
+		if ((condition.constant == NotAConstant) || (condition.constant.booleanValue() != true)) {
+			flowInfo = condition.analyseCode(scope, (condLoopContext = new LoopingFlowContext(flowContext, this, null, null, scope)), flowInfo);
+		}
+	}
+
+	// process the action
+	LoopingFlowContext loopingContext;
+	FlowInfo actionInfo;
+	if ((action == null) || action.isEmptyBlock()) {
+		if (condLoopContext != null) condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
+		if ((condition == null) || ((condition.constant != NotAConstant) && (condition.constant.booleanValue() == true))) {
+			return FlowInfo.DeadEnd;
+		} else {
+			actionInfo = flowInfo.initsWhenTrue().copy();
+			loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope);
+		}
+	} else {
+		loopingContext = new LoopingFlowContext(flowContext, this, breakLabel, continueLabel, scope);
+		FlowInfo initsWhenTrue = flowInfo.initsWhenTrue();
+		condIfTrueInitStateIndex = currentScope.methodScope().recordInitializationStates(initsWhenTrue);
+		actionInfo = action.analyseCode(
+			scope, 
+			loopingContext, 
+			((condition != null) && (condition.constant != NotAConstant) && (condition.constant.booleanValue() == false)) ? // unreachable when condition inlined to false
+				FlowInfo.DeadEnd : 
+				initsWhenTrue.copy());
+
+		// code generation can be optimized when no need to continue in the loop
+		if (((actionInfo == FlowInfo.DeadEnd) || actionInfo.isFakeReachable())
+			&& ((loopingContext.initsOnContinue == FlowInfo.DeadEnd) || loopingContext.initsOnContinue.isFakeReachable())){
+				continueLabel = null;
+		} else {
+			if (condLoopContext != null) condLoopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
+			loopingContext.complainOnFinalAssignmentsInLoop(scope, actionInfo);
+			actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue.unconditionalInits()); // for increments
+		}
+	}
+	if ((continueLabel != null) && (increments != null)) {
+		LoopingFlowContext loopContext = new LoopingFlowContext(flowContext, this, null, null, scope);
+		int i = 0, count = increments.length;
+		while (i < count)
+			actionInfo = increments[i++].analyseCode(scope, loopContext, actionInfo);
+		loopContext.complainOnFinalAssignmentsInLoop(scope, flowInfo);
+	}
+
+	// infinite loop
+	FlowInfo mergedInfo;
+	if ((condition == null) || ((condition.constant != NotAConstant) && (condition.constant.booleanValue() == true))) {
+		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo = loopingContext.initsOnBreak);
+		return mergedInfo;
+	}
+
+	//end of loop: either condition false or break
+	mergedInfo = flowInfo.initsWhenFalse().unconditionalInits().mergedWith(loopingContext.initsOnBreak.unconditionalInits());
+	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+	return mergedInfo;
+}
+/**
+ * For statement code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	// generate the initializations
+	if (initializations != null){
+		for (int i = 0, max = initializations.length; i < max; i++){
+			initializations[i].generateCode(scope, codeStream);
+		}
+	}
+
+	// label management
+	Label actionLabel = new Label(codeStream);
+	Label conditionLabel = new Label(codeStream);
+	breakLabel.codeStream = codeStream;
+	if (continueLabel != null) {
+		continueLabel.codeStream = codeStream;
+	}
+	// jump over the actionBlock
+	if ((condition != null) 
+		&& (condition.constant == NotAConstant) 
+		&& !((action == null || action.isEmptyBlock()) && (increments == null))) {
+		int jumpPC = codeStream.position;
+		codeStream.goto_(conditionLabel);
+		codeStream.recordPositionsFrom(jumpPC, condition);
+	}
+	// generate the loop action
+	actionLabel.place();
+	if (action != null) {
+		// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+		if (condIfTrueInitStateIndex != -1){ // insert all locals initialized inside the condition into the action generated prior to the condition
+			codeStream.addDefinitelyAssignedVariables(currentScope, condIfTrueInitStateIndex);
+		}
+		action.generateCode(scope, codeStream);
+	}
+	// continuation point
+	if (continueLabel != null) {
+		continueLabel.place();
+		// generate the increments for next iteration
+		if (increments != null) {
+			for (int i = 0, max = increments.length; i < max; i++) {
+				increments[i].generateCode(scope, codeStream);
+			}
+		}
+	}
+	
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (preCondInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, preCondInitStateIndex);
+	}	
+	
+	// generate the condition
+	conditionLabel.place();
+	if ((condition != null) && (condition.constant == NotAConstant)) {
+		condition.generateOptimizedBoolean(scope, codeStream, actionLabel, null, true);
+	} else {
+		if (continueLabel != null) {
+			codeStream.goto_(actionLabel);
+		}
+	}
+	breakLabel.place();
+	
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (neededScope) {
+		codeStream.exitUserScope(scope);		
+	}
+	if (mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void resolve(BlockScope upperScope) {
+	// use the scope that will hold the init declarations
+
+	scope = neededScope ? new BlockScope(upperScope) : upperScope;
+	if (initializations != null)
+		for (int i = 0, length = initializations.length; i < length; i++)
+			initializations[i].resolve(scope);
+	if (condition != null) {
+		TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding);
+		condition.implicitWidening(type, type);
+	}
+	if (increments != null)
+		for (int i = 0, length = increments.length; i < length; i++)
+			increments[i].resolve(scope);
+	if (action != null)
+		action.resolve(scope);
+}
+public String toString(int tab ){
+	/* slow code */
+	
+	String s = tabString(tab) + "for ("/*nonNLS*/;
+	if (!neededScope)
+		s = s + " //--NO upperscope scope needed\n"/*nonNLS*/ + tabString(tab) + "     "/*nonNLS*/ ;
+	//inits
+	if (initializations != null)
+	{	for (int i = 0 ; i < initializations.length ; i++){
+			//nice only with expressions
+			s = s + initializations[i].toString(0);
+			if (i != (initializations.length -1)) s = s + " , "/*nonNLS*/ ;}};
+	s = s + "; "/*nonNLS*/ ;
+	//cond
+	if (condition != null)
+		s = s + condition.toStringExpression() ;
+	s = s + "; "/*nonNLS*/ ;
+	//updates
+	if (increments != null)
+	{	for (int i = 0 ; i < increments.length ; i++){
+			//nice only with expressions
+			s = s + increments[i].toString(0);
+			if (i != (increments.length -1)) s = s + " , "/*nonNLS*/ ;}};
+	s = s + ") "/*nonNLS*/ ;
+	//block
+	if (action == null)
+		s = s + "{}"/*nonNLS*/ ;
+	else
+		s = s + "\n"/*nonNLS*/+ action.toString(tab+1) ;
+	return s;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		if (initializations != null) {
+			int initializationsLength = initializations.length;
+			for (int i = 0; i < initializationsLength; i++)
+				initializations[i].traverse(visitor, scope);
+		}
+
+		if (condition != null)
+			condition.traverse(visitor, scope);
+
+		if (increments != null) {
+			int incrementsLength = increments.length;
+			for (int i = 0; i < incrementsLength; i++)
+				increments[i].traverse(visitor, scope);
+		}
+
+		if (action != null)
+			action.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
index af82fee..116ea35 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
@@ -1,52 +1,51 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class ImportReference extends AstNode {
-	public char[][] tokens;
-	public long[] sourcePositions; //each entry is using the code : (start<<32) + end
-	public boolean onDemand = true; //most of the time
-
-	public int declarationSourceStart;
-	public int declarationSourceEnd;
-
-public ImportReference(char[][] sources , long[] poss , boolean d) {
-	tokens = sources ;
-	sourcePositions = poss ;
-	onDemand = d;
-	sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFF);
-	sourceStart = (int)(sourcePositions[0]>>>32) ;
-}
-/**
- * @return char[][]
- */
-public char[][] getImportName() {
-	return tokens;
-}
-public String toString(int tab ){
-
-	return toString(tab,true);}
-public String toString(int tab, boolean withOnDemand) {
-	/* when withOnDemand is false, only the name is printed */
-	StringBuffer buffer = new StringBuffer();
-	for (int i = 0; i < tokens.length; i++) {
-		buffer.append(tokens[i]);
-		if (i < (tokens.length - 1)) {
-			buffer.append("."/*nonNLS*/);
-		}
-	}
-	if (withOnDemand && onDemand) {
-		buffer.append(".*"/*nonNLS*/);
-	}
-	return buffer.toString();
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) {
-	visitor.visit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ImportReference extends AstNode {
+	public char[][] tokens;
+	public long[] sourcePositions; //each entry is using the code : (start<<32) + end
+	public boolean onDemand = true; //most of the time
+
+	public int declarationSourceStart;
+	public int declarationSourceEnd;
+
+public ImportReference(char[][] sources , long[] poss , boolean d) {
+	tokens = sources ;
+	sourcePositions = poss ;
+	onDemand = d;
+	sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFF);
+	sourceStart = (int)(sourcePositions[0]>>>32) ;
+}
+/**
+ * @return char[][]
+ */
+public char[][] getImportName() {
+	return tokens;
+}
+public String toString(int tab ){
+
+	return toString(tab,true);}
+public String toString(int tab, boolean withOnDemand) {
+	/* when withOnDemand is false, only the name is printed */
+	StringBuffer buffer = new StringBuffer();
+	for (int i = 0; i < tokens.length; i++) {
+		buffer.append(tokens[i]);
+		if (i < (tokens.length - 1)) {
+			buffer.append("."/*nonNLS*/);
+		}
+	}
+	if (withOnDemand && onDemand) {
+		buffer.append(".*"/*nonNLS*/);
+	}
+	return buffer.toString();
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, CompilationUnitScope scope) {
+	visitor.visit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
index b796c10..61d0422 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
@@ -1,88 +1,87 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.parser.*;
-
-public class Initializer extends FieldDeclaration {
-	//public boolean isStatic = false ;
-	public Block block;
-	public int lastFieldID;
-	public int bodyStart;
-public Initializer(Block block, int modifiers) {
-	this.block = block;
-	this.modifiers = modifiers;
-
-	declarationSourceStart = sourceStart = block.sourceStart;
-}
-public FlowInfo analyseCode(MethodScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return block.analyseCode(currentScope, flowContext, flowInfo);
-}
-/**
- * Code generation for a non-static initializer
- *	i.e. normal block code gen
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	int pc = codeStream.position;
-	block.generateCode(currentScope, codeStream);
-	codeStream.recordPositionsFrom(pc, this);
-}
-public boolean isField() {
-	return false;
-}
-public boolean isStatic() {
-	return (modifiers & AccStatic) != 0;
-}
-public void parseStatements(Parser parser, TypeDeclaration type, CompilationUnitDeclaration unit) {
-	//fill up the method body with statement
-
-	parser.parse(this, type, unit);
-}
-public void resolve(MethodScope scope) {
-	int previous = scope.fieldDeclarationIndex;
-	try {
-		scope.fieldDeclarationIndex = lastFieldID;
-		if (isStatic()) {
-			ReferenceBinding declaringType = scope.enclosingSourceType();
-			if (declaringType.isNestedType() && !declaringType.isStatic())
-				scope.problemReporter().innerTypesCannotDeclareStaticInitializers(declaringType, this);
-		}
-		block.resolve(scope);
-	} finally {
-		scope.fieldDeclarationIndex = previous;
-	}
-}
-public String toString(int tab){
-	/*slow code */
-
-	if (modifiers != 0){
-		StringBuffer buffer = new StringBuffer();
-		buffer.append(tabString(tab));
-		buffer.append(modifiersString(modifiers));
-		buffer.append("{\n"/*nonNLS*/);
-		buffer.append(block.toStringStatements(tab));
-		buffer.append(tabString(tab));
-		buffer.append("}"/*nonNLS*/);
-		return buffer.toString();
-	} else {
-		return block.toString(tab);
-	}
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) {
-	visitor.visit(this, scope);
-	block.traverse(visitor, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+
+public class Initializer extends FieldDeclaration {
+	//public boolean isStatic = false ;
+	public Block block;
+	public int lastFieldID;
+	public int bodyStart;
+public Initializer(Block block, int modifiers) {
+	this.block = block;
+	this.modifiers = modifiers;
+
+	declarationSourceStart = sourceStart = block.sourceStart;
+}
+public FlowInfo analyseCode(MethodScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return block.analyseCode(currentScope, flowContext, flowInfo);
+}
+/**
+ * Code generation for a non-static initializer
+ *	i.e. normal block code gen
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	block.generateCode(currentScope, codeStream);
+	codeStream.recordPositionsFrom(pc, this);
+}
+public boolean isField() {
+	return false;
+}
+public boolean isStatic() {
+	return (modifiers & AccStatic) != 0;
+}
+public void parseStatements(Parser parser, TypeDeclaration type, CompilationUnitDeclaration unit) {
+	//fill up the method body with statement
+
+	parser.parse(this, type, unit);
+}
+public void resolve(MethodScope scope) {
+	int previous = scope.fieldDeclarationIndex;
+	try {
+		scope.fieldDeclarationIndex = lastFieldID;
+		if (isStatic()) {
+			ReferenceBinding declaringType = scope.enclosingSourceType();
+			if (declaringType.isNestedType() && !declaringType.isStatic())
+				scope.problemReporter().innerTypesCannotDeclareStaticInitializers(declaringType, this);
+		}
+		block.resolve(scope);
+	} finally {
+		scope.fieldDeclarationIndex = previous;
+	}
+}
+public String toString(int tab){
+	/*slow code */
+
+	if (modifiers != 0){
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(tabString(tab));
+		buffer.append(modifiersString(modifiers));
+		buffer.append("{\n"/*nonNLS*/);
+		buffer.append(block.toStringStatements(tab));
+		buffer.append(tabString(tab));
+		buffer.append("}"/*nonNLS*/);
+		return buffer.toString();
+	} else {
+		return block.toString(tab);
+	}
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, MethodScope scope) {
+	visitor.visit(this, scope);
+	block.traverse(visitor, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/InnerTypeDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/InnerTypeDeclaration.java
index b93207d..6c845f6 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/InnerTypeDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/InnerTypeDeclaration.java
@@ -1,12 +1,8 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public class InnerTypeDeclaration extends TypeDeclaration {
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class InnerTypeDeclaration extends TypeDeclaration {
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index fbf019b..2445e450 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -1,211 +1,208 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class InstanceOfExpression extends OperatorExpression {
-	public Expression expression;
-	public TypeReference type;
-public InstanceOfExpression(Expression expression, TypeReference type, int operator) {
-	this.expression = expression;
-	this.type = type;
-	this.bits |= operator << OperatorSHIFT;
-	this.sourceStart = expression.sourceStart;
-	this.sourceEnd = type.sourceEnd;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-}
-public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb, TypeBinding expressionTb) {
-	//	see specifications p.68
-	//A more cpmplete version of this method is provided on
-	//CastExpression (it deals with constant and need runtime checkcast)
-
-	//by grammatical construction, the first test is ALWAYS false
-	//if (castTb.isBaseType())
-	//{	if (expressionTb.isBaseType())
-	//	{	if (expression.isConstantValueOfTypeAssignableToType(expressionTb,castTb))
-	//		{	return true;}
-	//		else
-	//		{	if (expressionTb==castTb)
-	//			{	return true;}
-	//			else 
-	//			{	if (scope.areTypesCompatible(expressionTb,castTb))
-	//				{	return true; }
-	//				
-	//				if (BaseTypeBinding.isNarrowing(castTb.id,expressionTb.id))
-	//				{	return true;}
-	//				return false;}}}
-	//	else
-	//	{	return false; }}
-	//else
-	{ //-------------checkcast to something which is NOT a basetype----------------------------------	
-
-		if (NullBinding == expressionTb)
-			//null is compatible with every thing .... 
-			{
-			return true;
-		}
-		if (expressionTb.isArrayType()) {
-			if (castTb.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
-				TypeBinding expressionEltTb = ((ArrayBinding) expressionTb).elementsType(scope);
-				if (expressionEltTb.isBaseType())
-					// <---stop the recursion------- 
-					return ((ArrayBinding) castTb).elementsType(scope) == expressionEltTb;
-				//recursivly on the elts...
-				return areTypesCastCompatible(scope, ((ArrayBinding) castTb).elementsType(scope), expressionEltTb);
-			}
-			if (castTb.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------	
-				if (scope.isJavaLangObject(castTb))
-					return true;
-				return false;
-			}
-			if (castTb.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
-				if (scope.isJavaLangCloneable(castTb) || scope.isJavaIoSerializable(castTb)) {
-					return true;
-				}
-				return false;
-			}
-
-			//=========hoops=============
-			return false;
-		}
-		if (expressionTb.isBaseType()) {
-			return false;
-		}
-		if (expressionTb.isClass()) {
-			if (castTb.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
-				if (scope.isJavaLangObject(expressionTb)) {
-					return true;
-				} else {
-					return false;
-				}
-			}
-			if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ 
-				if (scope.areTypesCompatible(expressionTb, castTb))
-					return true;
-				else {
-					if (scope.areTypesCompatible(castTb, expressionTb)) {
-						return true;
-					}
-					return false;
-				}
-			}
-			if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------  
-				if (((ReferenceBinding) expressionTb).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
-					if (scope.areTypesCompatible(expressionTb, castTb))
-						return true;
-					return false;
-				} else {
-					return true;
-				}
-			}
-
-			//=========hoops==============
-			return false;
-		}
-		if (expressionTb.isInterface()) {
-			if (castTb.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
-				if (scope.isJavaLangCloneable(expressionTb) || scope.isJavaIoSerializable(expressionTb))
-					//potential runtime error
-					{
-					return true;
-				}
-				return false;
-			}
-			if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
-				if (scope.isJavaLangObject(castTb))
-					return true;
-				if (((ReferenceBinding) castTb).isFinal()) { //no subclass for castTb, thus compile-time check is valid
-					if (scope.areTypesCompatible(castTb, expressionTb)) {
-						return true;
-					}
-					return false;
-				}
-				return true;
-			}
-			if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
-				if (castTb != expressionTb && (scope.compareTypes(castTb, expressionTb) == NotRelated)) {
-					MethodBinding[] castTbMethods = ((ReferenceBinding) castTb).methods();
-					int castTbMethodsLength = castTbMethods.length;
-					MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionTb).methods();
-					int expressionTbMethodsLength = expressionTbMethods.length;
-					for (int i = 0; i < castTbMethodsLength; i++) {
-						for (int j = 0; j < expressionTbMethodsLength; j++) {
-							if (castTbMethods[i].selector == expressionTbMethods[j].selector) {
-								if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) {
-									if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) {
-										return false;
-									}
-								}
-							}
-						}
-					}
-				}
-				return true;
-			}
-
-			//============hoops===========	
-			return false;
-		} // true;}
-
-		//=======hoops==========
-		return false;
-	}
-}
-/**
- * Code generation for instanceOfExpression
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
-*/ 
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	expression.generateCode(currentScope, codeStream, true);
-	codeStream.instance_of(type.binding);
-	if (!valueRequired)
-		codeStream.pop();
-	codeStream.recordPositionsFrom(pc, this);
-}
-public TypeBinding resolveType(BlockScope scope) {
-	constant = NotAConstant;
-	TypeBinding expressionTb = expression.resolveType(scope);
-	TypeBinding checkTb = type.resolveType(scope);
-	if (expressionTb == null || checkTb == null)
-		return null;
-
-	//===== by grammatical construction, the next test is always false =====
-	//if (checkTb.isBaseType()) {
-	//	scope.problemReporter().invalidTypeError(type,checkTb);
-	//	return null;
-	//}
-
-	if (!areTypesCastCompatible(scope, checkTb, expressionTb)) {
-		scope.problemReporter().notCompatibleTypesError(this, expressionTb, checkTb);
-		return null;
-	}
-	return BooleanBinding;
-}
-public String toStringExpressionNoParenthesis(){
-	/* slow code*/
-
-	return	expression.toStringExpression() + " instanceof "/*nonNLS*/ +
-			type.toString(0) ; }
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		expression.traverse(visitor, scope);
-		type.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class InstanceOfExpression extends OperatorExpression {
+	public Expression expression;
+	public TypeReference type;
+public InstanceOfExpression(Expression expression, TypeReference type, int operator) {
+	this.expression = expression;
+	this.type = type;
+	this.bits |= operator << OperatorSHIFT;
+	this.sourceStart = expression.sourceStart;
+	this.sourceEnd = type.sourceEnd;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+}
+public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb, TypeBinding expressionTb) {
+	//	see specifications p.68
+	//A more cpmplete version of this method is provided on
+	//CastExpression (it deals with constant and need runtime checkcast)
+
+	//by grammatical construction, the first test is ALWAYS false
+	//if (castTb.isBaseType())
+	//{	if (expressionTb.isBaseType())
+	//	{	if (expression.isConstantValueOfTypeAssignableToType(expressionTb,castTb))
+	//		{	return true;}
+	//		else
+	//		{	if (expressionTb==castTb)
+	//			{	return true;}
+	//			else 
+	//			{	if (scope.areTypesCompatible(expressionTb,castTb))
+	//				{	return true; }
+	//				
+	//				if (BaseTypeBinding.isNarrowing(castTb.id,expressionTb.id))
+	//				{	return true;}
+	//				return false;}}}
+	//	else
+	//	{	return false; }}
+	//else
+	{ //-------------checkcast to something which is NOT a basetype----------------------------------	
+
+		if (NullBinding == expressionTb)
+			//null is compatible with every thing .... 
+			{
+			return true;
+		}
+		if (expressionTb.isArrayType()) {
+			if (castTb.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
+				TypeBinding expressionEltTb = ((ArrayBinding) expressionTb).elementsType(scope);
+				if (expressionEltTb.isBaseType())
+					// <---stop the recursion------- 
+					return ((ArrayBinding) castTb).elementsType(scope) == expressionEltTb;
+				//recursivly on the elts...
+				return areTypesCastCompatible(scope, ((ArrayBinding) castTb).elementsType(scope), expressionEltTb);
+			}
+			if (castTb.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------	
+				if (scope.isJavaLangObject(castTb))
+					return true;
+				return false;
+			}
+			if (castTb.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
+				if (scope.isJavaLangCloneable(castTb) || scope.isJavaIoSerializable(castTb)) {
+					return true;
+				}
+				return false;
+			}
+
+			//=========hoops=============
+			return false;
+		}
+		if (expressionTb.isBaseType()) {
+			return false;
+		}
+		if (expressionTb.isClass()) {
+			if (castTb.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
+				if (scope.isJavaLangObject(expressionTb)) {
+					return true;
+				} else {
+					return false;
+				}
+			}
+			if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ 
+				if (scope.areTypesCompatible(expressionTb, castTb))
+					return true;
+				else {
+					if (scope.areTypesCompatible(castTb, expressionTb)) {
+						return true;
+					}
+					return false;
+				}
+			}
+			if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------  
+				if (((ReferenceBinding) expressionTb).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
+					if (scope.areTypesCompatible(expressionTb, castTb))
+						return true;
+					return false;
+				} else {
+					return true;
+				}
+			}
+
+			//=========hoops==============
+			return false;
+		}
+		if (expressionTb.isInterface()) {
+			if (castTb.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
+				if (scope.isJavaLangCloneable(expressionTb) || scope.isJavaIoSerializable(expressionTb))
+					//potential runtime error
+					{
+					return true;
+				}
+				return false;
+			}
+			if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
+				if (scope.isJavaLangObject(castTb))
+					return true;
+				if (((ReferenceBinding) castTb).isFinal()) { //no subclass for castTb, thus compile-time check is valid
+					if (scope.areTypesCompatible(castTb, expressionTb)) {
+						return true;
+					}
+					return false;
+				}
+				return true;
+			}
+			if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
+				if (castTb != expressionTb && (scope.compareTypes(castTb, expressionTb) == NotRelated)) {
+					MethodBinding[] castTbMethods = ((ReferenceBinding) castTb).methods();
+					int castTbMethodsLength = castTbMethods.length;
+					MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionTb).methods();
+					int expressionTbMethodsLength = expressionTbMethods.length;
+					for (int i = 0; i < castTbMethodsLength; i++) {
+						for (int j = 0; j < expressionTbMethodsLength; j++) {
+							if (castTbMethods[i].selector == expressionTbMethods[j].selector) {
+								if (castTbMethods[i].returnType != expressionTbMethods[j].returnType) {
+									if (castTbMethods[i].areParametersEqual(expressionTbMethods[j])) {
+										return false;
+									}
+								}
+							}
+						}
+					}
+				}
+				return true;
+			}
+
+			//============hoops===========	
+			return false;
+		} // true;}
+
+		//=======hoops==========
+		return false;
+	}
+}
+/**
+ * Code generation for instanceOfExpression
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+*/ 
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	expression.generateCode(currentScope, codeStream, true);
+	codeStream.instance_of(type.binding);
+	if (!valueRequired)
+		codeStream.pop();
+	codeStream.recordPositionsFrom(pc, this);
+}
+public TypeBinding resolveType(BlockScope scope) {
+	constant = NotAConstant;
+	TypeBinding expressionTb = expression.resolveType(scope);
+	TypeBinding checkTb = type.resolveType(scope);
+	if (expressionTb == null || checkTb == null)
+		return null;
+
+	//===== by grammatical construction, the next test is always false =====
+	//if (checkTb.isBaseType()) {
+	//	scope.problemReporter().invalidTypeError(type,checkTb);
+	//	return null;
+	//}
+
+	if (!areTypesCastCompatible(scope, checkTb, expressionTb)) {
+		scope.problemReporter().notCompatibleTypesError(this, expressionTb, checkTb);
+		return null;
+	}
+	return BooleanBinding;
+}
+public String toStringExpressionNoParenthesis(){
+	/* slow code*/
+
+	return	expression.toStringExpression() + " instanceof "/*nonNLS*/ +
+			type.toString(0) ; }
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		expression.traverse(visitor, scope);
+		type.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java b/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
index e68be09..13731d2 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
@@ -1,23 +1,21 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class IntLiteralMinValue extends IntLiteral {
-
-	final static char[] CharValue = new char[]{'-','2','1','4','7','4','8','3','6','4','8'};
-	final static Constant MIN_VALUE = Constant.fromValue(Integer.MIN_VALUE) ; 
-
-public IntLiteralMinValue() {
-	super(CharValue,0,0,Integer.MIN_VALUE);
-	constant = MIN_VALUE;
-}
-public void computeConstant(){
-	
-	/*precomputed at creation time*/ }
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.impl.*;
+
+public class IntLiteralMinValue extends IntLiteral {
+
+	final static char[] CharValue = new char[]{'-','2','1','4','7','4','8','3','6','4','8'};
+	final static Constant MIN_VALUE = Constant.fromValue(Integer.MIN_VALUE) ; 
+
+public IntLiteralMinValue() {
+	super(CharValue,0,0,Integer.MIN_VALUE);
+	constant = MIN_VALUE;
+}
+public void computeConstant(){
+	
+	/*precomputed at creation time*/ }
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
index 436ded9..e2a58b1 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
@@ -1,89 +1,88 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class LabeledStatement extends Statement {
-	public Statement statement;
-	public char[] label;
-	public Label targetLabel;
-
-	// for local variables table attributes
-	int mergedInitStateIndex = -1;
-/**
- * LabeledStatement constructor comment.
- */
-public LabeledStatement(char[] l , Statement st, int s,int e) {
-	statement = st ;
-	label = l ;
-	sourceStart = s;
-	sourceEnd = e;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	// need to stack a context to store explicit label, answer inits in case of normal completion merged
-	// with those relative to the exit path from break statement occurring inside the labeled statement.
-
-	if (statement == null) {
-		return flowInfo;
-	} else {
-		LabelFlowContext labelContext;
-		FlowInfo mergedInfo = statement.analyseCode(
-			currentScope,
-			(labelContext = new LabelFlowContext(flowContext, this, label, (targetLabel = new Label()), currentScope)),
-			flowInfo).
-				mergedWith(labelContext.initsOnBreak);
-		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
-		return mergedInfo;
-	}
-}
-public AstNode concreteStatement() {
-	return statement.concreteStatement();
-}
-/**
- * Code generation for labeled statement
- *
- * may not need actual source positions recording
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	int pc = codeStream.position;
-	if (targetLabel != null) {
-		targetLabel.codeStream = codeStream;
-		if (statement != null) {
-			statement.generateCode(currentScope, codeStream);
-		}
-		targetLabel.place();
-	}
-	// May loose some local variable initializations : affecting the local variable attributes
-	if (mergedInitStateIndex != -1) {
-		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void resolve(BlockScope scope) {
-	statement.resolve(scope);
-}
-public String toString(int tab) {
-	/* slow code */
-
-	String s = tabString(tab);
-	s += new String(label) + ": "/*nonNLS*/ + statement.toString(0);
-	return s;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		statement.traverse(visitor, blockScope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class LabeledStatement extends Statement {
+	public Statement statement;
+	public char[] label;
+	public Label targetLabel;
+
+	// for local variables table attributes
+	int mergedInitStateIndex = -1;
+/**
+ * LabeledStatement constructor comment.
+ */
+public LabeledStatement(char[] l , Statement st, int s,int e) {
+	statement = st ;
+	label = l ;
+	sourceStart = s;
+	sourceEnd = e;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// need to stack a context to store explicit label, answer inits in case of normal completion merged
+	// with those relative to the exit path from break statement occurring inside the labeled statement.
+
+	if (statement == null) {
+		return flowInfo;
+	} else {
+		LabelFlowContext labelContext;
+		FlowInfo mergedInfo = statement.analyseCode(
+			currentScope,
+			(labelContext = new LabelFlowContext(flowContext, this, label, (targetLabel = new Label()), currentScope)),
+			flowInfo).
+				mergedWith(labelContext.initsOnBreak);
+		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+}
+public AstNode concreteStatement() {
+	return statement.concreteStatement();
+}
+/**
+ * Code generation for labeled statement
+ *
+ * may not need actual source positions recording
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	int pc = codeStream.position;
+	if (targetLabel != null) {
+		targetLabel.codeStream = codeStream;
+		if (statement != null) {
+			statement.generateCode(currentScope, codeStream);
+		}
+		targetLabel.place();
+	}
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void resolve(BlockScope scope) {
+	statement.resolve(scope);
+}
+public String toString(int tab) {
+	/* slow code */
+
+	String s = tabString(tab);
+	s += new String(label) + ": "/*nonNLS*/ + statement.toString(0);
+	return s;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		statement.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
index 438e59c..bed411e 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
@@ -1,33 +1,32 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public abstract class Literal extends Expression {
-	
-
-public Literal(int s,int e) {
-	sourceStart = s ;
-	sourceEnd= e;
-}
-public abstract void computeConstant() ;
-	//ON ERROR constant STAYS NULL
-public abstract TypeBinding literalType(BlockScope scope);
-public TypeBinding resolveType(BlockScope scope) {
-	// compute the real value, which must range its type's range
-
-	computeConstant();
-	if (constant == null) {
-		scope.problemReporter().constantOutOfRange(this);
-		constant = Constant.NotAConstant;
-		return null;
-	}
-	return literalType(scope);
-}
-public abstract char[] source() ;
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class Literal extends Expression {
+	
+
+public Literal(int s,int e) {
+	sourceStart = s ;
+	sourceEnd= e;
+}
+public abstract void computeConstant() ;
+	//ON ERROR constant STAYS NULL
+public abstract TypeBinding literalType(BlockScope scope);
+public TypeBinding resolveType(BlockScope scope) {
+	// compute the real value, which must range its type's range
+
+	computeConstant();
+	if (constant == null) {
+		scope.problemReporter().constantOutOfRange(this);
+		constant = Constant.NotAConstant;
+		return null;
+	}
+	return literalType(scope);
+}
+public abstract char[] source() ;
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/LocalTypeDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/LocalTypeDeclaration.java
index 1da2fd7..ee186df 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/LocalTypeDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/LocalTypeDeclaration.java
@@ -1,57 +1,56 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public class LocalTypeDeclaration extends InnerTypeDeclaration {
-	public AbstractMethodDeclaration enclosingMethod;
-
-/**
- *	Iteration for a local innertype
- *
- */
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (ignoreFurtherInvestigation)
-		return;
-	try {
-		if (visitor.visit(this, blockScope)) {
-			if (superclass != null)
-				superclass.traverse(visitor, scope);
-			if (superInterfaces != null) {
-				int superInterfaceLength = superInterfaces.length;
-				for (int i = 0; i < superInterfaceLength; i++)
-					superInterfaces[i].traverse(visitor, scope);
-			}
-			if (memberTypes != null) {
-				int memberTypesLength = memberTypes.length;
-				for (int i = 0; i < memberTypesLength; i++)
-					memberTypes[i].traverse(visitor, scope);
-			}
-			if (fields != null) {
-				int fieldsLength = fields.length;
-				for (int i = 0; i < fieldsLength; i++) {
-					FieldDeclaration field;
-					if ((field = fields[i]).isStatic()) {
-						// local type cannot have static fields
-					} else {
-						field.traverse(visitor, initializerScope);
-					}
-				}
-			}
-			if (methods != null) {
-				int methodsLength = methods.length;
-				for (int i = 0; i < methodsLength; i++)
-					methods[i].traverse(visitor, scope);
-			}
-		}
-		visitor.endVisit(this, blockScope);
-	} catch (AbortType e) {
-	}
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+
+public class LocalTypeDeclaration extends InnerTypeDeclaration {
+	public AbstractMethodDeclaration enclosingMethod;
+
+/**
+ *	Iteration for a local innertype
+ *
+ */
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (ignoreFurtherInvestigation)
+		return;
+	try {
+		if (visitor.visit(this, blockScope)) {
+			if (superclass != null)
+				superclass.traverse(visitor, scope);
+			if (superInterfaces != null) {
+				int superInterfaceLength = superInterfaces.length;
+				for (int i = 0; i < superInterfaceLength; i++)
+					superInterfaces[i].traverse(visitor, scope);
+			}
+			if (memberTypes != null) {
+				int memberTypesLength = memberTypes.length;
+				for (int i = 0; i < memberTypesLength; i++)
+					memberTypes[i].traverse(visitor, scope);
+			}
+			if (fields != null) {
+				int fieldsLength = fields.length;
+				for (int i = 0; i < fieldsLength; i++) {
+					FieldDeclaration field;
+					if ((field = fields[i]).isStatic()) {
+						// local type cannot have static fields
+					} else {
+						field.traverse(visitor, initializerScope);
+					}
+				}
+			}
+			if (methods != null) {
+				int methodsLength = methods.length;
+				for (int i = 0; i < methodsLength; i++)
+					methods[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	} catch (AbortType e) {
+	}
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java b/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
index 626153b..0f89977 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
@@ -1,22 +1,21 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class LongLiteralMinValue extends LongLiteral {
-
-	final static char[] CharValue = new char[]{'-', '9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8','L'};
-	final static Constant MIN_VALUE = Constant.fromValue(Long.MIN_VALUE) ; 
-
-public LongLiteralMinValue(){
-	super(CharValue,0,0,Long.MIN_VALUE);
-	constant = MIN_VALUE;
-}
-public void computeConstant() {
-
-	/*precomputed at creation time*/}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.impl.*;
+
+public class LongLiteralMinValue extends LongLiteral {
+
+	final static char[] CharValue = new char[]{'-', '9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8','L'};
+	final static Constant MIN_VALUE = Constant.fromValue(Long.MIN_VALUE) ; 
+
+public LongLiteralMinValue(){
+	super(CharValue,0,0,Long.MIN_VALUE);
+	constant = MIN_VALUE;
+}
+public void computeConstant() {
+
+	/*precomputed at creation time*/}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java b/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
index 6c063d0..7508644 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
@@ -1,26 +1,25 @@
-package org.eclipse.jdt.internal.compiler.ast;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*; 
-
-public abstract class  MagicLiteral extends Literal {
-public MagicLiteral(int s , int e) {
-	super(s,e);
-}
-public boolean isValidJavaStatement(){
-	//should never be reach, but with a bug in the ast tree....
-	//see comment on the Statement class
-	
-	return false ;}
-/**
- * source method comment.
- */
-public char[] source() {
-	return null;
-}
-public String toStringExpression(){
-
-	return  new String(source()) ; }
-}
+package org.eclipse.jdt.internal.compiler.ast;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public abstract class  MagicLiteral extends Literal {
+public MagicLiteral(int s , int e) {
+	super(s,e);
+}
+public boolean isValidJavaStatement(){
+	//should never be reach, but with a bug in the ast tree....
+	//see comment on the Statement class
+	
+	return false ;}
+/**
+ * source method comment.
+ */
+public char[] source() {
+	return null;
+}
+public String toStringExpression(){
+
+	return  new String(source()) ; }
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 656ea2a..da151d6 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -1,263 +1,262 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class MessageSend extends Expression implements InvocationSite {
-	public Expression receiver ;
-	public char[] selector ;
-	public Expression[] arguments ;
-	public MethodBinding binding;
-
-	public long nameSourcePosition ; //(start<<32)+end
-
-
-	MethodBinding syntheticAccessor;
-
-	public TypeBinding receiverType;
-
-public MessageSend() {
-	
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()).unconditionalInits();
-	if (arguments != null) {
-		int length = arguments.length;
-		for (int i = 0; i < length; i++) {
-			flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-		}
-	}
-	ReferenceBinding[] thrownExceptions;
-	if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) {
-		// must verify that exceptions potentially thrown by this expression are caught in the method
-		flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo, currentScope);
-	}
-	// if invoking through an enclosing instance, then must perform the field generation -- only if reachable
-	manageEnclosingInstanceAccessIfNecessary(currentScope);
-	manageSyntheticAccessIfNecessary(currentScope);	
-	return flowInfo;
-}
-/**
- * MessageSend code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */ 
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	int pc = codeStream.position;
-
-	// generate receiver/enclosing instance access
-	boolean isStatic = binding.isStatic();
-	// outer access ?
-	if (!isStatic && ((bits & DepthMASK) != 0)){
-		// outer method can be reached through emulation
-		Object[] path = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-		if (path == null) {
-			// emulation was not possible (should not happen per construction)
-			currentScope.problemReporter().needImplementation();
-		} else {
-			codeStream.generateOuterAccess(path, this, currentScope);
-		}
-	} else {
-		receiver.generateCode(currentScope, codeStream, !isStatic);
-	}
-	// generate arguments
-	if (arguments != null){
-		for (int i = 0, max = arguments.length; i < max; i++){
-			arguments[i].generateCode(currentScope, codeStream, true);
-		}
-	}
-	// actual message invocation
-	if (syntheticAccessor == null){
-		if (isStatic){
-			codeStream.invokestatic(binding);
-		} else {
-			if( (receiver.isSuper()) || binding.isPrivate()){
-				codeStream.invokespecial(binding);
-			} else {
-				if (binding.declaringClass.isInterface()){
-					codeStream.invokeinterface(binding);
-				} else {
-					codeStream.invokevirtual(binding);
-				}
-			}
-		}
-	} else {
-		codeStream.invokestatic(syntheticAccessor);
-	}
-	// operation on the returned value
-	if (valueRequired){
-		// implicit conversion if necessary
-		codeStream.generateImplicitConversion(implicitConversion);
-	} else {
-		// pop return value if any
-		switch(binding.returnType.id){
-			case T_long :
-			case T_double :
-				codeStream.pop2();
-				break;
-			case T_void :
-				break;
-			default:
-				codeStream.pop();
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public boolean isSuperAccess() {	
-	return receiver.isSuper();
-}
-public boolean isTypeAccess() {	
-	return receiver != null && receiver.isTypeReference();
-}
-public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-	if (((bits & DepthMASK) != 0) && (!binding.isStatic()) && (receiver == ThisReference.ThisImplicit)) {
-		ReferenceBinding compatibleType = currentScope.enclosingSourceType();
-		// the declaringClass of the target binding must be compatible with the enclosing
-		// type at <depth> levels outside
-		for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
-			compatibleType = compatibleType.enclosingType();
-		}
-		currentScope.emulateOuterAccess((SourceTypeBinding) compatibleType, false); // request cascade of accesses
-	}
-}
-public void manageSyntheticAccessIfNecessary(BlockScope currentScope){
-
-	if (((bits & DepthMASK) != 0) 
-		|| currentScope.enclosingSourceType() != binding.declaringClass){ // implicit only have a depth set
-		if (binding.isPrivate()){ // private access 
-			syntheticAccessor = ((SourceTypeBinding)binding.declaringClass).addSyntheticMethod(binding);
-			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
-			return;
-		}
-		if (receiver == ThisReference.ThisImplicit  
-			&& binding.isProtected()
-			&& (bits & DepthMASK) != 0 // only if outer access			
-			&& binding.declaringClass.getPackage() 
-				!= currentScope.enclosingSourceType().getPackage()){ // protected access (implicit access only)
-			syntheticAccessor = ((SourceTypeBinding)currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).addSyntheticMethod(binding);
-			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
-		}
-		if (receiver instanceof QualifiedSuperReference){ // qualified super
-			SourceTypeBinding destinationType = (SourceTypeBinding)(((QualifiedSuperReference)receiver).currentCompatibleType);
-			syntheticAccessor = destinationType.addSyntheticMethod(binding);
-			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
-		}
-	}
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// Answer the signature return type
-	// Base type promotion
-
-	constant = NotAConstant;
-	this.receiverType = receiver.resolveType(scope); 
-	// will check for null after args are resolved
-	TypeBinding[] argumentTypes = NoParameters;
-	if (arguments != null) {
-		boolean argHasError = false; // typeChecks all arguments 
-		int length = arguments.length;
-		argumentTypes = new TypeBinding[length];
-		for (int i = 0; i < length; i++)
-			if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
-				argHasError = true;
-		if (argHasError)
-			return null;
-	}
-	if (this.receiverType == null)
-		return null;
-
-	// base type cannot receive any message
-	if (this.receiverType.isBaseType()) {
-		scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes);
-		return null;
-	}
-
-	binding = 
-		receiver == ThisReference.ThisImplicit
-			? scope.getImplicitMethod(selector, argumentTypes, this)
-			: scope.getMethod(this.receiverType, selector, argumentTypes, this); 
-	if (!binding.isValidBinding()) {
-		if (binding.declaringClass == null) {
-			if (this.receiverType instanceof ReferenceBinding) {
-				binding.declaringClass = (ReferenceBinding) this.receiverType;
-			} else { // really bad error ....
-				scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes);
-				return null;
-			}
-		}
-		scope.problemReporter().invalidMethod(this, binding);
-		return null;
-	}
-	if (!binding.isStatic()) {
-		// the "receiver" must not be a type, i.e. a NameReference that the TC has bound to a Type
-		if (receiver instanceof NameReference) {
-			if ((((NameReference) receiver).bits & BindingIds.TYPE) != 0) {
-				scope.problemReporter().mustUseAStaticMethod(this, binding);
-				return null;
-			}
-		}
-	}
-	if (arguments != null)
-		for (int i = 0; i < arguments.length; i++)
-			arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
-
-	//-------message send that are known to fail at compile time-----------
-	if (binding.isAbstract()) {
-		if (receiver.isSuper()) {
-			scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, binding);
-			return null;
-		}
-		// abstract private methods cannot occur nor abstract static............
-	}
-	if (isMethodUseDeprecated(binding, scope))
-		scope.problemReporter().deprecatedMethod(binding, this);
-	// if the binding declaring class is not visible, need special action
-	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
-	if (binding.declaringClass != this.receiverType
-		&& !binding.declaringClass.canBeSeenBy(scope))
-		binding = new MethodBinding(binding, (ReferenceBinding) this.receiverType);
-	return binding.returnType;
-}
-public void setDepth(int depth) {
-	if (depth > 0) {
-		bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
-	}
-}
-public void setFieldIndex(int depth) {
-	// ignore for here
-}
-public String toStringExpression(){
-	/*slow code*/
-	
-	String s = ""/*nonNLS*/;
-	if (receiver != ThisReference.ThisImplicit)
-		s = s + receiver.toStringExpression()+"."/*nonNLS*/;
-	s = s + new String(selector) + "("/*nonNLS*/ ;
-	if (arguments != null)
-		for (int i = 0; i < arguments.length ; i ++)
-		{	s = s + arguments[i].toStringExpression();
-			if ( i != arguments.length -1 ) s = s + " , "/*nonNLS*/ ;};;
-	s =s + ")"/*nonNLS*/ ;
-	return s;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		receiver.traverse(visitor, blockScope);
-		if (arguments != null) {
-			int argumentsLength = arguments.length;
-			for (int i = 0; i < argumentsLength; i++)
-				arguments[i].traverse(visitor, blockScope);
-		}
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class MessageSend extends Expression implements InvocationSite {
+	public Expression receiver ;
+	public char[] selector ;
+	public Expression[] arguments ;
+	public MethodBinding binding;
+
+	public long nameSourcePosition ; //(start<<32)+end
+
+
+	MethodBinding syntheticAccessor;
+
+	public TypeBinding receiverType;
+
+public MessageSend() {
+	
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	flowInfo = receiver.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic()).unconditionalInits();
+	if (arguments != null) {
+		int length = arguments.length;
+		for (int i = 0; i < length; i++) {
+			flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+		}
+	}
+	ReferenceBinding[] thrownExceptions;
+	if ((thrownExceptions = binding.thrownExceptions) != NoExceptions) {
+		// must verify that exceptions potentially thrown by this expression are caught in the method
+		flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo, currentScope);
+	}
+	// if invoking through an enclosing instance, then must perform the field generation -- only if reachable
+	manageEnclosingInstanceAccessIfNecessary(currentScope);
+	manageSyntheticAccessIfNecessary(currentScope);	
+	return flowInfo;
+}
+/**
+ * MessageSend code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */ 
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	int pc = codeStream.position;
+
+	// generate receiver/enclosing instance access
+	boolean isStatic = binding.isStatic();
+	// outer access ?
+	if (!isStatic && ((bits & DepthMASK) != 0)){
+		// outer method can be reached through emulation
+		Object[] path = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+		if (path == null) {
+			// emulation was not possible (should not happen per construction)
+			currentScope.problemReporter().needImplementation();
+		} else {
+			codeStream.generateOuterAccess(path, this, currentScope);
+		}
+	} else {
+		receiver.generateCode(currentScope, codeStream, !isStatic);
+	}
+	// generate arguments
+	if (arguments != null){
+		for (int i = 0, max = arguments.length; i < max; i++){
+			arguments[i].generateCode(currentScope, codeStream, true);
+		}
+	}
+	// actual message invocation
+	if (syntheticAccessor == null){
+		if (isStatic){
+			codeStream.invokestatic(binding);
+		} else {
+			if( (receiver.isSuper()) || binding.isPrivate()){
+				codeStream.invokespecial(binding);
+			} else {
+				if (binding.declaringClass.isInterface()){
+					codeStream.invokeinterface(binding);
+				} else {
+					codeStream.invokevirtual(binding);
+				}
+			}
+		}
+	} else {
+		codeStream.invokestatic(syntheticAccessor);
+	}
+	// operation on the returned value
+	if (valueRequired){
+		// implicit conversion if necessary
+		codeStream.generateImplicitConversion(implicitConversion);
+	} else {
+		// pop return value if any
+		switch(binding.returnType.id){
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			case T_void :
+				break;
+			default:
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public boolean isSuperAccess() {	
+	return receiver.isSuper();
+}
+public boolean isTypeAccess() {	
+	return receiver != null && receiver.isTypeReference();
+}
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+	if (((bits & DepthMASK) != 0) && (!binding.isStatic()) && (receiver == ThisReference.ThisImplicit)) {
+		ReferenceBinding compatibleType = currentScope.enclosingSourceType();
+		// the declaringClass of the target binding must be compatible with the enclosing
+		// type at <depth> levels outside
+		for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
+			compatibleType = compatibleType.enclosingType();
+		}
+		currentScope.emulateOuterAccess((SourceTypeBinding) compatibleType, false); // request cascade of accesses
+	}
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope){
+
+	if (((bits & DepthMASK) != 0) 
+		|| currentScope.enclosingSourceType() != binding.declaringClass){ // implicit only have a depth set
+		if (binding.isPrivate()){ // private access 
+			syntheticAccessor = ((SourceTypeBinding)binding.declaringClass).addSyntheticMethod(binding);
+			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
+			return;
+		}
+		if (receiver == ThisReference.ThisImplicit  
+			&& binding.isProtected()
+			&& (bits & DepthMASK) != 0 // only if outer access			
+			&& binding.declaringClass.getPackage() 
+				!= currentScope.enclosingSourceType().getPackage()){ // protected access (implicit access only)
+			syntheticAccessor = ((SourceTypeBinding)currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).addSyntheticMethod(binding);
+			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
+		}
+		if (receiver instanceof QualifiedSuperReference){ // qualified super
+			SourceTypeBinding destinationType = (SourceTypeBinding)(((QualifiedSuperReference)receiver).currentCompatibleType);
+			syntheticAccessor = destinationType.addSyntheticMethod(binding);
+			currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
+		}
+	}
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature return type
+	// Base type promotion
+
+	constant = NotAConstant;
+	this.receiverType = receiver.resolveType(scope); 
+	// will check for null after args are resolved
+	TypeBinding[] argumentTypes = NoParameters;
+	if (arguments != null) {
+		boolean argHasError = false; // typeChecks all arguments 
+		int length = arguments.length;
+		argumentTypes = new TypeBinding[length];
+		for (int i = 0; i < length; i++)
+			if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
+				argHasError = true;
+		if (argHasError)
+			return null;
+	}
+	if (this.receiverType == null)
+		return null;
+
+	// base type cannot receive any message
+	if (this.receiverType.isBaseType()) {
+		scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes);
+		return null;
+	}
+
+	binding = 
+		receiver == ThisReference.ThisImplicit
+			? scope.getImplicitMethod(selector, argumentTypes, this)
+			: scope.getMethod(this.receiverType, selector, argumentTypes, this); 
+	if (!binding.isValidBinding()) {
+		if (binding.declaringClass == null) {
+			if (this.receiverType instanceof ReferenceBinding) {
+				binding.declaringClass = (ReferenceBinding) this.receiverType;
+			} else { // really bad error ....
+				scope.problemReporter().errorNoMethodFor(this, this.receiverType, argumentTypes);
+				return null;
+			}
+		}
+		scope.problemReporter().invalidMethod(this, binding);
+		return null;
+	}
+	if (!binding.isStatic()) {
+		// the "receiver" must not be a type, i.e. a NameReference that the TC has bound to a Type
+		if (receiver instanceof NameReference) {
+			if ((((NameReference) receiver).bits & BindingIds.TYPE) != 0) {
+				scope.problemReporter().mustUseAStaticMethod(this, binding);
+				return null;
+			}
+		}
+	}
+	if (arguments != null)
+		for (int i = 0; i < arguments.length; i++)
+			arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
+
+	//-------message send that are known to fail at compile time-----------
+	if (binding.isAbstract()) {
+		if (receiver.isSuper()) {
+			scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, binding);
+			return null;
+		}
+		// abstract private methods cannot occur nor abstract static............
+	}
+	if (isMethodUseDeprecated(binding, scope))
+		scope.problemReporter().deprecatedMethod(binding, this);
+	// if the binding declaring class is not visible, need special action
+	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+	if (binding.declaringClass != this.receiverType
+		&& !binding.declaringClass.canBeSeenBy(scope))
+		binding = new MethodBinding(binding, (ReferenceBinding) this.receiverType);
+	return binding.returnType;
+}
+public void setDepth(int depth) {
+	if (depth > 0) {
+		bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
+	}
+}
+public void setFieldIndex(int depth) {
+	// ignore for here
+}
+public String toStringExpression(){
+	/*slow code*/
+	
+	String s = ""/*nonNLS*/;
+	if (receiver != ThisReference.ThisImplicit)
+		s = s + receiver.toStringExpression()+"."/*nonNLS*/;
+	s = s + new String(selector) + "("/*nonNLS*/ ;
+	if (arguments != null)
+		for (int i = 0; i < arguments.length ; i ++)
+		{	s = s + arguments[i].toStringExpression();
+			if ( i != arguments.length -1 ) s = s + " , "/*nonNLS*/ ;};;
+	s =s + ")"/*nonNLS*/ ;
+	return s;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		receiver.traverse(visitor, blockScope);
+		if (arguments != null) {
+			int argumentsLength = arguments.length;
+			for (int i = 0; i < argumentsLength; i++)
+				arguments[i].traverse(visitor, blockScope);
+		}
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 4fa13eb..de35fb7 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -1,98 +1,97 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.parser.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class MethodDeclaration extends AbstractMethodDeclaration {
-	public TypeReference returnType;
-/**
- * MethodDeclaration constructor comment.
- */
-public MethodDeclaration() {
-	super();
-}
-public void checkName() {
-	// look if the name of the method is correct
-	if (isTypeUseDeprecated(binding.returnType, scope))
-		scope.problemReporter().deprecatedType(binding.returnType, returnType);
-
-	if (CharOperation.equals(scope.enclosingSourceType().sourceName, selector))
-		scope.problemReporter().methodWithConstructorName(this);
-
-	// by grammatical construction, interface methods are always abstract
-	if (scope.enclosingSourceType().isInterface())
-		return;
-
-	// if a method has an semicolon body and is not declared as abstract==>error
-	// native methods may have a semicolon body 
-	if ((modifiers & AccSemicolonBody) != 0) {
-		if ((modifiers & AccNative) == 0)
-			if ((modifiers & AccAbstract) == 0)
-				scope.problemReporter().methodNeedingAbstractModifier(this);
-	} else {
-		// the method HAS a body --> abstract native modifiers are forbiden
-		if (((modifiers & AccNative) != 0) || ((modifiers & AccAbstract) != 0))
-			scope.problemReporter().methodNeedingNoBody(this);
-	}
-}
-public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
-	//fill up the method body with statement
-
-	if (ignoreFurtherInvestigation) return;
-	parser.parse(this, unit);
-	
-}
-public void resolve(ClassScope upperScope) {
-	if (binding == null) {
-		ignoreFurtherInvestigation = true;
-		return;
-	}
-	// ========= abort on fatal error =============
-	try {
-		if (this.returnType != null){
-			this.returnType.binding = this.binding.returnType; // record the return type binding
-		}
-	} catch (AbortMethod e) {
-		this.ignoreFurtherInvestigation = true;		
-	}
-	super.resolve(upperScope);
-
-}
-public String returnTypeToString(int tab) {
-	/*slow code */
-
-	if (returnType == null)
-		return ""/*nonNLS*/;
-	return returnType.toString(tab)+" "/*nonNLS*/;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
-	if (visitor.visit(this, classScope)) {
-		if (returnType != null)
-			returnType.traverse(visitor, scope);
-		if (arguments != null) {
-			int argumentLength = arguments.length;
-			for (int i = 0; i < argumentLength; i++)
-				arguments[i].traverse(visitor, scope);
-		}
-		if (thrownExceptions != null) {
-			int thrownExceptionsLength = thrownExceptions.length;
-			for (int i = 0; i < thrownExceptionsLength; i++)
-				thrownExceptions[i].traverse(visitor, scope);
-		}
-		if (statements != null) {
-			int statementsLength = statements.length;
-			for (int i = 0; i < statementsLength; i++)
-				statements[i].traverse(visitor, scope);
-		}
-	}
-	visitor.endVisit(this, classScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class MethodDeclaration extends AbstractMethodDeclaration {
+	public TypeReference returnType;
+/**
+ * MethodDeclaration constructor comment.
+ */
+public MethodDeclaration() {
+	super();
+}
+public void checkName() {
+	// look if the name of the method is correct
+	if (isTypeUseDeprecated(binding.returnType, scope))
+		scope.problemReporter().deprecatedType(binding.returnType, returnType);
+
+	if (CharOperation.equals(scope.enclosingSourceType().sourceName, selector))
+		scope.problemReporter().methodWithConstructorName(this);
+
+	// by grammatical construction, interface methods are always abstract
+	if (scope.enclosingSourceType().isInterface())
+		return;
+
+	// if a method has an semicolon body and is not declared as abstract==>error
+	// native methods may have a semicolon body 
+	if ((modifiers & AccSemicolonBody) != 0) {
+		if ((modifiers & AccNative) == 0)
+			if ((modifiers & AccAbstract) == 0)
+				scope.problemReporter().methodNeedingAbstractModifier(this);
+	} else {
+		// the method HAS a body --> abstract native modifiers are forbiden
+		if (((modifiers & AccNative) != 0) || ((modifiers & AccAbstract) != 0))
+			scope.problemReporter().methodNeedingNoBody(this);
+	}
+}
+public void parseStatements(Parser parser, CompilationUnitDeclaration unit){
+	//fill up the method body with statement
+
+	if (ignoreFurtherInvestigation) return;
+	parser.parse(this, unit);
+	
+}
+public void resolve(ClassScope upperScope) {
+	if (binding == null) {
+		ignoreFurtherInvestigation = true;
+		return;
+	}
+	// ========= abort on fatal error =============
+	try {
+		if (this.returnType != null){
+			this.returnType.binding = this.binding.returnType; // record the return type binding
+		}
+	} catch (AbortMethod e) {
+		this.ignoreFurtherInvestigation = true;		
+	}
+	super.resolve(upperScope);
+
+}
+public String returnTypeToString(int tab) {
+	/*slow code */
+
+	if (returnType == null)
+		return ""/*nonNLS*/;
+	return returnType.toString(tab)+" "/*nonNLS*/;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
+	if (visitor.visit(this, classScope)) {
+		if (returnType != null)
+			returnType.traverse(visitor, scope);
+		if (arguments != null) {
+			int argumentLength = arguments.length;
+			for (int i = 0; i < argumentLength; i++)
+				arguments[i].traverse(visitor, scope);
+		}
+		if (thrownExceptions != null) {
+			int thrownExceptionsLength = thrownExceptions.length;
+			for (int i = 0; i < thrownExceptionsLength; i++)
+				thrownExceptions[i].traverse(visitor, scope);
+		}
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++)
+				statements[i].traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, classScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
index d870fc8..e544a94 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
@@ -1,51 +1,49 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public abstract class NameReference extends Reference implements InvocationSite, BindingIds {
-	public Binding binding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding
-	
-	public TypeBinding receiverType;
-
-	//the error printing
-	//some name reference are build as name reference but
-	//only used as type reference. When it happens, instead of
-	//creating a new objet (aTypeReference) we just flag a boolean
-	//This concesion is valuable while their are cases when the NameReference
-	//will be a TypeReference (static message sends.....) and there is
-	//no changeClass in java.
-public NameReference() {
-	super();
-	bits |= TYPE | VARIABLE; // restrictiveFlag
-	
-}
-public FieldBinding fieldBinding() {
-	//this method should be sent ONLY after a check against isFieldReference()
-	//check its use doing senders.........
-
-	return (FieldBinding) binding ;
-}
-public boolean isSuperAccess() {
-	return false;
-}
-public boolean isTypeAccess() {
-	// null is acceptable when we are resolving the first part of a reference
-	return binding == null || binding instanceof ReferenceBinding;
-}
-public boolean isTypeReference() {
-	return binding instanceof ReferenceBinding;
-}
-public void setDepth(int depth) {
-	if (depth > 0) {
-		bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
-	}
-}
-public void setFieldIndex(int index){}
-public abstract String unboundReferenceErrorName();
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class NameReference extends Reference implements InvocationSite, BindingIds {
+	public Binding binding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding
+	
+	public TypeBinding receiverType;
+
+	//the error printing
+	//some name reference are build as name reference but
+	//only used as type reference. When it happens, instead of
+	//creating a new objet (aTypeReference) we just flag a boolean
+	//This concesion is valuable while their are cases when the NameReference
+	//will be a TypeReference (static message sends.....) and there is
+	//no changeClass in java.
+public NameReference() {
+	super();
+	bits |= TYPE | VARIABLE; // restrictiveFlag
+	
+}
+public FieldBinding fieldBinding() {
+	//this method should be sent ONLY after a check against isFieldReference()
+	//check its use doing senders.........
+
+	return (FieldBinding) binding ;
+}
+public boolean isSuperAccess() {
+	return false;
+}
+public boolean isTypeAccess() {
+	// null is acceptable when we are resolving the first part of a reference
+	return binding == null || binding instanceof ReferenceBinding;
+}
+public boolean isTypeReference() {
+	return binding instanceof ReferenceBinding;
+}
+public void setDepth(int depth) {
+	if (depth > 0) {
+		bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
+	}
+}
+public void setFieldIndex(int index){}
+public abstract String unboundReferenceErrorName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java b/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
index b995f82..d824e24 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
@@ -1,27 +1,25 @@
-package org.eclipse.jdt.internal.compiler.ast;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public abstract class NumberLiteral extends Literal {
-	char[] source;
-public NumberLiteral(char[] token, int s, int e) {
-	this(s,e) ;
-	source = token ;
-}
-public NumberLiteral(int s, int e) {
-	super (s,e) ;
-}
-public boolean isValidJavaStatement(){
-	//should never be reach, but with a bug in the ast tree....
-	//see comment on the Statement class
-	
-	return false ;}
-public char[] source(){
-	return source;}
-public String toStringExpression(){
-
-	return new String(source);}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public abstract class NumberLiteral extends Literal {
+	char[] source;
+public NumberLiteral(char[] token, int s, int e) {
+	this(s,e) ;
+	source = token ;
+}
+public NumberLiteral(int s, int e) {
+	super (s,e) ;
+}
+public boolean isValidJavaStatement(){
+	//should never be reach, but with a bug in the ast tree....
+	//see comment on the Statement class
+	
+	return false ;}
+public char[] source(){
+	return source;}
+public String toStringExpression(){
+
+	return new String(source);}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
index 2b674f6..149771b 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
@@ -1,1600 +1,1598 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-
-public abstract class OperatorExpression extends Expression implements OperatorIds {
-	public static int[][] ResolveTypeTables = new int[NumberOfTables][];
-	static {classInitialize();}
-/**
- * OperatorExpression constructor comment.
- */
-public OperatorExpression() {
-	super();
-}
-public static final void classInitialize() {
-	ResolveTypeTables[AND] = get_AND();
-	ResolveTypeTables[AND_AND] = get_AND_AND();
-	ResolveTypeTables[DIVIDE] = get_DIVIDE();
-	ResolveTypeTables[EQUAL_EQUAL] = get_EQUAL_EQUAL();
-	ResolveTypeTables[GREATER] = get_GREATER();
-	ResolveTypeTables[GREATER_EQUAL] = get_GREATER_EQUAL();
-	ResolveTypeTables[LEFT_SHIFT] = get_LEFT_SHIFT();
-	ResolveTypeTables[LESS] = get_LESS();
-	ResolveTypeTables[LESS_EQUAL] = get_LESS_EQUAL();
-	ResolveTypeTables[MINUS] = get_MINUS();
-	ResolveTypeTables[MULTIPLY] = get_MULTIPLY();
-	ResolveTypeTables[OR] = get_OR();
-	ResolveTypeTables[OR_OR] = get_OR_OR();
-	ResolveTypeTables[PLUS] = get_PLUS();
-	ResolveTypeTables[REMAINDER] = get_REMAINDER();
-	ResolveTypeTables[RIGHT_SHIFT] = get_RIGHT_SHIFT();
-	ResolveTypeTables[UNSIGNED_RIGHT_SHIFT] = get_UNSIGNED_RIGHT_SHIFT();
-	ResolveTypeTables[XOR] = get_XOR();
-}
-public static final String generateTableTestCase(){
-	//return a String which is a java method allowing to test
-	//the non zero entries of all tables
-
-	/* slow code */
-
-	/*
-	org.eclipse.jdt.internal.compiler.ast.
-	OperatorExpression.generateTableTestCase();
-	*/
-
-	int[] operators = new int[]{AND,AND_AND,DIVIDE,GREATER,GREATER_EQUAL,
-			LEFT_SHIFT,LESS,LESS_EQUAL,MINUS,MULTIPLY,OR,OR_OR,PLUS,REMAINDER,
-			RIGHT_SHIFT,UNSIGNED_RIGHT_SHIFT,XOR};
-
-	class Decode {
-		public  final String constant(int code){
-			switch(code){ 
-				case T_boolean 	: return "true"/*nonNLS*/ ;
-				case T_byte		: return "((byte) 3)"/*nonNLS*/ ;
-				case T_char		: return "'A'"/*nonNLS*/ ;
-				case T_double	: return "300.0d"/*nonNLS*/ ;
-				case T_float	: return "100.0f"/*nonNLS*/ ;
-				case T_int		: return "1"/*nonNLS*/ ;
-				case T_long		: return "7L"/*nonNLS*/ ;
-				case T_String	: return "\"hello-world\""/*nonNLS*/ ;
-				case T_null		: return "null"/*nonNLS*/;
-				case T_short	: return "((short) 5)"/*nonNLS*/;
-				case T_Object	: return "null"/*nonNLS*/;}
-			return ""/*nonNLS*/;}
-
-		public  final String type(int code){
-			switch(code){ 
-				case T_boolean 	: return "z"/*nonNLS*/ ;
-				case T_byte		: return "b"/*nonNLS*/ ;
-				case T_char		: return "c"/*nonNLS*/ ;
-				case T_double	: return "d"/*nonNLS*/ ;
-				case T_float	: return "f"/*nonNLS*/ ;
-				case T_int		: return "i"/*nonNLS*/ ;
-				case T_long		: return "l"/*nonNLS*/ ;
-				case T_String	: return "str"/*nonNLS*/ ;
-				case T_null		: return "null"/*nonNLS*/;
-				case T_short	: return "s"/*nonNLS*/;
-				case T_Object	: return "obj"/*nonNLS*/;}
-			return "xxx"/*nonNLS*/;}
-		
-		public  final String operator(int operator){
-				switch (operator) {
-				case EQUAL_EQUAL :	return "=="/*nonNLS*/;
-				case LESS_EQUAL :	return "<="/*nonNLS*/;
-				case GREATER_EQUAL :return ">="/*nonNLS*/;
-				case LEFT_SHIFT :	return "<<"/*nonNLS*/;
-				case RIGHT_SHIFT :	return ">>"/*nonNLS*/;
-				case UNSIGNED_RIGHT_SHIFT :	return ">>>"/*nonNLS*/;
-				case OR_OR :return "||"/*nonNLS*/;
-				case AND_AND :		return "&&"/*nonNLS*/;
-				case PLUS :			return "+"/*nonNLS*/;
-				case MINUS :		return "-"/*nonNLS*/;
-				case NOT :			return "!"/*nonNLS*/;
-				case REMAINDER :	return "%"/*nonNLS*/;
-				case XOR :			return "^"/*nonNLS*/;
-				case AND :			return "&"/*nonNLS*/;
-				case MULTIPLY :		return "*"/*nonNLS*/;
-				case OR :			return "|"/*nonNLS*/;
-				case TWIDDLE :		return "~"/*nonNLS*/;
-				case DIVIDE :		return "/"/*nonNLS*/;
-				case GREATER :		return ">"/*nonNLS*/;
-				case LESS :			return "<"/*nonNLS*/;	};
-			return "????"/*nonNLS*/;}
-	}
-
-		
-	Decode decode = new Decode();
-	String s ;
-	s = "\tpublic static void binaryOperationTablesTestCase(){\n"/*nonNLS*/ +
-
-		"\t\t//TC test : all binary operation (described in tables)\n"/*nonNLS*/+
-		"\t\t//method automatically generated by\n"/*nonNLS*/+
-		"\t\t//org.eclipse.jdt.internal.compiler.ast.OperatorExpression.generateTableTestCase();\n"/*nonNLS*/+
-	
-		"\t\tString str0 ;\t String str\t= "/*nonNLS*/+decode.constant(T_String)+";\n"/*nonNLS*/+
-		"\t\tint i0 ;\t int i\t= "/*nonNLS*/+decode.constant(T_int)+" ;\n"/*nonNLS*/+
-		"\t\tboolean z0;\t boolean z\t= "/*nonNLS*/+decode.constant(T_boolean)+";\n"/*nonNLS*/+
-		"\t\tchar c0; \t char  c\t= "/*nonNLS*/+decode.constant(T_char)+" ;\n"/*nonNLS*/+
-		"\t\tfloat f0; \t float f\t= "/*nonNLS*/+decode.constant(T_float)+" ;\n"/*nonNLS*/+
-		"\t\tdouble d0;\t double d\t= "/*nonNLS*/+decode.constant(T_double)+" ;\n"/*nonNLS*/+
-		"\t\tbyte b0; \t byte b\t= "/*nonNLS*/+decode.constant(T_byte)+";\n"/*nonNLS*/+
-		"\t\tshort s0; \t short s\t= "/*nonNLS*/+decode.constant(T_short)+";\n"/*nonNLS*/+
-		"\t\tlong l0; \t long l\t= "/*nonNLS*/+decode.constant(T_long)+" ;\n"/*nonNLS*/+
-		"\t\tObject obj0; \t Object obj\t= "/*nonNLS*/+decode.constant(T_Object)+" ;\n"/*nonNLS*/+
-
-		"\n"/*nonNLS*/;
-
-	int error = 0;		
-	for (int i=0; i < operators.length ; i++)
-	{	int operator = operators[i];
-		for (int left=0; left<16;left++)
-		for (int right=0; right<16;right++)
-		{	int result = (ResolveTypeTables[operator][(left<<4)+right]) & 0x0000F;
-			if (result != T_undefined)
-
-				//1/ First regular computation then 2/ comparaison
-				//with a compile time constant (generated by the compiler)
-				//	z0 = s >= s;
-				//	if ( z0 != (((short) 5) >= ((short) 5)))
-				//		System.out.println(155);
-
-			{	s += "\t\t"/*nonNLS*/+decode.type(result)+"0"/*nonNLS*/+" = "/*nonNLS*/+decode.type(left);
-				s += " "/*nonNLS*/+decode.operator(operator)+" "/*nonNLS*/+decode.type(right)+";\n"/*nonNLS*/;
-				String begin = result == T_String ? "\t\tif (! "/*nonNLS*/ : "\t\tif ( "/*nonNLS*/;
-				String test = result == T_String ? ".equals("/*nonNLS*/ : " != ("/*nonNLS*/ ;
-				s += begin	+decode.type(result)+"0"/*nonNLS*/+test
-							+decode.constant(left)+" "/*nonNLS*/
-							+decode.operator(operator)+" "/*nonNLS*/
-							+decode.constant(right)+"))\n"/*nonNLS*/;
-				s += "\t\t\tSystem.out.println("/*nonNLS*/+ (++error) +");\n"/*nonNLS*/;
-								
-				}}}
-		
-	return s += "\n\t\tSystem.out.println(\"binary tables test : done\");}"/*nonNLS*/ ;
-		}
-public static final int[] get_AND(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-	
-//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12) +(Byte2Int<<4) +T_int ;
-	table[(T_byte<<4)+T_long]		= (Byte2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12) +(Short2Int<<4)+T_int;
-//	table[(T_byte<<4)+T_void] 		= T_undefined ;
-//	table[(T_byte<<4)+T_String] 	= T_undefined ;
-//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
-//	table[(T_byte<<4)+T_double] 	= T_undefined ;
-//	table[(T_byte<<4)+T_float] 		= T_undefined ;
-//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12) +(Char2Int<<4) +T_int ;
-	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12) +(Int2Int<<4)  +T_int ;
-//	table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
-	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
-	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long; ;
-//	table[(T_long<<4)+T_void] 		= T_undefined ;
-//	table[(T_long<<4)+T_String] 	= T_undefined ;
-//	table[(T_long<<4)+T_Object] 	= T_undefined ;
-//	table[(T_long<<4)+T_double] 	= T_undefined ;
-//	table[(T_long<<4)+T_float] 		= T_undefined ;
-//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
-	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long ;
-	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long ;
-//	table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
-	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_void] 			= T_undefined ;
-//	table[(T_short<<4)+T_String] 		= T_undefined ;
-//	table[(T_short<<4)+T_Object] 		= T_undefined ;
-//	table[(T_short<<4)+T_double] 		= T_undefined ;
-//	table[(T_short<<4)+T_float] 		= T_undefined ;
-//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
-	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_void<<4)+T_byte] 		= T_undefined ;
-//	table[(T_void<<4)+T_long] 		= T_undefined ;
-//	table[(T_void<<4)+T_short] 		= T_undefined ;
-//	table[(T_void<<4)+T_void] 		= T_undefined ;
-//	table[(T_void<<4)+T_String] 	= T_undefined ;
-//	table[(T_void<<4)+T_Object] 	= T_undefined ;
-//	table[(T_void<<4)+T_double] 	= T_undefined ;
-//	table[(T_void<<4)+T_float] 		= T_undefined ;
-//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//	table[(T_void<<4)+T_char] 		= T_undefined ;
-//	table[(T_void<<4)+T_int] 		= T_undefined ;
-//	table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_String<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_String<<4)+T_byte] 		= T_undefined ;
-//	table[(T_String<<4)+T_long] 		= T_undefined ;
-//	table[(T_String<<4)+T_short] 		= T_undefined ;
-//	table[(T_String<<4)+T_void] 		= T_undefined ;
-//	table[(T_String<<4)+T_String] 		= T_undefined ;
-//	table[(T_String<<4)+T_Object] 		= T_undefined ;
-//	table[(T_String<<4)+T_double] 		= T_undefined ;
-//	table[(T_String<<4)+T_float] 		= T_undefined ;
-//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_String<<4)+T_char] 		= T_undefined ;
-//	table[(T_String<<4)+T_int] 			= T_undefined ;
-//	table[(T_String<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//	table[(T_Object<<4)+T_long] 		= T_undefined ;
-//	table[(T_Object<<4)+T_short]		= T_undefined ;
-//	table[(T_Object<<4)+T_void] 		= T_undefined ;
-//	table[(T_Object<<4)+T_String] 		= T_undefined ;
-//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
-//	table[(T_Object<<4)+T_double] 		= T_undefined ;
-//	table[(T_Object<<4)+T_float] 		= T_undefined ;
-//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//	table[(T_Object<<4)+T_char] 		= T_undefined ;
-//	table[(T_Object<<4)+T_int] 			= T_undefined ;
-//	table[(T_Object<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_double<<4)+T_byte] 		= T_undefined ;
-//	table[(T_double<<4)+T_long] 		= T_undefined ;
-//	table[(T_double<<4)+T_short] 		= T_undefined ;
-//	table[(T_double<<4)+T_void] 		= T_undefined ;
-//	table[(T_double<<4)+T_String] 		= T_undefined ;
-//	table[(T_double<<4)+T_Object] 		= T_undefined ;
-//	table[(T_double<<4)+T_double] 		= T_undefined ;
-//	table[(T_double<<4)+T_float] 		= T_undefined ;
-//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_double<<4)+T_char] 		= T_undefined ;
-//	table[(T_double<<4)+T_int] 			= T_undefined;
-//	table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_float<<4)+T_byte] 			= T_undefined ;
-//	table[(T_float<<4)+T_long] 			= T_undefined ;
-//	table[(T_float<<4)+T_short] 		= T_undefined ;
-//	table[(T_float<<4)+T_void] 			= T_undefined ;
-//	table[(T_float<<4)+T_String] 		= T_undefined ;
-//	table[(T_float<<4)+T_Object] 		= T_undefined ;
-//	table[(T_float<<4)+T_double] 		= T_undefined ;
-//	table[(T_float<<4)+T_float] 		= T_undefined ;
-//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_float<<4)+T_char] 			= T_undefined ;
-//	table[(T_float<<4)+T_int] 			= T_undefined ;
-//	table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
-	table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean << 12)+(Boolean2Boolean << 4)+T_boolean ;
-//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
-	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long;
-	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_void] 			= T_undefined ;
-//	table[(T_char<<4)+T_String] 		= T_undefined ;
-//	table[(T_char<<4)+T_Object] 		= T_undefined ;
-//	table[(T_char<<4)+T_double] 		= T_undefined ;
-//	table[(T_char<<4)+T_float] 			= T_undefined ;
-//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
-	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
-	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_void] 		= T_undefined ;
-//	table[(T_int<<4)+T_String] 		= T_undefined ;
-//	table[(T_int<<4)+T_Object] 		= T_undefined ;
-//	table[(T_int<<4)+T_double] 		= T_undefined ;
-//	table[(T_int<<4)+T_float] 		= T_undefined ;
-//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
-	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_null<<4)+T_byte] 			= T_undefined ;
-//	table[(T_null<<4)+T_long] 			= T_undefined ;
-//	table[(T_null<<4)+T_short] 			= T_undefined ;
-//	table[(T_null<<4)+T_void] 			= T_undefined ;
-//	table[(T_null<<4)+T_String] 		= T_undefined ;
-//	table[(T_null<<4)+T_Object] 		= T_undefined ;
-//	table[(T_null<<4)+T_double] 		= T_undefined ;
-//	table[(T_null<<4)+T_float] 			= T_undefined ;
-//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_null<<4)+T_char] 			= T_undefined ;
-//	table[(T_null<<4)+T_int] 			= T_undefined ;
-//	table[(T_null<<4)+T_null] 			= T_undefined ;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_AND_AND(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-	
-//     table[(T_undefined<<4)+T_undefined] 		= T_undefined ;
-//     table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_short] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//     table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//     table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//     table[(T_undefined<<4)+T_float] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//     table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//     table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_byte<<4)+T_byte] 		= T_undefined ;
-//     table[(T_byte<<4)+T_long] 		= T_undefined ;
-//     table[(T_byte<<4)+T_short] 		= T_undefined ;
-//     table[(T_byte<<4)+T_void] 		= T_undefined ;
-//     table[(T_byte<<4)+T_String] 		= T_undefined ;
-//     table[(T_byte<<4)+T_Object] 		= T_undefined ;
-//     table[(T_byte<<4)+T_double] 		= T_undefined ;
-//     table[(T_byte<<4)+T_float] 		= T_undefined ;
-//     table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-//     table[(T_byte<<4)+T_char] 		= T_undefined ;
-//     table[(T_byte<<4)+T_int] 		= T_undefined ;
-//     table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_long<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_long<<4)+T_byte] 		= T_undefined;
-//     table[(T_long<<4)+T_long] 		= T_undefined ;
-//     table[(T_long<<4)+T_short] 		= T_undefined ;
-//     table[(T_long<<4)+T_void] 		= T_undefined ;
-//     table[(T_long<<4)+T_String] 		= T_undefined ;
-//     table[(T_long<<4)+T_Object] 		= T_undefined ;
-//     table[(T_long<<4)+T_double] 		= T_undefined ;
-//     table[(T_long<<4)+T_float] 		= T_undefined ;
-//     table[(T_long<<4)+T_boolean] 	= T_undefined ;
-//     table[(T_long<<4)+T_char] 		= T_undefined ;
-//     table[(T_long<<4)+T_int] 		= T_undefined ;
-//     table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_short<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_short<<4)+T_byte] 		= T_undefined ;
-//     table[(T_short<<4)+T_long] 		= T_undefined ;
-//     table[(T_short<<4)+T_short] 		= T_undefined ;
-//     table[(T_short<<4)+T_void] 		= T_undefined ;
-//     table[(T_short<<4)+T_String] 	= T_undefined ;
-//     table[(T_short<<4)+T_Object] 	= T_undefined ;
-//     table[(T_short<<4)+T_double] 	= T_undefined ;
-//     table[(T_short<<4)+T_float] 		= T_undefined ;
-//     table[(T_short<<4)+T_boolean]	= T_undefined ;
-//     table[(T_short<<4)+T_char] 		= T_undefined ;
-//     table[(T_short<<4)+T_int] 		= T_undefined ;
-//     table[(T_short<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_void<<4)+T_byte] 		= T_undefined ;
-//     table[(T_void<<4)+T_long] 		= T_undefined ;
-//     table[(T_void<<4)+T_short] 		= T_undefined ;
-//     table[(T_void<<4)+T_void] 		= T_undefined ;
-//     table[(T_void<<4)+T_String] 	= T_undefined ;
-//     table[(T_void<<4)+T_Object] 	= T_undefined ;
-//     table[(T_void<<4)+T_double] 	= T_undefined ;
-//     table[(T_void<<4)+T_float] 		= T_undefined ;
-//     table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//     table[(T_void<<4)+T_char] 		= T_undefined ;
-//     table[(T_void<<4)+T_int] 		= T_undefined ;
-//     table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_String<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_String<<4)+T_byte] 		= T_undefined ;
-//     table[(T_String<<4)+T_long] 		= T_undefined ;
-//     table[(T_String<<4)+T_short] 		= T_undefined ;
-//     table[(T_String<<4)+T_void] 		= T_undefined ;
-//     table[(T_String<<4)+T_String] 		= T_undefined ;
-//     table[(T_String<<4)+T_Object] 		= T_undefined ;
-//     table[(T_String<<4)+T_double] 		= T_undefined ;
-//     table[(T_String<<4)+T_float] 		= T_undefined ;
-//     table[(T_String<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_String<<4)+T_char] 		= T_undefined ;
-//     table[(T_String<<4)+T_int] 			= T_undefined ;
-//     table[(T_String<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//     table[(T_Object<<4)+T_long] 		= T_undefined ;
-//     table[(T_Object<<4)+T_short]		= T_undefined ;
-//     table[(T_Object<<4)+T_void] 		= T_undefined ;
-//     table[(T_Object<<4)+T_String] 		= T_undefined ;
-//     table[(T_Object<<4)+T_Object] 		= T_undefined ;
-//     table[(T_Object<<4)+T_double] 		= T_undefined ;
-//     table[(T_Object<<4)+T_float] 		= T_undefined ;
-//     table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//     table[(T_Object<<4)+T_char] 		= T_undefined ;
-//     table[(T_Object<<4)+T_int] 			= T_undefined ;
-//     table[(T_Object<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_double<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_double<<4)+T_byte] 		= T_undefined ;
-//     table[(T_double<<4)+T_long] 		= T_undefined ;
-//     table[(T_double<<4)+T_short] 		= T_undefined ;
-//     table[(T_double<<4)+T_void] 		= T_undefined ;
-//     table[(T_double<<4)+T_String] 		= T_undefined ;
-//     table[(T_double<<4)+T_Object] 		= T_undefined ;
-//     table[(T_double<<4)+T_double] 		= T_undefined ;
-//     table[(T_double<<4)+T_float] 		= T_undefined ;
-//     table[(T_double<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_double<<4)+T_char] 		= T_undefined ;
-//     table[(T_double<<4)+T_int] 			= T_undefined;
-//     table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_float<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_float<<4)+T_byte] 			= T_undefined ;
-//     table[(T_float<<4)+T_long] 			= T_undefined ;
-//     table[(T_float<<4)+T_short] 		= T_undefined ;
-//     table[(T_float<<4)+T_void] 			= T_undefined ;
-//     table[(T_float<<4)+T_String] 		= T_undefined ;
-//     table[(T_float<<4)+T_Object] 		= T_undefined ;
-//     table[(T_float<<4)+T_double] 		= T_undefined ;
-//     table[(T_float<<4)+T_float] 		= T_undefined ;
-//     table[(T_float<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_float<<4)+T_char] 			= T_undefined ;
-//     table[(T_float<<4)+T_int] 			= T_undefined ;
-//     table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//     table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//     table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_void] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_String] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_float] 			= T_undefined ;
-	   table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ;
-//     table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//     table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//     table[(T_char<<4)+T_undefined] 		= T_undefined ;
-//     table[(T_char<<4)+T_byte] 			= T_undefined ;
-//     table[(T_char<<4)+T_long] 			= T_undefined;
-//     table[(T_char<<4)+T_short] 			= T_undefined ;
-//     table[(T_char<<4)+T_void] 			= T_undefined ;
-//     table[(T_char<<4)+T_String] 		= T_undefined ;
-//     table[(T_char<<4)+T_Object] 		= T_undefined ;
-//     table[(T_char<<4)+T_double] 		= T_undefined ;
-//     table[(T_char<<4)+T_float] 			= T_undefined ;
-//     table[(T_char<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_char<<4)+T_char] 			= T_undefined ;
-//     table[(T_char<<4)+T_int] 			= T_undefined ;
-//     table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//     table[(T_int<<4)+T_undefined] 	= T_undefined ;
-//     table[(T_int<<4)+T_byte] 		= T_undefined ;
-//     table[(T_int<<4)+T_long] 		= T_undefined ;
-//     table[(T_int<<4)+T_short] 		= T_undefined ;
-//     table[(T_int<<4)+T_void] 		= T_undefined ;
-//     table[(T_int<<4)+T_String] 		= T_undefined ;
-//     table[(T_int<<4)+T_Object] 		= T_undefined ;
-//     table[(T_int<<4)+T_double] 		= T_undefined ;
-//     table[(T_int<<4)+T_float] 		= T_undefined ;
-//     table[(T_int<<4)+T_boolean] 	= T_undefined ;
-//     table[(T_int<<4)+T_char] 		= T_undefined ;
-//     table[(T_int<<4)+T_int] 		= T_undefined ;
-//     table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//     table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//     table[(T_null<<4)+T_byte] 			= T_undefined ;
-//     table[(T_null<<4)+T_long] 			= T_undefined ;
-//     table[(T_null<<4)+T_short] 			= T_undefined ;
-//     table[(T_null<<4)+T_void] 			= T_undefined ;
-//     table[(T_null<<4)+T_String] 		= T_undefined ;
-//     table[(T_null<<4)+T_Object] 		= T_undefined ;
-//     table[(T_null<<4)+T_double] 		= T_undefined ;
-//     table[(T_null<<4)+T_float] 			= T_undefined ;
-//     table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//     table[(T_null<<4)+T_char] 			= T_undefined ;
-//     table[(T_null<<4)+T_int] 			= T_undefined ;
-//     table[(T_null<<4)+T_null] 			= T_undefined ;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_DIVIDE(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-	
-	return get_MINUS();
-			
-//	return table ;
-}
-public static final int[] get_EQUAL_EQUAL(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	int[] table  = new int[16*16] ;
-	
-//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_byte<<4)+T_void] 		= T_undefined ;
-//	table[(T_byte<<4)+T_String] 	= T_undefined ;
-//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
-	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
-//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean;
-//	table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
-	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
-	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean ;
-//	table[(T_long<<4)+T_void] 		= T_undefined ;
-//	table[(T_long<<4)+T_String] 	= T_undefined ;
-//	table[(T_long<<4)+T_Object] 	= T_undefined ;
-	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
-	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean ;
-	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean ;
-//	table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
-	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_short<<4)+T_void] 			= T_undefined ;
-//	table[(T_short<<4)+T_String] 		= T_undefined ;
-//	table[(T_short<<4)+T_Object] 		= T_undefined ;
-	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
-	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_short<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_void<<4)+T_byte] 		= T_undefined ;
-//	table[(T_void<<4)+T_long] 		= T_undefined ;
-//	table[(T_void<<4)+T_short] 		= T_undefined ;
-//	table[(T_void<<4)+T_void] 		= T_undefined ;
-//	table[(T_void<<4)+T_String] 	= T_undefined ;
-//	table[(T_void<<4)+T_Object] 	= T_undefined ;
-//	table[(T_void<<4)+T_double] 	= T_undefined ;
-//	table[(T_void<<4)+T_float] 		= T_undefined ;
-//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//	table[(T_void<<4)+T_char] 		= T_undefined ;
-//	table[(T_void<<4)+T_int] 		= T_undefined ;
-//	table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
-//	table[(T_String<<4)+T_byte] 		= T_undefined ;
-//	table[(T_String<<4)+T_long] 		= T_undefined ; 
-//	table[(T_String<<4)+T_short] 		= T_undefined ;
-//	table[(T_String<<4)+T_void] 		= T_undefined ;
-	table[(T_String<<4)+T_String] 		= /*String2Object                 String2Object*/
-										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
-	table[(T_String<<4)+T_Object] 		= /*String2Object                 Object2Object*/
-										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ;
-//	table[(T_String<<4)+T_double] 		= T_undefined ;
-//	table[(T_String<<4)+T_float] 		= T_undefined ; 
-//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_String<<4)+T_char] 		= T_undefined ;
-//	table[(T_String<<4)+T_int] 			= T_undefined ;
-	table[(T_String<<4)+T_null] 		= /*Object2String                null2Object */
-										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
-
-//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//	table[(T_Object<<4)+T_long] 		= T_undefined ;
-//	table[(T_Object<<4)+T_short]		= T_undefined ;
-//	table[(T_Object<<4)+T_void] 		= T_undefined ;
-	table[(T_Object<<4)+T_String] 		= /*Object2Object                 String2Object*/
-										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
-	table[(T_Object<<4)+T_Object] 		= /*Object2Object                 Object2Object*/
-										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ;
-//	table[(T_Object<<4)+T_double] 		= T_undefined ;
-//	table[(T_Object<<4)+T_float] 		= T_undefined ;
-//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//	table[(T_Object<<4)+T_char] 		= T_undefined ;
-//	table[(T_Object<<4)+T_int] 			= T_undefined ;
-	table[(T_Object<<4)+T_null] 		= /*Object2Object                 null2Object*/
-										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
-
-//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
-	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean ;
-//	table[(T_double<<4)+T_void] 		= T_undefined ;
-//	table[(T_double<<4)+T_String] 		= T_undefined ;
-//	table[(T_double<<4)+T_Object] 		= T_undefined ;
-	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean;
-//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
-	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean ;
-//	table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
-	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_void] 			= T_undefined ;
-//	table[(T_float<<4)+T_String] 		= T_undefined ;
-//	table[(T_float<<4)+T_Object] 		= T_undefined ;
-	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
-	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
-	table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ;
-//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
-	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_char<<4)+T_void] 			= T_undefined ;
-//	table[(T_char<<4)+T_String] 		= T_undefined ;
-//	table[(T_char<<4)+T_Object] 		= T_undefined ;
-	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
-	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
-	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_int<<4)+T_void] 		= T_undefined ;
-//	table[(T_int<<4)+T_String] 		= T_undefined ;
-//	table[(T_int<<4)+T_Object] 		= T_undefined ;
-	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean;
-//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
-	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_null<<4)+T_byte] 			= T_undefined ;
-//	table[(T_null<<4)+T_long] 			= T_undefined ;
-//	table[(T_null<<4)+T_short] 			= T_undefined ;
-//	table[(T_null<<4)+T_void] 			= T_undefined ;
-	table[(T_null<<4)+T_String] 		= /*null2Object                 String2Object*/
-										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
-	table[(T_null<<4)+T_Object] 		= /*null2Object                 Object2Object*/
-										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ; ;
-//	table[(T_null<<4)+T_double] 		= T_undefined ;
-//	table[(T_null<<4)+T_float] 			= T_undefined ;
-//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_null<<4)+T_char] 			= T_undefined ;
-//	table[(T_null<<4)+T_int] 			= T_undefined ;
-	table[(T_null<<4)+T_null] 			= /*null2Object                 null2Object*/
-										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_GREATER(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_LESS();
-			
-//	return table ;
-}
-public static final int[] get_GREATER_EQUAL(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_LESS();
-			
-//	return table ;
-}
-public static final int[] get_LEFT_SHIFT(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-	
-//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_byte<<4)+T_long] 		= (Byte2Int<<12)+(Long2Int<<4)+T_int ;
-	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_byte<<4)+T_void] 		= T_undefined ;
-//	table[(T_byte<<4)+T_String] 	= T_undefined ;
-//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
-//	table[(T_byte<<4)+T_double] 	= T_undefined ;
-//	table[(T_byte<<4)+T_float] 		= T_undefined ;
-//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
-	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Int<<4)+T_long;
-	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Int<<4)+T_long ;
-	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Int<<4)+T_long ;
-//	table[(T_long<<4)+T_void] 		= T_undefined ;
-//	table[(T_long<<4)+T_String] 	= T_undefined ;
-//	table[(T_long<<4)+T_Object] 	= T_undefined ;
-//	table[(T_long<<4)+T_double] 	= T_undefined ;
-//	table[(T_long<<4)+T_float] 		= T_undefined ;
-//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
-	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Int<<4)+T_long ;
-	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Int<<4)+T_long ;
-//	table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
-	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_short<<4)+T_long] 			= (Short2Int<<12)+(Long2Int<<4)+T_int ;
-	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_void] 			= T_undefined ;
-//	table[(T_short<<4)+T_String] 		= T_undefined ;
-//	table[(T_short<<4)+T_Object] 		= T_undefined ;
-//	table[(T_short<<4)+T_double] 		= T_undefined ;
-//	table[(T_short<<4)+T_float] 		= T_undefined ;
-//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
-	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_void<<4)+T_byte] 		= T_undefined ;
-//	table[(T_void<<4)+T_long] 		= T_undefined ;
-//	table[(T_void<<4)+T_short] 		= T_undefined ;
-//	table[(T_void<<4)+T_void] 		= T_undefined ;
-//	table[(T_void<<4)+T_String] 	= T_undefined ;
-//	table[(T_void<<4)+T_Object] 	= T_undefined ;
-//	table[(T_void<<4)+T_double] 	= T_undefined ;
-//	table[(T_void<<4)+T_float] 		= T_undefined ;
-//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//	table[(T_void<<4)+T_char] 		= T_undefined ;
-//	table[(T_void<<4)+T_int] 		= T_undefined ;
-//	table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_String<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_String<<4)+T_byte] 		= T_undefined ;
-//	table[(T_String<<4)+T_long] 		= T_undefined ;
-//	table[(T_String<<4)+T_short] 		= T_undefined ;
-//	table[(T_String<<4)+T_void] 		= T_undefined ;
-//	table[(T_String<<4)+T_String] 		= T_undefined ;
-//	table[(T_String<<4)+T_Object] 		= T_undefined ;
-//	table[(T_String<<4)+T_double] 		= T_undefined ;
-//	table[(T_String<<4)+T_float] 		= T_undefined ;
-//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_String<<4)+T_char] 		= T_undefined ;
-//	table[(T_String<<4)+T_int] 			= T_undefined ;
-//	table[(T_String<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//	table[(T_Object<<4)+T_long] 		= T_undefined ;
-//	table[(T_Object<<4)+T_short]		= T_undefined ;
-//	table[(T_Object<<4)+T_void] 		= T_undefined ;
-//	table[(T_Object<<4)+T_String] 		= T_undefined ;
-//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
-//	table[(T_Object<<4)+T_double] 		= T_undefined ;
-//	table[(T_Object<<4)+T_float] 		= T_undefined ;
-//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//	table[(T_Object<<4)+T_char] 		= T_undefined ;
-//	table[(T_Object<<4)+T_int] 			= T_undefined ;
-//	table[(T_Object<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_double<<4)+T_byte] 		= T_undefined ;
-//	table[(T_double<<4)+T_long] 		= T_undefined ;
-//	table[(T_double<<4)+T_short] 		= T_undefined ;
-//	table[(T_double<<4)+T_void] 		= T_undefined ;
-//	table[(T_double<<4)+T_String] 		= T_undefined ;
-//	table[(T_double<<4)+T_Object] 		= T_undefined ;
-//	table[(T_double<<4)+T_double] 		= T_undefined ;
-//	table[(T_double<<4)+T_float] 		= T_undefined ;
-//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_double<<4)+T_char] 		= T_undefined ;
-//	table[(T_double<<4)+T_int] 			= T_undefined;
-//	table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_float<<4)+T_byte] 			= T_undefined ;
-//	table[(T_float<<4)+T_long] 			= T_undefined ;
-//	table[(T_float<<4)+T_short] 		= T_undefined ;
-//	table[(T_float<<4)+T_void] 			= T_undefined ;
-//	table[(T_float<<4)+T_String] 		= T_undefined ;
-//	table[(T_float<<4)+T_Object] 		= T_undefined ;
-//	table[(T_float<<4)+T_double] 		= T_undefined ;
-//	table[(T_float<<4)+T_float] 		= T_undefined ;
-//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_float<<4)+T_char] 			= T_undefined ;
-//	table[(T_float<<4)+T_int] 			= T_undefined ;
-//	table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
-	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_char<<4)+T_long] 			= (Char2Int<<12)+(Long2Int<<4)+T_int ;
-	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_void] 			= T_undefined ;
-//	table[(T_char<<4)+T_String] 		= T_undefined ;
-//	table[(T_char<<4)+T_Object] 		= T_undefined ;
-//	table[(T_char<<4)+T_double] 		= T_undefined ;
-//	table[(T_char<<4)+T_float] 			= T_undefined ;
-//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
-	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
-	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_int<<4)+T_long] 		= (Int2Int<<12)+(Long2Int<<4)+T_int ;
-	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_void] 		= T_undefined ;
-//	table[(T_int<<4)+T_String] 		= T_undefined ;
-//	table[(T_int<<4)+T_Object] 		= T_undefined ;
-//	table[(T_int<<4)+T_double] 		= T_undefined ;
-//	table[(T_int<<4)+T_float] 		= T_undefined ;
-//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
-	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_null<<4)+T_byte] 			= T_undefined ;
-//	table[(T_null<<4)+T_long] 			= T_undefined ;
-//	table[(T_null<<4)+T_short] 			= T_undefined ;
-//	table[(T_null<<4)+T_void] 			= T_undefined ;
-//	table[(T_null<<4)+T_String] 		= T_undefined ;
-//	table[(T_null<<4)+T_Object] 		= T_undefined ;
-//	table[(T_null<<4)+T_double] 		= T_undefined ;
-//	table[(T_null<<4)+T_float] 			= T_undefined ;
-//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_null<<4)+T_char] 			= T_undefined ;
-//	table[(T_null<<4)+T_int] 			= T_undefined ;
-//	table[(T_null<<4)+T_null] 			= T_undefined ;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_LESS(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-	
-//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_byte<<4)+T_void] 		= T_undefined ;
-//	table[(T_byte<<4)+T_String] 	= T_undefined ;
-//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
-	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
-//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
-	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
-	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean ;
-//	table[(T_long<<4)+T_void] 		= T_undefined ;
-//	table[(T_long<<4)+T_String] 	= T_undefined ;
-//	table[(T_long<<4)+T_Object] 	= T_undefined ;
-	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
-	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean ;
-	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean ;
-//	table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
-	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_short<<4)+T_void] 			= T_undefined ;
-//	table[(T_short<<4)+T_String] 		= T_undefined ;
-//	table[(T_short<<4)+T_Object] 		= T_undefined ;
-	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
-	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_short<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_void<<4)+T_byte] 		= T_undefined ;
-//	table[(T_void<<4)+T_long] 		= T_undefined ;
-//	table[(T_void<<4)+T_short] 		= T_undefined ;
-//	table[(T_void<<4)+T_void] 		= T_undefined ;
-//	table[(T_void<<4)+T_String] 	= T_undefined ;
-//	table[(T_void<<4)+T_Object] 	= T_undefined ;
-//	table[(T_void<<4)+T_double] 	= T_undefined ;
-//	table[(T_void<<4)+T_float] 		= T_undefined ;
-//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//	table[(T_void<<4)+T_char] 		= T_undefined ;
-//	table[(T_void<<4)+T_int] 		= T_undefined ;
-//	table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
-//	table[(T_String<<4)+T_byte] 		= T_undefined ;
-//	table[(T_String<<4)+T_long] 		= T_undefined ; 
-//	table[(T_String<<4)+T_short] 		= T_undefined ;
-//	table[(T_String<<4)+T_void] 		= T_undefined ;
-//	table[(T_String<<4)+T_String] 		= T_undefined ;
-//	table[(T_String<<4)+T_Object] 		= T_undefined ;
-//	table[(T_String<<4)+T_double] 		= T_undefined ;
-//	table[(T_String<<4)+T_float] 		= T_undefined ; 
-//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_String<<4)+T_char] 		= T_undefined ;
-//	table[(T_String<<4)+T_int] 			= T_undefined ;
-//	table[(T_String<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//	table[(T_Object<<4)+T_long] 		= T_undefined ;
-//	table[(T_Object<<4)+T_short]		= T_undefined ;
-//	table[(T_Object<<4)+T_void] 		= T_undefined ;
-//	table[(T_Object<<4)+T_String] 		= T_undefined ;
-//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
-//	table[(T_Object<<4)+T_double] 		= T_undefined ;
-//	table[(T_Object<<4)+T_float] 		= T_undefined ;
-//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//	table[(T_Object<<4)+T_char] 		= T_undefined ;
-//	table[(T_Object<<4)+T_int] 			= T_undefined ;
-//	table[(T_Object<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
-	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean;
-	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean ;
-//	table[(T_double<<4)+T_void] 		= T_undefined ;
-//	table[(T_double<<4)+T_String] 		= T_undefined ;
-//	table[(T_double<<4)+T_Object] 		= T_undefined ;
-	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean ;
-//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
-	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean ;
-	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean;
-//	table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
-	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_void] 			= T_undefined ;
-//	table[(T_float<<4)+T_String] 		= T_undefined ;
-//	table[(T_float<<4)+T_Object] 		= T_undefined ;
-	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
-	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean ;
-	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean ;
-//	table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
-	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean ;
-	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_char<<4)+T_void] 			= T_undefined ;
-//	table[(T_char<<4)+T_String] 		= T_undefined ;
-//	table[(T_char<<4)+T_Object] 		= T_undefined ;
-	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
-	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean ;
-//	table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
-	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean ;
-	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean;
-	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean ;
-//	table[(T_int<<4)+T_void] 		= T_undefined ;
-//	table[(T_int<<4)+T_String] 		= T_undefined ;
-//	table[(T_int<<4)+T_Object] 		= T_undefined ;
-	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean ;
-	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean ;
-//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
-	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean ;
-	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean;
-//	table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_null<<4)+T_byte] 			= T_undefined ;
-//	table[(T_null<<4)+T_long] 			= T_undefined ;
-//	table[(T_null<<4)+T_short] 			= T_undefined ;
-//	table[(T_null<<4)+T_void] 			= T_undefined ;
-//	table[(T_null<<4)+T_String] 		= T_undefined ;
-//	table[(T_null<<4)+T_Object] 		= T_undefined ;
-//	table[(T_null<<4)+T_double] 		= T_undefined ;
-//	table[(T_null<<4)+T_float] 			= T_undefined ;
-//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_null<<4)+T_char] 			= T_undefined ;
-//	table[(T_null<<4)+T_int] 			= T_undefined ;
-//	table[(T_null<<4)+T_null] 			= T_undefined ;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_LESS_EQUAL(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_LESS();
-			
-//	return table ;
-}
-public static final int[] get_MINUS(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-
-	table = (int[]) get_PLUS().clone();
-
-	table[(T_String<<4)+T_byte] 		= T_undefined ;
-	table[(T_String<<4)+T_long] 		= T_undefined ;
-	table[(T_String<<4)+T_short] 		= T_undefined ;
-	table[(T_String<<4)+T_void] 		= T_undefined ;
-	table[(T_String<<4)+T_String] 		= T_undefined ;
-	table[(T_String<<4)+T_Object] 		= T_undefined ;
-	table[(T_String<<4)+T_double] 		= T_undefined ;
-	table[(T_String<<4)+T_float] 		= T_undefined ;
-	table[(T_String<<4)+T_boolean] 		= T_undefined ;
-	table[(T_String<<4)+T_char] 		= T_undefined ;
-	table[(T_String<<4)+T_int] 			= T_undefined ;
-	table[(T_String<<4)+T_null] 		= T_undefined ;
-	
-	table[(T_byte<<4)	+T_String] 		= T_undefined ;
-	table[(T_long<<4)	+T_String] 		= T_undefined ;
-	table[(T_short<<4)	+T_String] 		= T_undefined ;
-	table[(T_void<<4)	+T_String] 		= T_undefined ;
-	table[(T_Object<<4)	+T_String] 		= T_undefined ;
-	table[(T_double<<4)	+T_String] 		= T_undefined ;
-	table[(T_float<<4)	+T_String] 		= T_undefined ;
-	table[(T_boolean<<4)+T_String] 		= T_undefined ;
-	table[(T_char<<4)	+T_String] 		= T_undefined ;
-	table[(T_int<<4)	+T_String] 		= T_undefined ;
-	table[(T_null<<4)	+T_String] 		= T_undefined ;
-	
-	table[(T_null<<4)	+T_null] 		= T_undefined ;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_MULTIPLY(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_MINUS();
-			
-//	return table ;
-}
-public static final int[] get_OR(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-	
-	return get_AND() ;
-			
-//	return table ;
-}
-public static final int[] get_OR_OR(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-	
-	return get_AND_AND() ;
-			
-//	return table ;
-}
-public static final int[] get_PLUS(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-	int[] table  = new int[16*16] ;
-	
-//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
-//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
-	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_byte<<4)+T_void] 		= T_undefined ;
-	table[(T_byte<<4)+T_String] 	= (Byte2Byte<<12)+(String2String<<4)+T_String ;
-//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
-	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_float;
-//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
-	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_byte<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
-	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
-	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long ;
-//	table[(T_long<<4)+T_void] 		= T_undefined ;
-	table[(T_long<<4)+T_String] 	= (Long2Long<<12)+(String2String<<4)+T_String ;
-//	table[(T_long<<4)+T_Object] 	= T_undefined ;
-	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_float ;
-//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
-	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long ;
-	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long ; ;
-//	table[(T_long<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
-	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_void] 			= T_undefined ;
-	table[(T_short<<4)+T_String] 		= (Short2Short<<12)+(String2String<<4)+T_String ;
-//	table[(T_short<<4)+T_Object] 		= T_undefined ;
-	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_float ;
-//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
-	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_short<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_void<<4)+T_byte] 		= T_undefined ;
-//	table[(T_void<<4)+T_long] 		= T_undefined ;
-//	table[(T_void<<4)+T_short] 		= T_undefined ;
-//	table[(T_void<<4)+T_void] 		= T_undefined ;
-//	table[(T_void<<4)+T_String] 	= T_undefined ;
-//	table[(T_void<<4)+T_Object] 	= T_undefined ;
-//	table[(T_void<<4)+T_double] 	= T_undefined ;
-//	table[(T_void<<4)+T_float] 		= T_undefined ;
-//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
-//	table[(T_void<<4)+T_char] 		= T_undefined ;
-//	table[(T_void<<4)+T_int] 		= T_undefined ;
-//	table[(T_void<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
-	table[(T_String<<4)+T_byte] 		= (String2String<<12)+(Byte2Byte<<4)+T_String ;
-	table[(T_String<<4)+T_long] 		= (String2String<<12)+(Long2Long<<4)+T_String ; 
-	table[(T_String<<4)+T_short] 		= (String2String<<12)+(Short2Short<<4)+T_String ;
-//	table[(T_String<<4)+T_void] 		= T_undefined ;
-	table[(T_String<<4)+T_String] 		= (String2String<<12)+(String2String<<4)+T_String ;
-	table[(T_String<<4)+T_Object] 		= (String2String<<12)+(T_Object<<8)+(T_Object<<4)+T_String ;
-	table[(T_String<<4)+T_double] 		= (String2String<<12)+(Double2Double<<4)+T_String ;
-	table[(T_String<<4)+T_float] 		= (String2String<<12)+(Float2Float<<4)+T_String ; 
-	table[(T_String<<4)+T_boolean] 		= (String2String<<12)+(Boolean2Boolean<<4)+T_String ;
-	table[(T_String<<4)+T_char] 		= (String2String<<12)+(Char2Char<<4)+T_String ;
-	table[(T_String<<4)+T_int] 			= (String2String<<12)+(Int2Int<<4)+T_String ;
-	table[(T_String<<4)+T_null] 		= (String2String<<12)+(T_null<<8)+(T_null<<4)+T_String ;
-
-//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
-//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
-//	table[(T_Object<<4)+T_long] 		= T_undefined ;
-//	table[(T_Object<<4)+T_short]		= T_undefined ;
-//	table[(T_Object<<4)+T_void] 		= T_undefined ;
-	table[(T_Object<<4)+T_String] 		= (T_Object<<16)+(T_Object<<12)+(String2String<<4)+T_String ;
-//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
-//	table[(T_Object<<4)+T_double] 		= T_undefined ;
-//	table[(T_Object<<4)+T_float] 		= T_undefined ;
-//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
-//	table[(T_Object<<4)+T_char] 		= T_undefined ;
-//	table[(T_Object<<4)+T_int] 			= T_undefined ;
-//	table[(T_Object<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
-	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_double ;
-	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_double ;
-	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_double ; ;
-//	table[(T_double<<4)+T_void] 		= T_undefined ;
-	table[(T_double<<4)+T_String] 		= (Double2Double<<12)+(String2String<<4)+T_String ;
-//	table[(T_double<<4)+T_Object] 		= T_undefined ;
-	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_double ; ;
-//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
-	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_double ; ;
-	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_double ; ;
-//	table[(T_double<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
-	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_float ;
-	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_float ;
-	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_float ;
-//	table[(T_float<<4)+T_void] 			= T_undefined ;
-	table[(T_float<<4)+T_String] 		= (Float2Float<<12)+(String2String<<4)+T_String ;
-//	table[(T_float<<4)+T_Object] 		= T_undefined ;
-	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_float ;
-//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
-	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_float ;
-	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_float ;
-//	table[(T_float<<4)+T_null] 			= T_undefined ;
-
-//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
-	table[(T_boolean<<4)+T_String] 			= (Boolean2Boolean<<12)+(String2String<<4)+T_String ;
-//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
-//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
-	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_void] 			= T_undefined ;
-	table[(T_char<<4)+T_String] 		= (Char2Char<<12)+(String2String<<4)+T_String ;
-//	table[(T_char<<4)+T_Object] 		= T_undefined ;
-	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_float ;
-//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
-	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ; ;
-	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_char<<4)+T_null] 			= T_undefined ;
-	
-//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
-	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
-	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long ;
-	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_void] 		= T_undefined ;
-	table[(T_int<<4)+T_String] 		= (Int2Int<<12)+(String2String<<4)+T_String ;
-//	table[(T_int<<4)+T_Object] 		= T_undefined ;
-	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_double ;
-	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_float ;
-//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
-	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
-	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
-//	table[(T_int<<4)+T_null] 		= T_undefined ;
-
-//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
-//	table[(T_null<<4)+T_byte] 			= T_undefined ;
-//	table[(T_null<<4)+T_long] 			= T_undefined ;
-//	table[(T_null<<4)+T_short] 			= T_undefined ;
-//	table[(T_null<<4)+T_void] 			= T_undefined ;
-	table[(T_null<<4)+T_String] 		= (T_null<<16)+(T_null<<12)+(String2String<<4)+T_String ;
-//	table[(T_null<<4)+T_Object] 		= T_undefined ;
-//	table[(T_null<<4)+T_double] 		= T_undefined ;
-//	table[(T_null<<4)+T_float] 			= T_undefined ;
-//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
-//	table[(T_null<<4)+T_char] 			= T_undefined ;
-//	table[(T_null<<4)+T_int] 			= T_undefined ;
-//	table[(T_null<<4)+T_null] 			= (Null2String<<12)+(Null2String<<4)+T_String ;;
-
-	//and now.....the return.........
-			
-	return table ;
-}
-public static final int[] get_REMAINDER(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_MINUS();
-			
-//	return table ;
-}
-public static final int[] get_RIGHT_SHIFT(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_LEFT_SHIFT();
-			
-//	return table ;
-}
-public static final int[] get_UNSIGNED_RIGHT_SHIFT(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-
-	return get_LEFT_SHIFT();
-			
-//	return table ;
-}
-public static final int[] get_XOR(){
-
-	//the code is an int
-	// (cast)  left   Op (cast)  rigth --> result
-	//  0000   0000       0000   0000      0000
-	//  <<16   <<12       <<8    <<4       
-	
-	
-//	int[] table  = new int[16*16] ;
-	
-	return get_AND() ;
-			
-//	return table ;
-}
-public String operatorToString() {
-	switch ((bits & OperatorMASK) >> OperatorSHIFT) {
-		case EQUAL_EQUAL :
-			return "=="/*nonNLS*/;
-		case LESS_EQUAL :
-			return "<="/*nonNLS*/;
-		case GREATER_EQUAL :
-			return ">="/*nonNLS*/;
-		case NOT_EQUAL :
-			return "!="/*nonNLS*/;
-		case LEFT_SHIFT :
-			return "<<"/*nonNLS*/;
-		case RIGHT_SHIFT :
-			return ">>"/*nonNLS*/;
-		case UNSIGNED_RIGHT_SHIFT :
-			return ">>>"/*nonNLS*/;
-		case OR_OR :
-			return "||"/*nonNLS*/;
-		case AND_AND :
-			return "&&"/*nonNLS*/;
-		case PLUS :
-			return "+"/*nonNLS*/;
-		case MINUS :
-			return "-"/*nonNLS*/;
-		case NOT :
-			return "!"/*nonNLS*/;
-		case REMAINDER :
-			return "%"/*nonNLS*/;
-		case XOR :
-			return "^"/*nonNLS*/;
-		case AND :
-			return "&"/*nonNLS*/;
-		case MULTIPLY :
-			return "*"/*nonNLS*/;
-		case OR :
-			return "|"/*nonNLS*/;
-		case TWIDDLE :
-			return "~"/*nonNLS*/;
-		case DIVIDE :
-			return "/"/*nonNLS*/;
-		case GREATER :
-			return ">"/*nonNLS*/;
-		case LESS :
-			return "<"/*nonNLS*/;
-		case QUESTIONCOLON :
-			return "?:"/*nonNLS*/;
-		case EQUAL :
-			return "="/*nonNLS*/;
-	};
-	return "unknown operator"/*nonNLS*/;
-}
-public String toStringExpression(){
-	/* slow code*/
-
-	//subclass redefine toStringExpressionNoParenthesis()
-	
-	return	"("/*nonNLS*/ + toStringExpressionNoParenthesis() + ")"/*nonNLS*/; 
-}
-
-public abstract String toStringExpressionNoParenthesis();
-
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public abstract class OperatorExpression extends Expression implements OperatorIds {
+	public static int[][] ResolveTypeTables = new int[NumberOfTables][];
+	static {classInitialize();}
+/**
+ * OperatorExpression constructor comment.
+ */
+public OperatorExpression() {
+	super();
+}
+public static final void classInitialize() {
+	ResolveTypeTables[AND] = get_AND();
+	ResolveTypeTables[AND_AND] = get_AND_AND();
+	ResolveTypeTables[DIVIDE] = get_DIVIDE();
+	ResolveTypeTables[EQUAL_EQUAL] = get_EQUAL_EQUAL();
+	ResolveTypeTables[GREATER] = get_GREATER();
+	ResolveTypeTables[GREATER_EQUAL] = get_GREATER_EQUAL();
+	ResolveTypeTables[LEFT_SHIFT] = get_LEFT_SHIFT();
+	ResolveTypeTables[LESS] = get_LESS();
+	ResolveTypeTables[LESS_EQUAL] = get_LESS_EQUAL();
+	ResolveTypeTables[MINUS] = get_MINUS();
+	ResolveTypeTables[MULTIPLY] = get_MULTIPLY();
+	ResolveTypeTables[OR] = get_OR();
+	ResolveTypeTables[OR_OR] = get_OR_OR();
+	ResolveTypeTables[PLUS] = get_PLUS();
+	ResolveTypeTables[REMAINDER] = get_REMAINDER();
+	ResolveTypeTables[RIGHT_SHIFT] = get_RIGHT_SHIFT();
+	ResolveTypeTables[UNSIGNED_RIGHT_SHIFT] = get_UNSIGNED_RIGHT_SHIFT();
+	ResolveTypeTables[XOR] = get_XOR();
+}
+public static final String generateTableTestCase(){
+	//return a String which is a java method allowing to test
+	//the non zero entries of all tables
+
+	/* slow code */
+
+	/*
+	org.eclipse.jdt.internal.compiler.ast.
+	OperatorExpression.generateTableTestCase();
+	*/
+
+	int[] operators = new int[]{AND,AND_AND,DIVIDE,GREATER,GREATER_EQUAL,
+			LEFT_SHIFT,LESS,LESS_EQUAL,MINUS,MULTIPLY,OR,OR_OR,PLUS,REMAINDER,
+			RIGHT_SHIFT,UNSIGNED_RIGHT_SHIFT,XOR};
+
+	class Decode {
+		public  final String constant(int code){
+			switch(code){ 
+				case T_boolean 	: return "true"/*nonNLS*/ ;
+				case T_byte		: return "((byte) 3)"/*nonNLS*/ ;
+				case T_char		: return "'A'"/*nonNLS*/ ;
+				case T_double	: return "300.0d"/*nonNLS*/ ;
+				case T_float	: return "100.0f"/*nonNLS*/ ;
+				case T_int		: return "1"/*nonNLS*/ ;
+				case T_long		: return "7L"/*nonNLS*/ ;
+				case T_String	: return "\"hello-world\""/*nonNLS*/ ;
+				case T_null		: return "null"/*nonNLS*/;
+				case T_short	: return "((short) 5)"/*nonNLS*/;
+				case T_Object	: return "null"/*nonNLS*/;}
+			return ""/*nonNLS*/;}
+
+		public  final String type(int code){
+			switch(code){ 
+				case T_boolean 	: return "z"/*nonNLS*/ ;
+				case T_byte		: return "b"/*nonNLS*/ ;
+				case T_char		: return "c"/*nonNLS*/ ;
+				case T_double	: return "d"/*nonNLS*/ ;
+				case T_float	: return "f"/*nonNLS*/ ;
+				case T_int		: return "i"/*nonNLS*/ ;
+				case T_long		: return "l"/*nonNLS*/ ;
+				case T_String	: return "str"/*nonNLS*/ ;
+				case T_null		: return "null"/*nonNLS*/;
+				case T_short	: return "s"/*nonNLS*/;
+				case T_Object	: return "obj"/*nonNLS*/;}
+			return "xxx"/*nonNLS*/;}
+		
+		public  final String operator(int operator){
+				switch (operator) {
+				case EQUAL_EQUAL :	return "=="/*nonNLS*/;
+				case LESS_EQUAL :	return "<="/*nonNLS*/;
+				case GREATER_EQUAL :return ">="/*nonNLS*/;
+				case LEFT_SHIFT :	return "<<"/*nonNLS*/;
+				case RIGHT_SHIFT :	return ">>"/*nonNLS*/;
+				case UNSIGNED_RIGHT_SHIFT :	return ">>>"/*nonNLS*/;
+				case OR_OR :return "||"/*nonNLS*/;
+				case AND_AND :		return "&&"/*nonNLS*/;
+				case PLUS :			return "+"/*nonNLS*/;
+				case MINUS :		return "-"/*nonNLS*/;
+				case NOT :			return "!"/*nonNLS*/;
+				case REMAINDER :	return "%"/*nonNLS*/;
+				case XOR :			return "^"/*nonNLS*/;
+				case AND :			return "&"/*nonNLS*/;
+				case MULTIPLY :		return "*"/*nonNLS*/;
+				case OR :			return "|"/*nonNLS*/;
+				case TWIDDLE :		return "~"/*nonNLS*/;
+				case DIVIDE :		return "/"/*nonNLS*/;
+				case GREATER :		return ">"/*nonNLS*/;
+				case LESS :			return "<"/*nonNLS*/;	};
+			return "????"/*nonNLS*/;}
+	}
+
+		
+	Decode decode = new Decode();
+	String s ;
+	s = "\tpublic static void binaryOperationTablesTestCase(){\n"/*nonNLS*/ +
+
+		"\t\t//TC test : all binary operation (described in tables)\n"/*nonNLS*/+
+		"\t\t//method automatically generated by\n"/*nonNLS*/+
+		"\t\t//org.eclipse.jdt.internal.compiler.ast.OperatorExpression.generateTableTestCase();\n"/*nonNLS*/+
+	
+		"\t\tString str0 ;\t String str\t= "/*nonNLS*/+decode.constant(T_String)+";\n"/*nonNLS*/+
+		"\t\tint i0 ;\t int i\t= "/*nonNLS*/+decode.constant(T_int)+" ;\n"/*nonNLS*/+
+		"\t\tboolean z0;\t boolean z\t= "/*nonNLS*/+decode.constant(T_boolean)+";\n"/*nonNLS*/+
+		"\t\tchar c0; \t char  c\t= "/*nonNLS*/+decode.constant(T_char)+" ;\n"/*nonNLS*/+
+		"\t\tfloat f0; \t float f\t= "/*nonNLS*/+decode.constant(T_float)+" ;\n"/*nonNLS*/+
+		"\t\tdouble d0;\t double d\t= "/*nonNLS*/+decode.constant(T_double)+" ;\n"/*nonNLS*/+
+		"\t\tbyte b0; \t byte b\t= "/*nonNLS*/+decode.constant(T_byte)+";\n"/*nonNLS*/+
+		"\t\tshort s0; \t short s\t= "/*nonNLS*/+decode.constant(T_short)+";\n"/*nonNLS*/+
+		"\t\tlong l0; \t long l\t= "/*nonNLS*/+decode.constant(T_long)+" ;\n"/*nonNLS*/+
+		"\t\tObject obj0; \t Object obj\t= "/*nonNLS*/+decode.constant(T_Object)+" ;\n"/*nonNLS*/+
+
+		"\n"/*nonNLS*/;
+
+	int error = 0;		
+	for (int i=0; i < operators.length ; i++)
+	{	int operator = operators[i];
+		for (int left=0; left<16;left++)
+		for (int right=0; right<16;right++)
+		{	int result = (ResolveTypeTables[operator][(left<<4)+right]) & 0x0000F;
+			if (result != T_undefined)
+
+				//1/ First regular computation then 2/ comparaison
+				//with a compile time constant (generated by the compiler)
+				//	z0 = s >= s;
+				//	if ( z0 != (((short) 5) >= ((short) 5)))
+				//		System.out.println(155);
+
+			{	s += "\t\t"/*nonNLS*/+decode.type(result)+"0"/*nonNLS*/+" = "/*nonNLS*/+decode.type(left);
+				s += " "/*nonNLS*/+decode.operator(operator)+" "/*nonNLS*/+decode.type(right)+";\n"/*nonNLS*/;
+				String begin = result == T_String ? "\t\tif (! "/*nonNLS*/ : "\t\tif ( "/*nonNLS*/;
+				String test = result == T_String ? ".equals("/*nonNLS*/ : " != ("/*nonNLS*/ ;
+				s += begin	+decode.type(result)+"0"/*nonNLS*/+test
+							+decode.constant(left)+" "/*nonNLS*/
+							+decode.operator(operator)+" "/*nonNLS*/
+							+decode.constant(right)+"))\n"/*nonNLS*/;
+				s += "\t\t\tSystem.out.println("/*nonNLS*/+ (++error) +");\n"/*nonNLS*/;
+								
+				}}}
+		
+	return s += "\n\t\tSystem.out.println(\"binary tables test : done\");}"/*nonNLS*/ ;
+		}
+public static final int[] get_AND(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+	
+//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12) +(Byte2Int<<4) +T_int ;
+	table[(T_byte<<4)+T_long]		= (Byte2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12) +(Short2Int<<4)+T_int;
+//	table[(T_byte<<4)+T_void] 		= T_undefined ;
+//	table[(T_byte<<4)+T_String] 	= T_undefined ;
+//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
+//	table[(T_byte<<4)+T_double] 	= T_undefined ;
+//	table[(T_byte<<4)+T_float] 		= T_undefined ;
+//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12) +(Char2Int<<4) +T_int ;
+	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12) +(Int2Int<<4)  +T_int ;
+//	table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
+	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
+	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long; ;
+//	table[(T_long<<4)+T_void] 		= T_undefined ;
+//	table[(T_long<<4)+T_String] 	= T_undefined ;
+//	table[(T_long<<4)+T_Object] 	= T_undefined ;
+//	table[(T_long<<4)+T_double] 	= T_undefined ;
+//	table[(T_long<<4)+T_float] 		= T_undefined ;
+//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
+	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long ;
+	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long ;
+//	table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
+	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_void] 			= T_undefined ;
+//	table[(T_short<<4)+T_String] 		= T_undefined ;
+//	table[(T_short<<4)+T_Object] 		= T_undefined ;
+//	table[(T_short<<4)+T_double] 		= T_undefined ;
+//	table[(T_short<<4)+T_float] 		= T_undefined ;
+//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
+	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_void<<4)+T_byte] 		= T_undefined ;
+//	table[(T_void<<4)+T_long] 		= T_undefined ;
+//	table[(T_void<<4)+T_short] 		= T_undefined ;
+//	table[(T_void<<4)+T_void] 		= T_undefined ;
+//	table[(T_void<<4)+T_String] 	= T_undefined ;
+//	table[(T_void<<4)+T_Object] 	= T_undefined ;
+//	table[(T_void<<4)+T_double] 	= T_undefined ;
+//	table[(T_void<<4)+T_float] 		= T_undefined ;
+//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//	table[(T_void<<4)+T_char] 		= T_undefined ;
+//	table[(T_void<<4)+T_int] 		= T_undefined ;
+//	table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_String<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_String<<4)+T_byte] 		= T_undefined ;
+//	table[(T_String<<4)+T_long] 		= T_undefined ;
+//	table[(T_String<<4)+T_short] 		= T_undefined ;
+//	table[(T_String<<4)+T_void] 		= T_undefined ;
+//	table[(T_String<<4)+T_String] 		= T_undefined ;
+//	table[(T_String<<4)+T_Object] 		= T_undefined ;
+//	table[(T_String<<4)+T_double] 		= T_undefined ;
+//	table[(T_String<<4)+T_float] 		= T_undefined ;
+//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_String<<4)+T_char] 		= T_undefined ;
+//	table[(T_String<<4)+T_int] 			= T_undefined ;
+//	table[(T_String<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//	table[(T_Object<<4)+T_long] 		= T_undefined ;
+//	table[(T_Object<<4)+T_short]		= T_undefined ;
+//	table[(T_Object<<4)+T_void] 		= T_undefined ;
+//	table[(T_Object<<4)+T_String] 		= T_undefined ;
+//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
+//	table[(T_Object<<4)+T_double] 		= T_undefined ;
+//	table[(T_Object<<4)+T_float] 		= T_undefined ;
+//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//	table[(T_Object<<4)+T_char] 		= T_undefined ;
+//	table[(T_Object<<4)+T_int] 			= T_undefined ;
+//	table[(T_Object<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_double<<4)+T_byte] 		= T_undefined ;
+//	table[(T_double<<4)+T_long] 		= T_undefined ;
+//	table[(T_double<<4)+T_short] 		= T_undefined ;
+//	table[(T_double<<4)+T_void] 		= T_undefined ;
+//	table[(T_double<<4)+T_String] 		= T_undefined ;
+//	table[(T_double<<4)+T_Object] 		= T_undefined ;
+//	table[(T_double<<4)+T_double] 		= T_undefined ;
+//	table[(T_double<<4)+T_float] 		= T_undefined ;
+//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_double<<4)+T_char] 		= T_undefined ;
+//	table[(T_double<<4)+T_int] 			= T_undefined;
+//	table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_float<<4)+T_byte] 			= T_undefined ;
+//	table[(T_float<<4)+T_long] 			= T_undefined ;
+//	table[(T_float<<4)+T_short] 		= T_undefined ;
+//	table[(T_float<<4)+T_void] 			= T_undefined ;
+//	table[(T_float<<4)+T_String] 		= T_undefined ;
+//	table[(T_float<<4)+T_Object] 		= T_undefined ;
+//	table[(T_float<<4)+T_double] 		= T_undefined ;
+//	table[(T_float<<4)+T_float] 		= T_undefined ;
+//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_float<<4)+T_char] 			= T_undefined ;
+//	table[(T_float<<4)+T_int] 			= T_undefined ;
+//	table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
+	table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean << 12)+(Boolean2Boolean << 4)+T_boolean ;
+//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
+	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long;
+	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_void] 			= T_undefined ;
+//	table[(T_char<<4)+T_String] 		= T_undefined ;
+//	table[(T_char<<4)+T_Object] 		= T_undefined ;
+//	table[(T_char<<4)+T_double] 		= T_undefined ;
+//	table[(T_char<<4)+T_float] 			= T_undefined ;
+//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
+	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
+	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_void] 		= T_undefined ;
+//	table[(T_int<<4)+T_String] 		= T_undefined ;
+//	table[(T_int<<4)+T_Object] 		= T_undefined ;
+//	table[(T_int<<4)+T_double] 		= T_undefined ;
+//	table[(T_int<<4)+T_float] 		= T_undefined ;
+//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
+	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_null<<4)+T_byte] 			= T_undefined ;
+//	table[(T_null<<4)+T_long] 			= T_undefined ;
+//	table[(T_null<<4)+T_short] 			= T_undefined ;
+//	table[(T_null<<4)+T_void] 			= T_undefined ;
+//	table[(T_null<<4)+T_String] 		= T_undefined ;
+//	table[(T_null<<4)+T_Object] 		= T_undefined ;
+//	table[(T_null<<4)+T_double] 		= T_undefined ;
+//	table[(T_null<<4)+T_float] 			= T_undefined ;
+//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_null<<4)+T_char] 			= T_undefined ;
+//	table[(T_null<<4)+T_int] 			= T_undefined ;
+//	table[(T_null<<4)+T_null] 			= T_undefined ;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_AND_AND(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+	
+//     table[(T_undefined<<4)+T_undefined] 		= T_undefined ;
+//     table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_short] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//     table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//     table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//     table[(T_undefined<<4)+T_float] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//     table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//     table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_byte<<4)+T_byte] 		= T_undefined ;
+//     table[(T_byte<<4)+T_long] 		= T_undefined ;
+//     table[(T_byte<<4)+T_short] 		= T_undefined ;
+//     table[(T_byte<<4)+T_void] 		= T_undefined ;
+//     table[(T_byte<<4)+T_String] 		= T_undefined ;
+//     table[(T_byte<<4)+T_Object] 		= T_undefined ;
+//     table[(T_byte<<4)+T_double] 		= T_undefined ;
+//     table[(T_byte<<4)+T_float] 		= T_undefined ;
+//     table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+//     table[(T_byte<<4)+T_char] 		= T_undefined ;
+//     table[(T_byte<<4)+T_int] 		= T_undefined ;
+//     table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_long<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_long<<4)+T_byte] 		= T_undefined;
+//     table[(T_long<<4)+T_long] 		= T_undefined ;
+//     table[(T_long<<4)+T_short] 		= T_undefined ;
+//     table[(T_long<<4)+T_void] 		= T_undefined ;
+//     table[(T_long<<4)+T_String] 		= T_undefined ;
+//     table[(T_long<<4)+T_Object] 		= T_undefined ;
+//     table[(T_long<<4)+T_double] 		= T_undefined ;
+//     table[(T_long<<4)+T_float] 		= T_undefined ;
+//     table[(T_long<<4)+T_boolean] 	= T_undefined ;
+//     table[(T_long<<4)+T_char] 		= T_undefined ;
+//     table[(T_long<<4)+T_int] 		= T_undefined ;
+//     table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_short<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_short<<4)+T_byte] 		= T_undefined ;
+//     table[(T_short<<4)+T_long] 		= T_undefined ;
+//     table[(T_short<<4)+T_short] 		= T_undefined ;
+//     table[(T_short<<4)+T_void] 		= T_undefined ;
+//     table[(T_short<<4)+T_String] 	= T_undefined ;
+//     table[(T_short<<4)+T_Object] 	= T_undefined ;
+//     table[(T_short<<4)+T_double] 	= T_undefined ;
+//     table[(T_short<<4)+T_float] 		= T_undefined ;
+//     table[(T_short<<4)+T_boolean]	= T_undefined ;
+//     table[(T_short<<4)+T_char] 		= T_undefined ;
+//     table[(T_short<<4)+T_int] 		= T_undefined ;
+//     table[(T_short<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_void<<4)+T_byte] 		= T_undefined ;
+//     table[(T_void<<4)+T_long] 		= T_undefined ;
+//     table[(T_void<<4)+T_short] 		= T_undefined ;
+//     table[(T_void<<4)+T_void] 		= T_undefined ;
+//     table[(T_void<<4)+T_String] 	= T_undefined ;
+//     table[(T_void<<4)+T_Object] 	= T_undefined ;
+//     table[(T_void<<4)+T_double] 	= T_undefined ;
+//     table[(T_void<<4)+T_float] 		= T_undefined ;
+//     table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//     table[(T_void<<4)+T_char] 		= T_undefined ;
+//     table[(T_void<<4)+T_int] 		= T_undefined ;
+//     table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_String<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_String<<4)+T_byte] 		= T_undefined ;
+//     table[(T_String<<4)+T_long] 		= T_undefined ;
+//     table[(T_String<<4)+T_short] 		= T_undefined ;
+//     table[(T_String<<4)+T_void] 		= T_undefined ;
+//     table[(T_String<<4)+T_String] 		= T_undefined ;
+//     table[(T_String<<4)+T_Object] 		= T_undefined ;
+//     table[(T_String<<4)+T_double] 		= T_undefined ;
+//     table[(T_String<<4)+T_float] 		= T_undefined ;
+//     table[(T_String<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_String<<4)+T_char] 		= T_undefined ;
+//     table[(T_String<<4)+T_int] 			= T_undefined ;
+//     table[(T_String<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//     table[(T_Object<<4)+T_long] 		= T_undefined ;
+//     table[(T_Object<<4)+T_short]		= T_undefined ;
+//     table[(T_Object<<4)+T_void] 		= T_undefined ;
+//     table[(T_Object<<4)+T_String] 		= T_undefined ;
+//     table[(T_Object<<4)+T_Object] 		= T_undefined ;
+//     table[(T_Object<<4)+T_double] 		= T_undefined ;
+//     table[(T_Object<<4)+T_float] 		= T_undefined ;
+//     table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//     table[(T_Object<<4)+T_char] 		= T_undefined ;
+//     table[(T_Object<<4)+T_int] 			= T_undefined ;
+//     table[(T_Object<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_double<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_double<<4)+T_byte] 		= T_undefined ;
+//     table[(T_double<<4)+T_long] 		= T_undefined ;
+//     table[(T_double<<4)+T_short] 		= T_undefined ;
+//     table[(T_double<<4)+T_void] 		= T_undefined ;
+//     table[(T_double<<4)+T_String] 		= T_undefined ;
+//     table[(T_double<<4)+T_Object] 		= T_undefined ;
+//     table[(T_double<<4)+T_double] 		= T_undefined ;
+//     table[(T_double<<4)+T_float] 		= T_undefined ;
+//     table[(T_double<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_double<<4)+T_char] 		= T_undefined ;
+//     table[(T_double<<4)+T_int] 			= T_undefined;
+//     table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_float<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_float<<4)+T_byte] 			= T_undefined ;
+//     table[(T_float<<4)+T_long] 			= T_undefined ;
+//     table[(T_float<<4)+T_short] 		= T_undefined ;
+//     table[(T_float<<4)+T_void] 			= T_undefined ;
+//     table[(T_float<<4)+T_String] 		= T_undefined ;
+//     table[(T_float<<4)+T_Object] 		= T_undefined ;
+//     table[(T_float<<4)+T_double] 		= T_undefined ;
+//     table[(T_float<<4)+T_float] 		= T_undefined ;
+//     table[(T_float<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_float<<4)+T_char] 			= T_undefined ;
+//     table[(T_float<<4)+T_int] 			= T_undefined ;
+//     table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//     table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//     table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_void] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_String] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_float] 			= T_undefined ;
+	   table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ;
+//     table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//     table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//     table[(T_char<<4)+T_undefined] 		= T_undefined ;
+//     table[(T_char<<4)+T_byte] 			= T_undefined ;
+//     table[(T_char<<4)+T_long] 			= T_undefined;
+//     table[(T_char<<4)+T_short] 			= T_undefined ;
+//     table[(T_char<<4)+T_void] 			= T_undefined ;
+//     table[(T_char<<4)+T_String] 		= T_undefined ;
+//     table[(T_char<<4)+T_Object] 		= T_undefined ;
+//     table[(T_char<<4)+T_double] 		= T_undefined ;
+//     table[(T_char<<4)+T_float] 			= T_undefined ;
+//     table[(T_char<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_char<<4)+T_char] 			= T_undefined ;
+//     table[(T_char<<4)+T_int] 			= T_undefined ;
+//     table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//     table[(T_int<<4)+T_undefined] 	= T_undefined ;
+//     table[(T_int<<4)+T_byte] 		= T_undefined ;
+//     table[(T_int<<4)+T_long] 		= T_undefined ;
+//     table[(T_int<<4)+T_short] 		= T_undefined ;
+//     table[(T_int<<4)+T_void] 		= T_undefined ;
+//     table[(T_int<<4)+T_String] 		= T_undefined ;
+//     table[(T_int<<4)+T_Object] 		= T_undefined ;
+//     table[(T_int<<4)+T_double] 		= T_undefined ;
+//     table[(T_int<<4)+T_float] 		= T_undefined ;
+//     table[(T_int<<4)+T_boolean] 	= T_undefined ;
+//     table[(T_int<<4)+T_char] 		= T_undefined ;
+//     table[(T_int<<4)+T_int] 		= T_undefined ;
+//     table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//     table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//     table[(T_null<<4)+T_byte] 			= T_undefined ;
+//     table[(T_null<<4)+T_long] 			= T_undefined ;
+//     table[(T_null<<4)+T_short] 			= T_undefined ;
+//     table[(T_null<<4)+T_void] 			= T_undefined ;
+//     table[(T_null<<4)+T_String] 		= T_undefined ;
+//     table[(T_null<<4)+T_Object] 		= T_undefined ;
+//     table[(T_null<<4)+T_double] 		= T_undefined ;
+//     table[(T_null<<4)+T_float] 			= T_undefined ;
+//     table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//     table[(T_null<<4)+T_char] 			= T_undefined ;
+//     table[(T_null<<4)+T_int] 			= T_undefined ;
+//     table[(T_null<<4)+T_null] 			= T_undefined ;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_DIVIDE(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+	
+	return get_MINUS();
+			
+//	return table ;
+}
+public static final int[] get_EQUAL_EQUAL(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	int[] table  = new int[16*16] ;
+	
+//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_byte<<4)+T_void] 		= T_undefined ;
+//	table[(T_byte<<4)+T_String] 	= T_undefined ;
+//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
+	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
+//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean;
+//	table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
+	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
+	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean ;
+//	table[(T_long<<4)+T_void] 		= T_undefined ;
+//	table[(T_long<<4)+T_String] 	= T_undefined ;
+//	table[(T_long<<4)+T_Object] 	= T_undefined ;
+	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
+	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean ;
+	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean ;
+//	table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
+	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_short<<4)+T_void] 			= T_undefined ;
+//	table[(T_short<<4)+T_String] 		= T_undefined ;
+//	table[(T_short<<4)+T_Object] 		= T_undefined ;
+	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
+	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_short<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_void<<4)+T_byte] 		= T_undefined ;
+//	table[(T_void<<4)+T_long] 		= T_undefined ;
+//	table[(T_void<<4)+T_short] 		= T_undefined ;
+//	table[(T_void<<4)+T_void] 		= T_undefined ;
+//	table[(T_void<<4)+T_String] 	= T_undefined ;
+//	table[(T_void<<4)+T_Object] 	= T_undefined ;
+//	table[(T_void<<4)+T_double] 	= T_undefined ;
+//	table[(T_void<<4)+T_float] 		= T_undefined ;
+//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//	table[(T_void<<4)+T_char] 		= T_undefined ;
+//	table[(T_void<<4)+T_int] 		= T_undefined ;
+//	table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
+//	table[(T_String<<4)+T_byte] 		= T_undefined ;
+//	table[(T_String<<4)+T_long] 		= T_undefined ; 
+//	table[(T_String<<4)+T_short] 		= T_undefined ;
+//	table[(T_String<<4)+T_void] 		= T_undefined ;
+	table[(T_String<<4)+T_String] 		= /*String2Object                 String2Object*/
+										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
+	table[(T_String<<4)+T_Object] 		= /*String2Object                 Object2Object*/
+										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ;
+//	table[(T_String<<4)+T_double] 		= T_undefined ;
+//	table[(T_String<<4)+T_float] 		= T_undefined ; 
+//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_String<<4)+T_char] 		= T_undefined ;
+//	table[(T_String<<4)+T_int] 			= T_undefined ;
+	table[(T_String<<4)+T_null] 		= /*Object2String                null2Object */
+										  (T_Object<<16)+(T_String<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
+
+//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//	table[(T_Object<<4)+T_long] 		= T_undefined ;
+//	table[(T_Object<<4)+T_short]		= T_undefined ;
+//	table[(T_Object<<4)+T_void] 		= T_undefined ;
+	table[(T_Object<<4)+T_String] 		= /*Object2Object                 String2Object*/
+										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
+	table[(T_Object<<4)+T_Object] 		= /*Object2Object                 Object2Object*/
+										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ;
+//	table[(T_Object<<4)+T_double] 		= T_undefined ;
+//	table[(T_Object<<4)+T_float] 		= T_undefined ;
+//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//	table[(T_Object<<4)+T_char] 		= T_undefined ;
+//	table[(T_Object<<4)+T_int] 			= T_undefined ;
+	table[(T_Object<<4)+T_null] 		= /*Object2Object                 null2Object*/
+										  (T_Object<<16)+(T_Object<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
+
+//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
+	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean ;
+//	table[(T_double<<4)+T_void] 		= T_undefined ;
+//	table[(T_double<<4)+T_String] 		= T_undefined ;
+//	table[(T_double<<4)+T_Object] 		= T_undefined ;
+	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean;
+//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
+	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean ;
+//	table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
+	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_void] 			= T_undefined ;
+//	table[(T_float<<4)+T_String] 		= T_undefined ;
+//	table[(T_float<<4)+T_Object] 		= T_undefined ;
+	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
+	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
+	table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean ;
+//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
+	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_char<<4)+T_void] 			= T_undefined ;
+//	table[(T_char<<4)+T_String] 		= T_undefined ;
+//	table[(T_char<<4)+T_Object] 		= T_undefined ;
+	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
+	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
+	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_int<<4)+T_void] 		= T_undefined ;
+//	table[(T_int<<4)+T_String] 		= T_undefined ;
+//	table[(T_int<<4)+T_Object] 		= T_undefined ;
+	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean;
+//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
+	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_null<<4)+T_byte] 			= T_undefined ;
+//	table[(T_null<<4)+T_long] 			= T_undefined ;
+//	table[(T_null<<4)+T_short] 			= T_undefined ;
+//	table[(T_null<<4)+T_void] 			= T_undefined ;
+	table[(T_null<<4)+T_String] 		= /*null2Object                 String2Object*/
+										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_String<<4)+T_boolean ;
+	table[(T_null<<4)+T_Object] 		= /*null2Object                 Object2Object*/
+										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_Object<<4)+T_boolean ; ;
+//	table[(T_null<<4)+T_double] 		= T_undefined ;
+//	table[(T_null<<4)+T_float] 			= T_undefined ;
+//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_null<<4)+T_char] 			= T_undefined ;
+//	table[(T_null<<4)+T_int] 			= T_undefined ;
+	table[(T_null<<4)+T_null] 			= /*null2Object                 null2Object*/
+										  (T_Object<<16)+(T_null<<12)+(T_Object<<8)+(T_null<<4)+T_boolean ;
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_GREATER(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_LESS();
+			
+//	return table ;
+}
+public static final int[] get_GREATER_EQUAL(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_LESS();
+			
+//	return table ;
+}
+public static final int[] get_LEFT_SHIFT(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+	
+//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_byte<<4)+T_long] 		= (Byte2Int<<12)+(Long2Int<<4)+T_int ;
+	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_byte<<4)+T_void] 		= T_undefined ;
+//	table[(T_byte<<4)+T_String] 	= T_undefined ;
+//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
+//	table[(T_byte<<4)+T_double] 	= T_undefined ;
+//	table[(T_byte<<4)+T_float] 		= T_undefined ;
+//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
+	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Int<<4)+T_long;
+	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Int<<4)+T_long ;
+	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Int<<4)+T_long ;
+//	table[(T_long<<4)+T_void] 		= T_undefined ;
+//	table[(T_long<<4)+T_String] 	= T_undefined ;
+//	table[(T_long<<4)+T_Object] 	= T_undefined ;
+//	table[(T_long<<4)+T_double] 	= T_undefined ;
+//	table[(T_long<<4)+T_float] 		= T_undefined ;
+//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
+	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Int<<4)+T_long ;
+	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Int<<4)+T_long ;
+//	table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
+	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_short<<4)+T_long] 			= (Short2Int<<12)+(Long2Int<<4)+T_int ;
+	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_void] 			= T_undefined ;
+//	table[(T_short<<4)+T_String] 		= T_undefined ;
+//	table[(T_short<<4)+T_Object] 		= T_undefined ;
+//	table[(T_short<<4)+T_double] 		= T_undefined ;
+//	table[(T_short<<4)+T_float] 		= T_undefined ;
+//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
+	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_void<<4)+T_byte] 		= T_undefined ;
+//	table[(T_void<<4)+T_long] 		= T_undefined ;
+//	table[(T_void<<4)+T_short] 		= T_undefined ;
+//	table[(T_void<<4)+T_void] 		= T_undefined ;
+//	table[(T_void<<4)+T_String] 	= T_undefined ;
+//	table[(T_void<<4)+T_Object] 	= T_undefined ;
+//	table[(T_void<<4)+T_double] 	= T_undefined ;
+//	table[(T_void<<4)+T_float] 		= T_undefined ;
+//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//	table[(T_void<<4)+T_char] 		= T_undefined ;
+//	table[(T_void<<4)+T_int] 		= T_undefined ;
+//	table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_String<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_String<<4)+T_byte] 		= T_undefined ;
+//	table[(T_String<<4)+T_long] 		= T_undefined ;
+//	table[(T_String<<4)+T_short] 		= T_undefined ;
+//	table[(T_String<<4)+T_void] 		= T_undefined ;
+//	table[(T_String<<4)+T_String] 		= T_undefined ;
+//	table[(T_String<<4)+T_Object] 		= T_undefined ;
+//	table[(T_String<<4)+T_double] 		= T_undefined ;
+//	table[(T_String<<4)+T_float] 		= T_undefined ;
+//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_String<<4)+T_char] 		= T_undefined ;
+//	table[(T_String<<4)+T_int] 			= T_undefined ;
+//	table[(T_String<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//	table[(T_Object<<4)+T_long] 		= T_undefined ;
+//	table[(T_Object<<4)+T_short]		= T_undefined ;
+//	table[(T_Object<<4)+T_void] 		= T_undefined ;
+//	table[(T_Object<<4)+T_String] 		= T_undefined ;
+//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
+//	table[(T_Object<<4)+T_double] 		= T_undefined ;
+//	table[(T_Object<<4)+T_float] 		= T_undefined ;
+//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//	table[(T_Object<<4)+T_char] 		= T_undefined ;
+//	table[(T_Object<<4)+T_int] 			= T_undefined ;
+//	table[(T_Object<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_double<<4)+T_byte] 		= T_undefined ;
+//	table[(T_double<<4)+T_long] 		= T_undefined ;
+//	table[(T_double<<4)+T_short] 		= T_undefined ;
+//	table[(T_double<<4)+T_void] 		= T_undefined ;
+//	table[(T_double<<4)+T_String] 		= T_undefined ;
+//	table[(T_double<<4)+T_Object] 		= T_undefined ;
+//	table[(T_double<<4)+T_double] 		= T_undefined ;
+//	table[(T_double<<4)+T_float] 		= T_undefined ;
+//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_double<<4)+T_char] 		= T_undefined ;
+//	table[(T_double<<4)+T_int] 			= T_undefined;
+//	table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_float<<4)+T_byte] 			= T_undefined ;
+//	table[(T_float<<4)+T_long] 			= T_undefined ;
+//	table[(T_float<<4)+T_short] 		= T_undefined ;
+//	table[(T_float<<4)+T_void] 			= T_undefined ;
+//	table[(T_float<<4)+T_String] 		= T_undefined ;
+//	table[(T_float<<4)+T_Object] 		= T_undefined ;
+//	table[(T_float<<4)+T_double] 		= T_undefined ;
+//	table[(T_float<<4)+T_float] 		= T_undefined ;
+//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_float<<4)+T_char] 			= T_undefined ;
+//	table[(T_float<<4)+T_int] 			= T_undefined ;
+//	table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
+	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_char<<4)+T_long] 			= (Char2Int<<12)+(Long2Int<<4)+T_int ;
+	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_void] 			= T_undefined ;
+//	table[(T_char<<4)+T_String] 		= T_undefined ;
+//	table[(T_char<<4)+T_Object] 		= T_undefined ;
+//	table[(T_char<<4)+T_double] 		= T_undefined ;
+//	table[(T_char<<4)+T_float] 			= T_undefined ;
+//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
+	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
+	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_int<<4)+T_long] 		= (Int2Int<<12)+(Long2Int<<4)+T_int ;
+	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_void] 		= T_undefined ;
+//	table[(T_int<<4)+T_String] 		= T_undefined ;
+//	table[(T_int<<4)+T_Object] 		= T_undefined ;
+//	table[(T_int<<4)+T_double] 		= T_undefined ;
+//	table[(T_int<<4)+T_float] 		= T_undefined ;
+//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
+	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_null<<4)+T_byte] 			= T_undefined ;
+//	table[(T_null<<4)+T_long] 			= T_undefined ;
+//	table[(T_null<<4)+T_short] 			= T_undefined ;
+//	table[(T_null<<4)+T_void] 			= T_undefined ;
+//	table[(T_null<<4)+T_String] 		= T_undefined ;
+//	table[(T_null<<4)+T_Object] 		= T_undefined ;
+//	table[(T_null<<4)+T_double] 		= T_undefined ;
+//	table[(T_null<<4)+T_float] 			= T_undefined ;
+//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_null<<4)+T_char] 			= T_undefined ;
+//	table[(T_null<<4)+T_int] 			= T_undefined ;
+//	table[(T_null<<4)+T_null] 			= T_undefined ;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_LESS(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+	
+//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_byte<<4)+T_void] 		= T_undefined ;
+//	table[(T_byte<<4)+T_String] 	= T_undefined ;
+//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
+	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
+//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
+	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
+	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean ;
+//	table[(T_long<<4)+T_void] 		= T_undefined ;
+//	table[(T_long<<4)+T_String] 	= T_undefined ;
+//	table[(T_long<<4)+T_Object] 	= T_undefined ;
+	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
+	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean ;
+	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean ;
+//	table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
+	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_short<<4)+T_void] 			= T_undefined ;
+//	table[(T_short<<4)+T_String] 		= T_undefined ;
+//	table[(T_short<<4)+T_Object] 		= T_undefined ;
+	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
+	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_short<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_void<<4)+T_byte] 		= T_undefined ;
+//	table[(T_void<<4)+T_long] 		= T_undefined ;
+//	table[(T_void<<4)+T_short] 		= T_undefined ;
+//	table[(T_void<<4)+T_void] 		= T_undefined ;
+//	table[(T_void<<4)+T_String] 	= T_undefined ;
+//	table[(T_void<<4)+T_Object] 	= T_undefined ;
+//	table[(T_void<<4)+T_double] 	= T_undefined ;
+//	table[(T_void<<4)+T_float] 		= T_undefined ;
+//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//	table[(T_void<<4)+T_char] 		= T_undefined ;
+//	table[(T_void<<4)+T_int] 		= T_undefined ;
+//	table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
+//	table[(T_String<<4)+T_byte] 		= T_undefined ;
+//	table[(T_String<<4)+T_long] 		= T_undefined ; 
+//	table[(T_String<<4)+T_short] 		= T_undefined ;
+//	table[(T_String<<4)+T_void] 		= T_undefined ;
+//	table[(T_String<<4)+T_String] 		= T_undefined ;
+//	table[(T_String<<4)+T_Object] 		= T_undefined ;
+//	table[(T_String<<4)+T_double] 		= T_undefined ;
+//	table[(T_String<<4)+T_float] 		= T_undefined ; 
+//	table[(T_String<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_String<<4)+T_char] 		= T_undefined ;
+//	table[(T_String<<4)+T_int] 			= T_undefined ;
+//	table[(T_String<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//	table[(T_Object<<4)+T_long] 		= T_undefined ;
+//	table[(T_Object<<4)+T_short]		= T_undefined ;
+//	table[(T_Object<<4)+T_void] 		= T_undefined ;
+//	table[(T_Object<<4)+T_String] 		= T_undefined ;
+//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
+//	table[(T_Object<<4)+T_double] 		= T_undefined ;
+//	table[(T_Object<<4)+T_float] 		= T_undefined ;
+//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//	table[(T_Object<<4)+T_char] 		= T_undefined ;
+//	table[(T_Object<<4)+T_int] 			= T_undefined ;
+//	table[(T_Object<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
+	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean;
+	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean ;
+//	table[(T_double<<4)+T_void] 		= T_undefined ;
+//	table[(T_double<<4)+T_String] 		= T_undefined ;
+//	table[(T_double<<4)+T_Object] 		= T_undefined ;
+	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean ;
+//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
+	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean ;
+	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean;
+//	table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
+	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_void] 			= T_undefined ;
+//	table[(T_float<<4)+T_String] 		= T_undefined ;
+//	table[(T_float<<4)+T_Object] 		= T_undefined ;
+	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
+	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean ;
+	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean ;
+//	table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_String] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
+	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean ;
+	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_char<<4)+T_void] 			= T_undefined ;
+//	table[(T_char<<4)+T_String] 		= T_undefined ;
+//	table[(T_char<<4)+T_Object] 		= T_undefined ;
+	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
+	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean ;
+//	table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
+	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean ;
+	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean;
+	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean ;
+//	table[(T_int<<4)+T_void] 		= T_undefined ;
+//	table[(T_int<<4)+T_String] 		= T_undefined ;
+//	table[(T_int<<4)+T_Object] 		= T_undefined ;
+	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean ;
+	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean ;
+//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
+	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean ;
+	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean;
+//	table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_null<<4)+T_byte] 			= T_undefined ;
+//	table[(T_null<<4)+T_long] 			= T_undefined ;
+//	table[(T_null<<4)+T_short] 			= T_undefined ;
+//	table[(T_null<<4)+T_void] 			= T_undefined ;
+//	table[(T_null<<4)+T_String] 		= T_undefined ;
+//	table[(T_null<<4)+T_Object] 		= T_undefined ;
+//	table[(T_null<<4)+T_double] 		= T_undefined ;
+//	table[(T_null<<4)+T_float] 			= T_undefined ;
+//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_null<<4)+T_char] 			= T_undefined ;
+//	table[(T_null<<4)+T_int] 			= T_undefined ;
+//	table[(T_null<<4)+T_null] 			= T_undefined ;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_LESS_EQUAL(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_LESS();
+			
+//	return table ;
+}
+public static final int[] get_MINUS(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+
+	table = (int[]) get_PLUS().clone();
+
+	table[(T_String<<4)+T_byte] 		= T_undefined ;
+	table[(T_String<<4)+T_long] 		= T_undefined ;
+	table[(T_String<<4)+T_short] 		= T_undefined ;
+	table[(T_String<<4)+T_void] 		= T_undefined ;
+	table[(T_String<<4)+T_String] 		= T_undefined ;
+	table[(T_String<<4)+T_Object] 		= T_undefined ;
+	table[(T_String<<4)+T_double] 		= T_undefined ;
+	table[(T_String<<4)+T_float] 		= T_undefined ;
+	table[(T_String<<4)+T_boolean] 		= T_undefined ;
+	table[(T_String<<4)+T_char] 		= T_undefined ;
+	table[(T_String<<4)+T_int] 			= T_undefined ;
+	table[(T_String<<4)+T_null] 		= T_undefined ;
+	
+	table[(T_byte<<4)	+T_String] 		= T_undefined ;
+	table[(T_long<<4)	+T_String] 		= T_undefined ;
+	table[(T_short<<4)	+T_String] 		= T_undefined ;
+	table[(T_void<<4)	+T_String] 		= T_undefined ;
+	table[(T_Object<<4)	+T_String] 		= T_undefined ;
+	table[(T_double<<4)	+T_String] 		= T_undefined ;
+	table[(T_float<<4)	+T_String] 		= T_undefined ;
+	table[(T_boolean<<4)+T_String] 		= T_undefined ;
+	table[(T_char<<4)	+T_String] 		= T_undefined ;
+	table[(T_int<<4)	+T_String] 		= T_undefined ;
+	table[(T_null<<4)	+T_String] 		= T_undefined ;
+	
+	table[(T_null<<4)	+T_null] 		= T_undefined ;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_MULTIPLY(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_MINUS();
+			
+//	return table ;
+}
+public static final int[] get_OR(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+	
+	return get_AND() ;
+			
+//	return table ;
+}
+public static final int[] get_OR_OR(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+	
+	return get_AND_AND() ;
+			
+//	return table ;
+}
+public static final int[] get_PLUS(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+	int[] table  = new int[16*16] ;
+	
+//	table[(T_undefined<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_undefined<<4)+T_byte] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_long] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_short] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_void] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_String] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_Object] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_double] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_float] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_undefined<<4)+T_char] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_int] 			= T_undefined ;
+//	table[(T_undefined<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_byte<<4)+T_undefined] 	= T_undefined ;
+	table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_byte<<4)+T_void] 		= T_undefined ;
+	table[(T_byte<<4)+T_String] 	= (Byte2Byte<<12)+(String2String<<4)+T_String ;
+//	table[(T_byte<<4)+T_Object] 	= T_undefined ;
+	table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_float;
+//	table[(T_byte<<4)+T_boolean] 	= T_undefined ;
+	table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_byte<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_long<<4)+T_undefined] 	= T_undefined ;
+	table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
+	table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long ;
+//	table[(T_long<<4)+T_void] 		= T_undefined ;
+	table[(T_long<<4)+T_String] 	= (Long2Long<<12)+(String2String<<4)+T_String ;
+//	table[(T_long<<4)+T_Object] 	= T_undefined ;
+	table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_float ;
+//	table[(T_long<<4)+T_boolean] 	= T_undefined ;
+	table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long ;
+	table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long ; ;
+//	table[(T_long<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_short<<4)+T_undefined] 	= T_undefined ;
+	table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_void] 			= T_undefined ;
+	table[(T_short<<4)+T_String] 		= (Short2Short<<12)+(String2String<<4)+T_String ;
+//	table[(T_short<<4)+T_Object] 		= T_undefined ;
+	table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_float ;
+//	table[(T_short<<4)+T_boolean] 		= T_undefined ;
+	table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_short<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_void<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_void<<4)+T_byte] 		= T_undefined ;
+//	table[(T_void<<4)+T_long] 		= T_undefined ;
+//	table[(T_void<<4)+T_short] 		= T_undefined ;
+//	table[(T_void<<4)+T_void] 		= T_undefined ;
+//	table[(T_void<<4)+T_String] 	= T_undefined ;
+//	table[(T_void<<4)+T_Object] 	= T_undefined ;
+//	table[(T_void<<4)+T_double] 	= T_undefined ;
+//	table[(T_void<<4)+T_float] 		= T_undefined ;
+//	table[(T_void<<4)+T_boolean] 	= T_undefined ;
+//	table[(T_void<<4)+T_char] 		= T_undefined ;
+//	table[(T_void<<4)+T_int] 		= T_undefined ;
+//	table[(T_void<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_String<<4)+T_undefined] 	= T_undefined ; 
+	table[(T_String<<4)+T_byte] 		= (String2String<<12)+(Byte2Byte<<4)+T_String ;
+	table[(T_String<<4)+T_long] 		= (String2String<<12)+(Long2Long<<4)+T_String ; 
+	table[(T_String<<4)+T_short] 		= (String2String<<12)+(Short2Short<<4)+T_String ;
+//	table[(T_String<<4)+T_void] 		= T_undefined ;
+	table[(T_String<<4)+T_String] 		= (String2String<<12)+(String2String<<4)+T_String ;
+	table[(T_String<<4)+T_Object] 		= (String2String<<12)+(T_Object<<8)+(T_Object<<4)+T_String ;
+	table[(T_String<<4)+T_double] 		= (String2String<<12)+(Double2Double<<4)+T_String ;
+	table[(T_String<<4)+T_float] 		= (String2String<<12)+(Float2Float<<4)+T_String ; 
+	table[(T_String<<4)+T_boolean] 		= (String2String<<12)+(Boolean2Boolean<<4)+T_String ;
+	table[(T_String<<4)+T_char] 		= (String2String<<12)+(Char2Char<<4)+T_String ;
+	table[(T_String<<4)+T_int] 			= (String2String<<12)+(Int2Int<<4)+T_String ;
+	table[(T_String<<4)+T_null] 		= (String2String<<12)+(T_null<<8)+(T_null<<4)+T_String ;
+
+//	table[(T_Object<<4)+T_undefined] 	= T_undefined ;
+//	table[(T_Object<<4)+T_byte] 		= T_undefined ;
+//	table[(T_Object<<4)+T_long] 		= T_undefined ;
+//	table[(T_Object<<4)+T_short]		= T_undefined ;
+//	table[(T_Object<<4)+T_void] 		= T_undefined ;
+	table[(T_Object<<4)+T_String] 		= (T_Object<<16)+(T_Object<<12)+(String2String<<4)+T_String ;
+//	table[(T_Object<<4)+T_Object] 		= T_undefined ;
+//	table[(T_Object<<4)+T_double] 		= T_undefined ;
+//	table[(T_Object<<4)+T_float] 		= T_undefined ;
+//	table[(T_Object<<4)+T_boolean]		= T_undefined ;
+//	table[(T_Object<<4)+T_char] 		= T_undefined ;
+//	table[(T_Object<<4)+T_int] 			= T_undefined ;
+//	table[(T_Object<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_double<<4)+T_undefined] 	= T_undefined ;
+	table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_double ;
+	table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_double ;
+	table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_double ; ;
+//	table[(T_double<<4)+T_void] 		= T_undefined ;
+	table[(T_double<<4)+T_String] 		= (Double2Double<<12)+(String2String<<4)+T_String ;
+//	table[(T_double<<4)+T_Object] 		= T_undefined ;
+	table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_double ; ;
+//	table[(T_double<<4)+T_boolean] 		= T_undefined ;
+	table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_double ; ;
+	table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_double ; ;
+//	table[(T_double<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_float<<4)+T_undefined] 	= T_undefined ;
+	table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_float ;
+	table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_float ;
+	table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_float ;
+//	table[(T_float<<4)+T_void] 			= T_undefined ;
+	table[(T_float<<4)+T_String] 		= (Float2Float<<12)+(String2String<<4)+T_String ;
+//	table[(T_float<<4)+T_Object] 		= T_undefined ;
+	table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_float ;
+//	table[(T_float<<4)+T_boolean] 		= T_undefined ;
+	table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_float ;
+	table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_float ;
+//	table[(T_float<<4)+T_null] 			= T_undefined ;
+
+//	table[(T_boolean<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_byte] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_long] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_short] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_void] 			= T_undefined ;
+	table[(T_boolean<<4)+T_String] 			= (Boolean2Boolean<<12)+(String2String<<4)+T_String ;
+//	table[(T_boolean<<4)+T_Object] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_double] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_float] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_boolean<<4)+T_char] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_int] 			= T_undefined ;
+//	table[(T_boolean<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_char<<4)+T_undefined] 		= T_undefined ;
+	table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_void] 			= T_undefined ;
+	table[(T_char<<4)+T_String] 		= (Char2Char<<12)+(String2String<<4)+T_String ;
+//	table[(T_char<<4)+T_Object] 		= T_undefined ;
+	table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_float ;
+//	table[(T_char<<4)+T_boolean] 		= T_undefined ;
+	table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int ; ;
+	table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_char<<4)+T_null] 			= T_undefined ;
+	
+//	table[(T_int<<4)+T_undefined] 	= T_undefined ;
+	table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int ;
+	table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long ;
+	table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_void] 		= T_undefined ;
+	table[(T_int<<4)+T_String] 		= (Int2Int<<12)+(String2String<<4)+T_String ;
+//	table[(T_int<<4)+T_Object] 		= T_undefined ;
+	table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_double ;
+	table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_float ;
+//	table[(T_int<<4)+T_boolean] 	= T_undefined ;
+	table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int ;
+	table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int ;
+//	table[(T_int<<4)+T_null] 		= T_undefined ;
+
+//	table[(T_null<<4)+T_undefined] 		= T_undefined ;
+//	table[(T_null<<4)+T_byte] 			= T_undefined ;
+//	table[(T_null<<4)+T_long] 			= T_undefined ;
+//	table[(T_null<<4)+T_short] 			= T_undefined ;
+//	table[(T_null<<4)+T_void] 			= T_undefined ;
+	table[(T_null<<4)+T_String] 		= (T_null<<16)+(T_null<<12)+(String2String<<4)+T_String ;
+//	table[(T_null<<4)+T_Object] 		= T_undefined ;
+//	table[(T_null<<4)+T_double] 		= T_undefined ;
+//	table[(T_null<<4)+T_float] 			= T_undefined ;
+//	table[(T_null<<4)+T_boolean] 		= T_undefined ;
+//	table[(T_null<<4)+T_char] 			= T_undefined ;
+//	table[(T_null<<4)+T_int] 			= T_undefined ;
+//	table[(T_null<<4)+T_null] 			= (Null2String<<12)+(Null2String<<4)+T_String ;;
+
+	//and now.....the return.........
+			
+	return table ;
+}
+public static final int[] get_REMAINDER(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_MINUS();
+			
+//	return table ;
+}
+public static final int[] get_RIGHT_SHIFT(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_LEFT_SHIFT();
+			
+//	return table ;
+}
+public static final int[] get_UNSIGNED_RIGHT_SHIFT(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+
+	return get_LEFT_SHIFT();
+			
+//	return table ;
+}
+public static final int[] get_XOR(){
+
+	//the code is an int
+	// (cast)  left   Op (cast)  rigth --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       
+	
+	
+//	int[] table  = new int[16*16] ;
+	
+	return get_AND() ;
+			
+//	return table ;
+}
+public String operatorToString() {
+	switch ((bits & OperatorMASK) >> OperatorSHIFT) {
+		case EQUAL_EQUAL :
+			return "=="/*nonNLS*/;
+		case LESS_EQUAL :
+			return "<="/*nonNLS*/;
+		case GREATER_EQUAL :
+			return ">="/*nonNLS*/;
+		case NOT_EQUAL :
+			return "!="/*nonNLS*/;
+		case LEFT_SHIFT :
+			return "<<"/*nonNLS*/;
+		case RIGHT_SHIFT :
+			return ">>"/*nonNLS*/;
+		case UNSIGNED_RIGHT_SHIFT :
+			return ">>>"/*nonNLS*/;
+		case OR_OR :
+			return "||"/*nonNLS*/;
+		case AND_AND :
+			return "&&"/*nonNLS*/;
+		case PLUS :
+			return "+"/*nonNLS*/;
+		case MINUS :
+			return "-"/*nonNLS*/;
+		case NOT :
+			return "!"/*nonNLS*/;
+		case REMAINDER :
+			return "%"/*nonNLS*/;
+		case XOR :
+			return "^"/*nonNLS*/;
+		case AND :
+			return "&"/*nonNLS*/;
+		case MULTIPLY :
+			return "*"/*nonNLS*/;
+		case OR :
+			return "|"/*nonNLS*/;
+		case TWIDDLE :
+			return "~"/*nonNLS*/;
+		case DIVIDE :
+			return "/"/*nonNLS*/;
+		case GREATER :
+			return ">"/*nonNLS*/;
+		case LESS :
+			return "<"/*nonNLS*/;
+		case QUESTIONCOLON :
+			return "?:"/*nonNLS*/;
+		case EQUAL :
+			return "="/*nonNLS*/;
+	};
+	return "unknown operator"/*nonNLS*/;
+}
+public String toStringExpression(){
+	/* slow code*/
+
+	//subclass redefine toStringExpressionNoParenthesis()
+	
+	return	"("/*nonNLS*/ + toStringExpressionNoParenthesis() + ")"/*nonNLS*/; 
+}
+
+public abstract String toStringExpressionNoParenthesis();
+
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java b/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
index c4ca1cc..50e54ef 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
@@ -1,38 +1,36 @@
-package org.eclipse.jdt.internal.compiler.ast;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface OperatorIds {
-	public static final int AND_AND = 0;
-	public static final int OR_OR = 1;
-	public static final int AND = 2; 
-	public static final int OR = 3; 
-	public static final int LESS = 4;
-	public static final int LESS_EQUAL = 5;
-	public static final int GREATER = 6;
-	public static final int GREATER_EQUAL = 7;
-	public static final int XOR = 8;
-	public static final int DIVIDE = 9; 
-	public static final int LEFT_SHIFT = 10;
-	public static final int NOT = 11; 
-	public static final int TWIDDLE = 12; 
-	public static final int MINUS = 13; 
-	public static final int PLUS = 14; 
-	public static final int MULTIPLY = 15; 
-	public static final int REMAINDER = 16;
-	public static final int RIGHT_SHIFT = 17;
-	public static final int EQUAL_EQUAL = 18;
-	public static final int UNSIGNED_RIGHT_SHIFT= 19;
-	public static final int NumberOfTables = 20;
-
-	public static final int QUESTIONCOLON = 23;
-
-	public static final int NOT_EQUAL = 29;
-	public static final int EQUAL = 30;
-	public static final int INSTANCEOF = 31;
-	public static final int PLUS_PLUS = 32;
-	public static final int MINUS_MINUS = 33;
-}
+package org.eclipse.jdt.internal.compiler.ast;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public interface OperatorIds {
+	public static final int AND_AND = 0;
+	public static final int OR_OR = 1;
+	public static final int AND = 2; 
+	public static final int OR = 3; 
+	public static final int LESS = 4;
+	public static final int LESS_EQUAL = 5;
+	public static final int GREATER = 6;
+	public static final int GREATER_EQUAL = 7;
+	public static final int XOR = 8;
+	public static final int DIVIDE = 9; 
+	public static final int LEFT_SHIFT = 10;
+	public static final int NOT = 11; 
+	public static final int TWIDDLE = 12; 
+	public static final int MINUS = 13; 
+	public static final int PLUS = 14; 
+	public static final int MULTIPLY = 15; 
+	public static final int REMAINDER = 16;
+	public static final int RIGHT_SHIFT = 17;
+	public static final int EQUAL_EQUAL = 18;
+	public static final int UNSIGNED_RIGHT_SHIFT= 19;
+	public static final int NumberOfTables = 20;
+
+	public static final int QUESTIONCOLON = 23;
+
+	public static final int NOT_EQUAL = 29;
+	public static final int EQUAL = 30;
+	public static final int INSTANCEOF = 31;
+	public static final int PLUS_PLUS = 32;
+	public static final int MINUS_MINUS = 33;
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
index 008c712..05c2e3d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
@@ -1,59 +1,58 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class PostfixExpression extends CompoundAssignment {
-
-public PostfixExpression(Expression l, Expression e, int op, int pos) {
-	super(l, e, op);
-	sourceStart = l.sourceStart;
-	sourceEnd = pos ;
-}
-/**
- * Code generation for PostfixExpression
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */ 
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	// various scenarii are possible, setting an array reference, 
-	// a field reference, a blank final field reference, a field of an enclosing instance or 
-	// just a local variable.
-
-	int pc = codeStream.position;
-	lhs.generatePostIncrement(currentScope, codeStream, this, valueRequired);
-	if (valueRequired) {
-		codeStream.generateImplicitConversion(implicitConversion);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public String operatorToString() {
-	switch (operator) {
-		case PLUS :
-			return "++"/*nonNLS*/;
-		case MINUS :
-			return "--"/*nonNLS*/;}
-	return "unknown operator"/*nonNLS*/;
-}
-public boolean restrainUsageToNumericTypes(){
-	return true ;}
-public String toStringExpressionNoParenthesis(){
-	/* slow code*/
-
-	return	lhs.toStringExpression() + " "/*nonNLS*/ + operatorToString(); }
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		lhs.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class PostfixExpression extends CompoundAssignment {
+
+public PostfixExpression(Expression l, Expression e, int op, int pos) {
+	super(l, e, op);
+	sourceStart = l.sourceStart;
+	sourceEnd = pos ;
+}
+/**
+ * Code generation for PostfixExpression
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */ 
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	// various scenarii are possible, setting an array reference, 
+	// a field reference, a blank final field reference, a field of an enclosing instance or 
+	// just a local variable.
+
+	int pc = codeStream.position;
+	lhs.generatePostIncrement(currentScope, codeStream, this, valueRequired);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public String operatorToString() {
+	switch (operator) {
+		case PLUS :
+			return "++"/*nonNLS*/;
+		case MINUS :
+			return "--"/*nonNLS*/;}
+	return "unknown operator"/*nonNLS*/;
+}
+public boolean restrainUsageToNumericTypes(){
+	return true ;}
+public String toStringExpressionNoParenthesis(){
+	/* slow code*/
+
+	return	lhs.toStringExpression() + " "/*nonNLS*/ + operatorToString(); }
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		lhs.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
index 7912487..1b1db93 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
@@ -1,45 +1,44 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class PrefixExpression extends CompoundAssignment {
-/**
- * PrefixExpression constructor comment.
- * @param l org.eclipse.jdt.internal.compiler.ast.Expression
- * @param r org.eclipse.jdt.internal.compiler.ast.Expression
- * @param op int
- */
-public PrefixExpression(Expression l, Expression e, int op, int pos) {
-	super(l, e, op);
-	sourceStart = pos;
-	sourceEnd = l.sourceEnd;
-}
-public String operatorToString() {
-	switch (operator) {
-		case PLUS :
-			return "++"/*nonNLS*/;
-		case MINUS :
-			return "--"/*nonNLS*/;}
-	return "unknown operator"/*nonNLS*/;
-}
-public boolean restrainUsageToNumericTypes(){
-	return true ;}
-public String toStringExpressionNoParenthesis(){
-	/* slow code */
-	
-	return operatorToString() + " "/*nonNLS*/ + lhs.toStringExpression() ;
-
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		lhs.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class PrefixExpression extends CompoundAssignment {
+/**
+ * PrefixExpression constructor comment.
+ * @param l org.eclipse.jdt.internal.compiler.ast.Expression
+ * @param r org.eclipse.jdt.internal.compiler.ast.Expression
+ * @param op int
+ */
+public PrefixExpression(Expression l, Expression e, int op, int pos) {
+	super(l, e, op);
+	sourceStart = pos;
+	sourceEnd = l.sourceEnd;
+}
+public String operatorToString() {
+	switch (operator) {
+		case PLUS :
+			return "++"/*nonNLS*/;
+		case MINUS :
+			return "--"/*nonNLS*/;}
+	return "unknown operator"/*nonNLS*/;
+}
+public boolean restrainUsageToNumericTypes(){
+	return true ;}
+public String toStringExpressionNoParenthesis(){
+	/* slow code */
+	
+	return operatorToString() + " "/*nonNLS*/ + lhs.toStringExpression() ;
+
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		lhs.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index fc7d922..7b03177 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,263 +1,262 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class QualifiedAllocationExpression extends AllocationExpression {
-	//qualification may be on both side
-	public Expression enclosingInstance;
-	public AnonymousLocalTypeDeclaration anonymousType;
-
-public QualifiedAllocationExpression() {
-	
-}
-public QualifiedAllocationExpression(AnonymousLocalTypeDeclaration anonymous) {
-	anonymousType = anonymous ;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	// variation on allocation, where can be specified an enclosing instance and an anonymous type
-
-	// analyse the enclosing instance
-	if (enclosingInstance != null) {
-		flowInfo = enclosingInstance.analyseCode(currentScope, flowContext, flowInfo);
-	}
-	// process arguments
-	if (arguments != null) {
-		for (int i = 0, count = arguments.length; i < count; i++) {
-			flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo);
-		}
-	}
-	// record some dependency information for exception types
-	int count;
-	ReferenceBinding[] thrownExceptions;
-	if ((count = (thrownExceptions = binding.thrownExceptions).length) != 0) {
-		// check exception handling
-		flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo, currentScope);
-	}
-
-	// analyse the anonymous nested type
-	if (anonymousType != null) {
-		flowInfo = anonymousType.analyseCode(currentScope, flowContext, flowInfo);
-	}
-	manageEnclosingInstanceAccessIfNecessary(currentScope);
-	manageSyntheticAccessIfNecessary(currentScope);
-	return flowInfo;
-}
-public Expression enclosingInstance() {
-	return enclosingInstance;
-}
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	ReferenceBinding allocatedType = binding.declaringClass;
-	if (allocatedType.isLocalType()) {
-		LocalTypeBinding localType = (LocalTypeBinding) allocatedType;
-		localType.constantPoolName(codeStream.classFile.outerMostEnclosingClassFile().computeConstantPoolName(localType));
-	}
-	if (syntheticAccessor == null) {
-		codeStream.new_(allocatedType);
-		if (valueRequired) {
-			codeStream.dup();
-		}
-		// better highlight for allocation: display the type individually
-		codeStream.recordPositionsFrom(pc, type);
-	}
-	// handling innerclass instance allocation
-	if (allocatedType.isNestedType()) { // make sure its name is computed before arguments, since may be necessary for argument emulation
-		codeStream.generateSyntheticArgumentValues(currentScope, allocatedType, enclosingInstance(), this);
-	}
-	// generate the arguments for constructor
-	if (arguments != null) {
-		for (int i = 0, count = arguments.length; i < count; i++) {
-			arguments[i].generateCode(currentScope, codeStream, true);
-		}
-	}
-	// invoke constructor
-	if (syntheticAccessor == null) {
-		codeStream.invokespecial(binding);
-	} else {
-		codeStream.invokestatic(syntheticAccessor);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-	if (anonymousType != null) {
-		anonymousType.generateCode(currentScope, codeStream);
-	}
-}
-public boolean isSuperAccess() {
-	// necessary to lookup super constructor of anonymous type
-	return anonymousType != null;
-}
-/* Inner emulation consists in either recording a dependency 
- * link only, or performing one level of propagation.
- *
- * Dependency mechanism is used whenever dealing with source target
- * types, since by the time we reach them, we might not yet know their
- * exact need.
- */
-public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-	ReferenceBinding invocationType, allocatedType;
-
-	// perform some emulation work in case there is some and we are inside a local type only
-	if ((allocatedType = binding.declaringClass).isNestedType() && currentScope.enclosingSourceType().isLocalType()) {
-
-		if (allocatedType.isLocalType()){
-			((LocalTypeBinding)allocatedType).addInnerEmulationDependent(currentScope, enclosingInstance != null, false); // request cascade of accesses
-		} else {
-			// locally propagate, since we already now the desired shape for sure
-			currentScope.propagateInnerEmulation(allocatedType, enclosingInstance != null, false); // request cascade of accesses
-		}
-	}
-}
-public TypeBinding resolveType(BlockScope scope) {
-	if (anonymousType == null && enclosingInstance == null)
-		return super.resolveType(scope); // added for code assist... is not possible with 'normal' code
-
-	// Propagate the type checking to the arguments, and checks if the constructor is defined.
-
-	// ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
-	// ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
-	// ==> by construction, when there is an enclosing instance the typename may NOT be qualified
-	// ==> therefore by construction the type is always a SingleTypeReferenceType instead of being either 
-	// sometime a SingleTypeReference and sometime a QualifedTypeReference
-
-	constant = NotAConstant;
-	TypeBinding enclosingInstTb = null;
-	TypeBinding recType;
-	if (anonymousType == null) {
-		//----------------no anonymous class------------------------	
-		if ((enclosingInstTb = enclosingInstance.resolveType(scope)) == null)
-			return null;
-		if (enclosingInstTb.isBaseType() | enclosingInstTb.isArrayType()) {
-			scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance(enclosingInstTb, enclosingInstance);
-			return null;
-		}
-		recType = ((SingleTypeReference) type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstTb); // will check for null after args are resolved
-		TypeBinding[] argumentTypes = NoParameters;
-		if (arguments != null) {
-			boolean argHasError = false;
-			int length = arguments.length;
-			argumentTypes = new TypeBinding[length];
-			for (int i = 0; i < length; i++)
-				if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
-					argHasError = true;
-			if (argHasError)
-				return recType;
-		}
-		if (recType == null)
-			return null;
-		if (!recType.canBeInstantiated()) {
-			scope.problemReporter().cannotInstantiate(type, recType);
-			return recType;
-		}
-		if ((binding = scope.getConstructor((ReferenceBinding) recType, argumentTypes, this)).isValidBinding()) {
-			if (isMethodUseDeprecated(binding, scope))
-				scope.problemReporter().deprecatedMethod(binding, this);
-
-			if (arguments != null)
-				for (int i = 0; i < arguments.length; i++)
-					arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
-		} else {
-			if (binding.declaringClass == null)
-				binding.declaringClass = (ReferenceBinding) recType;
-			scope.problemReporter().invalidConstructor(this, binding);
-			return recType;
-		}
-
-		// The enclosing instance must be compatible with the innermost enclosing type
-		ReferenceBinding expectedType = binding.declaringClass.enclosingType();
-		if (scope.areTypesCompatible(enclosingInstTb, expectedType))
-			return recType;
-		scope.problemReporter().typeMismatchErrorActualTypeExpectedType(enclosingInstance, enclosingInstTb, expectedType);
-		return recType;
-	}
-
-	//--------------there is an anonymous type declaration-----------------
-	if (enclosingInstance != null) {
-		if ((enclosingInstTb = enclosingInstance.resolveType(scope)) == null)
-			return null;
-		if (enclosingInstTb.isBaseType() | enclosingInstTb.isArrayType()) {
-			scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance(enclosingInstTb, enclosingInstance);
-			return null;
-		}
-	}
-	// due to syntax-construction, recType is a ReferenceBinding		
-	recType =
-		(enclosingInstance == null)
-			? type.resolveType(scope)
-			: ((SingleTypeReference) type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstTb);
-	if (recType == null)
-		return null;
-	if (((ReferenceBinding) recType).isFinal()) {
-		scope.problemReporter().anonymousClassCannotExtendFinalClass(type, recType);
-		return null;
-	}
-	TypeBinding[] argumentTypes = NoParameters;
-	if (arguments != null) {
-		int length = arguments.length;
-		argumentTypes = new TypeBinding[length];
-		for (int i = 0; i < length; i++)
-			if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
-				return null;
-	}
-
-	// an anonymous class inherits from java.lang.Object when declared "after" an interface
-	ReferenceBinding superBinding = recType.isInterface() ? scope.getJavaLangObject() : (ReferenceBinding) recType;
-	MethodBinding inheritedBinding = scope.getConstructor(superBinding, argumentTypes, this);
-	if (!inheritedBinding.isValidBinding()) {
-		if (inheritedBinding.declaringClass == null)
-			inheritedBinding.declaringClass = superBinding;
-		scope.problemReporter().invalidConstructor(this, inheritedBinding);
-		return null;
-	}
-	if (enclosingInstance != null) {
-		if (!scope.areTypesCompatible(enclosingInstTb, inheritedBinding.declaringClass.enclosingType())) {
-			scope.problemReporter().typeMismatchErrorActualTypeExpectedType(enclosingInstance, enclosingInstTb, inheritedBinding.declaringClass.enclosingType());
-			return null;
-		}
-	}
-
-	// this promotion has to be done somewhere: here or inside the constructor of the
-	// anonymous class. We do it here while the constructor of the inner is then easier.
-	if (arguments != null)
-		for (int i = 0; i < arguments.length; i++)
-			arguments[i].implicitWidening(inheritedBinding.parameters[i], argumentTypes[i]);
-
-		// Update the anonymous inner class : superclass, interface  
-	scope.addAnonymousType(anonymousType, (ReferenceBinding) recType);
-	anonymousType.resolve(scope);
-	binding = anonymousType.createsInternalConstructorWithBinding(inheritedBinding);
-	return anonymousType.binding; // 1.2 change
-}
-public String toStringExpression(int tab) {
-	/*slow code */
-
-	String s = ""/*nonNLS*/;
-	if (enclosingInstance != null)
-		s += enclosingInstance.toString() + "."/*nonNLS*/;
-	s += super.toStringExpression(tab);
-	if (anonymousType != null) {
-		s += anonymousType.toString(tab);
-	} //allows to restart just after the } one line under ....
-	return s;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	if (visitor.visit(this, scope)) {
-		if (enclosingInstance != null) enclosingInstance.traverse(visitor, scope);
-		type.traverse(visitor, scope);
-		if (arguments != null) {
-			int argumentsLength = arguments.length;
-			for (int i = 0; i < argumentsLength; i++)
-				arguments[i].traverse(visitor, scope);
-		}
-		if (anonymousType != null) anonymousType.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedAllocationExpression extends AllocationExpression {
+	//qualification may be on both side
+	public Expression enclosingInstance;
+	public AnonymousLocalTypeDeclaration anonymousType;
+
+public QualifiedAllocationExpression() {
+	
+}
+public QualifiedAllocationExpression(AnonymousLocalTypeDeclaration anonymous) {
+	anonymousType = anonymous ;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// variation on allocation, where can be specified an enclosing instance and an anonymous type
+
+	// analyse the enclosing instance
+	if (enclosingInstance != null) {
+		flowInfo = enclosingInstance.analyseCode(currentScope, flowContext, flowInfo);
+	}
+	// process arguments
+	if (arguments != null) {
+		for (int i = 0, count = arguments.length; i < count; i++) {
+			flowInfo = arguments[i].analyseCode(currentScope, flowContext, flowInfo);
+		}
+	}
+	// record some dependency information for exception types
+	int count;
+	ReferenceBinding[] thrownExceptions;
+	if ((count = (thrownExceptions = binding.thrownExceptions).length) != 0) {
+		// check exception handling
+		flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo, currentScope);
+	}
+
+	// analyse the anonymous nested type
+	if (anonymousType != null) {
+		flowInfo = anonymousType.analyseCode(currentScope, flowContext, flowInfo);
+	}
+	manageEnclosingInstanceAccessIfNecessary(currentScope);
+	manageSyntheticAccessIfNecessary(currentScope);
+	return flowInfo;
+}
+public Expression enclosingInstance() {
+	return enclosingInstance;
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	ReferenceBinding allocatedType = binding.declaringClass;
+	if (allocatedType.isLocalType()) {
+		LocalTypeBinding localType = (LocalTypeBinding) allocatedType;
+		localType.constantPoolName(codeStream.classFile.outerMostEnclosingClassFile().computeConstantPoolName(localType));
+	}
+	if (syntheticAccessor == null) {
+		codeStream.new_(allocatedType);
+		if (valueRequired) {
+			codeStream.dup();
+		}
+		// better highlight for allocation: display the type individually
+		codeStream.recordPositionsFrom(pc, type);
+	}
+	// handling innerclass instance allocation
+	if (allocatedType.isNestedType()) { // make sure its name is computed before arguments, since may be necessary for argument emulation
+		codeStream.generateSyntheticArgumentValues(currentScope, allocatedType, enclosingInstance(), this);
+	}
+	// generate the arguments for constructor
+	if (arguments != null) {
+		for (int i = 0, count = arguments.length; i < count; i++) {
+			arguments[i].generateCode(currentScope, codeStream, true);
+		}
+	}
+	// invoke constructor
+	if (syntheticAccessor == null) {
+		codeStream.invokespecial(binding);
+	} else {
+		codeStream.invokestatic(syntheticAccessor);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+	if (anonymousType != null) {
+		anonymousType.generateCode(currentScope, codeStream);
+	}
+}
+public boolean isSuperAccess() {
+	// necessary to lookup super constructor of anonymous type
+	return anonymousType != null;
+}
+/* Inner emulation consists in either recording a dependency 
+ * link only, or performing one level of propagation.
+ *
+ * Dependency mechanism is used whenever dealing with source target
+ * types, since by the time we reach them, we might not yet know their
+ * exact need.
+ */
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+	ReferenceBinding invocationType, allocatedType;
+
+	// perform some emulation work in case there is some and we are inside a local type only
+	if ((allocatedType = binding.declaringClass).isNestedType() && currentScope.enclosingSourceType().isLocalType()) {
+
+		if (allocatedType.isLocalType()){
+			((LocalTypeBinding)allocatedType).addInnerEmulationDependent(currentScope, enclosingInstance != null, false); // request cascade of accesses
+		} else {
+			// locally propagate, since we already now the desired shape for sure
+			currentScope.propagateInnerEmulation(allocatedType, enclosingInstance != null, false); // request cascade of accesses
+		}
+	}
+}
+public TypeBinding resolveType(BlockScope scope) {
+	if (anonymousType == null && enclosingInstance == null)
+		return super.resolveType(scope); // added for code assist... is not possible with 'normal' code
+
+	// Propagate the type checking to the arguments, and checks if the constructor is defined.
+
+	// ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	// ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	// ==> by construction, when there is an enclosing instance the typename may NOT be qualified
+	// ==> therefore by construction the type is always a SingleTypeReferenceType instead of being either 
+	// sometime a SingleTypeReference and sometime a QualifedTypeReference
+
+	constant = NotAConstant;
+	TypeBinding enclosingInstTb = null;
+	TypeBinding recType;
+	if (anonymousType == null) {
+		//----------------no anonymous class------------------------	
+		if ((enclosingInstTb = enclosingInstance.resolveType(scope)) == null)
+			return null;
+		if (enclosingInstTb.isBaseType() | enclosingInstTb.isArrayType()) {
+			scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance(enclosingInstTb, enclosingInstance);
+			return null;
+		}
+		recType = ((SingleTypeReference) type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstTb); // will check for null after args are resolved
+		TypeBinding[] argumentTypes = NoParameters;
+		if (arguments != null) {
+			boolean argHasError = false;
+			int length = arguments.length;
+			argumentTypes = new TypeBinding[length];
+			for (int i = 0; i < length; i++)
+				if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
+					argHasError = true;
+			if (argHasError)
+				return recType;
+		}
+		if (recType == null)
+			return null;
+		if (!recType.canBeInstantiated()) {
+			scope.problemReporter().cannotInstantiate(type, recType);
+			return recType;
+		}
+		if ((binding = scope.getConstructor((ReferenceBinding) recType, argumentTypes, this)).isValidBinding()) {
+			if (isMethodUseDeprecated(binding, scope))
+				scope.problemReporter().deprecatedMethod(binding, this);
+
+			if (arguments != null)
+				for (int i = 0; i < arguments.length; i++)
+					arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
+		} else {
+			if (binding.declaringClass == null)
+				binding.declaringClass = (ReferenceBinding) recType;
+			scope.problemReporter().invalidConstructor(this, binding);
+			return recType;
+		}
+
+		// The enclosing instance must be compatible with the innermost enclosing type
+		ReferenceBinding expectedType = binding.declaringClass.enclosingType();
+		if (scope.areTypesCompatible(enclosingInstTb, expectedType))
+			return recType;
+		scope.problemReporter().typeMismatchErrorActualTypeExpectedType(enclosingInstance, enclosingInstTb, expectedType);
+		return recType;
+	}
+
+	//--------------there is an anonymous type declaration-----------------
+	if (enclosingInstance != null) {
+		if ((enclosingInstTb = enclosingInstance.resolveType(scope)) == null)
+			return null;
+		if (enclosingInstTb.isBaseType() | enclosingInstTb.isArrayType()) {
+			scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance(enclosingInstTb, enclosingInstance);
+			return null;
+		}
+	}
+	// due to syntax-construction, recType is a ReferenceBinding		
+	recType =
+		(enclosingInstance == null)
+			? type.resolveType(scope)
+			: ((SingleTypeReference) type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstTb);
+	if (recType == null)
+		return null;
+	if (((ReferenceBinding) recType).isFinal()) {
+		scope.problemReporter().anonymousClassCannotExtendFinalClass(type, recType);
+		return null;
+	}
+	TypeBinding[] argumentTypes = NoParameters;
+	if (arguments != null) {
+		int length = arguments.length;
+		argumentTypes = new TypeBinding[length];
+		for (int i = 0; i < length; i++)
+			if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
+				return null;
+	}
+
+	// an anonymous class inherits from java.lang.Object when declared "after" an interface
+	ReferenceBinding superBinding = recType.isInterface() ? scope.getJavaLangObject() : (ReferenceBinding) recType;
+	MethodBinding inheritedBinding = scope.getConstructor(superBinding, argumentTypes, this);
+	if (!inheritedBinding.isValidBinding()) {
+		if (inheritedBinding.declaringClass == null)
+			inheritedBinding.declaringClass = superBinding;
+		scope.problemReporter().invalidConstructor(this, inheritedBinding);
+		return null;
+	}
+	if (enclosingInstance != null) {
+		if (!scope.areTypesCompatible(enclosingInstTb, inheritedBinding.declaringClass.enclosingType())) {
+			scope.problemReporter().typeMismatchErrorActualTypeExpectedType(enclosingInstance, enclosingInstTb, inheritedBinding.declaringClass.enclosingType());
+			return null;
+		}
+	}
+
+	// this promotion has to be done somewhere: here or inside the constructor of the
+	// anonymous class. We do it here while the constructor of the inner is then easier.
+	if (arguments != null)
+		for (int i = 0; i < arguments.length; i++)
+			arguments[i].implicitWidening(inheritedBinding.parameters[i], argumentTypes[i]);
+
+		// Update the anonymous inner class : superclass, interface  
+	scope.addAnonymousType(anonymousType, (ReferenceBinding) recType);
+	anonymousType.resolve(scope);
+	binding = anonymousType.createsInternalConstructorWithBinding(inheritedBinding);
+	return anonymousType.binding; // 1.2 change
+}
+public String toStringExpression(int tab) {
+	/*slow code */
+
+	String s = ""/*nonNLS*/;
+	if (enclosingInstance != null)
+		s += enclosingInstance.toString() + "."/*nonNLS*/;
+	s += super.toStringExpression(tab);
+	if (anonymousType != null) {
+		s += anonymousType.toString(tab);
+	} //allows to restart just after the } one line under ....
+	return s;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (enclosingInstance != null) enclosingInstance.traverse(visitor, scope);
+		type.traverse(visitor, scope);
+		if (arguments != null) {
+			int argumentsLength = arguments.length;
+			for (int i = 0; i < argumentsLength; i++)
+				arguments[i].traverse(visitor, scope);
+		}
+		if (anonymousType != null) anonymousType.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 9114662..5ae24c0 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -1,612 +1,612 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class QualifiedNameReference extends NameReference {
-	public char[][] tokens;
-	public FieldBinding[] otherBindings;
-	public int indexOfFirstFieldBinding; //points (into tokens) for the first token that corresponds to first FieldBinding
-	
-	SyntheticAccessMethodBinding syntheticWriteAccessor;
-	SyntheticAccessMethodBinding[] syntheticReadAccessors;
-	protected FieldBinding lastFieldBinding;
-public QualifiedNameReference(char[][] sources, int sourceStart, int sourceEnd) {
-	super();
-	tokens = sources;
-	this.sourceStart = sourceStart;
-	this.sourceEnd = sourceEnd;
-}
-public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
-	if (assignment.expression != null) {
-		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-	}
-	// determine the rank until which we now we do not need any actual value for the field access
-	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
-	int indexOfFirstValueRequired = otherBindingsCount;
-	while (indexOfFirstValueRequired > 0) {
-		FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
-		if (otherBinding.isStatic())
-			break; // no longer need any value before this point
-		indexOfFirstValueRequired--;
-	}
-
-	FieldBinding lastFieldBinding = null;
-	if ((bits & FIELD) != 0) {
-		// reading from a field
-		// check if final blank field
-		if ((lastFieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
-			if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) {
-				currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
-			}
-		}
-	} else {
-		if ((bits & LOCAL) != 0) {
-			// first binding is a local variable
-			LocalVariableBinding localBinding;
-			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
-				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
-			}
-			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
-		}
-	}
-	if (indexOfFirstValueRequired == 0) {
-		manageEnclosingInstanceAccessIfNecessary(currentScope); // only for first binding
-	}
-	// all intermediate field accesses are read accesses
-	if (otherBindings != null) {
-		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
-		for (int i = start; i < otherBindingsCount; i++) {
-			if (lastFieldBinding != null) { // could be null if first was a local variable
-				manageSyntheticReadAccessIfNecessary(currentScope, lastFieldBinding, i);
-			}
-			lastFieldBinding = otherBindings[i];
-		}
-	}
-	if (isCompound) {
-		if (binding == lastFieldBinding && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding) && (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) {
-			currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
-		}
-		manageSyntheticReadAccessIfNecessary(currentScope, lastFieldBinding, binding == lastFieldBinding ? 0 : otherBindings.length);
-	}
-	// the last field access is a write access
-	if (lastFieldBinding.isFinal()) {
-		// in a context where it can be assigned?
-		if (currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
-			if (flowInfo.isPotentiallyAssigned(lastFieldBinding)) {
-				if (indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
-					currentScope.problemReporter().duplicateInitializationOfBlankFinalField(lastFieldBinding, this);
-				} else {
-					currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this); // attempting to assign a non implicit reference
-				}
-			}
-			flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
-			flowContext.recordSettingFinal(lastFieldBinding, this);
-		} else {
-			currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this);
-		}
-	}
-	// equivalent to valuesRequired[maxOtherBindings]
-	manageSyntheticWriteAccessIfNecessary(currentScope, lastFieldBinding);
-	return flowInfo;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return analyseCode(currentScope, flowContext, flowInfo, true);
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
-
-	// determine the rank until which we now we do not need any actual value for the field access
-	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
-	int indexOfFirstValueRequired;
-	if (valueRequired) {
-		indexOfFirstValueRequired = otherBindingsCount;
-		while (indexOfFirstValueRequired > 0) {
-			FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
-			if (otherBinding.isStatic())
-				break; // no longer need any value before this point
-			indexOfFirstValueRequired--;
-		}
-	} else {
-		indexOfFirstValueRequired = otherBindingsCount + 1;
-	}
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // reading a field
-			if (indexOfFirstValueRequired == 0) {
-				manageSyntheticReadAccessIfNecessary(currentScope, (FieldBinding) binding, 0);
-			}
-			// check if reading a final blank field
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding) binding).isFinal()
-				&& (indexOfFirstFieldBinding == 1) // was an implicit reference to the first field binding
-				&& currentScope.allowBlankFinalFieldAssignment(fieldBinding)
-				&& (!flowInfo.isDefinitelyAssigned(fieldBinding))) {
-					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
-			}
-			break;
-		case LOCAL : // reading a local variable
-			LocalVariableBinding localBinding;
-			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
-				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
-			}
-			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
-	}
-	if (indexOfFirstValueRequired == 0) { 
-		manageEnclosingInstanceAccessIfNecessary(currentScope); // only for first binding
-	}
-	if (otherBindings != null) {
-		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
-		for (int i = start; i < otherBindingsCount; i++) {
-			manageSyntheticReadAccessIfNecessary(currentScope, otherBindings[i], i + 1);
-		}
-	}
-	return flowInfo;
-}
-/**
- * Check and/or redirect the field access to the delegate receiver if any
- */
-public TypeBinding checkFieldAccess(BlockScope scope) {
-	// check for forward references
-	FieldBinding fieldBinding = (FieldBinding) binding;
-	MethodScope methodScope = scope.methodScope();
-	if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
-		&& methodScope.fieldDeclarationIndex != methodScope.NotInFieldDecl
-		&& fieldBinding.id >= methodScope.fieldDeclarationIndex) {
-		if ((!fieldBinding.isStatic() || methodScope.isStatic)
-			&& this.indexOfFirstFieldBinding == 1)
-			scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
-	}
-	bits &= ~RestrictiveFlagMASK; // clear bits
-	bits |= FIELD;
-	return getOtherFieldBindings(scope);
-}
-public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
-	generateReadSequence(currentScope, codeStream, true);
-	// the last field access is a write access
-	assignment.expression.generateCode(currentScope, codeStream, true);
-	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); // equivalent to valuesRequired[maxOtherBindings]
-	if (valueRequired) {
-		codeStream.generateImplicitConversion(assignment.implicitConversion);
-	}
-}
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	if (constant != NotAConstant) {
-		if (valueRequired) {
-			codeStream.generateConstant(constant, implicitConversion);
-		}
-	} else {
-		generateReadSequence(currentScope, codeStream, valueRequired);
-		if (valueRequired) {
-			if (lastFieldBinding.declaringClass == null) { // array length
-				codeStream.arraylength();
-				codeStream.generateImplicitConversion(implicitConversion);
-			} else {
-				if (lastFieldBinding.constant != NotAConstant) {
-					// inline the last field constant
-					codeStream.generateConstant(lastFieldBinding.constant, implicitConversion);
-				} else {					
-					SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
-					if (accessor == null) {
-						if (lastFieldBinding.isStatic()) {
-							codeStream.getstatic(lastFieldBinding);
-						} else {
-							codeStream.getfield(lastFieldBinding);
-						}
-					} else {
-						codeStream.invokestatic(accessor);
-					}
-					codeStream.generateImplicitConversion(implicitConversion);
-				}
-			}
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
-	
-	generateReadSequence(currentScope, codeStream, true);
-	SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
-	
-	if (lastFieldBinding.isStatic()){
-		if (accessor == null) {
-			codeStream.getstatic(lastFieldBinding);
-		} else {
-			codeStream.invokestatic(accessor);
-		}
-	} else {
-		codeStream.dup();
-		if (accessor == null) {
-			codeStream.getfield(lastFieldBinding);
-		} else {
-			codeStream.invokestatic(accessor);
-		}
-	}
-	// the last field access is a write access
-	// perform the actual compound operation
-	int operationTypeID;
-	if ((operationTypeID = implicitConversion >> 4) == T_String) {
-		codeStream.generateStringAppend(currentScope, null, expression);
-	} else {
-		// promote the array reference to the suitable operation type
-		codeStream.generateImplicitConversion(implicitConversion);
-		// generate the increment value (will by itself  be promoted to the operation value)
-		if (expression == IntLiteral.One){ // prefix operation
-			codeStream.generateConstant(expression.constant, implicitConversion);			
-		} else {
-			expression.generateCode(currentScope, codeStream, true);
-		}
-		// perform the operation
-		codeStream.sendOperator(operator, operationTypeID);
-		// cast the value back to the array reference type
-		codeStream.generateImplicitConversion(assignmentImplicitConversion);
-	}
-	// actual assignment
-	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); // equivalent to valuesRequired[maxOtherBindings]
-}
-public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
-	generateReadSequence(currentScope, codeStream, true);
-	SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
-
-	if (lastFieldBinding.isStatic()){
-		if (accessor == null) {
-			codeStream.getstatic(lastFieldBinding);
-		} else {
-			codeStream.invokestatic(accessor);
-		}
-	} else {
-		codeStream.dup();
-		if (accessor == null) {
-			codeStream.getfield(lastFieldBinding);
-		} else {
-			codeStream.invokestatic(accessor);
-		}
-	}	
-	// duplicate the old field value
-	if (valueRequired) {
-		if (lastFieldBinding.isStatic()) {
-			if ((lastFieldBinding.type == LongBinding) || (lastFieldBinding.type == DoubleBinding)) {
-				codeStream.dup2();
-			} else {
-				codeStream.dup();
-			}
-		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
-			if ((lastFieldBinding.type == LongBinding) || (lastFieldBinding.type == DoubleBinding)) {
-				codeStream.dup2_x1();
-			} else {
-				codeStream.dup_x1();
-			}
-		}
-	}
-	codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
-	codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
-	codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
-	
-	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, false);
-}
-/*
- * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
- * for a read or write access.
- */
-public void generateReadSequence(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
-	// determine the rank until which we now we do not need any actual value for the field access
-	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
-	int indexOfFirstValueRequired;
-	if (valueRequired) {
-		indexOfFirstValueRequired = otherBindingsCount;
-		while (indexOfFirstValueRequired > 0) {
-			FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
-			if (otherBinding.isStatic() || otherBinding.constant != NotAConstant)
-				break; // no longer need any value before this point
-			indexOfFirstValueRequired--;
-		}
-	} else {
-		indexOfFirstValueRequired = otherBindingsCount + 1;
-	}
-	if (indexOfFirstValueRequired == 0) {
-		switch (bits & RestrictiveFlagMASK) {
-			case FIELD :
-				lastFieldBinding = (FieldBinding) binding;
-
-				// if first field is actually constant, we can inline it
-				if (lastFieldBinding.constant != NotAConstant) {
-					codeStream.generateConstant(lastFieldBinding.constant, 0); // no implicit conversion
-					lastFieldBinding = null; // will not generate it again
-					break;
-				}
-				if (!lastFieldBinding.isStatic()) {
-					if ((bits & DepthMASK) != 0) {
-						Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-						if (emulationPath == null) {
-							// internal error, per construction we should have found it
-							currentScope.problemReporter().needImplementation();
-						} else {
-							codeStream.generateOuterAccess(emulationPath, this, currentScope);
-						}
-					} else {
-						generateReceiver(codeStream);
-					}
-				}
-				break;
-			case LOCAL : // reading the first local variable
-				lastFieldBinding = null;
-				LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-
-				// regular local variable read
-				if (localBinding.constant != NotAConstant) {
-					codeStream.generateConstant(localBinding.constant, 0); // no implicit conversion
-				} else {
-					// outer local?
-					if ((bits & DepthMASK) != 0) {
-						// outer local can be reached either through a synthetic arg or a synthetic field
-						VariableBinding[] path = currentScope.getEmulationPath(localBinding);
-						if (path == null) {
-							// emulation was not possible (should not happen per construction)
-							currentScope.problemReporter().needImplementation();
-						} else {
-							codeStream.generateOuterAccess(path, this, currentScope);
-						}
-					} else {
-						codeStream.load(localBinding);
-					}
-				}
-		}
-	} else {
-		lastFieldBinding = null;
-	}
-	// all intermediate field accesses are read accesses
-	// only the last field binding is a write access
-	if (otherBindings != null) {
-		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
-		for (int i = start; i < otherBindingsCount; i++) {
-			if (lastFieldBinding != null) {
-				MethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[i];
-				if (accessor == null)
-					if (lastFieldBinding.isStatic())
-						codeStream.getstatic(lastFieldBinding);
-					else
-						codeStream.getfield(lastFieldBinding);
-				else
-					codeStream.invokestatic(accessor);
-			}
-			lastFieldBinding = otherBindings[i];
-		}
-	}
-}
-public void generateReceiver(CodeStream codeStream) {
-	codeStream.aload_0();
-}
-public TypeBinding getOtherFieldBindings(BlockScope scope) {
-	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
-
-	if ((bits & FIELD) != 0) {
-		if (!((FieldBinding) binding).isStatic()) { //must check for the static status....
-			if (indexOfFirstFieldBinding == 1) {
-				//the field is the first token of the qualified reference....
-				if (scope.methodScope().isStatic) {
-					scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) binding);
-					return null;
-				}
-			} else { //accessing to a field using a type as "receiver" is allowed only with static field	
-				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) binding);
-				return null;
-			}
-		}
-		if (isFieldUseDeprecated((FieldBinding) binding, scope))
-			scope.problemReporter().deprecatedField((FieldBinding) binding, this);
-
-		// if the binding declaring class is not visible, need special action
-		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
-		FieldBinding fieldBinding = (FieldBinding)binding;
-		if (fieldBinding.declaringClass != null
-			&& fieldBinding.constant == NotAConstant
-			&& !fieldBinding.declaringClass.canBeSeenBy(scope))
-				binding = new FieldBinding(fieldBinding, scope.enclosingSourceType());
-	}
-
-	TypeBinding type = ((VariableBinding) binding).type;
-	int index = indexOfFirstFieldBinding;
-	int length = tokens.length;
-	if (index == length) { //	restrictiveFlag == FIELD
-		constant = FieldReference.getConstantFor((FieldBinding) binding, false, this, index - 1);
-		return type;
-	}
-
-	// allocation of the fieldBindings array	and its respective constants
-	int otherBindingsLength = length - index;
-	otherBindings = new FieldBinding[otherBindingsLength];
-	
-	// fill the first constant (the one of the binding)
-	constant =
-		((bits & FIELD) != 0)
-			? FieldReference.getConstantFor((FieldBinding) binding, false, this, index - 1)
-			: ((VariableBinding) binding).constant;
-
-	// iteration on each field	
-	while (index < length) {
-		char[] token = tokens[index];
-		if (type == null) return null; // could not resolve type prior to this point
-		FieldBinding field = scope.getField(type, token, this);
-		int place = index - indexOfFirstFieldBinding;
-		otherBindings[place] = field;
-		if (field.isValidBinding()) {
-			if (isFieldUseDeprecated(field, scope))
-				scope.problemReporter().deprecatedField(field, this);
-			Constant someConstant = FieldReference.getConstantFor(field, false, this, place);
-			// constant propagation can only be performed as long as the previous one is a constant too.
-			if (constant != NotAConstant){
-				constant = someConstant;
-			}
-			// if the binding declaring class is not visible, need special action
-			// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
-			if (field.declaringClass != type
-				&& field.declaringClass != null // array.length
-				&& field.constant == NotAConstant
-				&& !field.declaringClass.canBeSeenBy(scope))
-					otherBindings[place] = new FieldBinding(field, (ReferenceBinding)type);
-			type = field.type;
-			index++;
-		} else {
-			constant = NotAConstant; //don't fill other constants slots...
-			scope.problemReporter().invalidField(this, field, index, type);
-			return null;
-		}
-	}
-	return (otherBindings[otherBindingsLength - 1]).type;
-}
-public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-	//If inlinable field, forget the access emulation, the code gen will directly target it
-	if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) {
-		return;
-	}
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD :
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding)binding).isStatic() || (fieldBinding.constant != NotAConstant)) return;		
-			ReferenceBinding compatibleType = currentScope.enclosingSourceType();
-			// the declaringClass of the target binding must be compatible with the enclosing
-			// type at <depth> levels outside
-			for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
-				compatibleType = compatibleType.enclosingType();
-			}
-			currentScope.emulateOuterAccess(compatibleType, false); // request cascade of accesses
-			break;
-		case LOCAL :
-			currentScope.emulateOuterAccess((LocalVariableBinding) binding);
-	}
-}
-public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index) {
-	// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings'
-
-	if (fieldBinding.constant != NotAConstant) return;
-	if (fieldBinding.isPrivate()) { // private access
-		if (fieldBinding.declaringClass != currentScope.enclosingSourceType()) {
-			if (syntheticReadAccessors == null) {
-				if (otherBindings == null)
-					syntheticReadAccessors = new SyntheticAccessMethodBinding[1];
-				else
-					syntheticReadAccessors = new SyntheticAccessMethodBinding[otherBindings.length + 1];
-			}
-			syntheticReadAccessors[index] = fieldBinding.getSyntheticReadAccess();
-			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
-		}
-		return;
-	}
-	if (fieldBinding.isProtected() // implicit protected access (only for first one)
-		&& index == 0
-		&& (bits & DepthMASK) != 0
-		&& (fieldBinding.declaringClass.getPackage() 
-			!= currentScope.enclosingSourceType().getPackage())){	
-			if (syntheticReadAccessors == null) {
-				if (otherBindings == null)
-					syntheticReadAccessors = new SyntheticAccessMethodBinding[1];
-				else
-					syntheticReadAccessors = new SyntheticAccessMethodBinding[otherBindings.length + 1];
-			}
-			syntheticReadAccessors[index] = 
-				((SourceTypeBinding)currentScope.enclosingSourceType().
-					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
-						addSyntheticMethod(fieldBinding, true);
-			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
-	}
-}
-/*
- * No need to emulate access to protected fields since not implicitly accessed
- */
-public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding) {
-	if (fieldBinding.isPrivate() && fieldBinding.declaringClass != currentScope.enclosingSourceType()) {
-		syntheticWriteAccessor = fieldBinding.getSyntheticWriteAccess();
-		currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this);
-	}
-}
-/**
- * Normal field binding did not work, try to bind to a field of the delegate receiver.
- */
-public TypeBinding reportError(BlockScope scope) {
-	if (binding instanceof ProblemFieldBinding) {
-		scope.problemReporter().invalidField(this, (FieldBinding) binding);
-	} else if (binding instanceof ProblemReferenceBinding) {
-		scope.problemReporter().invalidType(this, (TypeBinding) binding);
-	} else {
-		scope.problemReporter().unresolvableReference(this, binding);
-	}
-	return null;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// field and/or local are done before type lookups
-
-	// the only available value for the restrictiveFlag BEFORE
-	// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField 
-	this.receiverType = scope.enclosingSourceType();
-	
-	constant = Constant.NotAConstant;
-	if ((binding = scope.getBinding(tokens, bits & RestrictiveFlagMASK, this)).isValidBinding()) {
-		switch (bits & RestrictiveFlagMASK) {
-			case VARIABLE : //============only variable===========
-			case TYPE | VARIABLE :
-				if (binding instanceof LocalVariableBinding) {
-					if (!((LocalVariableBinding) binding).isFinal() && ((bits & DepthMASK) != 0))
-						scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) binding, this);
-					bits &= ~RestrictiveFlagMASK;  // clear bits
-					bits |= LOCAL;
-					return getOtherFieldBindings(scope);
-				}
-				if (binding instanceof FieldBinding) {
-					// check for forward references
-					FieldBinding fieldBinding = (FieldBinding) binding;
-					MethodScope methodScope = scope.methodScope() ;
-					if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
-						&& methodScope.fieldDeclarationIndex != methodScope.NotInFieldDecl
-						&& fieldBinding.id >= methodScope.fieldDeclarationIndex) {
-							if ((!fieldBinding.isStatic() || methodScope.isStatic) && this.indexOfFirstFieldBinding == 1)
-								scope.problemReporter().forwardReference(this,0,scope.enclosingSourceType());
-					}					
-					bits &= ~RestrictiveFlagMASK;  // clear bits
-					bits |= FIELD;					
-					return getOtherFieldBindings(scope);
-				}
-
-				// thus it was a type
-				bits &= ~RestrictiveFlagMASK;  // clear bits
-				bits |= TYPE;				
-			case TYPE : //=============only type ==============
-				//deprecated test
-				if (isTypeUseDeprecated((TypeBinding) binding, scope))
-					scope.problemReporter().deprecatedType((TypeBinding) binding, this);
-				return (TypeBinding) binding;
-		}
-	}
-
-	//========error cases===============
-	return this.reportError(scope);
-}
-public void setFieldIndex(int index){
-
-	indexOfFirstFieldBinding = index ;
-}
-public String toStringExpression() {
-	/* slow speed */
-	StringBuffer buffer = new StringBuffer();
-	for (int i = 0; i < tokens.length; i++) {
-		buffer.append(tokens[i]);
-		if (i < (tokens.length - 1)) {
-			buffer.append("."/*nonNLS*/);
-		}
-	}
-	return buffer.toString();
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-public  String unboundReferenceErrorName(){
-
-	return new String(tokens[0]);}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedNameReference extends NameReference {
+	public char[][] tokens;
+	public FieldBinding[] otherBindings;
+	public int indexOfFirstFieldBinding; //points (into tokens) for the first token that corresponds to first FieldBinding
+	
+	SyntheticAccessMethodBinding syntheticWriteAccessor;
+	SyntheticAccessMethodBinding[] syntheticReadAccessors;
+	protected FieldBinding lastFieldBinding;
+public QualifiedNameReference(char[][] sources, int sourceStart, int sourceEnd) {
+	super();
+	tokens = sources;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+	if (assignment.expression != null) {
+		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+	}
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
+	int indexOfFirstValueRequired = otherBindingsCount;
+	while (indexOfFirstValueRequired > 0) {
+		FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
+		if (otherBinding.isStatic())
+			break; // no longer need any value before this point
+		indexOfFirstValueRequired--;
+	}
+
+	FieldBinding lastFieldBinding = null;
+	if ((bits & FIELD) != 0) {
+		// reading from a field
+		// check if final blank field
+		if ((lastFieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
+			if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) {
+				currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
+			}
+		}
+	} else {
+		if ((bits & LOCAL) != 0) {
+			// first binding is a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
+		}
+	}
+	if (indexOfFirstValueRequired == 0) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope); // only for first binding
+	}
+	// all intermediate field accesses are read accesses
+	if (otherBindings != null) {
+		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
+		for (int i = start; i < otherBindingsCount; i++) {
+			if (lastFieldBinding != null) { // could be null if first was a local variable
+				manageSyntheticReadAccessIfNecessary(currentScope, lastFieldBinding, i);
+			}
+			lastFieldBinding = otherBindings[i];
+		}
+	}
+	if (isCompound) {
+		if (binding == lastFieldBinding && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding) && (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) {
+			currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
+		}
+		manageSyntheticReadAccessIfNecessary(currentScope, lastFieldBinding, binding == lastFieldBinding ? 0 : otherBindings.length);
+	}
+	// the last field access is a write access
+	if (lastFieldBinding.isFinal()) {
+		// in a context where it can be assigned?
+		if (currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
+			if (flowInfo.isPotentiallyAssigned(lastFieldBinding)) {
+				if (indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
+					currentScope.problemReporter().duplicateInitializationOfBlankFinalField(lastFieldBinding, this);
+				} else {
+					currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this); // attempting to assign a non implicit reference
+				}
+			}
+			flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
+			flowContext.recordSettingFinal(lastFieldBinding, this);
+		} else {
+			currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this);
+		}
+	}
+	// equivalent to valuesRequired[maxOtherBindings]
+	manageSyntheticWriteAccessIfNecessary(currentScope, lastFieldBinding);
+	return flowInfo;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
+	int indexOfFirstValueRequired;
+	if (valueRequired) {
+		indexOfFirstValueRequired = otherBindingsCount;
+		while (indexOfFirstValueRequired > 0) {
+			FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
+			if (otherBinding.isStatic())
+				break; // no longer need any value before this point
+			indexOfFirstValueRequired--;
+		}
+	} else {
+		indexOfFirstValueRequired = otherBindingsCount + 1;
+	}
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // reading a field
+			if (indexOfFirstValueRequired == 0) {
+				manageSyntheticReadAccessIfNecessary(currentScope, (FieldBinding) binding, 0);
+			}
+			// check if reading a final blank field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) binding).isFinal()
+				&& (indexOfFirstFieldBinding == 1) // was an implicit reference to the first field binding
+				&& currentScope.allowBlankFinalFieldAssignment(fieldBinding)
+				&& (!flowInfo.isDefinitelyAssigned(fieldBinding))) {
+					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+			}
+			break;
+		case LOCAL : // reading a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
+	}
+	if (indexOfFirstValueRequired == 0) { 
+		manageEnclosingInstanceAccessIfNecessary(currentScope); // only for first binding
+	}
+	if (otherBindings != null) {
+		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
+		for (int i = start; i < otherBindingsCount; i++) {
+			manageSyntheticReadAccessIfNecessary(currentScope, otherBindings[i], i + 1);
+		}
+	}
+	return flowInfo;
+}
+/**
+ * Check and/or redirect the field access to the delegate receiver if any
+ */
+public TypeBinding checkFieldAccess(BlockScope scope) {
+	// check for forward references
+	FieldBinding fieldBinding = (FieldBinding) binding;
+	MethodScope methodScope = scope.methodScope();
+	if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
+		&& methodScope.fieldDeclarationIndex != MethodScope.NotInFieldDecl
+		&& fieldBinding.id >= methodScope.fieldDeclarationIndex) {
+		if ((!fieldBinding.isStatic() || methodScope.isStatic)
+			&& this.indexOfFirstFieldBinding == 1)
+			scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
+	}
+	bits &= ~RestrictiveFlagMASK; // clear bits
+	bits |= FIELD;
+	return getOtherFieldBindings(scope);
+}
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	generateReadSequence(currentScope, codeStream, true);
+	// the last field access is a write access
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); // equivalent to valuesRequired[maxOtherBindings]
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (constant != NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(constant, implicitConversion);
+		}
+	} else {
+		generateReadSequence(currentScope, codeStream, valueRequired);
+		if (valueRequired) {
+			if (lastFieldBinding.declaringClass == null) { // array length
+				codeStream.arraylength();
+				codeStream.generateImplicitConversion(implicitConversion);
+			} else {
+				if (lastFieldBinding.constant != NotAConstant) {
+					// inline the last field constant
+					codeStream.generateConstant(lastFieldBinding.constant, implicitConversion);
+				} else {					
+					SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
+					if (accessor == null) {
+						if (lastFieldBinding.isStatic()) {
+							codeStream.getstatic(lastFieldBinding);
+						} else {
+							codeStream.getfield(lastFieldBinding);
+						}
+					} else {
+						codeStream.invokestatic(accessor);
+					}
+					codeStream.generateImplicitConversion(implicitConversion);
+				}
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	
+	generateReadSequence(currentScope, codeStream, true);
+	SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
+	
+	if (lastFieldBinding.isStatic()){
+		if (accessor == null) {
+			codeStream.getstatic(lastFieldBinding);
+		} else {
+			codeStream.invokestatic(accessor);
+		}
+	} else {
+		codeStream.dup();
+		if (accessor == null) {
+			codeStream.getfield(lastFieldBinding);
+		} else {
+			codeStream.invokestatic(accessor);
+		}
+	}
+	// the last field access is a write access
+	// perform the actual compound operation
+	int operationTypeID;
+	if ((operationTypeID = implicitConversion >> 4) == T_String) {
+		codeStream.generateStringAppend(currentScope, null, expression);
+	} else {
+		// promote the array reference to the suitable operation type
+		codeStream.generateImplicitConversion(implicitConversion);
+		// generate the increment value (will by itself  be promoted to the operation value)
+		if (expression == IntLiteral.One){ // prefix operation
+			codeStream.generateConstant(expression.constant, implicitConversion);			
+		} else {
+			expression.generateCode(currentScope, codeStream, true);
+		}
+		// perform the operation
+		codeStream.sendOperator(operator, operationTypeID);
+		// cast the value back to the array reference type
+		codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// actual assignment
+	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired); // equivalent to valuesRequired[maxOtherBindings]
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	generateReadSequence(currentScope, codeStream, true);
+	SyntheticAccessMethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[syntheticReadAccessors.length - 1];
+
+	if (lastFieldBinding.isStatic()){
+		if (accessor == null) {
+			codeStream.getstatic(lastFieldBinding);
+		} else {
+			codeStream.invokestatic(accessor);
+		}
+	} else {
+		codeStream.dup();
+		if (accessor == null) {
+			codeStream.getfield(lastFieldBinding);
+		} else {
+			codeStream.invokestatic(accessor);
+		}
+	}	
+	// duplicate the old field value
+	if (valueRequired) {
+		if (lastFieldBinding.isStatic()) {
+			if ((lastFieldBinding.type == LongBinding) || (lastFieldBinding.type == DoubleBinding)) {
+				codeStream.dup2();
+			} else {
+				codeStream.dup();
+			}
+		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+			if ((lastFieldBinding.type == LongBinding) || (lastFieldBinding.type == DoubleBinding)) {
+				codeStream.dup2_x1();
+			} else {
+				codeStream.dup_x1();
+			}
+		}
+	}
+	codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
+	codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+	
+	fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, false);
+}
+/*
+ * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
+ * for a read or write access.
+ */
+public void generateReadSequence(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = otherBindings == null ? 0 : otherBindings.length;
+	int indexOfFirstValueRequired;
+	if (valueRequired) {
+		indexOfFirstValueRequired = otherBindingsCount;
+		while (indexOfFirstValueRequired > 0) {
+			FieldBinding otherBinding = otherBindings[indexOfFirstValueRequired - 1];
+			if (otherBinding.isStatic() || otherBinding.constant != NotAConstant)
+				break; // no longer need any value before this point
+			indexOfFirstValueRequired--;
+		}
+	} else {
+		indexOfFirstValueRequired = otherBindingsCount + 1;
+	}
+	if (indexOfFirstValueRequired == 0) {
+		switch (bits & RestrictiveFlagMASK) {
+			case FIELD :
+				lastFieldBinding = (FieldBinding) binding;
+
+				// if first field is actually constant, we can inline it
+				if (lastFieldBinding.constant != NotAConstant) {
+					codeStream.generateConstant(lastFieldBinding.constant, 0); // no implicit conversion
+					lastFieldBinding = null; // will not generate it again
+					break;
+				}
+				if (!lastFieldBinding.isStatic()) {
+					if ((bits & DepthMASK) != 0) {
+						Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+						if (emulationPath == null) {
+							// internal error, per construction we should have found it
+							currentScope.problemReporter().needImplementation();
+						} else {
+							codeStream.generateOuterAccess(emulationPath, this, currentScope);
+						}
+					} else {
+						generateReceiver(codeStream);
+					}
+				}
+				break;
+			case LOCAL : // reading the first local variable
+				lastFieldBinding = null;
+				LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+
+				// regular local variable read
+				if (localBinding.constant != NotAConstant) {
+					codeStream.generateConstant(localBinding.constant, 0); // no implicit conversion
+				} else {
+					// outer local?
+					if ((bits & DepthMASK) != 0) {
+						// outer local can be reached either through a synthetic arg or a synthetic field
+						VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+						if (path == null) {
+							// emulation was not possible (should not happen per construction)
+							currentScope.problemReporter().needImplementation();
+						} else {
+							codeStream.generateOuterAccess(path, this, currentScope);
+						}
+					} else {
+						codeStream.load(localBinding);
+					}
+				}
+		}
+	} else {
+		lastFieldBinding = null;
+	}
+	// all intermediate field accesses are read accesses
+	// only the last field binding is a write access
+	if (otherBindings != null) {
+		int start = indexOfFirstValueRequired == 0 ? 0 : indexOfFirstValueRequired - 1;
+		for (int i = start; i < otherBindingsCount; i++) {
+			if (lastFieldBinding != null) {
+				MethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[i];
+				if (accessor == null)
+					if (lastFieldBinding.isStatic())
+						codeStream.getstatic(lastFieldBinding);
+					else
+						codeStream.getfield(lastFieldBinding);
+				else
+					codeStream.invokestatic(accessor);
+			}
+			lastFieldBinding = otherBindings[i];
+		}
+	}
+}
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+}
+public TypeBinding getOtherFieldBindings(BlockScope scope) {
+	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
+
+	if ((bits & FIELD) != 0) {
+		if (!((FieldBinding) binding).isStatic()) { //must check for the static status....
+			if (indexOfFirstFieldBinding == 1) {
+				//the field is the first token of the qualified reference....
+				if (scope.methodScope().isStatic) {
+					scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) binding);
+					return null;
+				}
+			} else { //accessing to a field using a type as "receiver" is allowed only with static field	
+				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) binding);
+				return null;
+			}
+		}
+		if (isFieldUseDeprecated((FieldBinding) binding, scope))
+			scope.problemReporter().deprecatedField((FieldBinding) binding, this);
+
+		// if the binding declaring class is not visible, need special action
+		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+		FieldBinding fieldBinding = (FieldBinding)binding;
+		if (fieldBinding.declaringClass != null
+			&& fieldBinding.constant == NotAConstant
+			&& !fieldBinding.declaringClass.canBeSeenBy(scope))
+				binding = new FieldBinding(fieldBinding, scope.enclosingSourceType());
+	}
+
+	TypeBinding type = ((VariableBinding) binding).type;
+	int index = indexOfFirstFieldBinding;
+	int length = tokens.length;
+	if (index == length) { //	restrictiveFlag == FIELD
+		constant = FieldReference.getConstantFor((FieldBinding) binding, false, this, index - 1);
+		return type;
+	}
+
+	// allocation of the fieldBindings array	and its respective constants
+	int otherBindingsLength = length - index;
+	otherBindings = new FieldBinding[otherBindingsLength];
+	
+	// fill the first constant (the one of the binding)
+	constant =
+		((bits & FIELD) != 0)
+			? FieldReference.getConstantFor((FieldBinding) binding, false, this, index - 1)
+			: ((VariableBinding) binding).constant;
+
+	// iteration on each field	
+	while (index < length) {
+		char[] token = tokens[index];
+		if (type == null) return null; // could not resolve type prior to this point
+		FieldBinding field = scope.getField(type, token, this);
+		int place = index - indexOfFirstFieldBinding;
+		otherBindings[place] = field;
+		if (field.isValidBinding()) {
+			if (isFieldUseDeprecated(field, scope))
+				scope.problemReporter().deprecatedField(field, this);
+			Constant someConstant = FieldReference.getConstantFor(field, false, this, place);
+			// constant propagation can only be performed as long as the previous one is a constant too.
+			if (constant != NotAConstant){
+				constant = someConstant;
+			}
+			// if the binding declaring class is not visible, need special action
+			// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+			if (field.declaringClass != type
+				&& field.declaringClass != null // array.length
+				&& field.constant == NotAConstant
+				&& !field.declaringClass.canBeSeenBy(scope))
+					otherBindings[place] = new FieldBinding(field, (ReferenceBinding)type);
+			type = field.type;
+			index++;
+		} else {
+			constant = NotAConstant; //don't fill other constants slots...
+			scope.problemReporter().invalidField(this, field, index, type);
+			return null;
+		}
+	}
+	return (otherBindings[otherBindingsLength - 1]).type;
+}
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) {
+		return;
+	}
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD :
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding)binding).isStatic() || (fieldBinding.constant != NotAConstant)) return;		
+			ReferenceBinding compatibleType = currentScope.enclosingSourceType();
+			// the declaringClass of the target binding must be compatible with the enclosing
+			// type at <depth> levels outside
+			for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
+				compatibleType = compatibleType.enclosingType();
+			}
+			currentScope.emulateOuterAccess(compatibleType, false); // request cascade of accesses
+			break;
+		case LOCAL :
+			currentScope.emulateOuterAccess((LocalVariableBinding) binding);
+	}
+}
+public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index) {
+	// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings'
+
+	if (fieldBinding.constant != NotAConstant) return;
+	if (fieldBinding.isPrivate()) { // private access
+		if (fieldBinding.declaringClass != currentScope.enclosingSourceType()) {
+			if (syntheticReadAccessors == null) {
+				if (otherBindings == null)
+					syntheticReadAccessors = new SyntheticAccessMethodBinding[1];
+				else
+					syntheticReadAccessors = new SyntheticAccessMethodBinding[otherBindings.length + 1];
+			}
+			syntheticReadAccessors[index] = fieldBinding.getSyntheticReadAccess();
+			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
+		}
+		return;
+	}
+	if (fieldBinding.isProtected() // implicit protected access (only for first one)
+		&& index == 0
+		&& (bits & DepthMASK) != 0
+		&& (fieldBinding.declaringClass.getPackage() 
+			!= currentScope.enclosingSourceType().getPackage())){	
+			if (syntheticReadAccessors == null) {
+				if (otherBindings == null)
+					syntheticReadAccessors = new SyntheticAccessMethodBinding[1];
+				else
+					syntheticReadAccessors = new SyntheticAccessMethodBinding[otherBindings.length + 1];
+			}
+			syntheticReadAccessors[index] = 
+				((SourceTypeBinding)currentScope.enclosingSourceType().
+					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
+						addSyntheticMethod(fieldBinding, true);
+			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
+	}
+}
+/*
+ * No need to emulate access to protected fields since not implicitly accessed
+ */
+public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding) {
+	if (fieldBinding.isPrivate() && fieldBinding.declaringClass != currentScope.enclosingSourceType()) {
+		syntheticWriteAccessor = fieldBinding.getSyntheticWriteAccess();
+		currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this);
+	}
+}
+/**
+ * Normal field binding did not work, try to bind to a field of the delegate receiver.
+ */
+public TypeBinding reportError(BlockScope scope) {
+	if (binding instanceof ProblemFieldBinding) {
+		scope.problemReporter().invalidField(this, (FieldBinding) binding);
+	} else if (binding instanceof ProblemReferenceBinding) {
+		scope.problemReporter().invalidType(this, (TypeBinding) binding);
+	} else {
+		scope.problemReporter().unresolvableReference(this, binding);
+	}
+	return null;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// field and/or local are done before type lookups
+
+	// the only available value for the restrictiveFlag BEFORE
+	// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField 
+	this.receiverType = scope.enclosingSourceType();
+	
+	constant = Constant.NotAConstant;
+	if ((binding = scope.getBinding(tokens, bits & RestrictiveFlagMASK, this)).isValidBinding()) {
+		switch (bits & RestrictiveFlagMASK) {
+			case VARIABLE : //============only variable===========
+			case TYPE | VARIABLE :
+				if (binding instanceof LocalVariableBinding) {
+					if (!((LocalVariableBinding) binding).isFinal() && ((bits & DepthMASK) != 0))
+						scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) binding, this);
+					bits &= ~RestrictiveFlagMASK;  // clear bits
+					bits |= LOCAL;
+					return getOtherFieldBindings(scope);
+				}
+				if (binding instanceof FieldBinding) {
+					// check for forward references
+					FieldBinding fieldBinding = (FieldBinding) binding;
+					MethodScope methodScope = scope.methodScope() ;
+					if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
+						&& methodScope.fieldDeclarationIndex != MethodScope.NotInFieldDecl
+						&& fieldBinding.id >= methodScope.fieldDeclarationIndex) {
+							if ((!fieldBinding.isStatic() || methodScope.isStatic) && this.indexOfFirstFieldBinding == 1)
+								scope.problemReporter().forwardReference(this,0,scope.enclosingSourceType());
+					}					
+					bits &= ~RestrictiveFlagMASK;  // clear bits
+					bits |= FIELD;					
+					return getOtherFieldBindings(scope);
+				}
+
+				// thus it was a type
+				bits &= ~RestrictiveFlagMASK;  // clear bits
+				bits |= TYPE;				
+			case TYPE : //=============only type ==============
+				//deprecated test
+				if (isTypeUseDeprecated((TypeBinding) binding, scope))
+					scope.problemReporter().deprecatedType((TypeBinding) binding, this);
+				return (TypeBinding) binding;
+		}
+	}
+
+	//========error cases===============
+	return this.reportError(scope);
+}
+public void setFieldIndex(int index){
+
+	indexOfFirstFieldBinding = index ;
+}
+public String toStringExpression() {
+	/* slow speed */
+	StringBuffer buffer = new StringBuffer();
+	for (int i = 0; i < tokens.length; i++) {
+		buffer.append(tokens[i]);
+		if (i < (tokens.length - 1)) {
+			buffer.append("."/*nonNLS*/);
+		}
+	}
+	return buffer.toString();
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+public  String unboundReferenceErrorName(){
+
+	return new String(tokens[0]);}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
index 7b40115..ba98d9a 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
@@ -1,47 +1,44 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class QualifiedSuperReference extends QualifiedThisReference {
-public QualifiedSuperReference(TypeReference name, int pos, int sourceEnd) {
-	super(name, pos, sourceEnd);
-}
-public boolean isSuper() {
-	
-	return true;
-}
-public boolean isThis() {
-	
-	return false ;
-}
-public TypeBinding resolveType(BlockScope scope) {
-
-	super.resolveType(scope);
-	if (currentCompatibleType == null) return null; // error case
-	
-	if (scope.isJavaLangObject(currentCompatibleType)) {
-		scope.problemReporter().cannotUseSuperInJavaLangObject(this);
-		return null;
-	}
-	return currentCompatibleType.superclass();	
-}
-public String toStringExpression(){
-	/* slow code */
-	
-	return qualification.toString(0)+".super"/*nonNLS*/ ;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		qualification.traverse(visitor, blockScope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedSuperReference extends QualifiedThisReference {
+public QualifiedSuperReference(TypeReference name, int pos, int sourceEnd) {
+	super(name, pos, sourceEnd);
+}
+public boolean isSuper() {
+	
+	return true;
+}
+public boolean isThis() {
+	
+	return false ;
+}
+public TypeBinding resolveType(BlockScope scope) {
+
+	super.resolveType(scope);
+	if (currentCompatibleType == null) return null; // error case
+	
+	if (scope.isJavaLangObject(currentCompatibleType)) {
+		scope.problemReporter().cannotUseSuperInJavaLangObject(this);
+		return null;
+	}
+	return currentCompatibleType.superclass();	
+}
+public String toStringExpression(){
+	/* slow code */
+	
+	return qualification.toString(0)+".super"/*nonNLS*/ ;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		qualification.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
index 45987d1..304dbd1 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
@@ -1,130 +1,129 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class QualifiedThisReference extends ThisReference {
-	public TypeReference qualification;
-
-	ReferenceBinding currentCompatibleType;
-public QualifiedThisReference(TypeReference name, int pos, int sourceEnd) {
-	qualification = name ;
-	this.sourceEnd = sourceEnd;
-	this.sourceStart = name.sourceStart;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	manageEnclosingInstanceAccessIfNecessary(currentScope);
-	return flowInfo;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
-	if (valueRequired) {
-		manageEnclosingInstanceAccessIfNecessary(currentScope);
-	}
-	return flowInfo;
-}
-protected boolean checkAccess(MethodScope methodScope, TypeBinding targetType) {
-	// this/super cannot be used in constructor call
-	if (methodScope.isConstructorCall) {
-		methodScope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this);
-		return false;
-	}
-
-	// static may not refer to this/super
-	if (methodScope.isStatic) {
-		methodScope.problemReporter().incorrectEnclosingInstanceReference(this, targetType);
-		return false;
-	}
-	return true;
-}
-/**
- * Code generation for QualifiedThisReference
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- * @param valueRequired boolean
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	if (valueRequired) {
-		if ((bits & DepthMASK) != 0) {
-			Object[] emulationPath = currentScope.getExactEmulationPath(currentCompatibleType);
-			if (emulationPath == null) {
-				// internal error, per construction we should have found it
-				currentScope.problemReporter().needImplementation();
-			} else {
-				codeStream.generateOuterAccess(emulationPath, this, currentScope);
-			}
-		} else {
-			// nothing particular after all
-			codeStream.aload_0();
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-	currentScope.emulateOuterAccess((SourceTypeBinding) currentCompatibleType, false); // request cascade of accesses
-}
-public TypeBinding resolveType(BlockScope scope) {
-	constant = NotAConstant;
-	TypeBinding qualificationTb = qualification.resolveType(scope);
-	if (qualificationTb == null)
-		return null;
-		
-	// the qualification MUST exactly match some enclosing type name
-	// Its possible to qualify 'this' by the name of the current class
-	int depth = 0;
-	currentCompatibleType = scope.referenceType().binding;
-	while (currentCompatibleType != null && currentCompatibleType != qualificationTb) {
-		depth++;
-		currentCompatibleType = currentCompatibleType.isStatic() ? null : currentCompatibleType.enclosingType();
-	}
-	bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits
-	
-	if (currentCompatibleType == null) {
-		scope.problemReporter().incorrectEnclosingInstanceReference(this, qualificationTb);
-		return null;
-	}
-
-	// Ensure one cannot write code like: B() { super(B.this); }
-	if (depth == 0) {
-		if (!checkAccess(scope.methodScope(), qualificationTb))
-			return null;
-	} else {
-		// Could also be targeting an enclosing instance inside a super constructor invocation
-		//	class X {
-		//		public X(int i) {
-		//			this(new Object() { Object obj = X.this; });
-		//		}
-		//	}
-
-		MethodScope methodScope = scope.methodScope();
-		while (methodScope != null) {
-			if (methodScope.enclosingSourceType() == currentCompatibleType) {
-				if (!this.checkAccess(methodScope, qualificationTb))
-					return null;
-				break;
-			}
-			methodScope = methodScope.parent.methodScope();
-		}
-	}
-	return qualificationTb;
-}
-public String toStringExpression(){
-	/* slow code */
-	
-	return qualification.toString(0)+".this"/*nonNLS*/ ;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		qualification.traverse(visitor, blockScope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedThisReference extends ThisReference {
+	public TypeReference qualification;
+
+	ReferenceBinding currentCompatibleType;
+public QualifiedThisReference(TypeReference name, int pos, int sourceEnd) {
+	qualification = name ;
+	this.sourceEnd = sourceEnd;
+	this.sourceStart = name.sourceStart;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	manageEnclosingInstanceAccessIfNecessary(currentScope);
+	return flowInfo;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	if (valueRequired) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope);
+	}
+	return flowInfo;
+}
+protected boolean checkAccess(MethodScope methodScope, TypeBinding targetType) {
+	// this/super cannot be used in constructor call
+	if (methodScope.isConstructorCall) {
+		methodScope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this);
+		return false;
+	}
+
+	// static may not refer to this/super
+	if (methodScope.isStatic) {
+		methodScope.problemReporter().incorrectEnclosingInstanceReference(this, targetType);
+		return false;
+	}
+	return true;
+}
+/**
+ * Code generation for QualifiedThisReference
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		if ((bits & DepthMASK) != 0) {
+			Object[] emulationPath = currentScope.getExactEmulationPath(currentCompatibleType);
+			if (emulationPath == null) {
+				// internal error, per construction we should have found it
+				currentScope.problemReporter().needImplementation();
+			} else {
+				codeStream.generateOuterAccess(emulationPath, this, currentScope);
+			}
+		} else {
+			// nothing particular after all
+			codeStream.aload_0();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+	currentScope.emulateOuterAccess((SourceTypeBinding) currentCompatibleType, false); // request cascade of accesses
+}
+public TypeBinding resolveType(BlockScope scope) {
+	constant = NotAConstant;
+	TypeBinding qualificationTb = qualification.resolveType(scope);
+	if (qualificationTb == null)
+		return null;
+		
+	// the qualification MUST exactly match some enclosing type name
+	// Its possible to qualify 'this' by the name of the current class
+	int depth = 0;
+	currentCompatibleType = scope.referenceType().binding;
+	while (currentCompatibleType != null && currentCompatibleType != qualificationTb) {
+		depth++;
+		currentCompatibleType = currentCompatibleType.isStatic() ? null : currentCompatibleType.enclosingType();
+	}
+	bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits
+	
+	if (currentCompatibleType == null) {
+		scope.problemReporter().incorrectEnclosingInstanceReference(this, qualificationTb);
+		return null;
+	}
+
+	// Ensure one cannot write code like: B() { super(B.this); }
+	if (depth == 0) {
+		if (!checkAccess(scope.methodScope(), qualificationTb))
+			return null;
+	} else {
+		// Could also be targeting an enclosing instance inside a super constructor invocation
+		//	class X {
+		//		public X(int i) {
+		//			this(new Object() { Object obj = X.this; });
+		//		}
+		//	}
+
+		MethodScope methodScope = scope.methodScope();
+		while (methodScope != null) {
+			if (methodScope.enclosingSourceType() == currentCompatibleType) {
+				if (!this.checkAccess(methodScope, qualificationTb))
+					return null;
+				break;
+			}
+			methodScope = methodScope.parent.methodScope();
+		}
+	}
+	return qualificationTb;
+}
+public String toStringExpression(){
+	/* slow code */
+	
+	return qualification.toString(0)+".this"/*nonNLS*/ ;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		qualification.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index cb2ccca..f97f238 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -1,57 +1,56 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class QualifiedTypeReference extends TypeReference {
-	public char[][] tokens;
-	public long[] sourcePositions;
-public QualifiedTypeReference(char[][] sources , long[] poss) {
-	tokens = sources ;
-	sourcePositions = poss ;
-	sourceStart = (int) (sourcePositions[0]>>>32) ;
-	sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFFL ) ;
-}
-public QualifiedTypeReference(char[][] sources , TypeBinding tb , long[] poss) {
-	this(sources,poss);
-	binding = tb;
-}
-public TypeReference copyDims(int dim){
-	//return a type reference copy of me with some dimensions
-	//warning : the new type ref has a null binding
-	
-	return new ArrayQualifiedTypeReference(tokens,null,dim,sourcePositions) ;
-}
-public TypeBinding getTypeBinding(Scope scope) {
-	if (binding != null)
-		return binding;
-	return scope.getType(tokens);
-}
-public char[][] getTypeName(){
-
-	return tokens;
-}
-public String toStringExpression(int tab) {
-	StringBuffer buffer = new StringBuffer();
-	for (int i = 0; i < tokens.length; i++) {
-		buffer.append(tokens[i]);
-		if (i < (tokens.length - 1)) {
-			buffer.append("."/*nonNLS*/);
-		}
-	}
-	return buffer.toString();
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedTypeReference extends TypeReference {
+	public char[][] tokens;
+	public long[] sourcePositions;
+public QualifiedTypeReference(char[][] sources , long[] poss) {
+	tokens = sources ;
+	sourcePositions = poss ;
+	sourceStart = (int) (sourcePositions[0]>>>32) ;
+	sourceEnd = (int)(sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFFL ) ;
+}
+public QualifiedTypeReference(char[][] sources , TypeBinding tb , long[] poss) {
+	this(sources,poss);
+	binding = tb;
+}
+public TypeReference copyDims(int dim){
+	//return a type reference copy of me with some dimensions
+	//warning : the new type ref has a null binding
+	
+	return new ArrayQualifiedTypeReference(tokens,null,dim,sourcePositions) ;
+}
+public TypeBinding getTypeBinding(Scope scope) {
+	if (binding != null)
+		return binding;
+	return scope.getType(tokens);
+}
+public char[][] getTypeName(){
+
+	return tokens;
+}
+public String toStringExpression(int tab) {
+	StringBuffer buffer = new StringBuffer();
+	for (int i = 0; i < tokens.length; i++) {
+		buffer.append(tokens[i]);
+		if (i < (tokens.length - 1)) {
+			buffer.append("."/*nonNLS*/);
+		}
+	}
+	return buffer.toString();
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
index c69fd1e..f4d0779 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -1,72 +1,71 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-public abstract class Reference extends Expression  {
-/**
- * BaseLevelReference constructor comment.
- */
-public Reference() {
-	super();
-}
-public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
-	throw new ShouldNotImplement(Util.bind("ast.variableShouldProvide"/*nonNLS*/));
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return flowInfo;
-}
-public FieldBinding fieldBinding() {
-	//this method should be sent ONLY after a check against isFieldReference()
-	//check its use doing senders.........
-
-	return null ;
-}
-public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) {
-
-	if (fieldBinding.isStatic()) {
-		if (valueRequired) {
-			if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
-				codeStream.dup2();
-			} else {
-				codeStream.dup();
-			}
-		}
-		if (syntheticWriteAccessor == null) {
-			codeStream.putstatic(fieldBinding);
-		} else {
-			codeStream.invokestatic(syntheticWriteAccessor);
-		}
-	} else { // Stack:  [owner][new field value]  ---> [new field value][owner][new field value]
-		if (valueRequired) {
-			if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
-				codeStream.dup2_x1();
-			} else {
-				codeStream.dup_x1();
-			}
-		}
-		if (syntheticWriteAccessor == null) {
-			codeStream.putfield(fieldBinding);
-		} else {
-			codeStream.invokestatic(syntheticWriteAccessor);
-		}
-	}
-}
-public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
-	throw new ShouldNotImplement(Util.bind("ast.compoundPreShouldProvide"/*nonNLS*/));
-}
-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
-	throw new ShouldNotImplement(Util.bind("ast.compoundVariableShouldProvide"/*nonNLS*/));
-}
-public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
-	throw new ShouldNotImplement(Util.bind("ast.postIncrShouldProvide"/*nonNLS*/));
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public abstract class Reference extends Expression  {
+/**
+ * BaseLevelReference constructor comment.
+ */
+public Reference() {
+	super();
+}
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+	throw new ShouldNotImplement(Util.bind("ast.variableShouldProvide"/*nonNLS*/));
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return flowInfo;
+}
+public FieldBinding fieldBinding() {
+	//this method should be sent ONLY after a check against isFieldReference()
+	//check its use doing senders.........
+
+	return null ;
+}
+public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) {
+
+	if (fieldBinding.isStatic()) {
+		if (valueRequired) {
+			if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
+				codeStream.dup2();
+			} else {
+				codeStream.dup();
+			}
+		}
+		if (syntheticWriteAccessor == null) {
+			codeStream.putstatic(fieldBinding);
+		} else {
+			codeStream.invokestatic(syntheticWriteAccessor);
+		}
+	} else { // Stack:  [owner][new field value]  ---> [new field value][owner][new field value]
+		if (valueRequired) {
+			if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
+				codeStream.dup2_x1();
+			} else {
+				codeStream.dup_x1();
+			}
+		}
+		if (syntheticWriteAccessor == null) {
+			codeStream.putfield(fieldBinding);
+		} else {
+			codeStream.invokestatic(syntheticWriteAccessor);
+		}
+	}
+}
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	throw new ShouldNotImplement(Util.bind("ast.compoundPreShouldProvide"/*nonNLS*/));
+}
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	throw new ShouldNotImplement(Util.bind("ast.compoundVariableShouldProvide"/*nonNLS*/));
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	throw new ShouldNotImplement(Util.bind("ast.postIncrShouldProvide"/*nonNLS*/));
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 633908b..949c096 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -5,7 +5,6 @@
  * All Rights Reserved.
  */
 import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 3f9b1d6..d88300d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -1,658 +1,658 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class SingleNameReference extends NameReference implements OperatorIds {
-	public char[] token;
-
-	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
-	public static final int READ = 0;
-	public static final int WRITE = 1;
-public SingleNameReference(char[] source, long pos) {
-	super();
-	token = source;
-	sourceStart = (int) (pos >>> 32);
-	sourceEnd = (int) pos;
-}
-public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
-
-	// compound assignment extra work
-	if (isCompound) { // check the variable part is initialized if blank final
-		switch (bits & RestrictiveFlagMASK) {
-			case FIELD : // reading a field
-				FieldBinding fieldBinding;
-				if ((fieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
-					if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
-						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
-						// we could improve error msg here telling "cannot use compound assignment on final blank field"
-					}
-				}
-				manageSyntheticReadAccessIfNecessary(currentScope);
-				break;
-			case LOCAL : // reading a local variable
-				// check if assigning a final blank field
-				LocalVariableBinding localBinding;
-				if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
-					currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
-					// we could improve error msg here telling "cannot use compound assignment on final local variable"
-				}
-				if (!flowInfo.isFakeReachable()) localBinding.used = true;
-		}
-	}
-	if (assignment.expression != null) {
-		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
-	}
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // assigning to a field
-			manageSyntheticWriteAccessIfNecessary(currentScope);
-
-			// check if assigning a final field
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding) binding).isFinal()) {
-				// inside a context where allowed
-				if (currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
-					if (flowInfo.isPotentiallyAssigned(fieldBinding)) {
-						currentScope.problemReporter().duplicateInitializationOfBlankFinalField(fieldBinding, this);
-					}
-					flowInfo.markAsDefinitelyAssigned(fieldBinding);
-					flowContext.recordSettingFinal(fieldBinding, this);						
-				} else {
-					currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this);
-				}
-			}
-			break;
-		case LOCAL : // assigning to a local variable 
-			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-			if (!flowInfo.isDefinitelyAssigned(localBinding)){// for local variable debug attributes
-				bits |= FirstAssignmentToLocalMASK;
-			} else {
-				bits &= ~FirstAssignmentToLocalMASK;
-			}
-			if (localBinding.isFinal()) {
-				if ((bits & DepthMASK) == 0) {
-					if (flowInfo.isPotentiallyAssigned(localBinding)) {
-						currentScope.problemReporter().duplicateInitializationOfFinalLocal(localBinding, this);
-					}
-					flowContext.recordSettingFinal(localBinding, this);								
-				} else {
-					currentScope.problemReporter().cannotAssignToFinalOuterLocal(localBinding, this);
-				}
-			}
-			flowInfo.markAsDefinitelyAssigned(localBinding);
-	}
-	manageEnclosingInstanceAccessIfNecessary(currentScope);
-	return flowInfo;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return analyseCode(currentScope, flowContext, flowInfo, true);
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // reading a field
-			if (valueRequired) {
-				manageSyntheticReadAccessIfNecessary(currentScope);
-			}
-			// check if reading a final blank field
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
-				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
-					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
-				}
-			}
-			break;
-		case LOCAL : // reading a local variable
-			LocalVariableBinding localBinding;
-			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
-				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
-			}
-			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
-	}
-	if (valueRequired) {
-		manageEnclosingInstanceAccessIfNecessary(currentScope);
-	}
-	return flowInfo;
-}
-public TypeBinding checkFieldAccess(BlockScope scope) {
-
-	FieldBinding fieldBinding = (FieldBinding) binding;
-	
-	bits &= ~RestrictiveFlagMASK; // clear bits
-	bits |= FIELD;
-	if (!((FieldBinding) binding).isStatic()) {
-		// must check for the static status....
-		if (scope.methodScope().isStatic) {
-			scope.problemReporter().staticFieldAccessToNonStaticVariable(
-				this,
-				fieldBinding);
-			constant = NotAConstant;
-			return null;
-		}
-	}
-	constant = FieldReference.getConstantFor(fieldBinding, true, this, 0);
-	if (isFieldUseDeprecated(fieldBinding, scope))
-		scope.problemReporter().deprecatedField(fieldBinding, this);
-	// if the binding declaring class is not visible, need special action
-	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
-	if (fieldBinding.declaringClass != null
-		&& fieldBinding.constant == NotAConstant
-		&& !fieldBinding.declaringClass.canBeSeenBy(scope))
-		binding = new FieldBinding(fieldBinding, scope.enclosingSourceType());
-
-	//===============================================
-	//cycle are forbidden ONLY within the same class...why ?????? (poor javac....)
-	//Cycle can be done using cross class ref but not direct into a same class reference ????
-	//class A {	static int k = B.k+1;}
-	//class B {	static int k = A.k+2;}
-	//The k-cycle in this example is valid.
-
-	//class C { static int k = k + 1 ;}
-	//here it is forbidden ! ????
-	//but the next one is valid !!!
-	//class C { static int k = C.k + 1;}
-
-	//notice that the next one is also valid ?!?!
-	//class A {	static int k = foo().k+1 ; static A foo(){return new A();}}
-
-	//for all these reasons, the next piece of code is only here and not
-	//commun for all FieldRef and QualifiedNameRef....(i.e. in the getField(..) API.....
-
-	//instance field may refer to forward static field, like in
-	//int i = staticI;
-	//static int staticI = 2 ;
-
-	MethodScope ms = scope.methodScope();
-	if (ms.enclosingSourceType() == fieldBinding.declaringClass
-		&& ms.fieldDeclarationIndex != ms.NotInFieldDecl
-		&& fieldBinding.id >= ms.fieldDeclarationIndex) {
-		//if the field is static and ms is not .... then it is valid
-		if (!fieldBinding.isStatic() || ms.isStatic)
-			scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
-	}
-	//====================================================
-
-	return fieldBinding.type;
-
-}
-public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
-
-	// optimizing assignment like: i = i + 1 or i = 1 + i
-	if (assignment.expression.isCompactableOperation()) {
-		BinaryExpression operation = (BinaryExpression) assignment.expression;
-		SingleNameReference variableReference;
-		if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) {
-			// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
-			variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.left.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
-			return;
-		}
-		int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
-		if ((operation.right instanceof SingleNameReference)
-			&& ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
-			&& ((variableReference = (SingleNameReference) operation.right).binding == binding)
-			&& (operation.left.constant != NotAConstant) // exclude non constant expressions, since could have side-effect
-			&& ((operation.left.implicitConversion >> 4) != T_String) // exclude string concatenation which would occur backwards
-			&& ((operation.right.implicitConversion >> 4) != T_String)) { // exclude string concatenation which would occur backwards
-			// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
-			variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.right.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
-			return;
-		}
-	}
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // assigning to a field
-			FieldBinding fieldBinding;
-			if (!(fieldBinding = (FieldBinding) binding).isStatic()) { // need a receiver?
-				if ((bits & DepthMASK) != 0) {
-					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-					if (emulationPath == null) {
-						// internal error, per construction we should have found it
-						currentScope.problemReporter().needImplementation();
-					} else {
-						codeStream.generateOuterAccess(emulationPath, this, currentScope);
-					}
-				} else {
-					this.generateReceiver(codeStream);
-				}
-			}
-			assignment.expression.generateCode(currentScope, codeStream, true);
-			fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], valueRequired);
-			if (valueRequired) {
-				codeStream.generateImplicitConversion(assignment.implicitConversion);
-			}
-			return;
-		case LOCAL : // assigning to a local variable
-			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-			if (localBinding.resolvedPosition != -1) {
-				assignment.expression.generateCode(currentScope, codeStream, true);
-			} else {
-				if (assignment.expression.constant != NotAConstant) {
-					// assigning an unused local to a constant value = no actual assignment is necessary
-					if (valueRequired) {
-						codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion);
-					}
-				} else {
-					assignment.expression.generateCode(currentScope, codeStream, true);
-					/* Even though the value may not be required, we force it to be produced, and discard it later
-					on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3.	*/
-					if (valueRequired) {
-						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
-					} else {
-						if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
-							codeStream.pop2();
-						} else {
-							codeStream.pop();
-						}
-					}
-				}
-				return;
-			}
-			// normal local assignment (since cannot store in outer local which are final locations)
-			codeStream.store(localBinding, valueRequired);
-			if ((bits & FirstAssignmentToLocalMASK) != 0) { // for local variable debug attributes
-				localBinding.recordInitializationStartPC(codeStream.position);
-			}
-			// implicit conversion
-			if (valueRequired) {
-				codeStream.generateImplicitConversion(assignment.implicitConversion);
-			}
-	}
-}
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-	int pc = codeStream.position;
-	if (constant != NotAConstant) {
-		if (valueRequired) {
-			codeStream.generateConstant(constant, implicitConversion);
-		}
-	} else {
-		switch (bits & RestrictiveFlagMASK) {
-			case FIELD : // reading a field
-				FieldBinding fieldBinding;
-				if (valueRequired) {
-					if ((fieldBinding = (FieldBinding) binding).constant == NotAConstant) { // directly use inlined value for constant fields
-						boolean isStatic;
-						if (!(isStatic = fieldBinding.isStatic())) {
-							if ((bits & DepthMASK) != 0) {
-								Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-								if (emulationPath == null) {
-									// internal error, per construction we should have found it
-									currentScope.problemReporter().needImplementation();
-								} else {
-									codeStream.generateOuterAccess(emulationPath, this, currentScope);
-								}
-							} else {
-								generateReceiver(codeStream);
-							}
-						}
-						// managing private access							
-						if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
-							if (isStatic) {
-								codeStream.getstatic(fieldBinding);
-							} else {
-								codeStream.getfield(fieldBinding);
-							}
-						} else {
-							codeStream.invokestatic(syntheticAccessors[READ]);
-						}
-						codeStream.generateImplicitConversion(implicitConversion);
-					} else { // directly use the inlined value
-						codeStream.generateConstant(fieldBinding.constant, implicitConversion);
-					}
-				}
-				break;
-			case LOCAL : // reading a local
-				LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-				if (valueRequired) {
-					// outer local?
-					if ((bits & DepthMASK) != 0) {
-						// outer local can be reached either through a synthetic arg or a synthetic field
-						VariableBinding[] path = currentScope.getEmulationPath(localBinding);
-						if (path == null) {
-							// emulation was not possible (should not happen per construction)
-							currentScope.problemReporter().needImplementation();
-						} else {
-							codeStream.generateOuterAccess(path, this, currentScope);
-						}
-					} else {
-						// regular local variable read
-						codeStream.load(localBinding);
-					}
-					codeStream.generateImplicitConversion(implicitConversion);
-				}
-		}
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-/*
- * Regular API for compound assignment, relies on the fact that there is only one reference to the
- * variable, which carries both synthetic read/write accessors.
- * The APIs with an extra argument is used whenever there are two references to the same variable which
- * are optimized in one access: e.g "a = a + 1" optimized into "a++".
- */
-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
-
-	this.generateCompoundAssignment(
-		currentScope, 
-		codeStream, 
-		syntheticAccessors == null ? null : syntheticAccessors[WRITE],
-		expression,
-		operator, 
-		assignmentImplicitConversion, 
-		valueRequired);
-}
-/*
- * The APIs with an extra argument is used whenever there are two references to the same variable which
- * are optimized in one access: e.g "a = a + 1" optimized into "a++".
- */
-public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // assigning to a field
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding) binding).isStatic()) {
-				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
-					codeStream.getstatic(fieldBinding);
-				} else {
-					codeStream.invokestatic(syntheticAccessors[READ]);
-				}
-			} else {
-				if ((bits & DepthMASK) != 0) {
-					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-					if (emulationPath == null) {
-						// internal error, per construction we should have found it
-						currentScope.problemReporter().needImplementation();
-					} else {
-						codeStream.generateOuterAccess(emulationPath, this, currentScope);
-					}
-				} else {
-					codeStream.aload_0();
-				}
-				codeStream.dup();
-				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
-					codeStream.getfield(fieldBinding);
-				} else {
-					codeStream.invokestatic(syntheticAccessors[READ]);
-				}
-			}
-			break;
-		case LOCAL : // assigning to a local variable (cannot assign to outer local)
-			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-			Constant assignConstant;
-			int increment;
-			// using incr bytecode if possible
-			switch (localBinding.type.id) {
-				case T_String :
-					codeStream.generateStringAppend(currentScope, this, expression);
-					if (valueRequired) {
-						codeStream.dup();
-					}
-					codeStream.store(localBinding, false);
-					return;
-				case T_int :
-					if (((assignConstant = expression.constant) != NotAConstant) && ((increment = assignConstant.intValue()) == (short) increment)) { // 16 bits value
-						switch (operator) {
-							case PLUS :
-								codeStream.iinc(localBinding.resolvedPosition, increment);
-								if (valueRequired) {
-									codeStream.load(localBinding);
-								}
-								return;
-							case MINUS :
-								codeStream.iinc(localBinding.resolvedPosition, -increment);
-								if (valueRequired) {
-									codeStream.load(localBinding);
-								}
-								return;
-						}
-					}
-				default :
-					codeStream.load(localBinding);
-			}
-	}
-	// perform the actual compound operation
-	int operationTypeID;
-	if ((operationTypeID = implicitConversion >> 4) == T_String || operationTypeID == T_Object) {
-		// we enter here if the single name reference is a field of type java.lang.String or if the type of the 
-		// operation is java.lang.Object
-		// For example: o = o + ""; // where the compiled type of o is java.lang.Object.
-		codeStream.generateStringAppend(currentScope, null, expression);
-	} else {
-		// promote the array reference to the suitable operation type
-		codeStream.generateImplicitConversion(implicitConversion);
-		// generate the increment value (will by itself  be promoted to the operation value)
-		if (expression == IntLiteral.One){ // prefix operation
-			codeStream.generateConstant(expression.constant, implicitConversion);			
-		} else {
-			expression.generateCode(currentScope, codeStream, true);
-		}		
-		// perform the operation
-		codeStream.sendOperator(operator, operationTypeID);
-		// cast the value back to the array reference type
-		codeStream.generateImplicitConversion(assignmentImplicitConversion);
-	}
-	// store the result back into the variable
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // assigning to a field
-			fieldStore(codeStream, (FieldBinding) binding, writeAccessor, valueRequired);
-			return;
-		case LOCAL : // assigning to a local variable
-			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-			if (valueRequired) {
-				if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
-					codeStream.dup2();
-				} else {
-					codeStream.dup();
-				}
-			}
-			codeStream.store(localBinding, false);
-	}
-}
-public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD : // assigning to a field
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding) binding).isStatic()) {
-				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
-					codeStream.getstatic(fieldBinding);
-				} else {
-					codeStream.invokestatic(syntheticAccessors[READ]);
-				}
-			} else {
-				if ((bits & DepthMASK) != 0) {
-					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
-					if (emulationPath == null) {
-						// internal error, per construction we should have found it
-						currentScope.problemReporter().needImplementation();
-					} else {
-						codeStream.generateOuterAccess(emulationPath, this, currentScope);
-					}
-				} else {
-					codeStream.aload_0();
-				}
-				codeStream.dup();
-				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
-					codeStream.getfield(fieldBinding);
-				} else {
-					codeStream.invokestatic(syntheticAccessors[READ]);
-				}
-			}
-			if (valueRequired) {
-				if (fieldBinding.isStatic()) {
-					if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
-						codeStream.dup2();
-					} else {
-						codeStream.dup();
-					}
-				} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
-					if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
-						codeStream.dup2_x1();
-					} else {
-						codeStream.dup_x1();
-					}
-				}
-			}
-			codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
-			codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id);
-			codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
-			fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false);
-			return;
-		case LOCAL : // assigning to a local variable
-			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
-			// using incr bytecode if possible
-			if (localBinding.type == IntBinding) {
-				if (valueRequired) {
-					codeStream.load(localBinding);
-				}
-				if (postIncrement.operator == PLUS) {
-					codeStream.iinc(localBinding.resolvedPosition, 1);
-				} else {
-					codeStream.iinc(localBinding.resolvedPosition, -1);
-				}
-			} else {
-				codeStream.load(localBinding);
-				if (valueRequired){
-					if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
-						codeStream.dup2();
-					} else {
-						codeStream.dup();
-					}
-				}
-				codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
-				codeStream.sendOperator(postIncrement.operator, localBinding.type.id);
-				codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
-
-				codeStream.store(localBinding, false);
-			}
-	}
-}
-public void generateReceiver(CodeStream codeStream) {
-	codeStream.aload_0();
-}
-public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
-
-	//If inlinable field, forget the access emulation, the code gen will directly target it
-	if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) return;
-
-	switch (bits & RestrictiveFlagMASK) {
-		case FIELD :
-			FieldBinding fieldBinding;
-			if ((fieldBinding = (FieldBinding)binding).isStatic() || (fieldBinding.constant != NotAConstant)) return;
-			ReferenceBinding compatibleType = currentScope.enclosingSourceType();
-			// the declaringClass of the target binding must be compatible with the enclosing
-			// type at <depth> levels outside
-			for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
-				compatibleType = compatibleType.enclosingType();
-			}
-			currentScope.emulateOuterAccess(compatibleType, false); // request cascade of accesses
-			break;
-		case LOCAL :
-			currentScope.emulateOuterAccess((LocalVariableBinding) binding);
-	}
-}
-public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope) {
-
-	//If inlinable field, forget the access emulation, the code gen will directly target it
-	if (constant != NotAConstant)
-		return;
-
-	if ((bits & FIELD) != 0) {
-		FieldBinding fieldBinding = (FieldBinding) binding;
-		if (((bits & DepthMASK) != 0)
-			&& (fieldBinding.isPrivate() // private access
-				|| (fieldBinding.isProtected() // implicit protected access
-						&& fieldBinding.declaringClass.getPackage() 
-							!= currentScope.enclosingSourceType().getPackage()))) {
-			if (syntheticAccessors == null)
-				syntheticAccessors = new MethodBinding[2];
-			syntheticAccessors[READ] = 
-				((SourceTypeBinding)currentScope.enclosingSourceType().
-					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
-						addSyntheticMethod(fieldBinding, true);
-			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
-		}
-	}
-}
-public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope) {
-
-	if ((bits & FIELD) != 0) {
-		FieldBinding fieldBinding = (FieldBinding) binding;
-		if (((bits & DepthMASK) != 0) 
-			&& (fieldBinding.isPrivate() // private access
-				|| (fieldBinding.isProtected() // implicit protected access
-						&& fieldBinding.declaringClass.getPackage() 
-							!= currentScope.enclosingSourceType().getPackage()))) {
-			if (syntheticAccessors == null)
-				syntheticAccessors = new MethodBinding[2];
-			syntheticAccessors[WRITE] = 
-				((SourceTypeBinding)currentScope.enclosingSourceType().
-					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
-						addSyntheticMethod(fieldBinding, false);
-			currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this);
-		}
-	}
-}
-public TypeBinding reportError(BlockScope scope) {
-	//=====error cases=======
-	constant = Constant.NotAConstant;
-	if (binding instanceof ProblemFieldBinding) {
-		scope.problemReporter().invalidField(this, (FieldBinding) binding);
-	} else if (binding instanceof ProblemReferenceBinding) {
-		scope.problemReporter().invalidType(this, (TypeBinding) binding);
-	} else {
-		scope.problemReporter().unresolvableReference(this, binding);
-	}
-	return null;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// for code gen, harm the restrictiveFlag 	
-
-	this.receiverType = scope.enclosingSourceType();
-	
-	if ((binding = scope.getBinding(token, bits & RestrictiveFlagMASK, this)).isValidBinding()) {
-		switch (bits & RestrictiveFlagMASK) {
-			case VARIABLE : // =========only variable============
-			case VARIABLE | TYPE : //====both variable and type============
-				if (binding instanceof VariableBinding) {
-					VariableBinding vb = (VariableBinding) binding;
-					if (binding instanceof LocalVariableBinding) {
-						bits &= ~RestrictiveFlagMASK;  // clear bits
-						bits |= LOCAL;
-						constant = vb.constant;
-						if ((!vb.isFinal()) && ((bits & DepthMASK) != 0))
-							scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)vb, this);
-						return vb.type;
-					}
-					// a field
-					return checkFieldAccess(scope);
-				}
-
-				// thus it was a type
-				bits &= ~RestrictiveFlagMASK;  // clear bits
-				bits |= TYPE;
-			case TYPE : //========only type==============
-				constant = Constant.NotAConstant;
-				//deprecated test
-				if (isTypeUseDeprecated((TypeBinding) binding, scope))
-					scope.problemReporter().deprecatedType((TypeBinding) binding, this);
-				return (TypeBinding) binding;
-		}
-	}
-
-	// error scenarii
-	return this.reportError(scope);
-}
-public String toStringExpression(){
-
-	return new String(token);}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-public String unboundReferenceErrorName(){
-
-	return new String(token);}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SingleNameReference extends NameReference implements OperatorIds {
+	public char[] token;
+
+	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
+	public static final int READ = 0;
+	public static final int WRITE = 1;
+public SingleNameReference(char[] source, long pos) {
+	super();
+	token = source;
+	sourceStart = (int) (pos >>> 32);
+	sourceEnd = (int) pos;
+}
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+
+	// compound assignment extra work
+	if (isCompound) { // check the variable part is initialized if blank final
+		switch (bits & RestrictiveFlagMASK) {
+			case FIELD : // reading a field
+				FieldBinding fieldBinding;
+				if ((fieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
+					if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
+						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+						// we could improve error msg here telling "cannot use compound assignment on final blank field"
+					}
+				}
+				manageSyntheticReadAccessIfNecessary(currentScope);
+				break;
+			case LOCAL : // reading a local variable
+				// check if assigning a final blank field
+				LocalVariableBinding localBinding;
+				if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
+					currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+					// we could improve error msg here telling "cannot use compound assignment on final local variable"
+				}
+				if (!flowInfo.isFakeReachable()) localBinding.used = true;
+		}
+	}
+	if (assignment.expression != null) {
+		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+	}
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // assigning to a field
+			manageSyntheticWriteAccessIfNecessary(currentScope);
+
+			// check if assigning a final field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) binding).isFinal()) {
+				// inside a context where allowed
+				if (currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
+					if (flowInfo.isPotentiallyAssigned(fieldBinding)) {
+						currentScope.problemReporter().duplicateInitializationOfBlankFinalField(fieldBinding, this);
+					}
+					flowInfo.markAsDefinitelyAssigned(fieldBinding);
+					flowContext.recordSettingFinal(fieldBinding, this);						
+				} else {
+					currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this);
+				}
+			}
+			break;
+		case LOCAL : // assigning to a local variable 
+			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding)){// for local variable debug attributes
+				bits |= FirstAssignmentToLocalMASK;
+			} else {
+				bits &= ~FirstAssignmentToLocalMASK;
+			}
+			if (localBinding.isFinal()) {
+				if ((bits & DepthMASK) == 0) {
+					if (flowInfo.isPotentiallyAssigned(localBinding)) {
+						currentScope.problemReporter().duplicateInitializationOfFinalLocal(localBinding, this);
+					}
+					flowContext.recordSettingFinal(localBinding, this);								
+				} else {
+					currentScope.problemReporter().cannotAssignToFinalOuterLocal(localBinding, this);
+				}
+			}
+			flowInfo.markAsDefinitelyAssigned(localBinding);
+	}
+	manageEnclosingInstanceAccessIfNecessary(currentScope);
+	return flowInfo;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // reading a field
+			if (valueRequired) {
+				manageSyntheticReadAccessIfNecessary(currentScope);
+			}
+			// check if reading a final blank field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) binding).isFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
+				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
+					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+				}
+			}
+			break;
+		case LOCAL : // reading a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if (!flowInfo.isFakeReachable()) localBinding.used = true;			
+	}
+	if (valueRequired) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope);
+	}
+	return flowInfo;
+}
+public TypeBinding checkFieldAccess(BlockScope scope) {
+
+	FieldBinding fieldBinding = (FieldBinding) binding;
+	
+	bits &= ~RestrictiveFlagMASK; // clear bits
+	bits |= FIELD;
+	if (!((FieldBinding) binding).isStatic()) {
+		// must check for the static status....
+		if (scope.methodScope().isStatic) {
+			scope.problemReporter().staticFieldAccessToNonStaticVariable(
+				this,
+				fieldBinding);
+			constant = NotAConstant;
+			return null;
+		}
+	}
+	constant = FieldReference.getConstantFor(fieldBinding, true, this, 0);
+	if (isFieldUseDeprecated(fieldBinding, scope))
+		scope.problemReporter().deprecatedField(fieldBinding, this);
+	// if the binding declaring class is not visible, need special action
+	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+	if (fieldBinding.declaringClass != null
+		&& fieldBinding.constant == NotAConstant
+		&& !fieldBinding.declaringClass.canBeSeenBy(scope))
+		binding = new FieldBinding(fieldBinding, scope.enclosingSourceType());
+
+	//===============================================
+	//cycle are forbidden ONLY within the same class...why ?????? (poor javac....)
+	//Cycle can be done using cross class ref but not direct into a same class reference ????
+	//class A {	static int k = B.k+1;}
+	//class B {	static int k = A.k+2;}
+	//The k-cycle in this example is valid.
+
+	//class C { static int k = k + 1 ;}
+	//here it is forbidden ! ????
+	//but the next one is valid !!!
+	//class C { static int k = C.k + 1;}
+
+	//notice that the next one is also valid ?!?!
+	//class A {	static int k = foo().k+1 ; static A foo(){return new A();}}
+
+	//for all these reasons, the next piece of code is only here and not
+	//commun for all FieldRef and QualifiedNameRef....(i.e. in the getField(..) API.....
+
+	//instance field may refer to forward static field, like in
+	//int i = staticI;
+	//static int staticI = 2 ;
+
+	MethodScope ms = scope.methodScope();
+	if (ms.enclosingSourceType() == fieldBinding.declaringClass
+		&& ms.fieldDeclarationIndex != MethodScope.NotInFieldDecl
+		&& fieldBinding.id >= ms.fieldDeclarationIndex) {
+		//if the field is static and ms is not .... then it is valid
+		if (!fieldBinding.isStatic() || ms.isStatic)
+			scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
+	}
+	//====================================================
+
+	return fieldBinding.type;
+
+}
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+
+	// optimizing assignment like: i = i + 1 or i = 1 + i
+	if (assignment.expression.isCompactableOperation()) {
+		BinaryExpression operation = (BinaryExpression) assignment.expression;
+		SingleNameReference variableReference;
+		if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) {
+			// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.left.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+			return;
+		}
+		int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
+		if ((operation.right instanceof SingleNameReference)
+			&& ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
+			&& ((variableReference = (SingleNameReference) operation.right).binding == binding)
+			&& (operation.left.constant != NotAConstant) // exclude non constant expressions, since could have side-effect
+			&& ((operation.left.implicitConversion >> 4) != T_String) // exclude string concatenation which would occur backwards
+			&& ((operation.right.implicitConversion >> 4) != T_String)) { // exclude string concatenation which would occur backwards
+			// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.right.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+			return;
+		}
+	}
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // assigning to a field
+			FieldBinding fieldBinding;
+			if (!(fieldBinding = (FieldBinding) binding).isStatic()) { // need a receiver?
+				if ((bits & DepthMASK) != 0) {
+					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+					if (emulationPath == null) {
+						// internal error, per construction we should have found it
+						currentScope.problemReporter().needImplementation();
+					} else {
+						codeStream.generateOuterAccess(emulationPath, this, currentScope);
+					}
+				} else {
+					this.generateReceiver(codeStream);
+				}
+			}
+			assignment.expression.generateCode(currentScope, codeStream, true);
+			fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			return;
+		case LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+			if (localBinding.resolvedPosition != -1) {
+				assignment.expression.generateCode(currentScope, codeStream, true);
+			} else {
+				if (assignment.expression.constant != NotAConstant) {
+					// assigning an unused local to a constant value = no actual assignment is necessary
+					if (valueRequired) {
+						codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion);
+					}
+				} else {
+					assignment.expression.generateCode(currentScope, codeStream, true);
+					/* Even though the value may not be required, we force it to be produced, and discard it later
+					on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3.	*/
+					if (valueRequired) {
+						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
+					} else {
+						if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
+							codeStream.pop2();
+						} else {
+							codeStream.pop();
+						}
+					}
+				}
+				return;
+			}
+			// normal local assignment (since cannot store in outer local which are final locations)
+			codeStream.store(localBinding, valueRequired);
+			if ((bits & FirstAssignmentToLocalMASK) != 0) { // for local variable debug attributes
+				localBinding.recordInitializationStartPC(codeStream.position);
+			}
+			// implicit conversion
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+	}
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (constant != NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(constant, implicitConversion);
+		}
+	} else {
+		switch (bits & RestrictiveFlagMASK) {
+			case FIELD : // reading a field
+				FieldBinding fieldBinding;
+				if (valueRequired) {
+					if ((fieldBinding = (FieldBinding) binding).constant == NotAConstant) { // directly use inlined value for constant fields
+						boolean isStatic;
+						if (!(isStatic = fieldBinding.isStatic())) {
+							if ((bits & DepthMASK) != 0) {
+								Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+								if (emulationPath == null) {
+									// internal error, per construction we should have found it
+									currentScope.problemReporter().needImplementation();
+								} else {
+									codeStream.generateOuterAccess(emulationPath, this, currentScope);
+								}
+							} else {
+								generateReceiver(codeStream);
+							}
+						}
+						// managing private access							
+						if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
+							if (isStatic) {
+								codeStream.getstatic(fieldBinding);
+							} else {
+								codeStream.getfield(fieldBinding);
+							}
+						} else {
+							codeStream.invokestatic(syntheticAccessors[READ]);
+						}
+						codeStream.generateImplicitConversion(implicitConversion);
+					} else { // directly use the inlined value
+						codeStream.generateConstant(fieldBinding.constant, implicitConversion);
+					}
+				}
+				break;
+			case LOCAL : // reading a local
+				LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+				if (valueRequired) {
+					// outer local?
+					if ((bits & DepthMASK) != 0) {
+						// outer local can be reached either through a synthetic arg or a synthetic field
+						VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+						if (path == null) {
+							// emulation was not possible (should not happen per construction)
+							currentScope.problemReporter().needImplementation();
+						} else {
+							codeStream.generateOuterAccess(path, this, currentScope);
+						}
+					} else {
+						// regular local variable read
+						codeStream.load(localBinding);
+					}
+					codeStream.generateImplicitConversion(implicitConversion);
+				}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+/*
+ * Regular API for compound assignment, relies on the fact that there is only one reference to the
+ * variable, which carries both synthetic read/write accessors.
+ * The APIs with an extra argument is used whenever there are two references to the same variable which
+ * are optimized in one access: e.g "a = a + 1" optimized into "a++".
+ */
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+
+	this.generateCompoundAssignment(
+		currentScope, 
+		codeStream, 
+		syntheticAccessors == null ? null : syntheticAccessors[WRITE],
+		expression,
+		operator, 
+		assignmentImplicitConversion, 
+		valueRequired);
+}
+/*
+ * The APIs with an extra argument is used whenever there are two references to the same variable which
+ * are optimized in one access: e.g "a = a + 1" optimized into "a++".
+ */
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // assigning to a field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) binding).isStatic()) {
+				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
+					codeStream.getstatic(fieldBinding);
+				} else {
+					codeStream.invokestatic(syntheticAccessors[READ]);
+				}
+			} else {
+				if ((bits & DepthMASK) != 0) {
+					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+					if (emulationPath == null) {
+						// internal error, per construction we should have found it
+						currentScope.problemReporter().needImplementation();
+					} else {
+						codeStream.generateOuterAccess(emulationPath, this, currentScope);
+					}
+				} else {
+					codeStream.aload_0();
+				}
+				codeStream.dup();
+				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
+					codeStream.getfield(fieldBinding);
+				} else {
+					codeStream.invokestatic(syntheticAccessors[READ]);
+				}
+			}
+			break;
+		case LOCAL : // assigning to a local variable (cannot assign to outer local)
+			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+			Constant assignConstant;
+			int increment;
+			// using incr bytecode if possible
+			switch (localBinding.type.id) {
+				case T_String :
+					codeStream.generateStringAppend(currentScope, this, expression);
+					if (valueRequired) {
+						codeStream.dup();
+					}
+					codeStream.store(localBinding, false);
+					return;
+				case T_int :
+					if (((assignConstant = expression.constant) != NotAConstant) && ((increment = assignConstant.intValue()) == (short) increment)) { // 16 bits value
+						switch (operator) {
+							case PLUS :
+								codeStream.iinc(localBinding.resolvedPosition, increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+							case MINUS :
+								codeStream.iinc(localBinding.resolvedPosition, -increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+						}
+					}
+				default :
+					codeStream.load(localBinding);
+			}
+	}
+	// perform the actual compound operation
+	int operationTypeID;
+	if ((operationTypeID = implicitConversion >> 4) == T_String || operationTypeID == T_Object) {
+		// we enter here if the single name reference is a field of type java.lang.String or if the type of the 
+		// operation is java.lang.Object
+		// For example: o = o + ""; // where the compiled type of o is java.lang.Object.
+		codeStream.generateStringAppend(currentScope, null, expression);
+	} else {
+		// promote the array reference to the suitable operation type
+		codeStream.generateImplicitConversion(implicitConversion);
+		// generate the increment value (will by itself  be promoted to the operation value)
+		if (expression == IntLiteral.One){ // prefix operation
+			codeStream.generateConstant(expression.constant, implicitConversion);			
+		} else {
+			expression.generateCode(currentScope, codeStream, true);
+		}		
+		// perform the operation
+		codeStream.sendOperator(operator, operationTypeID);
+		// cast the value back to the array reference type
+		codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// store the result back into the variable
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // assigning to a field
+			fieldStore(codeStream, (FieldBinding) binding, writeAccessor, valueRequired);
+			return;
+		case LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+			if (valueRequired) {
+				if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
+					codeStream.dup2();
+				} else {
+					codeStream.dup();
+				}
+			}
+			codeStream.store(localBinding, false);
+	}
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD : // assigning to a field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) binding).isStatic()) {
+				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
+					codeStream.getstatic(fieldBinding);
+				} else {
+					codeStream.invokestatic(syntheticAccessors[READ]);
+				}
+			} else {
+				if ((bits & DepthMASK) != 0) {
+					Object[] emulationPath = currentScope.getExactEmulationPath(currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT));
+					if (emulationPath == null) {
+						// internal error, per construction we should have found it
+						currentScope.problemReporter().needImplementation();
+					} else {
+						codeStream.generateOuterAccess(emulationPath, this, currentScope);
+					}
+				} else {
+					codeStream.aload_0();
+				}
+				codeStream.dup();
+				if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) {
+					codeStream.getfield(fieldBinding);
+				} else {
+					codeStream.invokestatic(syntheticAccessors[READ]);
+				}
+			}
+			if (valueRequired) {
+				if (fieldBinding.isStatic()) {
+					if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
+						codeStream.dup2();
+					} else {
+						codeStream.dup();
+					}
+				} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+					if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
+						codeStream.dup2_x1();
+					} else {
+						codeStream.dup_x1();
+					}
+				}
+			}
+			codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
+			codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id);
+			codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+			fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false);
+			return;
+		case LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) binding;
+			// using incr bytecode if possible
+			if (localBinding.type == IntBinding) {
+				if (valueRequired) {
+					codeStream.load(localBinding);
+				}
+				if (postIncrement.operator == PLUS) {
+					codeStream.iinc(localBinding.resolvedPosition, 1);
+				} else {
+					codeStream.iinc(localBinding.resolvedPosition, -1);
+				}
+			} else {
+				codeStream.load(localBinding);
+				if (valueRequired){
+					if ((localBinding.type == LongBinding) || (localBinding.type == DoubleBinding)) {
+						codeStream.dup2();
+					} else {
+						codeStream.dup();
+					}
+				}
+				codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
+				codeStream.sendOperator(postIncrement.operator, localBinding.type.id);
+				codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+
+				codeStream.store(localBinding, false);
+			}
+	}
+}
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+}
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
+
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (((bits & DepthMASK) == 0) || (constant != NotAConstant)) return;
+
+	switch (bits & RestrictiveFlagMASK) {
+		case FIELD :
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding)binding).isStatic() || (fieldBinding.constant != NotAConstant)) return;
+			ReferenceBinding compatibleType = currentScope.enclosingSourceType();
+			// the declaringClass of the target binding must be compatible with the enclosing
+			// type at <depth> levels outside
+			for (int i = 0, depth = (bits & DepthMASK) >> DepthSHIFT; i < depth; i++) {
+				compatibleType = compatibleType.enclosingType();
+			}
+			currentScope.emulateOuterAccess(compatibleType, false); // request cascade of accesses
+			break;
+		case LOCAL :
+			currentScope.emulateOuterAccess((LocalVariableBinding) binding);
+	}
+}
+public void manageSyntheticReadAccessIfNecessary(BlockScope currentScope) {
+
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (constant != NotAConstant)
+		return;
+
+	if ((bits & FIELD) != 0) {
+		FieldBinding fieldBinding = (FieldBinding) binding;
+		if (((bits & DepthMASK) != 0)
+			&& (fieldBinding.isPrivate() // private access
+				|| (fieldBinding.isProtected() // implicit protected access
+						&& fieldBinding.declaringClass.getPackage() 
+							!= currentScope.enclosingSourceType().getPackage()))) {
+			if (syntheticAccessors == null)
+				syntheticAccessors = new MethodBinding[2];
+			syntheticAccessors[READ] = 
+				((SourceTypeBinding)currentScope.enclosingSourceType().
+					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
+						addSyntheticMethod(fieldBinding, true);
+			currentScope.problemReporter().needToEmulateFieldReadAccess(fieldBinding, this);
+		}
+	}
+}
+public void manageSyntheticWriteAccessIfNecessary(BlockScope currentScope) {
+
+	if ((bits & FIELD) != 0) {
+		FieldBinding fieldBinding = (FieldBinding) binding;
+		if (((bits & DepthMASK) != 0) 
+			&& (fieldBinding.isPrivate() // private access
+				|| (fieldBinding.isProtected() // implicit protected access
+						&& fieldBinding.declaringClass.getPackage() 
+							!= currentScope.enclosingSourceType().getPackage()))) {
+			if (syntheticAccessors == null)
+				syntheticAccessors = new MethodBinding[2];
+			syntheticAccessors[WRITE] = 
+				((SourceTypeBinding)currentScope.enclosingSourceType().
+					enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).
+						addSyntheticMethod(fieldBinding, false);
+			currentScope.problemReporter().needToEmulateFieldWriteAccess(fieldBinding, this);
+		}
+	}
+}
+public TypeBinding reportError(BlockScope scope) {
+	//=====error cases=======
+	constant = Constant.NotAConstant;
+	if (binding instanceof ProblemFieldBinding) {
+		scope.problemReporter().invalidField(this, (FieldBinding) binding);
+	} else if (binding instanceof ProblemReferenceBinding) {
+		scope.problemReporter().invalidType(this, (TypeBinding) binding);
+	} else {
+		scope.problemReporter().unresolvableReference(this, binding);
+	}
+	return null;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// for code gen, harm the restrictiveFlag 	
+
+	this.receiverType = scope.enclosingSourceType();
+	
+	if ((binding = scope.getBinding(token, bits & RestrictiveFlagMASK, this)).isValidBinding()) {
+		switch (bits & RestrictiveFlagMASK) {
+			case VARIABLE : // =========only variable============
+			case VARIABLE | TYPE : //====both variable and type============
+				if (binding instanceof VariableBinding) {
+					VariableBinding vb = (VariableBinding) binding;
+					if (binding instanceof LocalVariableBinding) {
+						bits &= ~RestrictiveFlagMASK;  // clear bits
+						bits |= LOCAL;
+						constant = vb.constant;
+						if ((!vb.isFinal()) && ((bits & DepthMASK) != 0))
+							scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)vb, this);
+						return vb.type;
+					}
+					// a field
+					return checkFieldAccess(scope);
+				}
+
+				// thus it was a type
+				bits &= ~RestrictiveFlagMASK;  // clear bits
+				bits |= TYPE;
+			case TYPE : //========only type==============
+				constant = Constant.NotAConstant;
+				//deprecated test
+				if (isTypeUseDeprecated((TypeBinding) binding, scope))
+					scope.problemReporter().deprecatedType((TypeBinding) binding, this);
+				return (TypeBinding) binding;
+		}
+	}
+
+	// error scenarii
+	return this.reportError(scope);
+}
+public String toStringExpression(){
+
+	return new String(token);}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+public String unboundReferenceErrorName(){
+
+	return new String(token);}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
index 311709e..8dc1568 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -1,60 +1,59 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class SingleTypeReference extends TypeReference {
-	public char[] token;
-	
-
-public SingleTypeReference(char[] source, long pos) {
-		token = source;
-		sourceStart = (int) (pos>>>32)  ;
-		sourceEnd = (int) (pos & 0x00000000FFFFFFFFL) ;
-	
-}
-public SingleTypeReference(char[] source ,TypeBinding tb, long pos) {
-	this(source, pos) ;
-	binding = tb ;
-}
-public TypeReference copyDims(int dim){
-	//return a type reference copy of me with some dimensions
-	//warning : the new type ref has a null binding
-	
-	return new ArrayTypeReference(token,null,dim,(((long)sourceStart)<<32)+sourceEnd) ;
-}
-public TypeBinding getTypeBinding(Scope scope) {
-	if (binding != null)
-		return binding;
-	return scope.getType(token);
-}
-public char [][] getTypeName() {
-	return new char[][] { token };
-}
-public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
-	ReferenceBinding memberTb = scope.getMemberType(token, enclosingType);
-	if (!memberTb.isValidBinding()) {
-		scope.problemReporter().invalidEnclosingType(this, memberTb, enclosingType);
-		return null;
-	}
-	if (isTypeUseDeprecated(memberTb, scope))
-		scope.problemReporter().deprecatedType(memberTb, this);
-	return binding = memberTb;
-}
-public String toStringExpression(int tab){
-	return new String(token) ;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) {
-	visitor.visit(this, scope);
-	visitor.endVisit(this, scope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SingleTypeReference extends TypeReference {
+	public char[] token;
+	
+
+public SingleTypeReference(char[] source, long pos) {
+		token = source;
+		sourceStart = (int) (pos>>>32)  ;
+		sourceEnd = (int) (pos & 0x00000000FFFFFFFFL) ;
+	
+}
+public SingleTypeReference(char[] source ,TypeBinding tb, long pos) {
+	this(source, pos) ;
+	binding = tb ;
+}
+public TypeReference copyDims(int dim){
+	//return a type reference copy of me with some dimensions
+	//warning : the new type ref has a null binding
+	
+	return new ArrayTypeReference(token,null,dim,(((long)sourceStart)<<32)+sourceEnd) ;
+}
+public TypeBinding getTypeBinding(Scope scope) {
+	if (binding != null)
+		return binding;
+	return scope.getType(token);
+}
+public char [][] getTypeName() {
+	return new char[][] { token };
+}
+public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
+	ReferenceBinding memberTb = scope.getMemberType(token, enclosingType);
+	if (!memberTb.isValidBinding()) {
+		scope.problemReporter().invalidEnclosingType(this, memberTb, enclosingType);
+		return null;
+	}
+	if (isTypeUseDeprecated(memberTb, scope))
+		scope.problemReporter().deprecatedType(memberTb, this);
+	return binding = memberTb;
+}
+public String toStringExpression(int tab){
+	return new String(token) ;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 5060063..0145ca9 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -1,108 +1,103 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-public abstract class Statement extends AstNode {
-	// storage for internal flags (32 bits)
-	public int bits = IsReachableMASK; // reachable by default
-
-	// for operators only
-	// Reach . . . . . . . . . . . . . . . . . O O O O O O V VrR R R R
-	public static final int ReturnTypeIDMASK = 15; // 4 lower bits for operators
-	public static final int ValueForReturnMASK = 16; // for binary expressions
-	public static final int OnlyValueRequiredMASK = 32; // for binary expressions
-	public static final int OperatorSHIFT = 6;
-	public static final int OperatorMASK = 63 << OperatorSHIFT;
-	
-	// for name references only
-	// Reach . . . . . . . . . . . . . . . . D D D D D D D D VrF R R R
-	public static final int RestrictiveFlagMASK = 7; // 3 lower bits for name references
-	public static final int FirstAssignmentToLocalMASK = 8; // for single name references
-	public static final int DepthSHIFT = 5;
-	public static final int DepthMASK = 0xFF << DepthSHIFT; // 8 bits for actual depth value (max. 255)
-
-	// for statements only
-	public static final int IsReachableMASK = 0x80000000; // highest bit
-
-	/*
-	public final static int BitMask1= 0x1; // decimal 1
-	public final static int BitMask2= 0x2; // decimal 2
-	public final static int BitMask3= 0x4; // decimal 4
-	public final static int BitMask4= 0x8; // decimal 8
-	public final static int BitMask5= 0x10; // decimal 16
-	public final static int BitMask6= 0x20; // decimal 32
-	public final static int BitMask7= 0x40; // decimal 64
-	public final static int BitMask8= 0x80; // decimal 128
-	public final static int BitMask9= 0x100; // decimal 256
-	public final static int BitMask10= 0x200; // decimal 512
-	public final static int BitMask11= 0x400; // decimal 1024
-	public final static int BitMask12= 0x800; // decimal 2048
-	public final static int BitMask13= 0x1000; // decimal 4096
-	public final static int BitMask14= 0x2000; // decimal 8192
-	public final static int BitMask15= 0x4000; // decimal 16384
-	public final static int BitMask16= 0x8000; // decimal 32768
-	public final static int BitMask17= 0x10000; // decimal 65536
-	public final static int BitMask18= 0x20000; // decimal 131072
-	public final static int BitMask19= 0x40000; // decimal 262144
-	public final static int BitMask20= 0x80000; // decimal 524288
-	public final static int BitMask21= 0x100000; // decimal 1048576
-	public final static int BitMask22= 0x200000; // decimal 2097152
-	public final static int BitMask23= 0x400000; // decimal 4194304
-	public final static int BitMask24= 0x800000; // decimal 8388608
-	public final static int BitMask25= 0x1000000; // decimal 16777216
-	public final static int BitMask26= 0x2000000; // decimal 33554432
-	public final static int BitMask27= 0x4000000; // decimal 67108864
-	public final static int BitMask28= 0x8000000; // decimal 134217728
-	public final static int BitMask29= 0x10000000; // decimal 268435456
-	public final static int BitMask30= 0x20000000; // decimal 536870912
-	public final static int BitMask31= 0x40000000; // decimal 1073741824
-	public final static int BitMask32= 0x80000000; // decimal 2147483648	
-	*/
-/**
- * Statement constructor comment.
- */
-public Statement() {
-	super();
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return flowInfo;
-}
-public void generateCode(BlockScope currentScope, CodeStream codeStream){
-	throw new ShouldNotImplement(Util.bind("ast.missingStatement"/*nonNLS*/));
-}
-public boolean isEmptyBlock(){
-	return false;
-}
-public boolean isValidJavaStatement(){
-	//the use of this method should be avoid in most cases
-	//and is here mostly for documentation purpose.....
-	//while the parser is responsable for creating
-	//welled formed expression statement, which results
-	//in the fact that java-non-semantic-expression-used-as-statement
-	//should not be parsable...thus not being built.
-	//It sounds like the java grammar as help the compiler job in removing
-	//-by construction- some statement that would have no effect....
-	//(for example all expression that may do side-effects are valid statement
-	// -this is an appromative idea.....-)
-	
-
-	return true ;}
-public void resolve(BlockScope scope) {
-}
-public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
-	// statement within a switch that are not case are treated as normal statement.... 
-
-	resolve(scope);
-	return null;
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public abstract class Statement extends AstNode {
+	// storage for internal flags (32 bits)
+	public int bits = IsReachableMASK; // reachable by default
+
+	// for operators only
+	// Reach . . . . . . . . . . . . . . . . . O O O O O O V VrR R R R
+	public static final int ReturnTypeIDMASK = 15; // 4 lower bits for operators
+	public static final int ValueForReturnMASK = 16; // for binary expressions
+	public static final int OnlyValueRequiredMASK = 32; // for binary expressions
+	public static final int OperatorSHIFT = 6;
+	public static final int OperatorMASK = 63 << OperatorSHIFT;
+	
+	// for name references only
+	// Reach . . . . . . . . . . . . . . . . D D D D D D D D VrF R R R
+	public static final int RestrictiveFlagMASK = 7; // 3 lower bits for name references
+	public static final int FirstAssignmentToLocalMASK = 8; // for single name references
+	public static final int DepthSHIFT = 5;
+	public static final int DepthMASK = 0xFF << DepthSHIFT; // 8 bits for actual depth value (max. 255)
+
+	// for statements only
+	public static final int IsReachableMASK = 0x80000000; // highest bit
+
+	/*
+	public final static int BitMask1= 0x1; // decimal 1
+	public final static int BitMask2= 0x2; // decimal 2
+	public final static int BitMask3= 0x4; // decimal 4
+	public final static int BitMask4= 0x8; // decimal 8
+	public final static int BitMask5= 0x10; // decimal 16
+	public final static int BitMask6= 0x20; // decimal 32
+	public final static int BitMask7= 0x40; // decimal 64
+	public final static int BitMask8= 0x80; // decimal 128
+	public final static int BitMask9= 0x100; // decimal 256
+	public final static int BitMask10= 0x200; // decimal 512
+	public final static int BitMask11= 0x400; // decimal 1024
+	public final static int BitMask12= 0x800; // decimal 2048
+	public final static int BitMask13= 0x1000; // decimal 4096
+	public final static int BitMask14= 0x2000; // decimal 8192
+	public final static int BitMask15= 0x4000; // decimal 16384
+	public final static int BitMask16= 0x8000; // decimal 32768
+	public final static int BitMask17= 0x10000; // decimal 65536
+	public final static int BitMask18= 0x20000; // decimal 131072
+	public final static int BitMask19= 0x40000; // decimal 262144
+	public final static int BitMask20= 0x80000; // decimal 524288
+	public final static int BitMask21= 0x100000; // decimal 1048576
+	public final static int BitMask22= 0x200000; // decimal 2097152
+	public final static int BitMask23= 0x400000; // decimal 4194304
+	public final static int BitMask24= 0x800000; // decimal 8388608
+	public final static int BitMask25= 0x1000000; // decimal 16777216
+	public final static int BitMask26= 0x2000000; // decimal 33554432
+	public final static int BitMask27= 0x4000000; // decimal 67108864
+	public final static int BitMask28= 0x8000000; // decimal 134217728
+	public final static int BitMask29= 0x10000000; // decimal 268435456
+	public final static int BitMask30= 0x20000000; // decimal 536870912
+	public final static int BitMask31= 0x40000000; // decimal 1073741824
+	public final static int BitMask32= 0x80000000; // decimal 2147483648	
+	*/
+/**
+ * Statement constructor comment.
+ */
+public Statement() {
+	super();
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return flowInfo;
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream){
+	throw new ShouldNotImplement(Util.bind("ast.missingStatement"/*nonNLS*/));
+}
+public boolean isEmptyBlock(){
+	return false;
+}
+public boolean isValidJavaStatement(){
+	//the use of this method should be avoid in most cases
+	//and is here mostly for documentation purpose.....
+	//while the parser is responsable for creating
+	//welled formed expression statement, which results
+	//in the fact that java-non-semantic-expression-used-as-statement
+	//should not be parsable...thus not being built.
+	//It sounds like the java grammar as help the compiler job in removing
+	//-by construction- some statement that would have no effect....
+	//(for example all expression that may do side-effects are valid statement
+	// -this is an appromative idea.....-)
+	
+
+	return true ;}
+public void resolve(BlockScope scope) {
+}
+public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
+	// statement within a switch that are not case are treated as normal statement.... 
+
+	resolve(scope);
+	return null;
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
index 83e55fe..f34769a 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
@@ -1,56 +1,55 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class SuperReference extends ThisReference {
-	public static final SuperReference Super = new SuperReference();
-	
-/**
- * SuperReference constructor comment.
- */
-public SuperReference() {
-	super();
-}
-public SuperReference(int pos, int sourceEnd) {
-	super();
-	sourceStart = pos;
-	this.sourceEnd = sourceEnd;
-}
-public static ExplicitConstructorCall implicitSuperConstructorCall() {
-	return new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
-}
-public boolean isSuper() {
-	
-	return true;
-}
-public boolean isThis() {
-	
-	return false ;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	constant = NotAConstant;
-	if (!checkAccess(scope.methodScope()))
-		return null;
-	SourceTypeBinding enclosingTb = scope.enclosingSourceType();
-	if (scope.isJavaLangObject(enclosingTb)) {
-		scope.problemReporter().cannotUseSuperInJavaLangObject(this);
-		return null;
-	}
-	return enclosingTb.superclass;
-}
-public String toStringExpression(){
-
-	return "super"/*nonNLS*/;
-	
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	visitor.visit(this, blockScope);
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SuperReference extends ThisReference {
+	public static final SuperReference Super = new SuperReference();
+	
+/**
+ * SuperReference constructor comment.
+ */
+public SuperReference() {
+	super();
+}
+public SuperReference(int pos, int sourceEnd) {
+	super();
+	sourceStart = pos;
+	this.sourceEnd = sourceEnd;
+}
+public static ExplicitConstructorCall implicitSuperConstructorCall() {
+	return new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
+}
+public boolean isSuper() {
+	
+	return true;
+}
+public boolean isThis() {
+	
+	return false ;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	constant = NotAConstant;
+	if (!checkAccess(scope.methodScope()))
+		return null;
+	SourceTypeBinding enclosingTb = scope.enclosingSourceType();
+	if (scope.isJavaLangObject(enclosingTb)) {
+		scope.problemReporter().cannotUseSuperInJavaLangObject(this);
+		return null;
+	}
+	return enclosingTb.superclass;
+}
+public String toStringExpression(){
+
+	return "super"/*nonNLS*/;
+	
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	visitor.visit(this, blockScope);
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index 61c0776..defeece 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -1,261 +1,260 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class SwitchStatement extends Statement {
-	public Expression testExpression;
-	public Statement[] statements;
-	public BlockScope scope;
-	public int explicitDeclarations;
-	public Label breakLabel;
-	public Case[] cases;
-	public DefaultCase defaultCase;
-	public int caseCount = 0;
-	
-	// for local variables table attributes
-	int preSwitchInitStateIndex = -1;
-	int mergedInitStateIndex = -1;
-/**
- * SwitchStatement constructor comment.
- */
-public SwitchStatement() {
-	super();
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	flowInfo = testExpression.analyseCode(currentScope, flowContext, flowInfo);
-	SwitchFlowContext switchContext = new SwitchFlowContext(flowContext, this, (breakLabel = new Label()));
-
-	// analyse the block by considering specially the case/default statements (need to bind them 
-	// to the entry point)
-	FlowInfo caseInits = FlowInfo.DeadEnd; // in case of statements before the first case
-	preSwitchInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
-	int caseIndex = 0;
-	if (statements != null) {
-		for (int i = 0, max = statements.length; i < max; i++) {
-			Statement statement = statements[i];
-			if ((caseIndex < caseCount) && (statement == cases[caseIndex])) { // statements[i] is a case or a default case
-				caseIndex++;
-				caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
-			} else {
-				if (statement == defaultCase) {
-					caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
-				}
-			}
-			if (!caseInits.complainIfUnreachable(statement, scope)) {
-				caseInits = statement.analyseCode(scope, switchContext, caseInits);
-			}
-		}
-	}
-
-	// if no default case, then record it may jump over the block directly to the end
-	if (defaultCase == null) {
-		// only retain the potential initializations
-		flowInfo.addPotentialInitializationsFrom(caseInits.mergedWith(switchContext.initsOnBreak));
-		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
-		return flowInfo;
-	}
-
-	// merge all branches inits
-	FlowInfo mergedInfo = caseInits.mergedWith(switchContext.initsOnBreak);
-	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
-	return mergedInfo;
-}
-/**
- * Switch code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	int[] sortedIndexes = new int[caseCount];
-	int[] localKeysCopy;
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	int pc = codeStream.position;
-
-	// prepare the labels and constants
-	breakLabel.codeStream = codeStream;
-	CaseLabel[] caseLabels = new CaseLabel[caseCount];
-	int[] constants = new int[caseCount];
-	boolean needSwitch = caseCount != 0;
-	for (int i = 0; i < caseCount; i++) {
-		constants[i] = cases[i].constantExpression.constant.intValue();
-		cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream));
-	}
-
-	// we sort the keys to be able to generate the code for tableswitch or lookupswitch
-	for (int i = 0; i < caseCount; i++) {
-		sortedIndexes[i] = i;
-	}
-	System.arraycopy(
-		constants, 
-		0, 
-		(localKeysCopy = new int[caseCount]), 
-		0, 
-		caseCount); 
-	CodeStream.sort(localKeysCopy, 0, caseCount - 1, sortedIndexes);
-	CaseLabel defaultLabel = new CaseLabel(codeStream);
-	if (defaultCase != null) {
-		defaultCase.targetLabel = defaultLabel;
-	}
-	// generate expression testes
-	testExpression.generateCode(currentScope, codeStream, needSwitch);
-
-	// generate the appropriate switch table
-	if (needSwitch) {
-		int max = localKeysCopy[caseCount - 1];
-		int min = localKeysCopy[0];
-		if ((long) (caseCount * 2.5) > ((long) max - (long) min)) {
-			codeStream.tableswitch(
-				defaultLabel, 
-				min, 
-				max, 
-				constants, 
-				sortedIndexes, 
-				caseLabels); 
-		} else {
-			codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels);
-		}
-		codeStream.updateLastRecordedEndPC(codeStream.position);
-	}
-	// generate the switch block statements
-	int caseIndex = 0;
-	if (statements != null) {
-		for (int i = 0, maxCases = statements.length; i < maxCases; i++) {
-			Statement statement = statements[i];
-			if ((caseIndex < caseCount)
-				&& (statement == cases[caseIndex])) { // statements[i] is a case
-				if (preSwitchInitStateIndex != -1) {
-					codeStream.removeNotDefinitelyAssignedVariables(
-						currentScope, 
-						preSwitchInitStateIndex); 
-					caseIndex++;
-				}
-			} else {
-				if (statement == defaultCase) { // statements[i] is a case or a default case
-					if (preSwitchInitStateIndex != -1) {
-						codeStream.removeNotDefinitelyAssignedVariables(
-							currentScope, 
-							preSwitchInitStateIndex); 
-					}
-				}
-			}
-			statement.generateCode(scope, codeStream);
-		}
-	}
-	// place the trailing labels (for break and default case)
-	breakLabel.place();
-	if (defaultCase == null) {
-		defaultLabel.place();
-	}
-	// May loose some local variable initializations : affecting the local variable attributes
-	if (mergedInitStateIndex != -1) {
-		codeStream.removeNotDefinitelyAssignedVariables(
-			currentScope, 
-			mergedInitStateIndex); 
-		codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
-	}
-	if (scope != currentScope) {
-		codeStream.exitUserScope(scope);
-	}
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void resolve(BlockScope upperScope) {
-	TypeBinding testType = testExpression.resolveType(upperScope);
-	if (testType == null)
-		return;
-	testExpression.implicitWidening(testType, testType);
-	if (!(testExpression.isConstantValueOfTypeAssignableToType(testType, IntBinding))) {
-		if (!upperScope.areTypesCompatible(testType, IntBinding)) {
-			upperScope.problemReporter().incorrectSwitchType(testExpression, testType);
-			return;
-		}
-	}
-	if (statements != null) {
-		scope = explicitDeclarations == 0 ? upperScope : new BlockScope(upperScope);
-		int length;
-		// collection of cases is too big but we will only iterate until caseCount
-		cases = new Case[length = statements.length];
-		int[] casesValues = new int[length];
-		int counter = 0;
-		for (int i = 0; i < length; i++) {
-			Constant cst;
-			if ((cst = statements[i].resolveCase(scope, testType, this)) != null) {
-				//----check for duplicate case statement------------
-				if (cst != NotAConstant) {
-					// a case with a welled typed constant, so intValue() is valid
-					int key = cst.intValue();
-					for (int j = 0; j < counter; j++) {
-						if (casesValues[j] == key) {
-							scope.problemReporter().duplicateCase((Case) statements[i], cst);
-						}
-					}
-					casesValues[counter++] = key;
-				}
-			}
-		}
-	}
-}
-public String toString(int tab){
-	/* slow code */
-	
-	String inFront , s = tabString(tab) ;
-	inFront = s ;
-	s = s + "switch ("/*nonNLS*/ + testExpression.toStringExpression() + ") "/*nonNLS*/;
-	if (statements == null)
-	{ 	s = s + "{}"/*nonNLS*/ ; 
-		return s;}
-	else
-		s = s + "{"/*nonNLS*/;
-
-	s = s + (explicitDeclarations != 0
-				? "// ---scope needed for "/*nonNLS*/+String.valueOf(explicitDeclarations) +" locals------------ \n"/*nonNLS*/
-				: "// ---NO scope needed------ \n"/*nonNLS*/) ;
-		
-	int i = 0;
-	String tabulation = "  "/*nonNLS*/;
-	try	{while(true){
-		//use instanceof in order not to polluate classes with behavior only needed for printing purpose.
-		if ( statements[i]  instanceof Expression)
-			s = s + "\n"/*nonNLS*/ + inFront + tabulation;
-		if ( statements[i]  instanceof Break)
-			s = s + statements[i].toString(0) ;
-		else	
-			s = s + "\n"/*nonNLS*/ + statements[i].toString(tab+2) ;
-		//=============	
-		if ( (statements[i] instanceof Case) || (statements[i] instanceof DefaultCase))
-		{	i++;
-			while(! ((statements[i] instanceof Case) || (statements[i] instanceof DefaultCase)))
-			{	if ( (statements[i] instanceof Expression) || (statements[i] instanceof Break))
-					s = s +  statements[i].toString(0) +" ; "/*nonNLS*/;
-				else
-					s = s + "\n"/*nonNLS*/ + statements[i].toString(tab+6) + " ; "/*nonNLS*/;
-				i++;}}
-		else
-		{	s = s + " ;"/*nonNLS*/ ;
-			i++;}}}
-	catch(IndexOutOfBoundsException e){};
-	s = s + "}"/*nonNLS*/;
-	return s;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		testExpression.traverse(visitor, scope);
-		if (statements != null) {
-			int statementsLength = statements.length;
-			for (int i = 0; i < statementsLength; i++)
-				statements[i].traverse(visitor, scope);
-		}
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SwitchStatement extends Statement {
+	public Expression testExpression;
+	public Statement[] statements;
+	public BlockScope scope;
+	public int explicitDeclarations;
+	public Label breakLabel;
+	public Case[] cases;
+	public DefaultCase defaultCase;
+	public int caseCount = 0;
+	
+	// for local variables table attributes
+	int preSwitchInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+/**
+ * SwitchStatement constructor comment.
+ */
+public SwitchStatement() {
+	super();
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	flowInfo = testExpression.analyseCode(currentScope, flowContext, flowInfo);
+	SwitchFlowContext switchContext = new SwitchFlowContext(flowContext, this, (breakLabel = new Label()));
+
+	// analyse the block by considering specially the case/default statements (need to bind them 
+	// to the entry point)
+	FlowInfo caseInits = FlowInfo.DeadEnd; // in case of statements before the first case
+	preSwitchInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+	int caseIndex = 0;
+	if (statements != null) {
+		for (int i = 0, max = statements.length; i < max; i++) {
+			Statement statement = statements[i];
+			if ((caseIndex < caseCount) && (statement == cases[caseIndex])) { // statements[i] is a case or a default case
+				caseIndex++;
+				caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
+			} else {
+				if (statement == defaultCase) {
+					caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
+				}
+			}
+			if (!caseInits.complainIfUnreachable(statement, scope)) {
+				caseInits = statement.analyseCode(scope, switchContext, caseInits);
+			}
+		}
+	}
+
+	// if no default case, then record it may jump over the block directly to the end
+	if (defaultCase == null) {
+		// only retain the potential initializations
+		flowInfo.addPotentialInitializationsFrom(caseInits.mergedWith(switchContext.initsOnBreak));
+		mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+		return flowInfo;
+	}
+
+	// merge all branches inits
+	FlowInfo mergedInfo = caseInits.mergedWith(switchContext.initsOnBreak);
+	mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+	return mergedInfo;
+}
+/**
+ * Switch code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	int[] sortedIndexes = new int[caseCount];
+	int[] localKeysCopy;
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	// prepare the labels and constants
+	breakLabel.codeStream = codeStream;
+	CaseLabel[] caseLabels = new CaseLabel[caseCount];
+	int[] constants = new int[caseCount];
+	boolean needSwitch = caseCount != 0;
+	for (int i = 0; i < caseCount; i++) {
+		constants[i] = cases[i].constantExpression.constant.intValue();
+		cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream));
+	}
+
+	// we sort the keys to be able to generate the code for tableswitch or lookupswitch
+	for (int i = 0; i < caseCount; i++) {
+		sortedIndexes[i] = i;
+	}
+	System.arraycopy(
+		constants, 
+		0, 
+		(localKeysCopy = new int[caseCount]), 
+		0, 
+		caseCount); 
+	CodeStream.sort(localKeysCopy, 0, caseCount - 1, sortedIndexes);
+	CaseLabel defaultLabel = new CaseLabel(codeStream);
+	if (defaultCase != null) {
+		defaultCase.targetLabel = defaultLabel;
+	}
+	// generate expression testes
+	testExpression.generateCode(currentScope, codeStream, needSwitch);
+
+	// generate the appropriate switch table
+	if (needSwitch) {
+		int max = localKeysCopy[caseCount - 1];
+		int min = localKeysCopy[0];
+		if ((long) (caseCount * 2.5) > ((long) max - (long) min)) {
+			codeStream.tableswitch(
+				defaultLabel, 
+				min, 
+				max, 
+				constants, 
+				sortedIndexes, 
+				caseLabels); 
+		} else {
+			codeStream.lookupswitch(defaultLabel, constants, sortedIndexes, caseLabels);
+		}
+		codeStream.updateLastRecordedEndPC(codeStream.position);
+	}
+	// generate the switch block statements
+	int caseIndex = 0;
+	if (statements != null) {
+		for (int i = 0, maxCases = statements.length; i < maxCases; i++) {
+			Statement statement = statements[i];
+			if ((caseIndex < caseCount)
+				&& (statement == cases[caseIndex])) { // statements[i] is a case
+				if (preSwitchInitStateIndex != -1) {
+					codeStream.removeNotDefinitelyAssignedVariables(
+						currentScope, 
+						preSwitchInitStateIndex); 
+					caseIndex++;
+				}
+			} else {
+				if (statement == defaultCase) { // statements[i] is a case or a default case
+					if (preSwitchInitStateIndex != -1) {
+						codeStream.removeNotDefinitelyAssignedVariables(
+							currentScope, 
+							preSwitchInitStateIndex); 
+					}
+				}
+			}
+			statement.generateCode(scope, codeStream);
+		}
+	}
+	// place the trailing labels (for break and default case)
+	breakLabel.place();
+	if (defaultCase == null) {
+		defaultLabel.place();
+	}
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(
+			currentScope, 
+			mergedInitStateIndex); 
+		codeStream.addDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
+	}
+	if (scope != currentScope) {
+		codeStream.exitUserScope(scope);
+	}
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void resolve(BlockScope upperScope) {
+	TypeBinding testType = testExpression.resolveType(upperScope);
+	if (testType == null)
+		return;
+	testExpression.implicitWidening(testType, testType);
+	if (!(testExpression.isConstantValueOfTypeAssignableToType(testType, IntBinding))) {
+		if (!upperScope.areTypesCompatible(testType, IntBinding)) {
+			upperScope.problemReporter().incorrectSwitchType(testExpression, testType);
+			return;
+		}
+	}
+	if (statements != null) {
+		scope = explicitDeclarations == 0 ? upperScope : new BlockScope(upperScope);
+		int length;
+		// collection of cases is too big but we will only iterate until caseCount
+		cases = new Case[length = statements.length];
+		int[] casesValues = new int[length];
+		int counter = 0;
+		for (int i = 0; i < length; i++) {
+			Constant cst;
+			if ((cst = statements[i].resolveCase(scope, testType, this)) != null) {
+				//----check for duplicate case statement------------
+				if (cst != NotAConstant) {
+					// a case with a welled typed constant, so intValue() is valid
+					int key = cst.intValue();
+					for (int j = 0; j < counter; j++) {
+						if (casesValues[j] == key) {
+							scope.problemReporter().duplicateCase((Case) statements[i], cst);
+						}
+					}
+					casesValues[counter++] = key;
+				}
+			}
+		}
+	}
+}
+public String toString(int tab){
+	/* slow code */
+	
+	String inFront , s = tabString(tab) ;
+	inFront = s ;
+	s = s + "switch ("/*nonNLS*/ + testExpression.toStringExpression() + ") "/*nonNLS*/;
+	if (statements == null)
+	{ 	s = s + "{}"/*nonNLS*/ ; 
+		return s;}
+	else
+		s = s + "{"/*nonNLS*/;
+
+	s = s + (explicitDeclarations != 0
+				? "// ---scope needed for "/*nonNLS*/+String.valueOf(explicitDeclarations) +" locals------------ \n"/*nonNLS*/
+				: "// ---NO scope needed------ \n"/*nonNLS*/) ;
+		
+	int i = 0;
+	String tabulation = "  "/*nonNLS*/;
+	try	{while(true){
+		//use instanceof in order not to polluate classes with behavior only needed for printing purpose.
+		if ( statements[i]  instanceof Expression)
+			s = s + "\n"/*nonNLS*/ + inFront + tabulation;
+		if ( statements[i]  instanceof Break)
+			s = s + statements[i].toString(0) ;
+		else	
+			s = s + "\n"/*nonNLS*/ + statements[i].toString(tab+2) ;
+		//=============	
+		if ( (statements[i] instanceof Case) || (statements[i] instanceof DefaultCase))
+		{	i++;
+			while(! ((statements[i] instanceof Case) || (statements[i] instanceof DefaultCase)))
+			{	if ( (statements[i] instanceof Expression) || (statements[i] instanceof Break))
+					s = s +  statements[i].toString(0) +" ; "/*nonNLS*/;
+				else
+					s = s + "\n"/*nonNLS*/ + statements[i].toString(tab+6) + " ; "/*nonNLS*/;
+				i++;}}
+		else
+		{	s = s + " ;"/*nonNLS*/ ;
+			i++;}}}
+	catch(IndexOutOfBoundsException e){};
+	s = s + "}"/*nonNLS*/;
+	return s;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		testExpression.traverse(visitor, scope);
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++)
+				statements[i].traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
index dc7cbe9..d09dada 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
@@ -1,141 +1,140 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class SynchronizedStatement extends Statement {
-	public Expression expression;
-	public Block block;
-	public BlockScope scope;
-
-	boolean blockExit;
-	public LocalVariableBinding synchroVariable;
-	static final char[] SecretLocalDeclarationName = " syncValue"/*nonNLS*/.toCharArray();
-
-public SynchronizedStatement(Expression expression , Block statement, int s, int e) {
-	this.expression = expression;
-	this.block = statement ;
-	sourceEnd = e;
-	sourceStart = s;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	// mark the synthetic variable as being used
-	synchroVariable.used = true;
-	
-	// simple propagation to subnodes
-	flowInfo = block.analyseCode(
-		scope, 
-		new InsideSubRoutineFlowContext(flowContext, this), 
-		expression.analyseCode(scope, flowContext, flowInfo));
-		
-	// optimizing code gen
-	if ((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable()) {
-		blockExit = true;
-	}
-	return flowInfo;
-}
-/**
- * Synchronized statement code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */ 
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	int pc = codeStream.position;
-
-	// generate the synchronization expression
-	expression.generateCode(scope, codeStream, true);
-	if (block.isEmptyBlock()) {
-		if ((synchroVariable.type == LongBinding) || (synchroVariable.type == DoubleBinding)) {
-			codeStream.dup2();
-		} else {
-			codeStream.dup();
-		}
-		// only take the lock
-		codeStream.monitorenter();
-		codeStream.monitorexit();
-	} else {
-		// enter the monitor
-		codeStream.store(synchroVariable, true);
-		codeStream.monitorenter();
-
-		// generate  the body of the synchronized block
-		ExceptionLabel anyExceptionHandler = new ExceptionLabel(codeStream, null); //'null' denotes any kind of exception
-		block.generateCode(scope, codeStream);
-		anyExceptionHandler.placeEnd();
-		Label endLabel = new Label(codeStream);
-		if (!blockExit) {
-			codeStream.load(synchroVariable);
-			codeStream.monitorexit();
-			codeStream.goto_(endLabel);
-		}
-		// generate the body of the exception handler
-		anyExceptionHandler.place();
-		codeStream.incrStackSize(1);
-		codeStream.load(synchroVariable);
-		codeStream.monitorexit();
-		codeStream.athrow();
-		if (!blockExit) {
-			endLabel.place();
-		}
-	}
-	if (scope != currentScope) {
-		codeStream.exitUserScope(scope);
-	}		
-	codeStream.recordPositionsFrom(pc, this);
-}
-public void resolve(BlockScope upperScope) {
-
-	// special scope for secret locals optimization.
-	scope = new BlockScope(upperScope);
-	TypeBinding type = expression.resolveType(scope);
-	if (type == null)
-		return;
-	switch (type.id) {
-		case (T_boolean) :
-		case (T_char) :
-		case (T_float) :
-		case (T_double) :
-		case (T_byte) :
-		case (T_short) :
-		case (T_int) :
-		case (T_long) :
-			scope.problemReporter().invalidTypeToSynchronize(expression, type);
-			break;
-		case (T_null) :
-			scope.problemReporter().invalidNullToSynchronize(expression);
-			break;
-	}
-	//continue even on errors in order to have the TC done into the statements
-	synchroVariable = new LocalVariableBinding(SecretLocalDeclarationName, type, 0);
-	scope.addLocalVariable(synchroVariable);
-	synchroVariable.constant = NotAConstant; // not inlinable
-	expression.implicitWidening(type, type);
-	block.resolveUsing(scope);
-}
-public String toString(int tab){
-	/* slow code */
-
-	String s = tabString(tab) ;
-	s = s + "synchronized ("/*nonNLS*/ + expression.toStringExpression() + ")"/*nonNLS*/;
-	s = s + "\n"/*nonNLS*/ + block.toString(tab+1) ;
-	return s;}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		expression.traverse(visitor, scope);
-		block.traverse(visitor, scope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SynchronizedStatement extends Statement {
+	public Expression expression;
+	public Block block;
+	public BlockScope scope;
+
+	boolean blockExit;
+	public LocalVariableBinding synchroVariable;
+	static final char[] SecretLocalDeclarationName = " syncValue"/*nonNLS*/.toCharArray();
+
+public SynchronizedStatement(Expression expression , Block statement, int s, int e) {
+	this.expression = expression;
+	this.block = statement ;
+	sourceEnd = e;
+	sourceStart = s;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// mark the synthetic variable as being used
+	synchroVariable.used = true;
+	
+	// simple propagation to subnodes
+	flowInfo = block.analyseCode(
+		scope, 
+		new InsideSubRoutineFlowContext(flowContext, this), 
+		expression.analyseCode(scope, flowContext, flowInfo));
+		
+	// optimizing code gen
+	if ((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable()) {
+		blockExit = true;
+	}
+	return flowInfo;
+}
+/**
+ * Synchronized statement code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */ 
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	// generate the synchronization expression
+	expression.generateCode(scope, codeStream, true);
+	if (block.isEmptyBlock()) {
+		if ((synchroVariable.type == LongBinding) || (synchroVariable.type == DoubleBinding)) {
+			codeStream.dup2();
+		} else {
+			codeStream.dup();
+		}
+		// only take the lock
+		codeStream.monitorenter();
+		codeStream.monitorexit();
+	} else {
+		// enter the monitor
+		codeStream.store(synchroVariable, true);
+		codeStream.monitorenter();
+
+		// generate  the body of the synchronized block
+		ExceptionLabel anyExceptionHandler = new ExceptionLabel(codeStream, null); //'null' denotes any kind of exception
+		block.generateCode(scope, codeStream);
+		anyExceptionHandler.placeEnd();
+		Label endLabel = new Label(codeStream);
+		if (!blockExit) {
+			codeStream.load(synchroVariable);
+			codeStream.monitorexit();
+			codeStream.goto_(endLabel);
+		}
+		// generate the body of the exception handler
+		anyExceptionHandler.place();
+		codeStream.incrStackSize(1);
+		codeStream.load(synchroVariable);
+		codeStream.monitorexit();
+		codeStream.athrow();
+		if (!blockExit) {
+			endLabel.place();
+		}
+	}
+	if (scope != currentScope) {
+		codeStream.exitUserScope(scope);
+	}		
+	codeStream.recordPositionsFrom(pc, this);
+}
+public void resolve(BlockScope upperScope) {
+
+	// special scope for secret locals optimization.
+	scope = new BlockScope(upperScope);
+	TypeBinding type = expression.resolveType(scope);
+	if (type == null)
+		return;
+	switch (type.id) {
+		case (T_boolean) :
+		case (T_char) :
+		case (T_float) :
+		case (T_double) :
+		case (T_byte) :
+		case (T_short) :
+		case (T_int) :
+		case (T_long) :
+			scope.problemReporter().invalidTypeToSynchronize(expression, type);
+			break;
+		case (T_null) :
+			scope.problemReporter().invalidNullToSynchronize(expression);
+			break;
+	}
+	//continue even on errors in order to have the TC done into the statements
+	synchroVariable = new LocalVariableBinding(SecretLocalDeclarationName, type, 0);
+	scope.addLocalVariable(synchroVariable);
+	synchroVariable.constant = NotAConstant; // not inlinable
+	expression.implicitWidening(type, type);
+	block.resolveUsing(scope);
+}
+public String toString(int tab){
+	/* slow code */
+
+	String s = tabString(tab) ;
+	s = s + "synchronized ("/*nonNLS*/ + expression.toStringExpression() + ")"/*nonNLS*/;
+	s = s + "\n"/*nonNLS*/ + block.toString(tab+1) ;
+	return s;}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		expression.traverse(visitor, scope);
+		block.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index f1adeb7..ff03076 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -1,69 +1,68 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.flow.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public class ThrowStatement extends Statement {
-	public Expression exception;
-	public TypeBinding exceptionType;
-public ThrowStatement(Expression exception,int startPosition) {
-	this.exception = exception;
-	this.sourceStart = startPosition ;
-	this.sourceEnd = exception.sourceEnd ;
-}
-public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-
-	// need to check that exception thrown is actually caught somewhere
-
-	exception.analyseCode(currentScope, flowContext, flowInfo);
-	flowContext.checkExceptionHandlers(exceptionType, this, flowInfo, currentScope);
-	return FlowInfo.DeadEnd;
-}
-/**
- * Throw code generation
- *
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */ 
-public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-
-	if ((bits & IsReachableMASK) == 0) {
-		return;
-	}
-	int pc = codeStream.position;
-	exception.generateCode(currentScope, codeStream, true);
-	codeStream.athrow();
-	codeStream.recordPositionsFrom(pc, this);
-	
-}
-public void resolve(BlockScope scope) {
-	exceptionType = exception.resolveTypeExpecting(scope, scope.getJavaLangThrowable());
-	if (exceptionType == NullBinding)
-		scope.problemReporter().cannotThrowNull(this);
-	exception.implicitWidening(exceptionType, exceptionType);
-}
-/* SHOULDN'T IT RATHER DO -
-scope.checkThrowable(exceptionType = expression.resolveType(scope)); 
-*/
-public String toString(int tab){
-	/* slow code */
-
-	String s = tabString(tab) ;
-	s = s + "throw "/*nonNLS*/;
-	s = s + exception.toStringExpression() ;
-	return s;
-}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
-	if (visitor.visit(this, blockScope)) {
-		exception.traverse(visitor, blockScope);
-	}
-	visitor.endVisit(this, blockScope);
-}
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ThrowStatement extends Statement {
+	public Expression exception;
+	public TypeBinding exceptionType;
+public ThrowStatement(Expression exception,int startPosition) {
+	this.exception = exception;
+	this.sourceStart = startPosition ;
+	this.sourceEnd = exception.sourceEnd ;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// need to check that exception thrown is actually caught somewhere
+
+	exception.analyseCode(currentScope, flowContext, flowInfo);
+	flowContext.checkExceptionHandlers(exceptionType, this, flowInfo, currentScope);
+	return FlowInfo.DeadEnd;
+}
+/**
+ * Throw code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */ 
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+	if ((bits & IsReachableMASK) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	exception.generateCode(currentScope, codeStream, true);
+	codeStream.athrow();
+	codeStream.recordPositionsFrom(pc, this);
+	
+}
+public void resolve(BlockScope scope) {
+	exceptionType = exception.resolveTypeExpecting(scope, scope.getJavaLangThrowable());
+	if (exceptionType == NullBinding)
+		scope.problemReporter().cannotThrowNull(this);
+	exception.implicitWidening(exceptionType, exceptionType);
+}
+/* SHOULDN'T IT RATHER DO -
+scope.checkThrowable(exceptionType = expression.resolveType(scope)); 
+*/
+public String toString(int tab){
+	/* slow code */
+
+	String s = tabString(tab) ;
+	s = s + "throw "/*nonNLS*/;
+	s = s + exception.toStringExpression() ;
+	return s;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		exception.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 6fe6431..b3c5bde 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -5,11 +5,9 @@
  * All Rights Reserved.
  */
 import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
 
 public class TryStatement extends Statement {
 	public Block tryBlock;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 5e257ac..6b86bf9 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -1,97 +1,96 @@
-package org.eclipse.jdt.internal.compiler.ast;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public abstract class TypeReference extends Expression {
-	public TypeBinding binding;
-public TypeReference() {
-		super () ;
-		}
-// allows us to trap completion & selection nodes
-
-public void aboutToResolve(Scope scope) {}
-/*
- * Answer a base type reference (can be an array of base type).
- */
-public static final TypeReference baseTypeReference(int baseType, int dim) {
-	
-	if (dim == 0) {
-		switch (baseType) {
-			case (T_void) :
-				return new SingleTypeReference(VoidBinding.simpleName, 0);
-			case (T_boolean) :
-				return new SingleTypeReference(BooleanBinding.simpleName, 0);
-			case (T_char) :
-				return new SingleTypeReference(CharBinding.simpleName, 0);
-			case (T_float) :
-				return new SingleTypeReference(FloatBinding.simpleName, 0);
-			case (T_double) :
-				return new SingleTypeReference(DoubleBinding.simpleName, 0);
-			case (T_byte) :
-				return new SingleTypeReference(ByteBinding.simpleName, 0);
-			case (T_short) :
-				return new SingleTypeReference(ShortBinding.simpleName, 0);
-			case (T_int) :
-				return new SingleTypeReference(IntBinding.simpleName, 0);
-			default : //T_long	
-				return new SingleTypeReference(LongBinding.simpleName, 0);
-		}
-	}
-	switch (baseType) {
-		case (T_void) :
-			return new ArrayTypeReference(VoidBinding.simpleName, dim, 0);
-		case (T_boolean) :
-			return new ArrayTypeReference(BooleanBinding.simpleName, dim, 0);
-		case (T_char) :
-			return new ArrayTypeReference(CharBinding.simpleName, dim, 0);
-		case (T_float) :
-			return new ArrayTypeReference(FloatBinding.simpleName, dim, 0);
-		case (T_double) :
-			return new ArrayTypeReference(DoubleBinding.simpleName, dim, 0);
-		case (T_byte) :
-			return new ArrayTypeReference(ByteBinding.simpleName, dim, 0);
-		case (T_short) :
-			return new ArrayTypeReference(ShortBinding.simpleName, dim, 0);
-		case (T_int) :
-			return new ArrayTypeReference(IntBinding.simpleName, dim, 0);
-		default : //T_long	
-			return new ArrayTypeReference(LongBinding.simpleName, dim, 0);
-	}
-}
-public abstract TypeReference copyDims(int dim);
-public int dimensions() {
-	return 0;
-}
-public abstract TypeBinding getTypeBinding(Scope scope);
-/**
- * @return char[][]
- */
-public abstract char [][] getTypeName() ;
-public boolean isTypeReference() {
-	return true;
-}
-public TypeBinding resolveType(BlockScope scope) {
-	// handle the error here
-	constant = NotAConstant;
-	if (binding != null) { // is a shared type reference which was already resolved
-		if (!binding.isValidBinding())
-			return null; // already reported error
-	} else {
-		binding = getTypeBinding(scope);
-		if (!binding.isValidBinding()) {
-			scope.problemReporter().invalidType(this, binding);
-			return null;
-		}
-		if (isTypeUseDeprecated(binding, scope))
-			scope.problemReporter().deprecatedType(binding, this);
-	}
-	return binding;
-}
-public abstract void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope);
-}
+package org.eclipse.jdt.internal.compiler.ast;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class TypeReference extends Expression {
+	public TypeBinding binding;
+public TypeReference() {
+		super () ;
+		}
+// allows us to trap completion & selection nodes
+
+public void aboutToResolve(Scope scope) {}
+/*
+ * Answer a base type reference (can be an array of base type).
+ */
+public static final TypeReference baseTypeReference(int baseType, int dim) {
+	
+	if (dim == 0) {
+		switch (baseType) {
+			case (T_void) :
+				return new SingleTypeReference(VoidBinding.simpleName, 0);
+			case (T_boolean) :
+				return new SingleTypeReference(BooleanBinding.simpleName, 0);
+			case (T_char) :
+				return new SingleTypeReference(CharBinding.simpleName, 0);
+			case (T_float) :
+				return new SingleTypeReference(FloatBinding.simpleName, 0);
+			case (T_double) :
+				return new SingleTypeReference(DoubleBinding.simpleName, 0);
+			case (T_byte) :
+				return new SingleTypeReference(ByteBinding.simpleName, 0);
+			case (T_short) :
+				return new SingleTypeReference(ShortBinding.simpleName, 0);
+			case (T_int) :
+				return new SingleTypeReference(IntBinding.simpleName, 0);
+			default : //T_long	
+				return new SingleTypeReference(LongBinding.simpleName, 0);
+		}
+	}
+	switch (baseType) {
+		case (T_void) :
+			return new ArrayTypeReference(VoidBinding.simpleName, dim, 0);
+		case (T_boolean) :
+			return new ArrayTypeReference(BooleanBinding.simpleName, dim, 0);
+		case (T_char) :
+			return new ArrayTypeReference(CharBinding.simpleName, dim, 0);
+		case (T_float) :
+			return new ArrayTypeReference(FloatBinding.simpleName, dim, 0);
+		case (T_double) :
+			return new ArrayTypeReference(DoubleBinding.simpleName, dim, 0);
+		case (T_byte) :
+			return new ArrayTypeReference(ByteBinding.simpleName, dim, 0);
+		case (T_short) :
+			return new ArrayTypeReference(ShortBinding.simpleName, dim, 0);
+		case (T_int) :
+			return new ArrayTypeReference(IntBinding.simpleName, dim, 0);
+		default : //T_long	
+			return new ArrayTypeReference(LongBinding.simpleName, dim, 0);
+	}
+}
+public abstract TypeReference copyDims(int dim);
+public int dimensions() {
+	return 0;
+}
+public abstract TypeBinding getTypeBinding(Scope scope);
+/**
+ * @return char[][]
+ */
+public abstract char [][] getTypeName() ;
+public boolean isTypeReference() {
+	return true;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// handle the error here
+	constant = NotAConstant;
+	if (binding != null) { // is a shared type reference which was already resolved
+		if (!binding.isValidBinding())
+			return null; // already reported error
+	} else {
+		binding = getTypeBinding(scope);
+		if (!binding.isValidBinding()) {
+			scope.problemReporter().invalidType(this, binding);
+			return null;
+		}
+		if (isTypeUseDeprecated(binding, scope))
+			scope.problemReporter().deprecatedType(binding, this);
+	}
+	return binding;
+}
+public abstract void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope);
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java b/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
index 1ff4e1f..18afe65 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
@@ -1,286 +1,285 @@
-package org.eclipse.jdt.internal.compiler.classfmt;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
- 
-abstract public class ClassFileStruct implements ClassFileConstants {
-	byte[] reference;
-	int structOffset;
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @param classFileBytes byte[]
- * @param offset int
- */
-public ClassFileStruct(byte classFileBytes[], int off) {
-	reference = classFileBytes;
-	structOffset = off;
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @param classFileBytes byte[]
- * @param offset int
- * @param verifyStructure boolean
- */
-public ClassFileStruct (byte classFileBytes[], int off, boolean verifyStructure) {
-	reference = classFileBytes;
-	structOffset = off;
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return double
- * @param relativeOffset int
- */
-public double doubleAt(int relativeOffset) {
-	return (Double.longBitsToDouble(this.i8At(relativeOffset)));
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return float
- * @param relativeOffset int
- */
-public float floatAt(int relativeOffset) {
-	return (Float.intBitsToFloat(this.i4At(relativeOffset)));
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public int i1At(int relativeOffset) {
-	return reference[relativeOffset + structOffset];
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public int i2At(int relativeOffset) {
-	int position = relativeOffset + structOffset;
-	return (reference[position++] << 8) + (reference[position] & 0xFF);
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public int i4At(int relativeOffset) {
-	int position = relativeOffset + structOffset;
-	return ((reference[position++] & 0xFF) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public long i8At(int relativeOffset) {
-	int position = relativeOffset + structOffset;
-	return (((long) (reference[position++] & 0xFF)) << 56) + (((long) (reference[position++] & 0xFF)) << 48) + (((long) (reference[position++] & 0xFF)) << 40) + (((long) (reference[position++] & 0xFF)) << 32) + (((long) (reference[position++] & 0xFF)) << 24) + (((long) (reference[position++] & 0xFF)) << 16) + (((long) (reference[position++] & 0xFF)) << 8) + ((long) (reference[position++] & 0xFF));
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @param modifiers int
- */
-public static String printTypeModifiers(int modifiers) {
-
-	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
-	java.io.PrintWriter print = new java.io.PrintWriter(out);
-
-	if ((modifiers & AccPublic) != 0) print.print("public "/*nonNLS*/);
-	if ((modifiers & AccPrivate) != 0) print.print("private "/*nonNLS*/);
-	if ((modifiers & AccFinal) != 0) print.print("final "/*nonNLS*/);
-	if ((modifiers & AccSuper) != 0) print.print("super "/*nonNLS*/);
-	if ((modifiers & AccInterface) != 0) print.print("interface "/*nonNLS*/);
-	if ((modifiers & AccAbstract) != 0) print.print("abstract "/*nonNLS*/);
-	print.flush();
-	return out.toString();
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public int u1At(int relativeOffset) {
-	return (reference[relativeOffset + structOffset] & 0xFF);
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public int u2At(int relativeOffset) {
-	int position = relativeOffset + structOffset;
-	return ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return int
- * @param relativeOffset int
- */
-public long u4At(int relativeOffset) {
-	int position = relativeOffset + structOffset;
-	return (((reference[position++] & 0xFFL) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return String
- * @param relativeOffset int
- */
-public char[] utf8At(int relativeOffset, int bytesAvailable) {
-	int x, y, z;
-	int length = bytesAvailable;
-	char outputBuf[] = new char[bytesAvailable];
-	int outputPos = 0;
-	int readOffset = structOffset + relativeOffset;
-	
-	while (length != 0) {
-		x = reference[readOffset++] & 0xFF;
-		length--;
-		if ((0x80 & x) != 0) {
-			y = this.reference[readOffset++] & 0xFF;
-			length--;
-			if ((x & 0x20) != 0) {
-				z = this.reference[readOffset++] & 0xFF;
-				length--;
-				x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
-			} else {
-				x = ((x & 0x1F) << 6) + (y & 0x3F);
-			}
-		}
-		outputBuf[outputPos++] = (char) x;
-	}
-
-	if (outputPos != bytesAvailable) {
-		System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
-	}
-	return outputBuf;
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- * @return String
- * @param relativeOffset int
- */
-public char[] utf8At(int relativeOffset, int bytesAvailable, boolean testValidity) throws ClassFormatException {
-	int x, y, z;
-	int length = bytesAvailable;
-	char outputBuf[] = new char[bytesAvailable];
-	int outputPos = 0;
-	int readOffset = structOffset + relativeOffset;
-	
-	while (length != 0) {
-		x = reference[readOffset++] & 0xFF;
-		length--;
-		if ((0x80 & x) != 0) {
-			if (testValidity) {
-				if ((0x40 & x) == 0) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-				if (length < 1) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-			}
-			y = this.reference[readOffset++] & 0xFF;
-			length--;
-			if (testValidity) {
-				if ((y & 0xC0) != 0x80) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-			}
-			if ((x & 0x20) != 0) {
-				if (testValidity && (length < 1)) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-				z = this.reference[readOffset++] & 0xFF;
-				length--;
-				if (testValidity && ((z & 0xC0) != 0x80)) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-				x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
-				if (testValidity && (x < 0x0800)) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-			} else {
-				x = ((x & 0x1F) << 6) + (y & 0x3F);
-				if (testValidity && !((x == 0) || (x >= 0x80))) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-				}
-			}
-		} else {
-			if (testValidity && x == 0) {
-					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
-			}
-		}
-		outputBuf[outputPos++] = (char) x;
-	}
-
-	if (outputPos != bytesAvailable) {
-		System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
-	}
-	return outputBuf;
-}
-public static void verifyMethodNameAndSignature(char[] name, char[] signature) throws ClassFormatException {
-
-	// ensure name is not empty 
-	if (name.length == 0) {
-		throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
-	}
-
-	// if name begins with the < character it must be clinit or init
-	if (name[0] == '<') {
-		if (new String(name).equals("<clinit>"/*nonNLS*/) || new String(name).equals("<init>"/*nonNLS*/)) {
-			int signatureLength = signature.length;
-			if (!((signatureLength > 2)
-				&& (signature[0] == '(')
-				&& (signature[signatureLength - 2] == ')')
-				&& (signature[signatureLength - 1] == 'V'))) {
-				throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
-			}
-		} else {
-			throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
-		}
-	}
-}
-}
+package org.eclipse.jdt.internal.compiler.classfmt;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+abstract public class ClassFileStruct implements ClassFileConstants {
+	byte[] reference;
+	int structOffset;
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @param classFileBytes byte[]
+ * @param offset int
+ */
+public ClassFileStruct(byte classFileBytes[], int off) {
+	reference = classFileBytes;
+	structOffset = off;
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @param classFileBytes byte[]
+ * @param offset int
+ * @param verifyStructure boolean
+ */
+public ClassFileStruct (byte classFileBytes[], int off, boolean verifyStructure) {
+	reference = classFileBytes;
+	structOffset = off;
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return double
+ * @param relativeOffset int
+ */
+public double doubleAt(int relativeOffset) {
+	return (Double.longBitsToDouble(this.i8At(relativeOffset)));
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return float
+ * @param relativeOffset int
+ */
+public float floatAt(int relativeOffset) {
+	return (Float.intBitsToFloat(this.i4At(relativeOffset)));
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public int i1At(int relativeOffset) {
+	return reference[relativeOffset + structOffset];
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public int i2At(int relativeOffset) {
+	int position = relativeOffset + structOffset;
+	return (reference[position++] << 8) + (reference[position] & 0xFF);
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public int i4At(int relativeOffset) {
+	int position = relativeOffset + structOffset;
+	return ((reference[position++] & 0xFF) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public long i8At(int relativeOffset) {
+	int position = relativeOffset + structOffset;
+	return (((long) (reference[position++] & 0xFF)) << 56) + (((long) (reference[position++] & 0xFF)) << 48) + (((long) (reference[position++] & 0xFF)) << 40) + (((long) (reference[position++] & 0xFF)) << 32) + (((long) (reference[position++] & 0xFF)) << 24) + (((long) (reference[position++] & 0xFF)) << 16) + (((long) (reference[position++] & 0xFF)) << 8) + ((long) (reference[position++] & 0xFF));
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @param modifiers int
+ */
+public static String printTypeModifiers(int modifiers) {
+
+	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
+	java.io.PrintWriter print = new java.io.PrintWriter(out);
+
+	if ((modifiers & AccPublic) != 0) print.print("public "/*nonNLS*/);
+	if ((modifiers & AccPrivate) != 0) print.print("private "/*nonNLS*/);
+	if ((modifiers & AccFinal) != 0) print.print("final "/*nonNLS*/);
+	if ((modifiers & AccSuper) != 0) print.print("super "/*nonNLS*/);
+	if ((modifiers & AccInterface) != 0) print.print("interface "/*nonNLS*/);
+	if ((modifiers & AccAbstract) != 0) print.print("abstract "/*nonNLS*/);
+	print.flush();
+	return out.toString();
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public int u1At(int relativeOffset) {
+	return (reference[relativeOffset + structOffset] & 0xFF);
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public int u2At(int relativeOffset) {
+	int position = relativeOffset + structOffset;
+	return ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return int
+ * @param relativeOffset int
+ */
+public long u4At(int relativeOffset) {
+	int position = relativeOffset + structOffset;
+	return (((reference[position++] & 0xFFL) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return String
+ * @param relativeOffset int
+ */
+public char[] utf8At(int relativeOffset, int bytesAvailable) {
+	int x, y, z;
+	int length = bytesAvailable;
+	char outputBuf[] = new char[bytesAvailable];
+	int outputPos = 0;
+	int readOffset = structOffset + relativeOffset;
+	
+	while (length != 0) {
+		x = reference[readOffset++] & 0xFF;
+		length--;
+		if ((0x80 & x) != 0) {
+			y = this.reference[readOffset++] & 0xFF;
+			length--;
+			if ((x & 0x20) != 0) {
+				z = this.reference[readOffset++] & 0xFF;
+				length--;
+				x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
+			} else {
+				x = ((x & 0x1F) << 6) + (y & 0x3F);
+			}
+		}
+		outputBuf[outputPos++] = (char) x;
+	}
+
+	if (outputPos != bytesAvailable) {
+		System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
+	}
+	return outputBuf;
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ * @return String
+ * @param relativeOffset int
+ */
+public char[] utf8At(int relativeOffset, int bytesAvailable, boolean testValidity) throws ClassFormatException {
+	int x, y, z;
+	int length = bytesAvailable;
+	char outputBuf[] = new char[bytesAvailable];
+	int outputPos = 0;
+	int readOffset = structOffset + relativeOffset;
+	
+	while (length != 0) {
+		x = reference[readOffset++] & 0xFF;
+		length--;
+		if ((0x80 & x) != 0) {
+			if (testValidity) {
+				if ((0x40 & x) == 0) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+				if (length < 1) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+			}
+			y = this.reference[readOffset++] & 0xFF;
+			length--;
+			if (testValidity) {
+				if ((y & 0xC0) != 0x80) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+			}
+			if ((x & 0x20) != 0) {
+				if (testValidity && (length < 1)) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+				z = this.reference[readOffset++] & 0xFF;
+				length--;
+				if (testValidity && ((z & 0xC0) != 0x80)) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+				x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
+				if (testValidity && (x < 0x0800)) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+			} else {
+				x = ((x & 0x1F) << 6) + (y & 0x3F);
+				if (testValidity && !((x == 0) || (x >= 0x80))) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+				}
+			}
+		} else {
+			if (testValidity && x == 0) {
+					throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
+			}
+		}
+		outputBuf[outputPos++] = (char) x;
+	}
+
+	if (outputPos != bytesAvailable) {
+		System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
+	}
+	return outputBuf;
+}
+public static void verifyMethodNameAndSignature(char[] name, char[] signature) throws ClassFormatException {
+
+	// ensure name is not empty 
+	if (name.length == 0) {
+		throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
+	}
+
+	// if name begins with the < character it must be clinit or init
+	if (name[0] == '<') {
+		if (new String(name).equals("<clinit>"/*nonNLS*/) || new String(name).equals("<init>"/*nonNLS*/)) {
+			int signatureLength = signature.length;
+			if (!((signatureLength > 2)
+				&& (signature[0] == '(')
+				&& (signature[signatureLength - 2] == ')')
+				&& (signature[signatureLength - 1] == 'V'))) {
+				throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+			}
+		} else {
+			throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
+		}
+	}
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java b/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
index d43bf73..44cc493 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
@@ -1,69 +1,68 @@
-package org.eclipse.jdt.internal.compiler.classfmt;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
- 
-public class ClassFormatException extends Exception {
-	private int errorCode;
-	private int bufferPosition;
-
-	public static final int ErrBadMagic = 1;
-	public static final int ErrBadMinorVersion = 2;
-	public static final int ErrBadMajorVersion = 3;
-
-	public static final int ErrBadConstantClass= 4;
-	public static final int ErrBadConstantString= 5;
-	public static final int ErrBadConstantNameAndType = 6;
-	public static final int ErrBadConstantFieldRef= 7;
-	public static final int ErrBadConstantMethodRef = 8;
-	public static final int ErrBadConstantInterfaceMethodRef = 9;
-	public static final int ErrBadConstantPoolIndex = 10;
-	public static final int ErrBadSuperclassName = 11;
-	public static final int ErrInterfaceCannotBeFinal = 12;
-	public static final int ErrInterfaceMustBeAbstract = 13;
-	public static final int ErrBadModifiers = 14;
-	public static final int ErrClassCannotBeAbstractFinal = 15;
-	public static final int ErrBadClassname = 16;
-	public static final int ErrBadFieldInfo = 17;
-	public static final int ErrBadMethodInfo = 17; 
-
-	public static final int ErrEmptyConstantPool =18;
-	public static final int ErrMalformedUtf8 = 19;
-	public static final int ErrUnknownConstantTag = 20;
-	public static final int ErrTruncatedInput = 21;
-	public static final int ErrMethodMustBeAbstract = 22;
-	public static final int ErrMalformedAttribute = 23;
-	public static final int ErrBadInterface = 24;
-	public static final int ErrInterfaceMustSubclassObject = 25;
-	public static final int ErrIncorrectInterfaceMethods = 26;
-	public static final int ErrInvalidMethodName = 27;
-	public static final int ErrInvalidMethodSignature = 28;
-    
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- */
-public ClassFormatException(int code) {
-	errorCode = code;
-}
-/**
- * (c)1998 Object Technology International.
- * (c)1998 International Business Machines Corporation.
- * 
- * 
- */
-public ClassFormatException(int code, int bufPos) {
-	errorCode = code;
-	bufferPosition = bufPos;
-}
-/**
- * @return int
- */
-public int getErrorCode() {
-	return errorCode;
-}
-}
+package org.eclipse.jdt.internal.compiler.classfmt;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+ 
+public class ClassFormatException extends Exception {
+	private int errorCode;
+	private int bufferPosition;
+
+	public static final int ErrBadMagic = 1;
+	public static final int ErrBadMinorVersion = 2;
+	public static final int ErrBadMajorVersion = 3;
+
+	public static final int ErrBadConstantClass= 4;
+	public static final int ErrBadConstantString= 5;
+	public static final int ErrBadConstantNameAndType = 6;
+	public static final int ErrBadConstantFieldRef= 7;
+	public static final int ErrBadConstantMethodRef = 8;
+	public static final int ErrBadConstantInterfaceMethodRef = 9;
+	public static final int ErrBadConstantPoolIndex = 10;
+	public static final int ErrBadSuperclassName = 11;
+	public static final int ErrInterfaceCannotBeFinal = 12;
+	public static final int ErrInterfaceMustBeAbstract = 13;
+	public static final int ErrBadModifiers = 14;
+	public static final int ErrClassCannotBeAbstractFinal = 15;
+	public static final int ErrBadClassname = 16;
+	public static final int ErrBadFieldInfo = 17;
+	public static final int ErrBadMethodInfo = 17; 
+
+	public static final int ErrEmptyConstantPool =18;
+	public static final int ErrMalformedUtf8 = 19;
+	public static final int ErrUnknownConstantTag = 20;
+	public static final int ErrTruncatedInput = 21;
+	public static final int ErrMethodMustBeAbstract = 22;
+	public static final int ErrMalformedAttribute = 23;
+	public static final int ErrBadInterface = 24;
+	public static final int ErrInterfaceMustSubclassObject = 25;
+	public static final int ErrIncorrectInterfaceMethods = 26;
+	public static final int ErrInvalidMethodName = 27;
+	public static final int ErrInvalidMethodSignature = 28;
+    
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ */
+public ClassFormatException(int code) {
+	errorCode = code;
+}
+/**
+ * (c)1998 Object Technology International.
+ * (c)1998 International Business Machines Corporation.
+ * 
+ * 
+ */
+public ClassFormatException(int code, int bufPos) {
+	errorCode = code;
+	bufferPosition = bufPos;
+}
+/**
+ * @return int
+ */
+public int getErrorCode() {
+	return errorCode;
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java b/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
index 0c371b5..2bb489e 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
@@ -1,282 +1,280 @@
-package org.eclipse.jdt.internal.compiler.classfmt;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.env.*;
-
-import org.eclipse.jdt.internal.compiler.impl.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class FieldInfo extends ClassFileStruct implements AttributeNamesConstants, IBinaryField {
-	private Constant constant;
-	private boolean isDeprecated;
-	private int[] constantPoolOffsets;
-	private int accessFlags;
-	private char[] name;
-	private char[] signature;
-	private int attributesCount;
-	private int attributeBytes;
-/**
- * @param classFileBytes byte[]
- * @param offsets int[]
- * @param offset int
- */
-public FieldInfo (byte classFileBytes[], int offsets[], int offset) throws ClassFormatException {
-	super(classFileBytes, offset);
-	constantPoolOffsets = offsets;
-	accessFlags = -1;
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	attributeBytes = readOffset;
-}
-/**
- * Return the constant of the field.
- * Return org.eclipse.jdt.internal.compiler.Constant.NotAConstant if there is none.
- * @return org.eclipse.jdt.internal.compiler.Constant
- */
-public Constant getConstant() {
-	if (constant == null) {
-		// read constant
-		readConstantAttribute();
-	}
-	return constant;
-}
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- * Set the AccDeprecated and AccSynthetic bits if necessary
- * @return int
- */
-public int getModifiers() {
-	if (accessFlags == -1) {
-		// compute the accessflag. Don't forget the deprecated attribute
-		accessFlags = u2At(0);
-		readDeprecatedAttributes();
-		if (isDeprecated) {
-			accessFlags |= AccDeprecated;
-		}
-		if (isSynthetic()) {
-			accessFlags |= AccSynthetic;
-		}
-	}
-	return accessFlags;
-}
-/**
- * Answer the name of the field.
- * @return char[]
- */
-public char[] getName() {
-	if (name == null) {
-		// read the name
-		int utf8Offset = constantPoolOffsets[u2At(2)] - structOffset;
-		name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	}
-	return name;
-}
-/**
- * Answer the resolved name of the receiver's type in the
- * class file format as specified in section 4.3.2 of the Java 2 VM spec.
- *
- * For example:
- *   - java.lang.String is Ljava/lang/String;
- *   - an int is I
- *   - a 2 dimensional array of strings is [[Ljava/lang/String;
- *   - an array of floats is [F
- * @return char[]
- */
-public char[] getTypeName() {
-	if (signature == null) {
-		// read the signature
-		int utf8Offset = constantPoolOffsets[u2At(4)] - structOffset;
-		signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	}
-	return signature;
-}
-/**
- * Return a wrapper that contains the constant of the field.
- * Throws a java.ibm.compiler.java.classfmt.ClassFormatException in case the signature is 
- * incompatible with the constant tag.
- * 
- * @exception java.ibm.compiler.java.classfmt.ClassFormatException
- * @return java.lang.Object
- */
-public Object getWrappedConstantValue() throws ClassFormatException {
-
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation
-			.equals(attributeName, ConstantValueName)) {
-			// read the right constant
-			int relativeOffset = constantPoolOffsets[u2At(14)] - structOffset;
-			switch (u1At(relativeOffset)) {
-				case IntegerTag :
-					return new Integer(i4At(relativeOffset + 1));
-				case FloatTag :
-					return new Float(floatAt(relativeOffset + 1));
-				case DoubleTag :
-					return new Double(doubleAt(relativeOffset + 1));
-				case LongTag :
-					return new Long(i8At(relativeOffset + 1));
-				case StringTag :
-					utf8Offset = constantPoolOffsets[u2At(relativeOffset + 1)] - structOffset;
-					return String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
-			}
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	return null;
-}
-/**
- * Return true if the field has a constant value attribute, false otherwise.
- * @return boolean
- */
-public boolean hasConstant() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	boolean isConstant = false;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, ConstantValueName)) {
-			isConstant = true;
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	return isConstant;
-}
-/**
- * Return true if the field is a synthetic field, false otherwise.
- * @return boolean
- */
-private boolean isSynthetic() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	boolean isSynthetic = false;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, SyntheticName)) {
-			isSynthetic = true;
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	return isSynthetic;
-}
-private void readConstantAttribute() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	boolean isConstant = false;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation
-			.equals(attributeName, ConstantValueName)) {
-			isConstant = true;
-			// read the right constant
-			int relativeOffset = constantPoolOffsets[u2At(14)] - structOffset;
-			switch (u1At(relativeOffset)) {
-				case IntegerTag :
-					char[] sign = getTypeName();
-					if (sign.length == 1) {
-						switch (sign[0]) {
-							case 'Z' : // boolean constant
-								constant = new BooleanConstant(i4At(relativeOffset + 1) == 1);
-								break;
-							case 'I' : // integer constant
-								constant = new IntConstant(i4At(relativeOffset + 1));
-								break;
-							case 'C' : // char constant
-								constant = new CharConstant((char) i4At(relativeOffset + 1));
-								break;
-							case 'B' : // byte constant
-								constant = new ByteConstant((byte) i4At(relativeOffset + 1));
-								break;
-							case 'S' : // short constant
-								constant = new ShortConstant((short) i4At(relativeOffset + 1));
-								break;
-							default:
-								constant = Constant.NotAConstant;                   
-						}
-					} else {
-						constant = Constant.NotAConstant;
-					}
-					break;
-				case FloatTag :
-					constant = new FloatConstant(floatAt(relativeOffset + 1));
-					break;
-				case DoubleTag :
-					constant = new DoubleConstant(doubleAt(relativeOffset + 1));
-					break;
-				case LongTag :
-					constant = new LongConstant(i8At(relativeOffset + 1));
-					break;
-				case StringTag :
-					utf8Offset = constantPoolOffsets[u2At(relativeOffset + 1)] - structOffset;
-					constant = 
-						new StringConstant(
-							String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)))); 
-					break;
-			}
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	if (!isConstant) {
-		constant = Constant.NotAConstant;
-	}
-}
-private void readDeprecatedAttributes() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, DeprecatedName)) {
-			isDeprecated = true;
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-}
-/**
- * Answer the size of the receiver in bytes.
- * 
- * @return int
- */
-public int sizeInBytes() {
-	return attributeBytes;
-}
-public void throwFormatException() throws ClassFormatException {
-	throw new ClassFormatException(ClassFormatException.ErrBadFieldInfo);
-}
-public String toString() {
-	StringBuffer buffer = new StringBuffer(this.getClass().getName());
-	int modifiers = getModifiers();
-	return buffer
-		.append("{"/*nonNLS*/)
-		.append(
-			((modifiers & AccDeprecated) != 0 ? "deprecated "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0001) == 1 ? "public "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0002) == 0x0002 ? "private "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0004) == 0x0004 ? "protected "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0008) == 0x000008 ? "static "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0010) == 0x0010 ? "final "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0040) == 0x0040 ? "volatile "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0080) == 0x0080 ? "transient "/*nonNLS*/ : ""/*nonNLS*/))
-		.append(getTypeName())
-		.append(" "/*nonNLS*/)
-		.append(getName())
-		.append(" "/*nonNLS*/)
-		.append(getConstant())
-		.append("}"/*nonNLS*/)
-		.toString(); 
-}
-}
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class FieldInfo extends ClassFileStruct implements AttributeNamesConstants, IBinaryField {
+	private Constant constant;
+	private boolean isDeprecated;
+	private int[] constantPoolOffsets;
+	private int accessFlags;
+	private char[] name;
+	private char[] signature;
+	private int attributeBytes;
+/**
+ * @param classFileBytes byte[]
+ * @param offsets int[]
+ * @param offset int
+ */
+public FieldInfo (byte classFileBytes[], int offsets[], int offset) throws ClassFormatException {
+	super(classFileBytes, offset);
+	constantPoolOffsets = offsets;
+	accessFlags = -1;
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	attributeBytes = readOffset;
+}
+/**
+ * Return the constant of the field.
+ * Return org.eclipse.jdt.internal.compiler.Constant.NotAConstant if there is none.
+ * @return org.eclipse.jdt.internal.compiler.Constant
+ */
+public Constant getConstant() {
+	if (constant == null) {
+		// read constant
+		readConstantAttribute();
+	}
+	return constant;
+}
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Set the AccDeprecated and AccSynthetic bits if necessary
+ * @return int
+ */
+public int getModifiers() {
+	if (accessFlags == -1) {
+		// compute the accessflag. Don't forget the deprecated attribute
+		accessFlags = u2At(0);
+		readDeprecatedAttributes();
+		if (isDeprecated) {
+			accessFlags |= AccDeprecated;
+		}
+		if (isSynthetic()) {
+			accessFlags |= AccSynthetic;
+		}
+	}
+	return accessFlags;
+}
+/**
+ * Answer the name of the field.
+ * @return char[]
+ */
+public char[] getName() {
+	if (name == null) {
+		// read the name
+		int utf8Offset = constantPoolOffsets[u2At(2)] - structOffset;
+		name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return name;
+}
+/**
+ * Answer the resolved name of the receiver's type in the
+ * class file format as specified in section 4.3.2 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - java.lang.String is Ljava/lang/String;
+ *   - an int is I
+ *   - a 2 dimensional array of strings is [[Ljava/lang/String;
+ *   - an array of floats is [F
+ * @return char[]
+ */
+public char[] getTypeName() {
+	if (signature == null) {
+		// read the signature
+		int utf8Offset = constantPoolOffsets[u2At(4)] - structOffset;
+		signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return signature;
+}
+/**
+ * Return a wrapper that contains the constant of the field.
+ * Throws a java.ibm.compiler.java.classfmt.ClassFormatException in case the signature is 
+ * incompatible with the constant tag.
+ * 
+ * @exception java.ibm.compiler.java.classfmt.ClassFormatException
+ * @return java.lang.Object
+ */
+public Object getWrappedConstantValue() throws ClassFormatException {
+
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation
+			.equals(attributeName, ConstantValueName)) {
+			// read the right constant
+			int relativeOffset = constantPoolOffsets[u2At(14)] - structOffset;
+			switch (u1At(relativeOffset)) {
+				case IntegerTag :
+					return new Integer(i4At(relativeOffset + 1));
+				case FloatTag :
+					return new Float(floatAt(relativeOffset + 1));
+				case DoubleTag :
+					return new Double(doubleAt(relativeOffset + 1));
+				case LongTag :
+					return new Long(i8At(relativeOffset + 1));
+				case StringTag :
+					utf8Offset = constantPoolOffsets[u2At(relativeOffset + 1)] - structOffset;
+					return String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	return null;
+}
+/**
+ * Return true if the field has a constant value attribute, false otherwise.
+ * @return boolean
+ */
+public boolean hasConstant() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	boolean isConstant = false;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, ConstantValueName)) {
+			isConstant = true;
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	return isConstant;
+}
+/**
+ * Return true if the field is a synthetic field, false otherwise.
+ * @return boolean
+ */
+private boolean isSynthetic() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	boolean isSynthetic = false;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, SyntheticName)) {
+			isSynthetic = true;
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	return isSynthetic;
+}
+private void readConstantAttribute() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	boolean isConstant = false;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation
+			.equals(attributeName, ConstantValueName)) {
+			isConstant = true;
+			// read the right constant
+			int relativeOffset = constantPoolOffsets[u2At(14)] - structOffset;
+			switch (u1At(relativeOffset)) {
+				case IntegerTag :
+					char[] sign = getTypeName();
+					if (sign.length == 1) {
+						switch (sign[0]) {
+							case 'Z' : // boolean constant
+								constant = new BooleanConstant(i4At(relativeOffset + 1) == 1);
+								break;
+							case 'I' : // integer constant
+								constant = new IntConstant(i4At(relativeOffset + 1));
+								break;
+							case 'C' : // char constant
+								constant = new CharConstant((char) i4At(relativeOffset + 1));
+								break;
+							case 'B' : // byte constant
+								constant = new ByteConstant((byte) i4At(relativeOffset + 1));
+								break;
+							case 'S' : // short constant
+								constant = new ShortConstant((short) i4At(relativeOffset + 1));
+								break;
+							default:
+								constant = Constant.NotAConstant;                   
+						}
+					} else {
+						constant = Constant.NotAConstant;
+					}
+					break;
+				case FloatTag :
+					constant = new FloatConstant(floatAt(relativeOffset + 1));
+					break;
+				case DoubleTag :
+					constant = new DoubleConstant(doubleAt(relativeOffset + 1));
+					break;
+				case LongTag :
+					constant = new LongConstant(i8At(relativeOffset + 1));
+					break;
+				case StringTag :
+					utf8Offset = constantPoolOffsets[u2At(relativeOffset + 1)] - structOffset;
+					constant = 
+						new StringConstant(
+							String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)))); 
+					break;
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	if (!isConstant) {
+		constant = Constant.NotAConstant;
+	}
+}
+private void readDeprecatedAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, DeprecatedName)) {
+			isDeprecated = true;
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+}
+/**
+ * Answer the size of the receiver in bytes.
+ * 
+ * @return int
+ */
+public int sizeInBytes() {
+	return attributeBytes;
+}
+public void throwFormatException() throws ClassFormatException {
+	throw new ClassFormatException(ClassFormatException.ErrBadFieldInfo);
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer(this.getClass().getName());
+	int modifiers = getModifiers();
+	return buffer
+		.append("{"/*nonNLS*/)
+		.append(
+			((modifiers & AccDeprecated) != 0 ? "deprecated "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0001) == 1 ? "public "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0002) == 0x0002 ? "private "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0004) == 0x0004 ? "protected "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0008) == 0x000008 ? "static "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0010) == 0x0010 ? "final "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0040) == 0x0040 ? "volatile "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0080) == 0x0080 ? "transient "/*nonNLS*/ : ""/*nonNLS*/))
+		.append(getTypeName())
+		.append(" "/*nonNLS*/)
+		.append(getName())
+		.append(" "/*nonNLS*/)
+		.append(getConstant())
+		.append("}"/*nonNLS*/)
+		.toString(); 
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
index 06146a5..345735e 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
@@ -1,210 +1,208 @@
-package org.eclipse.jdt.internal.compiler.classfmt;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.env.*;
-
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-public class MethodInfo extends ClassFileStruct implements IBinaryMethod, AttributeNamesConstants {
-	private char[][] exceptionNames;
-	private int[] constantPoolOffsets;
-	private boolean isDeprecated;
-	private int accessFlags;
-	private char[] name;
-	private char[] signature;
-	private int attributesCount;
-	private int attributeBytes;
-	static private final char[][] noException = new char[0][0];
-	private int decodeIndex;
-/**
- * @param classFileBytes byte[]
- * @param offsets int[]
- * @param offset int
- */
-public MethodInfo (byte classFileBytes[], int offsets[], int offset) throws ClassFormatException {
-	super(classFileBytes, offset);
-	constantPoolOffsets = offsets;
-	accessFlags = -1;
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	attributeBytes = readOffset;
-}
-/**
- * Answer the resolved names of the exception types in the
- * class file format as specified in section 4.2 of the Java 2 VM spec
- * or null if the array is empty.
- *
- * For example, java.lang.String is java/lang/String.
- * @return char[][]
- */
-public char[][] getExceptionTypeNames() {
-	if (exceptionNames == null) {
-		readExceptionAttributes();
-	}
-	return exceptionNames;
-}
-/**
- * Answer the receiver's method descriptor which describes the parameter &
- * return types as specified in section 4.3.3 of the Java 2 VM spec.
- *
- * For example:
- *   - int foo(String) is (Ljava/lang/String;)I
- *   - void foo(Object[]) is (I)[Ljava/lang/Object;
- * @return char[]
- */
-public char[] getMethodDescriptor() {
-	if (signature == null) {
-		// read the name
-		int utf8Offset = constantPoolOffsets[u2At(4)] - structOffset;
-		signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	}
-	return signature;
-}
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- * Set the AccDeprecated and AccSynthetic bits if necessary
- * @return int
- */
-public int getModifiers() {
-	if (accessFlags == -1) {
-		// compute the accessflag. Don't forget the deprecated attribute
-		accessFlags = u2At(0);
-		readDeprecatedAttributes();
-		if (isDeprecated) {
-			accessFlags |= AccDeprecated;
-		}
-		if (isSynthetic()) {
-			accessFlags |= AccSynthetic;
-		}
-	}
-	return accessFlags;
-}
-/**
- * Answer the name of the method.
- *
- * For a constructor, answer <init> & <clinit> for a clinit method.
- * @return char[]
- */
-public char[] getSelector() {
-	if (name == null) {
-		// read the name
-		int utf8Offset = constantPoolOffsets[u2At(2)] - structOffset;
-		name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	}
-	return name;
-}
-/**
- * Answer true if the method is a class initializer, false otherwise.
- * @return boolean
- */
-public boolean isClinit() {
-	char[] selector = getSelector();
-	return selector[0] == '<' && selector.length == 8; // Can only match <clinit>
-}
-/**
- * Answer true if the method is a constructor, false otherwise.
- * @return boolean
- */
-public boolean isConstructor() {
-	char[] selector = getSelector();
-	return selector[0] == '<' && selector.length == 6; // Can only match <init>
-}
-/**
- * Return true if the field is a synthetic method, false otherwise.
- * @return boolean
- */
-private boolean isSynthetic() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	boolean isSynthetic = false;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, SyntheticName)) {
-			isSynthetic = true;
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-	return isSynthetic;
-}
-private void readDeprecatedAttributes() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, DeprecatedName)) {
-			isDeprecated = true;
-		}
-		readOffset += (6 + u4At(readOffset + 2));
-	}
-}
-private void readExceptionAttributes() {
-	int attributesCount = u2At(6);
-	int readOffset = 8;
-	for (int i = 0; i < attributesCount; i++) {
-		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
-		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-		if (CharOperation.equals(attributeName, ExceptionsName)) {
-			// read the number of exception entries
-			int entriesNumber = u2At(readOffset + 6);
-			// place the readOffset at the beginning of the exceptions table
-			readOffset += 8;
-			if (entriesNumber == 0) {
-				exceptionNames = noException;
-			} else {
-				exceptionNames = new char[entriesNumber][];
-				for (int j = 0; j < entriesNumber; j++) {
-					utf8Offset = 
-						constantPoolOffsets[u2At(
-							constantPoolOffsets[u2At(readOffset)] - structOffset + 1)]
-							- structOffset; 
-					exceptionNames[j] = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-					readOffset += 2;
-				}
-			}
-		} else {
-			readOffset += (6 + u4At(readOffset + 2));
-		}
-	}
-	if (exceptionNames == null) {
-		exceptionNames = noException;
-	}
-}
-/**
- * Answer the size of the receiver in bytes.
- * 
- * @return int
- */
-public int sizeInBytes() {
-	return attributeBytes;
-}
-public String toString() {
-	int modifiers = getModifiers();
-	StringBuffer buffer = new StringBuffer(this.getClass().getName());
-	return buffer
-		.append("{"/*nonNLS*/)
-		.append(
-			((modifiers & AccDeprecated) != 0 ? "deprecated "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0001) == 1 ? "public "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0002) == 0x0002 ? "private "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0004) == 0x0004 ? "protected "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0008) == 0x000008 ? "static "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0010) == 0x0010 ? "final "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0040) == 0x0040 ? "volatile "/*nonNLS*/ : ""/*nonNLS*/)
-				+ ((modifiers & 0x0080) == 0x0080 ? "transient "/*nonNLS*/ : ""/*nonNLS*/))
-		.append(getSelector())
-		.append(getMethodDescriptor())
-		.append("}"/*nonNLS*/)
-		.toString(); 
-}
-}
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class MethodInfo extends ClassFileStruct implements IBinaryMethod, AttributeNamesConstants {
+	private char[][] exceptionNames;
+	private int[] constantPoolOffsets;
+	private boolean isDeprecated;
+	private int accessFlags;
+	private char[] name;
+	private char[] signature;
+	private int attributeBytes;
+	static private final char[][] noException = new char[0][0];
+
+/**
+ * @param classFileBytes byte[]
+ * @param offsets int[]
+ * @param offset int
+ */
+public MethodInfo (byte classFileBytes[], int offsets[], int offset) throws ClassFormatException {
+	super(classFileBytes, offset);
+	constantPoolOffsets = offsets;
+	accessFlags = -1;
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	attributeBytes = readOffset;
+}
+/**
+ * Answer the resolved names of the exception types in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[][]
+ */
+public char[][] getExceptionTypeNames() {
+	if (exceptionNames == null) {
+		readExceptionAttributes();
+	}
+	return exceptionNames;
+}
+/**
+ * Answer the receiver's method descriptor which describes the parameter &
+ * return types as specified in section 4.3.3 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - int foo(String) is (Ljava/lang/String;)I
+ *   - void foo(Object[]) is (I)[Ljava/lang/Object;
+ * @return char[]
+ */
+public char[] getMethodDescriptor() {
+	if (signature == null) {
+		// read the name
+		int utf8Offset = constantPoolOffsets[u2At(4)] - structOffset;
+		signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return signature;
+}
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Set the AccDeprecated and AccSynthetic bits if necessary
+ * @return int
+ */
+public int getModifiers() {
+	if (accessFlags == -1) {
+		// compute the accessflag. Don't forget the deprecated attribute
+		accessFlags = u2At(0);
+		readDeprecatedAttributes();
+		if (isDeprecated) {
+			accessFlags |= AccDeprecated;
+		}
+		if (isSynthetic()) {
+			accessFlags |= AccSynthetic;
+		}
+	}
+	return accessFlags;
+}
+/**
+ * Answer the name of the method.
+ *
+ * For a constructor, answer <init> & <clinit> for a clinit method.
+ * @return char[]
+ */
+public char[] getSelector() {
+	if (name == null) {
+		// read the name
+		int utf8Offset = constantPoolOffsets[u2At(2)] - structOffset;
+		name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return name;
+}
+/**
+ * Answer true if the method is a class initializer, false otherwise.
+ * @return boolean
+ */
+public boolean isClinit() {
+	char[] selector = getSelector();
+	return selector[0] == '<' && selector.length == 8; // Can only match <clinit>
+}
+/**
+ * Answer true if the method is a constructor, false otherwise.
+ * @return boolean
+ */
+public boolean isConstructor() {
+	char[] selector = getSelector();
+	return selector[0] == '<' && selector.length == 6; // Can only match <init>
+}
+/**
+ * Return true if the field is a synthetic method, false otherwise.
+ * @return boolean
+ */
+private boolean isSynthetic() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	boolean isSynthetic = false;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(8)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, SyntheticName)) {
+			isSynthetic = true;
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	return isSynthetic;
+}
+private void readDeprecatedAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, DeprecatedName)) {
+			isDeprecated = true;
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+}
+private void readExceptionAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = constantPoolOffsets[u2At(readOffset)] - structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, ExceptionsName)) {
+			// read the number of exception entries
+			int entriesNumber = u2At(readOffset + 6);
+			// place the readOffset at the beginning of the exceptions table
+			readOffset += 8;
+			if (entriesNumber == 0) {
+				exceptionNames = noException;
+			} else {
+				exceptionNames = new char[entriesNumber][];
+				for (int j = 0; j < entriesNumber; j++) {
+					utf8Offset = 
+						constantPoolOffsets[u2At(
+							constantPoolOffsets[u2At(readOffset)] - structOffset + 1)]
+							- structOffset; 
+					exceptionNames[j] = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+					readOffset += 2;
+				}
+			}
+		} else {
+			readOffset += (6 + u4At(readOffset + 2));
+		}
+	}
+	if (exceptionNames == null) {
+		exceptionNames = noException;
+	}
+}
+/**
+ * Answer the size of the receiver in bytes.
+ * 
+ * @return int
+ */
+public int sizeInBytes() {
+	return attributeBytes;
+}
+public String toString() {
+	int modifiers = getModifiers();
+	StringBuffer buffer = new StringBuffer(this.getClass().getName());
+	return buffer
+		.append("{"/*nonNLS*/)
+		.append(
+			((modifiers & AccDeprecated) != 0 ? "deprecated "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0001) == 1 ? "public "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0002) == 0x0002 ? "private "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0004) == 0x0004 ? "protected "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0008) == 0x000008 ? "static "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0010) == 0x0010 ? "final "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0040) == 0x0040 ? "volatile "/*nonNLS*/ : ""/*nonNLS*/)
+				+ ((modifiers & 0x0080) == 0x0080 ? "transient "/*nonNLS*/ : ""/*nonNLS*/))
+		.append(getSelector())
+		.append(getMethodDescriptor())
+		.append("}"/*nonNLS*/)
+		.toString(); 
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
index cff7340..52a2d68 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
@@ -1,18 +1,17 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
- 
-public interface AttributeNamesConstants {
-	final char[] SyntheticName = new char[] {'S', 'y', 'n', 't', 'h', 'e', 't', 'i', 'c'};
-	final char[] ConstantValueName = new char[] {'C', 'o', 'n', 's', 't', 'a', 'n', 't', 'V', 'a', 'l', 'u', 'e'};
-	final char[] LineNumberTableName = new char[] {'L', 'i', 'n', 'e', 'N', 'u', 'm', 'b', 'e', 'r', 'T', 'a', 'b', 'l', 'e'};
-	final char[] LocalVariableTableName = new char[] {'L', 'o', 'c', 'a', 'l', 'V', 'a', 'r', 'i', 'a', 'b', 'l', 'e', 'T', 'a', 'b', 'l', 'e'};
-	final char[] InnerClassName = new char[] {'I', 'n', 'n', 'e', 'r', 'C', 'l', 'a', 's', 's', 'e', 's'};
-	final char[] CodeName = new char[] {'C', 'o', 'd', 'e'};
-	final char[] ExceptionsName = new char[] {'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n', 's'};
-	final char[] SourceName = new char[] {'S', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e'};
-	final char[] DeprecatedName = new char[] {'D', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd'};
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface AttributeNamesConstants {
+	final char[] SyntheticName = new char[] {'S', 'y', 'n', 't', 'h', 'e', 't', 'i', 'c'};
+	final char[] ConstantValueName = new char[] {'C', 'o', 'n', 's', 't', 'a', 'n', 't', 'V', 'a', 'l', 'u', 'e'};
+	final char[] LineNumberTableName = new char[] {'L', 'i', 'n', 'e', 'N', 'u', 'm', 'b', 'e', 'r', 'T', 'a', 'b', 'l', 'e'};
+	final char[] LocalVariableTableName = new char[] {'L', 'o', 'c', 'a', 'l', 'V', 'a', 'r', 'i', 'a', 'b', 'l', 'e', 'T', 'a', 'b', 'l', 'e'};
+	final char[] InnerClassName = new char[] {'I', 'n', 'n', 'e', 'r', 'C', 'l', 'a', 's', 's', 'e', 's'};
+	final char[] CodeName = new char[] {'C', 'o', 'd', 'e'};
+	final char[] ExceptionsName = new char[] {'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n', 's'};
+	final char[] SourceName = new char[] {'S', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e'};
+	final char[] DeprecatedName = new char[] {'D', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd'};
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
index 0a36638..0b22cf1 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
@@ -1,76 +1,74 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public class CaseLabel extends Label {
-	public int instructionPosition = POS_NOT_SET;
-	public int backwardsBranch = POS_NOT_SET;
-/**
- * CaseLabel constructor comment.
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
- */
-public CaseLabel(CodeStream codeStream) {
-	super(codeStream);
-}
-/*
-* Put down  a refernece to the array at the location in the codestream.
-*/
-void branch() {
-	if (position == POS_NOT_SET) {
-		addForwardReference(codeStream.position);
-		// Leave 4 bytes free to generate the jump offset afterwards
-		codeStream.position += 4;
-		codeStream.classFileOffset += 4;
-	} else { //Position is set. Write it!
-		codeStream.writeSignedWord(position - codeStream.position + 1);
-	}
-}
-/*
-* Put down  a refernece to the array at the location in the codestream.
-*/
-void branchWide() {
-	if (position == POS_NOT_SET) {
-		addForwardReference(codeStream.position);
-		// Leave 4 bytes free to generate the jump offset afterwards
-		codeStream.position += 4;
-	} else { //Position is set. Write it!
-		codeStream.writeSignedWord(position - codeStream.position + 1);
-	}
-}
-public boolean isStandardLabel(){
-	return false;
-}
-/*
-* Put down  a refernece to the array at the location in the codestream.
-*/
-public void place() {
-	position = codeStream.position;
-	if (instructionPosition == POS_NOT_SET)
-		backwardsBranch = position;
-	else {
-		int offset = position - instructionPosition;
-		for (int i = 0; i < forwardReferenceCount; i++) {
-			codeStream.writeSignedWord(forwardReferences[i], offset);
-		}
-		// add the label int the codeStream labels collection
-		codeStream.addLabel(this);
-	}
-}
-/*
-* Put down  a refernece to the array at the location in the codestream.
-*/
-void placeInstruction() {
-	if (instructionPosition == POS_NOT_SET) {
-		instructionPosition = codeStream.position;
-		if (backwardsBranch != POS_NOT_SET) {
-			int offset = backwardsBranch - instructionPosition;
-			for (int i = 0; i < forwardReferenceCount; i++)
-				codeStream.writeSignedWord(forwardReferences[i], offset);
-			backwardsBranch = POS_NOT_SET;
-		}
-	}
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class CaseLabel extends Label {
+	public int instructionPosition = POS_NOT_SET;
+	public int backwardsBranch = POS_NOT_SET;
+/**
+ * CaseLabel constructor comment.
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public CaseLabel(CodeStream codeStream) {
+	super(codeStream);
+}
+/*
+* Put down  a refernece to the array at the location in the codestream.
+*/
+void branch() {
+	if (position == POS_NOT_SET) {
+		addForwardReference(codeStream.position);
+		// Leave 4 bytes free to generate the jump offset afterwards
+		codeStream.position += 4;
+		codeStream.classFileOffset += 4;
+	} else { //Position is set. Write it!
+		codeStream.writeSignedWord(position - codeStream.position + 1);
+	}
+}
+/*
+* Put down  a refernece to the array at the location in the codestream.
+*/
+void branchWide() {
+	if (position == POS_NOT_SET) {
+		addForwardReference(codeStream.position);
+		// Leave 4 bytes free to generate the jump offset afterwards
+		codeStream.position += 4;
+	} else { //Position is set. Write it!
+		codeStream.writeSignedWord(position - codeStream.position + 1);
+	}
+}
+public boolean isStandardLabel(){
+	return false;
+}
+/*
+* Put down  a refernece to the array at the location in the codestream.
+*/
+public void place() {
+	position = codeStream.position;
+	if (instructionPosition == POS_NOT_SET)
+		backwardsBranch = position;
+	else {
+		int offset = position - instructionPosition;
+		for (int i = 0; i < forwardReferenceCount; i++) {
+			codeStream.writeSignedWord(forwardReferences[i], offset);
+		}
+		// add the label int the codeStream labels collection
+		codeStream.addLabel(this);
+	}
+}
+/*
+* Put down  a refernece to the array at the location in the codestream.
+*/
+void placeInstruction() {
+	if (instructionPosition == POS_NOT_SET) {
+		instructionPosition = codeStream.position;
+		if (backwardsBranch != POS_NOT_SET) {
+			int offset = backwardsBranch - instructionPosition;
+			for (int i = 0; i < forwardReferenceCount; i++)
+				codeStream.writeSignedWord(forwardReferences[i], offset);
+			backwardsBranch = POS_NOT_SET;
+		}
+	}
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 5e581b2..f4a1652 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -4,9 +4,6 @@
  * (c) Copyright IBM Corp. 2000, 2001.
  * All Rights Reserved.
  */
-import java.io.*;
-import java.util.*;
-
 import org.eclipse.jdt.internal.compiler.*;
 
 import org.eclipse.jdt.internal.compiler.impl.*;
@@ -14,8 +11,6 @@
 import org.eclipse.jdt.internal.compiler.classfmt.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
 
 public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, BaseTypes, TypeConstants, TypeIds {
 	// It will be responsible for the following items.
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index e87240f..d10bf08 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -1,2682 +1,2680 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import java.io.*;
-
-import org.eclipse.jdt.internal.compiler.ClassFile;
-
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-/**
- * This type is used to store all the constant pool entries.
- */
-public class ConstantPool implements ClassFileConstants, TypeIds {
-	public static final int DOUBLE_INITIAL_SIZE = 5;
-	public static final int FLOAT_INITIAL_SIZE = 3;
-	public static final int INT_INITIAL_SIZE = 248;
-	public static final int LONG_INITIAL_SIZE = 5;
-	public static final int UTF8_INITIAL_SIZE = 778;
-	public static final int STRING_INITIAL_SIZE = 761;
-	public static final int FIELD_INITIAL_SIZE = 156;
-	public static final int METHOD_INITIAL_SIZE = 236;
-	public static final int INTERFACE_INITIAL_SIZE = 50;
-	public static final int CLASS_INITIAL_SIZE = 86;
-	public static final int NAMEANDTYPE_INITIAL_SIZE = 272;
-	public static final int CONSTANTPOOL_INITIAL_SIZE = 2000;
-	public static final int CONSTANTPOOL_GROW_SIZE = 6000;
-	protected DoubleCache doubleCache;
-	protected FloatCache floatCache;
-	protected IntegerCache intCache;
-	protected LongCache longCache;
-	public CharArrayCache UTF8Cache;
-	protected CharArrayCache stringCache;
-	protected ObjectCache fieldCache;
-	protected ObjectCache methodCache;
-	protected ObjectCache interfaceMethodCache;
-	protected ObjectCache classCache;
-	protected FieldNameAndTypeCache nameAndTypeCacheForFields;
-	protected MethodNameAndTypeCache nameAndTypeCacheForMethods;
-	int[] wellKnownTypes = new int[20];
-	int[] wellKnownMethods = new int[26];
-	int[] wellKnownFields = new int[10];
-	int[] wellKnownFieldNameAndTypes = new int[2];
-	int[] wellKnownMethodNameAndTypes = new int[24];
-	public byte[] poolContent;
-	public int currentIndex = 1;
-	public int currentOffset;
-	// predefined constant index for well known types
-	final static int JAVA_LANG_BOOLEAN_TYPE = 0;
-	final static int JAVA_LANG_BYTE_TYPE = 1;
-	final static int JAVA_LANG_CHARACTER_TYPE = 2;
-	final static int JAVA_LANG_DOUBLE_TYPE = 3;
-	final static int JAVA_LANG_FLOAT_TYPE = 4;
-	final static int JAVA_LANG_INTEGER_TYPE = 5;
-	final static int JAVA_LANG_LONG_TYPE = 6;
-	final static int JAVA_LANG_SHORT_TYPE = 7;
-	final static int JAVA_LANG_VOID_TYPE = 8;
-	final static int JAVA_LANG_CLASS_TYPE = 9;
-	final static int JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE = 10;
-	final static int JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE = 11;
-	final static int JAVA_LANG_OBJECT_TYPE = 12;
-	final static int JAVA_LANG_STRING_TYPE = 13;
-	final static int JAVA_LANG_STRINGBUFFER_TYPE = 14;
-	final static int JAVA_LANG_SYSTEM_TYPE = 15;
-	final static int JAVA_LANG_THROWABLE_TYPE = 16;
-	final static int JAVA_LANG_ERROR_TYPE = 17;
-	final static int JAVA_LANG_EXCEPTION_TYPE = 18;
-	final static int JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE = 19;
-	// predefined constant index for well known fields  
-	final static int TYPE_BYTE_FIELD = 0;
-	final static int TYPE_SHORT_FIELD = 1;
-	final static int TYPE_CHARACTER_FIELD = 2;
-	final static int TYPE_INTEGER_FIELD = 3;
-	final static int TYPE_LONG_FIELD = 4;
-	final static int TYPE_FLOAT_FIELD = 5;
-	final static int TYPE_DOUBLE_FIELD = 6;
-	final static int TYPE_BOOLEAN_FIELD = 7;
-	final static int TYPE_VOID_FIELD = 8;
-	final static int OUT_SYSTEM_FIELD = 9;
-	// predefined constant index for well known methods 
-	final static int FORNAME_CLASS_METHOD = 0;
-	final static int NOCLASSDEFFOUNDERROR_CONSTR_METHOD = 1;
-	final static int APPEND_INT_METHOD = 2;
-	final static int APPEND_FLOAT_METHOD = 3;
-	final static int APPEND_LONG_METHOD = 4;
-	final static int APPEND_OBJECT_METHOD = 5;
-	final static int APPEND_CHAR_METHOD = 6;
-	final static int APPEND_STRING_METHOD = 7;
-	final static int APPEND_BOOLEAN_METHOD = 8;
-	final static int APPEND_DOUBLE_METHOD = 9;
-	final static int STRINGBUFFER_STRING_CONSTR_METHOD = 10;
-	final static int STRINGBUFFER_DEFAULT_CONSTR_METHOD = 11;
-	final static int STRINGBUFFER_TOSTRING_METHOD = 12;
-	final static int SYSTEM_EXIT_METHOD = 13;
-	final static int THROWABLE_GETMESSAGE_METHOD = 14;
-	final static int JAVALANGERROR_CONSTR_METHOD = 15;
-	final static int GETCONSTRUCTOR_CLASS_METHOD = 16;
-	final static int NEWINSTANCE_CONSTRUCTOR_METHOD = 17;
-	final static int STRING_INTERN_METHOD = 18;
-	final static int VALUEOF_INT_METHOD = 19;
-	final static int VALUEOF_FLOAT_METHOD = 20;
-	final static int VALUEOF_LONG_METHOD = 21;
-	final static int VALUEOF_OBJECT_METHOD = 22;
-	final static int VALUEOF_CHAR_METHOD = 23;
-	final static int VALUEOF_BOOLEAN_METHOD = 24;
-	final static int VALUEOF_DOUBLE_METHOD = 25;
-	// predefined constant index for well known name and type for fields
-	final static int TYPE_JAVALANGCLASS_NAME_AND_TYPE = 0;
-	final static int OUT_SYSTEM_NAME_AND_TYPE = 1;
-	// predefined constant index for well known name and type for methods
-	final static int FORNAME_CLASS_METHOD_NAME_AND_TYPE = 0;
-	final static int STRING_CONSTR_METHOD_NAME_AND_TYPE = 1;
-	final static int DEFAULT_CONSTR_METHOD_NAME_AND_TYPE = 2;
-	final static int APPEND_INT_METHOD_NAME_AND_TYPE = 3;
-	final static int APPEND_FLOAT_METHOD_NAME_AND_TYPE = 4;
-	final static int APPEND_LONG_METHOD_NAME_AND_TYPE = 5;
-	final static int APPEND_OBJECT_METHOD_NAME_AND_TYPE = 6;
-	final static int APPEND_CHAR_METHOD_NAME_AND_TYPE = 7;
-	final static int APPEND_STRING_METHOD_NAME_AND_TYPE = 8;
-	final static int APPEND_BOOLEAN_METHOD_NAME_AND_TYPE = 9;
-	final static int APPEND_DOUBLE_METHOD_NAME_AND_TYPE = 10;
-	final static int TOSTRING_METHOD_NAME_AND_TYPE = 11;
-	final static int EXIT_METHOD_NAME_AND_TYPE = 12;
-	final static int GETMESSAGE_METHOD_NAME_AND_TYPE = 13;
-	final static int GETCONSTRUCTOR_METHOD_NAME_AND_TYPE = 14;
-	final static int NEWINSTANCE_METHOD_NAME_AND_TYPE = 15;
-	final static int INTERN_METHOD_NAME_AND_TYPE = 16;
-	final static int VALUEOF_INT_METHOD_NAME_AND_TYPE = 17;
-	final static int VALUEOF_FLOAT_METHOD_NAME_AND_TYPE = 18;
-	final static int VALUEOF_LONG_METHOD_NAME_AND_TYPE = 19;
-	final static int VALUEOF_OBJECT_METHOD_NAME_AND_TYPE = 20;
-	final static int VALUEOF_CHAR_METHOD_NAME_AND_TYPE = 21;
-	final static int VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE = 22;
-	final static int VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE = 23;
-	public ClassFile classFile;
-
-/**
- * ConstantPool constructor comment.
- */
-public ConstantPool(ClassFile classFile) {
-	this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE);
-	this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE);
-	this.fieldCache = new ObjectCache(FIELD_INITIAL_SIZE);
-	this.methodCache = new ObjectCache(METHOD_INITIAL_SIZE);
-	this.interfaceMethodCache = new ObjectCache(INTERFACE_INITIAL_SIZE);
-	this.classCache = new ObjectCache(CLASS_INITIAL_SIZE);
-	this.nameAndTypeCacheForMethods = new MethodNameAndTypeCache(NAMEANDTYPE_INITIAL_SIZE);
-	this.nameAndTypeCacheForFields = new FieldNameAndTypeCache(NAMEANDTYPE_INITIAL_SIZE);   
-	this.poolContent = classFile.header;
-	this.currentOffset = classFile.headerOffset;
-	// currentOffset is initialized to 0 by default
-	this.currentIndex = 1;
-	this.classFile = classFile;
-}
-/**
- * Return the content of the receiver
- */
-public byte[] dumpBytes() {
-	System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset);
-	return poolContent;
-}
-/**
- * Return the index of the @fieldBinding.
- *
- * Returns -1 if the @fieldBinding is not a predefined fieldBinding, 
- * the right index otherwise.
- *
- * @param fieldBinding com.ibm.compiler.namelookup.FieldBinding
- * @return <CODE>int</CODE>
- */
-public int indexOfWellKnownFieldNameAndType(FieldBinding fieldBinding) {
-	if ((fieldBinding.type.id == T_JavaLangClass) && (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE)))
-		return TYPE_JAVALANGCLASS_NAME_AND_TYPE;
-	if ((fieldBinding.type.id == T_JavaIoPrintStream) && (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.Out)))
-		return OUT_SYSTEM_NAME_AND_TYPE;
-	return -1;
-}
-/**
- * Return the index of the @fieldBinding.
- *
- * Returns -1 if the @fieldBinding is not a predefined fieldBinding, 
- * the right index otherwise.
- *
- * @param fieldBinding com.ibm.compiler.namelookup.FieldBinding
- * @return <CODE>int</CODE>
- */
-public int indexOfWellKnownFields(FieldBinding fieldBinding) {
-	switch (fieldBinding.declaringClass.id) {
-		case T_JavaLangByte :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_BYTE_FIELD;
-			break;
-		case T_JavaLangShort :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_SHORT_FIELD;
-			break;
-		case T_JavaLangCharacter :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_CHARACTER_FIELD;
-			break;
-		case T_JavaLangInteger :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_INTEGER_FIELD;
-			break;
-		case T_JavaLangLong :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_LONG_FIELD;
-			break;
-		case T_JavaLangFloat :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_FLOAT_FIELD;
-			break;
-		case T_JavaLangDouble :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_DOUBLE_FIELD;
-			break;
-		case T_JavaLangBoolean :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_BOOLEAN_FIELD;
-			break;
-		case T_JavaLangVoid :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
-				return TYPE_VOID_FIELD;
-			break;
-		case T_JavaLangSystem :
-			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.Out))
-				return OUT_SYSTEM_FIELD;
-	}
-	return -1;
-}
-/**
- * Return the index of the @methodBinding.
- *
- * Returns -1 if the @methodBinding is not a predefined methodBinding, 
- * the right index otherwise.
- *
- * @param methodBinding com.ibm.compiler.namelookup.MethodBinding
- * @return <CODE>int</CODE>
- */
-public int indexOfWellKnownMethodNameAndType(MethodBinding methodBinding) {
-	char firstChar = methodBinding.selector[0];
-	switch (firstChar) {
-		case 'f' :
-			if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (methodBinding.returnType.id == T_JavaLangClass) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ForName))) {
-				// This method binding is forName(java.lang.String)
-				return FORNAME_CLASS_METHOD_NAME_AND_TYPE;
-			}
-			break;
-		case '<' :
-			if (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init)) {
-				if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.StringConstructorSignature)) {
-					// This method binding is (java.lang.String)V
-					return STRING_CONSTR_METHOD_NAME_AND_TYPE;
-				} else
-					if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.DefaultConstructorSignature)) {
-						return DEFAULT_CONSTR_METHOD_NAME_AND_TYPE;
-					}
-			}
-			break;
-		case 'a' :
-			if ((methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangStringBuffer) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Append))) {
-				switch (methodBinding.parameters[0].id) {
-					case T_int :
-					case T_byte :
-					case T_short :
-						// This method binding is append(int)
-						return APPEND_INT_METHOD_NAME_AND_TYPE;
-					case T_float :
-						// This method binding is append(float)
-						return APPEND_FLOAT_METHOD_NAME_AND_TYPE;
-					case T_long :
-						// This method binding is append(long)
-						return APPEND_LONG_METHOD_NAME_AND_TYPE;
-					case T_JavaLangObject :
-						// This method binding is append(java.lang.Object)
-						return APPEND_OBJECT_METHOD_NAME_AND_TYPE;
-					case T_char :
-						// This method binding is append(char)
-						return APPEND_CHAR_METHOD_NAME_AND_TYPE;
-					case T_JavaLangString :
-						// This method binding is append(java.lang.String)
-						return APPEND_STRING_METHOD_NAME_AND_TYPE;
-					case T_boolean :
-						// This method binding is append(boolean)
-						return APPEND_BOOLEAN_METHOD_NAME_AND_TYPE;
-					case T_double :
-						// This method binding is append(double)
-						return APPEND_DOUBLE_METHOD_NAME_AND_TYPE;
-				}
-			}
-			break;
-		case 't' :
-			if ((methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ToString))) {
-				// This method binding is toString()
-				return TOSTRING_METHOD_NAME_AND_TYPE;
-			}
-			break;
-		case 'v' :
-			if ((methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ValueOf))) {
-				switch(methodBinding.parameters[0].id) {
-					case T_Object:
-						return VALUEOF_OBJECT_METHOD_NAME_AND_TYPE;
-					case T_int:
-					case T_short:
-					case T_byte:
-						return VALUEOF_INT_METHOD_NAME_AND_TYPE;
-					case T_long:
-						return VALUEOF_LONG_METHOD_NAME_AND_TYPE;
-					case T_float:
-						return VALUEOF_FLOAT_METHOD_NAME_AND_TYPE;
-					case T_double:
-						return VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE;
-					case T_boolean:
-						return VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE;
-					case T_char:
-						return VALUEOF_CHAR_METHOD_NAME_AND_TYPE;
-				}
-			}
-			break;
-		case 'e' :
-			if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_int) && (methodBinding.returnType.id == T_void) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Exit))) {
-				// This method binding is exit(int)
-				return EXIT_METHOD_NAME_AND_TYPE;
-			}
-			break;
-		case 'g' :
-			if ((methodBinding.selector.length == 10) && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetMessage))) {
-				// This method binding is getMessage()
-				return GETMESSAGE_METHOD_NAME_AND_TYPE;
-			}
-			break;
-		case 'i' :
-			if ((methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Intern))) {
-				// This method binding is toString()
-				return INTERN_METHOD_NAME_AND_TYPE;
-			}       
-	}
-	return -1;
-}
-/**
- * Return the index of the @methodBinding.
- *
- * Returns -1 if the @methodBinding is not a predefined methodBinding, 
- * the right index otherwise.
- *
- * @param methodBinding com.ibm.compiler.namelookup.MethodBinding
- * @return <CODE>int</CODE>
- */
-public int indexOfWellKnownMethods(MethodBinding methodBinding) {
-	char firstChar = methodBinding.selector[0];
-	switch (methodBinding.declaringClass.id) {
-		case T_JavaLangClass :
-			if ((firstChar == 'f') && (methodBinding.isStatic()) && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (methodBinding.returnType.id == T_JavaLangClass) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ForName))) {
-				// This method binding is forName(java.lang.String)
-				return FORNAME_CLASS_METHOD;
-			} else
-				if ((firstChar == 'g') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangReflectConstructor) && CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetConstructor) && CharOperation.equals(methodBinding.parameters[0].constantPoolName(), QualifiedNamesConstants.ArrayJavaLangClassConstantPoolName)) {
-					return GETCONSTRUCTOR_CLASS_METHOD;
-				}
-			break;
-		case T_JavaLangNoClassDefError :
-			if ((firstChar == '<') && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init))) {
-				// This method binding is NoClassDefFoundError(java.lang.String)
-				return NOCLASSDEFFOUNDERROR_CONSTR_METHOD;
-			}
-			break;
-		case T_JavaLangReflectConstructor :
-			if ((firstChar == 'n') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangObject) && CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.NewInstance) && CharOperation.equals(methodBinding.parameters[0].constantPoolName(), QualifiedNamesConstants.ArrayJavaLangObjectConstantPoolName)) {
-				return NEWINSTANCE_CONSTRUCTOR_METHOD;
-			}
-			break;
-		case T_JavaLangStringBuffer :
-			if ((firstChar == 'a') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangStringBuffer) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Append))) {
-				switch (methodBinding.parameters[0].id) {
-					case T_int :
-					case T_byte :
-					case T_short :
-						// This method binding is append(int)
-						return APPEND_INT_METHOD;
-					case T_float :
-						// This method binding is append(float)
-						return APPEND_FLOAT_METHOD;
-					case T_long :
-						// This method binding is append(long)
-						return APPEND_LONG_METHOD;
-					case T_JavaLangObject :
-						// This method binding is append(java.lang.Object)
-						return APPEND_OBJECT_METHOD;
-					case T_char :
-						// This method binding is append(char)
-						return APPEND_CHAR_METHOD;
-					case T_JavaLangString :
-						// This method binding is append(java.lang.String)
-						return APPEND_STRING_METHOD;
-					case T_boolean :
-						// This method binding is append(boolean)
-						return APPEND_BOOLEAN_METHOD;
-					case T_double :
-						// This method binding is append(double)
-						return APPEND_DOUBLE_METHOD;
-				}
-			} else
-				if ((firstChar == 't') && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ToString))) {
-					// This method binding is toString()
-					return STRINGBUFFER_TOSTRING_METHOD;
-				} else
-					if ((firstChar == '<') && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init))) {
-						if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString)) {
-							// This method binding is <init>(String)                    
-							return STRINGBUFFER_STRING_CONSTR_METHOD;
-						} else {
-							if (methodBinding.parameters.length == 0) {
-								// This method binding is <init>()
-								return STRINGBUFFER_DEFAULT_CONSTR_METHOD;
-							}
-						}
-					}
-			break;
-		case T_JavaLangString :
-			if ((firstChar == 'v') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ValueOf))) {
-				// This method binding is valueOf(java.lang.Object)
-				switch (methodBinding.parameters[0].id) {
-					case T_Object :
-						return VALUEOF_OBJECT_METHOD;
-					case T_int :
-					case T_short :
-					case T_byte :
-						return VALUEOF_INT_METHOD;
-					case T_long :
-						return VALUEOF_LONG_METHOD;
-					case T_float :
-						return VALUEOF_FLOAT_METHOD;
-					case T_double :
-						return VALUEOF_DOUBLE_METHOD;
-					case T_boolean :
-						return VALUEOF_BOOLEAN_METHOD;
-					case T_char :
-						return VALUEOF_CHAR_METHOD;
-				}
-			} else
-				if ((firstChar == 'i') && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Intern))) {
-					// This method binding is valueOf(java.lang.Object)
-					return STRING_INTERN_METHOD;
-				}
-			break;
-		case T_JavaLangSystem :
-			if ((firstChar == 'e') && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_int) && (methodBinding.returnType.id == T_void) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Exit))) {
-				// This method binding is exit(int)
-				return SYSTEM_EXIT_METHOD;
-			}
-			break;
-		case T_JavaLangThrowable :
-			if ((firstChar == 'g') && (methodBinding.selector.length == 10) && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetMessage))) {
-				// This method binding is getMessage()
-				return THROWABLE_GETMESSAGE_METHOD;
-			}
-		case T_JavaLangError :
-			if ((firstChar == '<') && (methodBinding.parameters.length == 1) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init)) && (methodBinding.parameters[0].id == T_String)) {
-				return JAVALANGERROR_CONSTR_METHOD;
-			}
-	}
-	return -1;
-}
-/**
- * Return the index of the @typeBinding
- *
- * Returns -1 if the @typeBinding is not a predefined binding, the right index 
- * otherwise.
- *
- * @param typeBinding com.ibm.compiler.namelookup.TypeBinding
- * @return <CODE>int</CODE>
- */
-public int indexOfWellKnownTypes(TypeBinding typeBinding) {
-	switch(typeBinding.id) {
-		case T_JavaLangBoolean : return JAVA_LANG_BOOLEAN_TYPE;
-		case T_JavaLangByte : return JAVA_LANG_BYTE_TYPE;
-		case T_JavaLangCharacter : return JAVA_LANG_CHARACTER_TYPE;
-		case T_JavaLangDouble : return JAVA_LANG_DOUBLE_TYPE;
-		case T_JavaLangFloat : return JAVA_LANG_FLOAT_TYPE;
-		case T_JavaLangInteger : return JAVA_LANG_INTEGER_TYPE;
-		case T_JavaLangLong : return JAVA_LANG_LONG_TYPE;
-		case T_JavaLangShort : return JAVA_LANG_SHORT_TYPE;
-		case T_JavaLangVoid : return JAVA_LANG_VOID_TYPE;
-		case T_JavaLangClass : return JAVA_LANG_CLASS_TYPE;
-		case T_JavaLangClassNotFoundException : return JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE;
-		case T_JavaLangNoClassDefError : return JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE;
-		case T_JavaLangObject : return JAVA_LANG_OBJECT_TYPE;
-		case T_JavaLangString : return JAVA_LANG_STRING_TYPE;
-		case T_JavaLangStringBuffer : return JAVA_LANG_STRINGBUFFER_TYPE;
-		case T_JavaLangSystem : return JAVA_LANG_SYSTEM_TYPE;
-		case T_JavaLangThrowable : return JAVA_LANG_THROWABLE_TYPE;
-		case T_JavaLangError : return JAVA_LANG_ERROR_TYPE;
-		case T_JavaLangException : return JAVA_LANG_EXCEPTION_TYPE;
-		case T_JavaLangReflectConstructor : return JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE;
-	}
-	return -1;
-}
-public int literalIndex(byte[] utf8encoding, char[] stringCharArray) {
-	int index;
-	if ((index = UTF8Cache.get(stringCharArray)) < 0) {
-		// The entry doesn't exit yet
-		index = UTF8Cache.put(stringCharArray, currentIndex);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		currentIndex++;
-		// Write the tag first
-		writeU1(Utf8Tag);
-		// Then the size of the stringName array
-		//writeU2(utf8Constant.length);
-		int savedCurrentOffset = currentOffset;
-		if (currentOffset + 2 >= poolContent.length) {
-			// we need to resize the poolContent array because we won't have
-			// enough space to write the length
-			int length = poolContent.length;
-			System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		}
-		currentOffset += 2;
-		// add in once the whole byte array
-		int length = poolContent.length;
-		int utf8encodingLength = utf8encoding.length;
-		if (currentOffset + utf8encodingLength >= length) {
-			System.arraycopy(poolContent, 0, (poolContent = new byte[length + utf8encodingLength + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		}
-		System.arraycopy(utf8encoding, 0, poolContent, currentOffset, utf8encodingLength);
-		currentOffset += utf8encodingLength;
-		// Now we know the length that we have to write in the constant pool
-		// we use savedCurrentOffset to do that
-		poolContent[savedCurrentOffset] = (byte) (utf8encodingLength >> 8);
-		poolContent[savedCurrentOffset + 1] = (byte) utf8encodingLength;
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param char[] stringName
- * @return <CODE>int</CODE>
- */
-public int literalIndex(char[] utf8Constant) {
-	int index;
-	if ((index = UTF8Cache.get(utf8Constant)) < 0) {
-		// The entry doesn't exit yet
-		// Write the tag first
-		writeU1(Utf8Tag);
-		// Then the size of the stringName array
-		int savedCurrentOffset = currentOffset;
-		if (currentOffset + 2 >= poolContent.length) {
-			// we need to resize the poolContent array because we won't have
-			// enough space to write the length
-			int length = poolContent.length;
-			System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		}
-		currentOffset += 2;
-		int length = 0;
-		for (int i = 0; i < utf8Constant.length; i++) {
-			char current = utf8Constant[i];
-			if ((current >= 0x0001) && (current <= 0x007F)) {
-				// we only need one byte: ASCII table
-				writeU1(current);
-				length++;
-			} else
-				if (current > 0x07FF) {
-					// we need 3 bytes
-					length += 3;
-					writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
-					writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
-					writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-				} else {
-					// we can be 0 or between 0x0080 and 0x07FF
-					// In that case we only need 2 bytes
-					length += 2;
-					writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
-					writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-				}
-		}
-		if (length >= 65535) {
-			currentOffset = savedCurrentOffset - 1;
-			return -1;
-		}
-		index = UTF8Cache.put(utf8Constant, currentIndex);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		currentIndex++;     
-		// Now we know the length that we have to write in the constant pool
-		// we use savedCurrentOffset to do that
-		poolContent[savedCurrentOffset] = (byte) (length >> 8);
-		poolContent[savedCurrentOffset + 1] = (byte) length;
-	}
-	return index;
-}
-public int literalIndex(char[] stringCharArray, byte[] utf8encoding) {
-	int index;
-	int stringIndex;
-	if ((index = stringCache.get(stringCharArray)) < 0) {
-		// The entry doesn't exit yet
-		stringIndex = literalIndex(utf8encoding, stringCharArray);
-		index = stringCache.put(stringCharArray, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the tag first
-		writeU1(StringTag);
-		// Then the string index
-		writeU2(stringIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the double
- * value. If the double is not already present into the pool, it is added. The 
- * double cache is updated and it returns the right index.
- *
- * @param <CODE>double</CODE> key
- * @return <CODE>int</CODE>
- */
-public int literalIndex(double key) {
-	//Retrieve the index from the cache
-	// The double constant takes two indexes into the constant pool, but we only store
-	// the first index into the long table
-	int index;
-	// lazy initialization for base type caches
-	// If it is null, initialize it, otherwise use it
-	if (doubleCache == null) {
-			doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE);
-	}
-	if ((index = doubleCache.get(key)) < 0) {
-		index = doubleCache.put(key, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		currentIndex++; // a double needs an extra place into the constant pool
-		// Write the double into the constant pool
-		// First add the tag
-		writeU1(DoubleTag);
-		// Then add the 8 bytes representing the double
-		long temp = java.lang.Double.doubleToLongBits(key);
-		for (int i = 0; i < 8; i++) {
-			try {
-				poolContent[currentOffset++] = (byte) (temp >>> (56 - (i << 3)));
-			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
-				int length = poolContent.length;
-				System.arraycopy(poolContent, 0, (poolContent = new byte[(length << 1) + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
-				poolContent[currentOffset - 1] = (byte) (temp >>> (56 - (i << 3)));
-			}
-		}
-	};
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the float
- * value. If the float is not already present into the pool, it is added. The 
- * int cache is updated and it returns the right index.
- *
- * @param <CODE>float</CODE> key
- * @return <CODE>int</CODE>
- */
-public int literalIndex(float key) {
-	//Retrieve the index from the cache
-	int index;
-	// lazy initialization for base type caches
-	// If it is null, initialize it, otherwise use it
-	if (floatCache == null) {
-		floatCache = new FloatCache(FLOAT_INITIAL_SIZE);
-	}
-	if ((index = floatCache.get(key)) < 0) {
-		index = floatCache.put(key, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the float constant entry into the constant pool
-		// First add the tag
-		writeU1(FloatTag);
-		// Then add the 4 bytes representing the float
-		int temp = java.lang.Float.floatToIntBits(key);
-		for (int i = 0; i < 4; i++) {
-			try {
-				poolContent[currentOffset++] = (byte) (temp >>> (24 - i * 8));
-			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
-				int length = poolContent.length;
-				System.arraycopy(poolContent, 0, (poolContent = new byte[length * 2 + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
-				poolContent[currentOffset - 1] = (byte) (temp >>> (24 - i * 8));
-			}
-		}
-	};
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the int
- * value. If the int is not already present into the pool, it is added. The 
- * int cache is updated and it returns the right index.
- *
- * @param <CODE>int</CODE> key
- * @return <CODE>int</CODE>
- */
-public int literalIndex(int key) {
-	//Retrieve the index from the cache
-	int index;
-	// lazy initialization for base type caches
-	// If it is null, initialize it, otherwise use it
-	if (intCache == null) {
-		intCache = new IntegerCache(INT_INITIAL_SIZE);
-	}
-	if ((index = intCache.get(key)) < 0) {
-		index = intCache.put(key, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the integer constant entry into the constant pool
-		// First add the tag
-		writeU1(IntegerTag);
-		// Then add the 4 bytes representing the int
-		for (int i = 0; i < 4; i++) {
-			try {
-				poolContent[currentOffset++] = (byte) (key >>> (24 - i * 8));
-			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
-				int length = poolContent.length;
-				System.arraycopy(poolContent, 0, (poolContent = new byte[length * 2 + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
-				poolContent[currentOffset - 1] = (byte) (key >>> (24 - i * 8));
-			}
-		}
-	};
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the long
- * value. If the long is not already present into the pool, it is added. The 
- * long cache is updated and it returns the right index.
- *
- * @param <CODE>long</CODE> key
- * @return <CODE>int</CODE>
- */
-public int literalIndex(long key) {
-	// Retrieve the index from the cache
-	// The long constant takes two indexes into the constant pool, but we only store
-	// the first index into the long table
-	int index;
-	// lazy initialization for base type caches
-	// If it is null, initialize it, otherwise use it
-	if (longCache == null) {
-		longCache = new LongCache(LONG_INITIAL_SIZE);
-	}
-	if ((index = longCache.get(key)) < 0) {
-		index = longCache.put(key, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		currentIndex++; // long value need an extra place into thwe constant pool
-		// Write the long into the constant pool
-		// First add the tag
-		writeU1(LongTag);
-		// Then add the 8 bytes representing the long
-		for (int i = 0; i < 8; i++) {
-			try {
-				poolContent[currentOffset++] = (byte) (key >>> (56 - (i << 3)));
-			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
-				int length = poolContent.length;
-				System.arraycopy(poolContent, 0, (poolContent = new byte[(length << 1) + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
-				poolContent[currentOffset - 1] = (byte) (key >>> (56 - (i << 3)));
-			}
-		}
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param stringConstant java.lang.String
- * @return <CODE>int</CODE>
- */
-public int literalIndex(String stringConstant) {
-	int index;
-	char[] stringCharArray = stringConstant.toCharArray();
-	if ((index = stringCache.get(stringCharArray)) < 0) {
-		// The entry doesn't exit yet
-		int stringIndex = literalIndex(stringCharArray);
-		index = stringCache.put(stringCharArray, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the tag first
-		writeU1(StringTag);
-		// Then the string index
-		writeU2(stringIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @param FieldBinding aFieldBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndex(FieldBinding aFieldBinding) {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	int indexWellKnownField;
-	if ((indexWellKnownField = indexOfWellKnownFields(aFieldBinding)) == -1) {
-		if ((index = fieldCache.get(aFieldBinding)) < 0) {
-			// The entry doesn't exit yet
-			classIndex = literalIndex(aFieldBinding.declaringClass);
-			nameAndTypeIndex = literalIndexForFields(literalIndex(aFieldBinding.name), literalIndex(aFieldBinding.type.signature()), aFieldBinding);
-			index = fieldCache.put(aFieldBinding, currentIndex++);
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(FieldRefTag);
-			writeU2(classIndex);
-			writeU2(nameAndTypeIndex);
-		}
-	} else {
-		if ((index = wellKnownFields[indexWellKnownField]) == 0) {
-			// that field need to be inserted
-			classIndex = literalIndex(aFieldBinding.declaringClass);
-			nameAndTypeIndex = literalIndexForFields(literalIndex(aFieldBinding.name), literalIndex(aFieldBinding.type.signature()), aFieldBinding);
-			index = wellKnownFields[indexWellKnownField] = currentIndex++;
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(FieldRefTag);
-			writeU2(classIndex);
-			writeU2(nameAndTypeIndex);
-		}
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @param MethodBinding aMethodBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndex(MethodBinding aMethodBinding) {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	int nameIndex;
-	int indexWellKnownMethod;
-	if ((indexWellKnownMethod = indexOfWellKnownMethods(aMethodBinding)) == -1) {
-		if (aMethodBinding.declaringClass.isInterface()) {
-			// Lookinf into the interface method ref table
-			if ((index = interfaceMethodCache.get(aMethodBinding)) < 0) {
-				classIndex = literalIndex(aMethodBinding.declaringClass);
-				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
-				index = interfaceMethodCache.put(aMethodBinding, currentIndex++);
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the interface method ref constant into the constant pool
-				// First add the tag
-				writeU1(InterfaceMethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-		} else {
-			// Lookinf into the method ref table
-			if ((index = methodCache.get(aMethodBinding)) < 0) {
-				classIndex = literalIndex(aMethodBinding.declaringClass);
-				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
-				index = methodCache.put(aMethodBinding, currentIndex++);
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-		}
-	} else {
-		// This is a well known method
-		if ((index = wellKnownMethods[indexWellKnownMethod]) == 0) {
-			// this methods was not inserted yet
-			if (aMethodBinding.declaringClass.isInterface()) {
-				// Lookinf into the interface method ref table
-				classIndex = literalIndex(aMethodBinding.declaringClass);
-				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
-				index = wellKnownMethods[indexWellKnownMethod] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the interface method ref constant into the constant pool
-				// First add the tag
-				writeU1(InterfaceMethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			} else {
-				// Lookinf into the method ref table
-				classIndex = literalIndex(aMethodBinding.declaringClass);
-				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
-				index = wellKnownMethods[indexWellKnownMethod] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-		}
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndex(TypeBinding aTypeBinding) {
-	int index;
-	int nameIndex;
-	int indexWellKnownType;
-	if ((indexWellKnownType = indexOfWellKnownTypes(aTypeBinding)) == -1) {
-		if ((index = classCache.get(aTypeBinding)) < 0) {
-			// The entry doesn't exit yet
-			nameIndex = literalIndex(aTypeBinding.constantPoolName());
-			index = classCache.put(aTypeBinding, currentIndex++);
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(ClassTag);
-			// Then add the 8 bytes representing the long
-			writeU2(nameIndex);
-		}
-	} else {
-		if ((index = wellKnownTypes[indexWellKnownType]) == 0) {
-			// Need to insert that binding
-			nameIndex = literalIndex(aTypeBinding.constantPoolName());
-			index = wellKnownTypes[indexWellKnownType] = currentIndex++;
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(ClassTag);
-			// Then add the 8 bytes representing the long
-			writeU2(nameIndex);
-		}
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding 
- * nameAndType constant with nameIndex, typeIndex.
- *
- * @param int nameIndex
- * @param int nameIndex
- * @param org.eclipse.jdt.internal.compiler.lookup.FieldBinding a FieldBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForFields(int nameIndex, int typeIndex, FieldBinding key) {
-	int index;
-	int indexOfWellKnownFieldNameAndType;
-	if ((indexOfWellKnownFieldNameAndType = indexOfWellKnownFieldNameAndType(key)) == -1) {
-		// check if the entry already exists
-		if ((index = nameAndTypeCacheForFields.get(key)) == -1) {
-			// The entry doesn't exit yet
-			index = nameAndTypeCacheForFields.put(key, currentIndex++);
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-	} else {
-		if ((index = wellKnownFieldNameAndTypes[indexOfWellKnownFieldNameAndType]) == 0) {
-			index = wellKnownFieldNameAndTypes[indexOfWellKnownFieldNameAndType] = currentIndex++;
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangBoolean() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_BOOLEAN_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangBooleanConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_BOOLEAN_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangBooleanTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_BOOLEAN_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangBoolean();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_BOOLEAN_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangByte() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_BYTE_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangByteConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_BYTE_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangByteTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_BYTE_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangByte();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_BYTE_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangCharacter() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_CHARACTER_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangCharacterConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_CHARACTER_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangCharacterTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_CHARACTER_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangCharacter();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_CHARACTER_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangClass() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_CLASS_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangClassConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_CLASS_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangClassForName() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[FORNAME_CLASS_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangClass();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[FORNAME_CLASS_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.ForName);
-			int typeIndex = literalIndex(QualifiedNamesConstants.ForNameSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[FORNAME_CLASS_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[FORNAME_CLASS_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangClassGetConstructor() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[GETCONSTRUCTOR_CLASS_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangClass();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[GETCONSTRUCTOR_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.GetConstructor);
-			int typeIndex = literalIndex(QualifiedNamesConstants.GetConstructorSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[GETCONSTRUCTOR_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[GETCONSTRUCTOR_CLASS_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangClassNotFoundException() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangClassNotFoundExceptionConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangDouble() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_DOUBLE_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangDoubleConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_DOUBLE_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangDoubleTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_DOUBLE_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangDouble();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_DOUBLE_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangError() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_ERROR_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangErrorConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_ERROR_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangErrorConstructor() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[JAVALANGERROR_CONSTR_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangError();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
-			int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[JAVALANGERROR_CONSTR_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-public int literalIndexForJavaLangException() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_EXCEPTION_TYPE]) == 0) {
-		// The entry doesn't exit yet
-		int nameIndex = literalIndex(QualifiedNamesConstants.JavaLangExceptionConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_EXCEPTION_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangFloat() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_FLOAT_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangFloatConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_FLOAT_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangFloatTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_FLOAT_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangFloat();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_FLOAT_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangInteger() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_INTEGER_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangIntegerConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_INTEGER_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangIntegerTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_INTEGER_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangInteger();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_INTEGER_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangLong() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_LONG_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangLongConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_LONG_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangLongTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_LONG_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangLong();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_LONG_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangNoClassDefFoundError() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangNoClassDefFoundErrorConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangNoClassDefFoundErrorStringConstructor() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[NOCLASSDEFFOUNDERROR_CONSTR_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangNoClassDefFoundError();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
-			int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[NOCLASSDEFFOUNDERROR_CONSTR_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangObject() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_OBJECT_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangObjectConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_OBJECT_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangReflectConstructor() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangReflectConstructor);
-		index = wellKnownTypes[JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-public int literalIndexForJavaLangReflectConstructorNewInstance() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[NEWINSTANCE_CONSTRUCTOR_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangReflectConstructor();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[NEWINSTANCE_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.NewInstance);
-			int typeIndex = literalIndex(QualifiedNamesConstants.NewInstanceSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[NEWINSTANCE_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[NEWINSTANCE_CONSTRUCTOR_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangShort() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_SHORT_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangShortConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_SHORT_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangShortTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_SHORT_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangShort();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_SHORT_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangString() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_STRING_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangStringConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_STRING_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringBuffer() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_STRINGBUFFER_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangStringBufferConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_STRINGBUFFER_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringBufferAppend(int typeID) {
-	int index = 0;
-	int nameAndTypeIndex = 0;
-	int classIndex = 0;
-	switch (typeID) {
-		case T_int :
-		case T_byte :
-		case T_short :
-			if ((index = wellKnownMethods[APPEND_INT_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_INT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendIntSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_INT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_INT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_long :
-			if ((index = wellKnownMethods[APPEND_LONG_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_LONG_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendLongSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_LONG_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_LONG_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_float :
-			if ((index = wellKnownMethods[APPEND_FLOAT_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_FLOAT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendFloatSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_FLOAT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_FLOAT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_double :
-			if ((index = wellKnownMethods[APPEND_DOUBLE_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_DOUBLE_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendDoubleSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_DOUBLE_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_DOUBLE_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_char :
-			if ((index = wellKnownMethods[APPEND_CHAR_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_CHAR_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendCharSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_CHAR_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_CHAR_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_boolean :
-			if ((index = wellKnownMethods[APPEND_BOOLEAN_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_BOOLEAN_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendBooleanSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_BOOLEAN_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_BOOLEAN_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_Object :
-			if ((index = wellKnownMethods[APPEND_OBJECT_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_OBJECT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendObjectSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_OBJECT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_OBJECT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_String :
-		case T_null :
-			if ((index = wellKnownMethods[APPEND_STRING_METHOD]) == 0) {
-				classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_STRING_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
-					int typeIndex = literalIndex(QualifiedNamesConstants.AppendStringSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_STRING_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[APPEND_STRING_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringBufferConstructor() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[STRINGBUFFER_STRING_CONSTR_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangStringBuffer();
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.Init);
-					int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-		index = wellKnownMethods[STRINGBUFFER_STRING_CONSTR_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringBufferDefaultConstructor() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[STRINGBUFFER_DEFAULT_CONSTR_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangStringBuffer();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[DEFAULT_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
-			int typeIndex = literalIndex(QualifiedNamesConstants.DefaultConstructorSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[DEFAULT_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[STRINGBUFFER_DEFAULT_CONSTR_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringBufferToString() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[STRINGBUFFER_TOSTRING_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangStringBuffer();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[TOSTRING_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.ToString);
-			int typeIndex = literalIndex(QualifiedNamesConstants.ToStringSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[TOSTRING_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[STRINGBUFFER_TOSTRING_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringIntern() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[STRING_INTERN_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangString();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[INTERN_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Intern);
-			int typeIndex = literalIndex(QualifiedNamesConstants.InternSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[INTERN_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[STRING_INTERN_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangStringValueOf(int typeID) {
-	int index = 0;
-	int nameAndTypeIndex = 0;
-	int classIndex = literalIndexForJavaLangString();
-	switch (typeID) {
-		case T_int :
-		case T_byte :
-		case T_short :
-			if ((index = wellKnownMethods[VALUEOF_INT_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_INT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfIntSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_INT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_INT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_long :
-			if ((index = wellKnownMethods[VALUEOF_LONG_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_LONG_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfLongSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_LONG_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_LONG_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_float :
-			if ((index = wellKnownMethods[VALUEOF_FLOAT_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_FLOAT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfFloatSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_FLOAT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_FLOAT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_double :
-			if ((index = wellKnownMethods[VALUEOF_DOUBLE_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfDoubleSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_DOUBLE_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_char :
-			if ((index = wellKnownMethods[VALUEOF_CHAR_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_CHAR_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfCharSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_CHAR_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_CHAR_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_boolean :
-			if ((index = wellKnownMethods[VALUEOF_BOOLEAN_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfBooleanSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_BOOLEAN_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-		case T_Object :
-			if ((index = wellKnownMethods[VALUEOF_OBJECT_METHOD]) == 0) {
-				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_OBJECT_METHOD_NAME_AND_TYPE]) == 0) {
-					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
-					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfObjectSignature);
-					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_OBJECT_METHOD_NAME_AND_TYPE] = currentIndex++;
-					writeU1(NameAndTypeTag);
-					writeU2(nameIndex);
-					writeU2(typeIndex);
-				}
-				index = wellKnownMethods[VALUEOF_OBJECT_METHOD] = currentIndex++;
-				if (index > 0xFFFF){
-					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-				}
-				// Write the method ref constant into the constant pool
-				// First add the tag
-				writeU1(MethodRefTag);
-				// Then write the class index
-				writeU2(classIndex);
-				// The write the nameAndType index
-				writeU2(nameAndTypeIndex);
-			}
-			break;
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangSystem() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_SYSTEM_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangSystemConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_SYSTEM_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangSystemExitInt() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[SYSTEM_EXIT_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangSystem();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[EXIT_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Exit);
-			int typeIndex = literalIndex(QualifiedNamesConstants.ExitIntSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[EXIT_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[SYSTEM_EXIT_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangSystemOut() {
-	int index;
-	if ((index = wellKnownFields[OUT_SYSTEM_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangSystem();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[OUT_SYSTEM_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.Out);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaIoPrintStreamSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[OUT_SYSTEM_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[OUT_SYSTEM_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangThrowable() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_THROWABLE_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangThrowableConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_THROWABLE_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the 
- * method descriptor. It can be either an interface method reference constant
- * or a method reference constant.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangThrowableGetMessage() {
-	int index;
-	int nameAndTypeIndex;
-	int classIndex;
-	// Looking into the method ref table
-	if ((index = wellKnownMethods[THROWABLE_GETMESSAGE_METHOD]) == 0) {
-		classIndex = literalIndexForJavaLangThrowable();
-		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[GETMESSAGE_METHOD_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.GetMessage);
-			int typeIndex = literalIndex(QualifiedNamesConstants.GetMessageSignature);
-			nameAndTypeIndex = wellKnownMethodNameAndTypes[GETMESSAGE_METHOD_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownMethods[THROWABLE_GETMESSAGE_METHOD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the method ref constant into the constant pool
-		// First add the tag
-		writeU1(MethodRefTag);
-		// Then write the class index
-		writeU2(classIndex);
-		// The write the nameAndType index
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param TypeBinding aTypeBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangVoid() {
-	int index;
-	if ((index = wellKnownTypes[JAVA_LANG_VOID_TYPE]) == 0) {
-		int nameIndex;
-		// The entry doesn't exit yet
-		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangVoidConstantPoolName);
-		index = wellKnownTypes[JAVA_LANG_VOID_TYPE] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(ClassTag);
-		// Then add the 8 bytes representing the long
-		writeU2(nameIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool 
- * corresponding to the field binding aFieldBinding.
- *
- * @return <CODE>int</CODE>
- */
-public int literalIndexForJavaLangVoidTYPE() {
-	int index;
-	if ((index = wellKnownFields[TYPE_VOID_FIELD]) == 0) {
-		int nameAndTypeIndex;
-		int classIndex;
-		// The entry doesn't exit yet
-		classIndex = literalIndexForJavaLangVoid();
-		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
-			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
-			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
-			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-		index = wellKnownFields[TYPE_VOID_FIELD] = currentIndex++;
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		writeU1(FieldRefTag);
-		writeU2(classIndex);
-		writeU2(nameAndTypeIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param char[] stringName
- * @return <CODE>int</CODE>
- */
-public int literalIndexForLdc(char[] stringCharArray) {
-	int index;
-	if ((index = stringCache.get(stringCharArray)) < 0) {
-		int stringIndex;
-		// The entry doesn't exit yet
-		if ((stringIndex = UTF8Cache.get(stringCharArray)) < 0) {
-			// The entry doesn't exit yet
-			// Write the tag first
-			writeU1(Utf8Tag);
-			// Then the size of the stringName array
-			int savedCurrentOffset = currentOffset;
-			if (currentOffset + 2 >= poolContent.length) {
-				// we need to resize the poolContent array because we won't have
-				// enough space to write the length
-				int length = poolContent.length;
-				System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-			}
-			currentOffset += 2;
-			int length = 0;
-			for (int i = 0; i < stringCharArray.length; i++) {
-				char current = stringCharArray[i];
-				if ((current >= 0x0001) && (current <= 0x007F)) {
-					// we only need one byte: ASCII table
-					writeU1(current);
-					length++;
-				} else
-					if (current > 0x07FF) {
-						// we need 3 bytes
-						length += 3;
-						writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
-						writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
-						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-					} else {
-						// we can be 0 or between 0x0080 and 0x07FF
-						// In that case we only need 2 bytes
-						length += 2;
-						writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
-						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-					}
-			}
-			if (length >= 65535) {
-				currentOffset = savedCurrentOffset - 1;
-				return -1;
-			}
-			stringIndex = UTF8Cache.put(stringCharArray, currentIndex++);
-			// Now we know the length that we have to write in the constant pool
-			// we use savedCurrentOffset to do that
-			if (length > 65535) {
-				return 0;
-			}
-			poolContent[savedCurrentOffset] = (byte) (length >> 8);
-			poolContent[savedCurrentOffset + 1] = (byte) length;
-		}
-		index = stringCache.put(stringCharArray, currentIndex++);
-		if (index > 0xFFFF){
-			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-		}
-		// Write the tag first
-		writeU1(StringTag);
-		// Then the string index
-		writeU2(stringIndex);
-	}
-	return index;
-}
-/**
- * This method returns the index into the constantPool corresponding 
- * nameAndType constant with nameIndex, typeIndex.
- *
- * @param int nameIndex
- * @param int nameIndex
- * @param org.eclipse.jdt.internal.compiler.lookup.MethodBinding a methodBinding
- * @return <CODE>int</CODE>
- */
-public int literalIndexForMethods(int nameIndex, int typeIndex, MethodBinding key) {
-	int index;
-	int indexOfWellKnownMethodNameAndType;
-	if ((indexOfWellKnownMethodNameAndType = indexOfWellKnownMethodNameAndType(key)) == -1) {
-		// check if the entry exists
-		if ((index = nameAndTypeCacheForMethods.get(key)) == -1) {
-			// The entry doesn't exit yet
-			index = nameAndTypeCacheForMethods.put(key, currentIndex++);
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-	} else {
-		if ((index = wellKnownMethodNameAndTypes[indexOfWellKnownMethodNameAndType]) == 0) {
-			index = wellKnownMethodNameAndTypes[indexOfWellKnownMethodNameAndType] = currentIndex++;
-			if (index > 0xFFFF){
-				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-			}
-			writeU1(NameAndTypeTag);
-			writeU2(nameIndex);
-			writeU2(typeIndex);
-		}
-	}
-	return index;
-}
-/**
- * This method is used to clean the receiver in case of a clinit header is generated, but the 
- * clinit has no code.
- * This implementation assumes that the clinit is the first method to be generated.
- * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.addClinit()
- */
-public void resetForClinit(int constantPoolIndex, int constantPoolOffset) {
-	currentIndex = constantPoolIndex;
-	currentOffset = constantPoolOffset;
-	if (UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) {
-		UTF8Cache.remove(AttributeNamesConstants.CodeName);
-	}
-	if (UTF8Cache.get(QualifiedNamesConstants.ClinitSignature) >= constantPoolIndex) {
-		UTF8Cache.remove(QualifiedNamesConstants.ClinitSignature);
-	}
-	if (UTF8Cache.get(QualifiedNamesConstants.Clinit) >= constantPoolIndex) {
-		UTF8Cache.remove(QualifiedNamesConstants.Clinit);
-	}
-}
-/**
- * Write a unsigned byte into the byte array
- * 
- * @param <CODE>int</CODE> The value to write into the byte array
- */
-protected final void writeU1(int value) {
-	try {
-		poolContent[currentOffset++] = (byte) value;
-	} catch (IndexOutOfBoundsException e) {
-		//currentOffset has been ++ already (see the -1)
-		int length = poolContent.length;
-		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		poolContent[currentOffset - 1] = (byte) value;
-	}
-}
-/**
- * Write a unsigned byte into the byte array
- * 
- * @param <CODE>int</CODE> The value to write into the byte array
- */
-protected final void writeU2(int value) {
-	//first byte
-	try {
-		poolContent[currentOffset++] = (byte) (value >> 8);
-	} catch (IndexOutOfBoundsException e) {
-		 //currentOffset has been ++ already (see the -1)
-		int length = poolContent.length;
-		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		poolContent[currentOffset - 1] = (byte) (value >> 8);
-	}
-	try {
-		poolContent[currentOffset++] = (byte) value;
-	} catch (IndexOutOfBoundsException e) {
-		 //currentOffset has been ++ already (see the -1)
-		int length = poolContent.length;
-		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
-		poolContent[currentOffset - 1] = (byte) value;
-	}
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ClassFile;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+/**
+ * This type is used to store all the constant pool entries.
+ */
+public class ConstantPool implements ClassFileConstants, TypeIds {
+	public static final int DOUBLE_INITIAL_SIZE = 5;
+	public static final int FLOAT_INITIAL_SIZE = 3;
+	public static final int INT_INITIAL_SIZE = 248;
+	public static final int LONG_INITIAL_SIZE = 5;
+	public static final int UTF8_INITIAL_SIZE = 778;
+	public static final int STRING_INITIAL_SIZE = 761;
+	public static final int FIELD_INITIAL_SIZE = 156;
+	public static final int METHOD_INITIAL_SIZE = 236;
+	public static final int INTERFACE_INITIAL_SIZE = 50;
+	public static final int CLASS_INITIAL_SIZE = 86;
+	public static final int NAMEANDTYPE_INITIAL_SIZE = 272;
+	public static final int CONSTANTPOOL_INITIAL_SIZE = 2000;
+	public static final int CONSTANTPOOL_GROW_SIZE = 6000;
+	protected DoubleCache doubleCache;
+	protected FloatCache floatCache;
+	protected IntegerCache intCache;
+	protected LongCache longCache;
+	public CharArrayCache UTF8Cache;
+	protected CharArrayCache stringCache;
+	protected ObjectCache fieldCache;
+	protected ObjectCache methodCache;
+	protected ObjectCache interfaceMethodCache;
+	protected ObjectCache classCache;
+	protected FieldNameAndTypeCache nameAndTypeCacheForFields;
+	protected MethodNameAndTypeCache nameAndTypeCacheForMethods;
+	int[] wellKnownTypes = new int[20];
+	int[] wellKnownMethods = new int[26];
+	int[] wellKnownFields = new int[10];
+	int[] wellKnownFieldNameAndTypes = new int[2];
+	int[] wellKnownMethodNameAndTypes = new int[24];
+	public byte[] poolContent;
+	public int currentIndex = 1;
+	public int currentOffset;
+	// predefined constant index for well known types
+	final static int JAVA_LANG_BOOLEAN_TYPE = 0;
+	final static int JAVA_LANG_BYTE_TYPE = 1;
+	final static int JAVA_LANG_CHARACTER_TYPE = 2;
+	final static int JAVA_LANG_DOUBLE_TYPE = 3;
+	final static int JAVA_LANG_FLOAT_TYPE = 4;
+	final static int JAVA_LANG_INTEGER_TYPE = 5;
+	final static int JAVA_LANG_LONG_TYPE = 6;
+	final static int JAVA_LANG_SHORT_TYPE = 7;
+	final static int JAVA_LANG_VOID_TYPE = 8;
+	final static int JAVA_LANG_CLASS_TYPE = 9;
+	final static int JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE = 10;
+	final static int JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE = 11;
+	final static int JAVA_LANG_OBJECT_TYPE = 12;
+	final static int JAVA_LANG_STRING_TYPE = 13;
+	final static int JAVA_LANG_STRINGBUFFER_TYPE = 14;
+	final static int JAVA_LANG_SYSTEM_TYPE = 15;
+	final static int JAVA_LANG_THROWABLE_TYPE = 16;
+	final static int JAVA_LANG_ERROR_TYPE = 17;
+	final static int JAVA_LANG_EXCEPTION_TYPE = 18;
+	final static int JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE = 19;
+	// predefined constant index for well known fields  
+	final static int TYPE_BYTE_FIELD = 0;
+	final static int TYPE_SHORT_FIELD = 1;
+	final static int TYPE_CHARACTER_FIELD = 2;
+	final static int TYPE_INTEGER_FIELD = 3;
+	final static int TYPE_LONG_FIELD = 4;
+	final static int TYPE_FLOAT_FIELD = 5;
+	final static int TYPE_DOUBLE_FIELD = 6;
+	final static int TYPE_BOOLEAN_FIELD = 7;
+	final static int TYPE_VOID_FIELD = 8;
+	final static int OUT_SYSTEM_FIELD = 9;
+	// predefined constant index for well known methods 
+	final static int FORNAME_CLASS_METHOD = 0;
+	final static int NOCLASSDEFFOUNDERROR_CONSTR_METHOD = 1;
+	final static int APPEND_INT_METHOD = 2;
+	final static int APPEND_FLOAT_METHOD = 3;
+	final static int APPEND_LONG_METHOD = 4;
+	final static int APPEND_OBJECT_METHOD = 5;
+	final static int APPEND_CHAR_METHOD = 6;
+	final static int APPEND_STRING_METHOD = 7;
+	final static int APPEND_BOOLEAN_METHOD = 8;
+	final static int APPEND_DOUBLE_METHOD = 9;
+	final static int STRINGBUFFER_STRING_CONSTR_METHOD = 10;
+	final static int STRINGBUFFER_DEFAULT_CONSTR_METHOD = 11;
+	final static int STRINGBUFFER_TOSTRING_METHOD = 12;
+	final static int SYSTEM_EXIT_METHOD = 13;
+	final static int THROWABLE_GETMESSAGE_METHOD = 14;
+	final static int JAVALANGERROR_CONSTR_METHOD = 15;
+	final static int GETCONSTRUCTOR_CLASS_METHOD = 16;
+	final static int NEWINSTANCE_CONSTRUCTOR_METHOD = 17;
+	final static int STRING_INTERN_METHOD = 18;
+	final static int VALUEOF_INT_METHOD = 19;
+	final static int VALUEOF_FLOAT_METHOD = 20;
+	final static int VALUEOF_LONG_METHOD = 21;
+	final static int VALUEOF_OBJECT_METHOD = 22;
+	final static int VALUEOF_CHAR_METHOD = 23;
+	final static int VALUEOF_BOOLEAN_METHOD = 24;
+	final static int VALUEOF_DOUBLE_METHOD = 25;
+	// predefined constant index for well known name and type for fields
+	final static int TYPE_JAVALANGCLASS_NAME_AND_TYPE = 0;
+	final static int OUT_SYSTEM_NAME_AND_TYPE = 1;
+	// predefined constant index for well known name and type for methods
+	final static int FORNAME_CLASS_METHOD_NAME_AND_TYPE = 0;
+	final static int STRING_CONSTR_METHOD_NAME_AND_TYPE = 1;
+	final static int DEFAULT_CONSTR_METHOD_NAME_AND_TYPE = 2;
+	final static int APPEND_INT_METHOD_NAME_AND_TYPE = 3;
+	final static int APPEND_FLOAT_METHOD_NAME_AND_TYPE = 4;
+	final static int APPEND_LONG_METHOD_NAME_AND_TYPE = 5;
+	final static int APPEND_OBJECT_METHOD_NAME_AND_TYPE = 6;
+	final static int APPEND_CHAR_METHOD_NAME_AND_TYPE = 7;
+	final static int APPEND_STRING_METHOD_NAME_AND_TYPE = 8;
+	final static int APPEND_BOOLEAN_METHOD_NAME_AND_TYPE = 9;
+	final static int APPEND_DOUBLE_METHOD_NAME_AND_TYPE = 10;
+	final static int TOSTRING_METHOD_NAME_AND_TYPE = 11;
+	final static int EXIT_METHOD_NAME_AND_TYPE = 12;
+	final static int GETMESSAGE_METHOD_NAME_AND_TYPE = 13;
+	final static int GETCONSTRUCTOR_METHOD_NAME_AND_TYPE = 14;
+	final static int NEWINSTANCE_METHOD_NAME_AND_TYPE = 15;
+	final static int INTERN_METHOD_NAME_AND_TYPE = 16;
+	final static int VALUEOF_INT_METHOD_NAME_AND_TYPE = 17;
+	final static int VALUEOF_FLOAT_METHOD_NAME_AND_TYPE = 18;
+	final static int VALUEOF_LONG_METHOD_NAME_AND_TYPE = 19;
+	final static int VALUEOF_OBJECT_METHOD_NAME_AND_TYPE = 20;
+	final static int VALUEOF_CHAR_METHOD_NAME_AND_TYPE = 21;
+	final static int VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE = 22;
+	final static int VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE = 23;
+	public ClassFile classFile;
+
+/**
+ * ConstantPool constructor comment.
+ */
+public ConstantPool(ClassFile classFile) {
+	this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE);
+	this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE);
+	this.fieldCache = new ObjectCache(FIELD_INITIAL_SIZE);
+	this.methodCache = new ObjectCache(METHOD_INITIAL_SIZE);
+	this.interfaceMethodCache = new ObjectCache(INTERFACE_INITIAL_SIZE);
+	this.classCache = new ObjectCache(CLASS_INITIAL_SIZE);
+	this.nameAndTypeCacheForMethods = new MethodNameAndTypeCache(NAMEANDTYPE_INITIAL_SIZE);
+	this.nameAndTypeCacheForFields = new FieldNameAndTypeCache(NAMEANDTYPE_INITIAL_SIZE);   
+	this.poolContent = classFile.header;
+	this.currentOffset = classFile.headerOffset;
+	// currentOffset is initialized to 0 by default
+	this.currentIndex = 1;
+	this.classFile = classFile;
+}
+/**
+ * Return the content of the receiver
+ */
+public byte[] dumpBytes() {
+	System.arraycopy(poolContent, 0, (poolContent = new byte[currentOffset]), 0, currentOffset);
+	return poolContent;
+}
+/**
+ * Return the index of the @fieldBinding.
+ *
+ * Returns -1 if the @fieldBinding is not a predefined fieldBinding, 
+ * the right index otherwise.
+ *
+ * @param fieldBinding com.ibm.compiler.namelookup.FieldBinding
+ * @return <CODE>int</CODE>
+ */
+public int indexOfWellKnownFieldNameAndType(FieldBinding fieldBinding) {
+	if ((fieldBinding.type.id == T_JavaLangClass) && (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE)))
+		return TYPE_JAVALANGCLASS_NAME_AND_TYPE;
+	if ((fieldBinding.type.id == T_JavaIoPrintStream) && (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.Out)))
+		return OUT_SYSTEM_NAME_AND_TYPE;
+	return -1;
+}
+/**
+ * Return the index of the @fieldBinding.
+ *
+ * Returns -1 if the @fieldBinding is not a predefined fieldBinding, 
+ * the right index otherwise.
+ *
+ * @param fieldBinding com.ibm.compiler.namelookup.FieldBinding
+ * @return <CODE>int</CODE>
+ */
+public int indexOfWellKnownFields(FieldBinding fieldBinding) {
+	switch (fieldBinding.declaringClass.id) {
+		case T_JavaLangByte :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_BYTE_FIELD;
+			break;
+		case T_JavaLangShort :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_SHORT_FIELD;
+			break;
+		case T_JavaLangCharacter :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_CHARACTER_FIELD;
+			break;
+		case T_JavaLangInteger :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_INTEGER_FIELD;
+			break;
+		case T_JavaLangLong :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_LONG_FIELD;
+			break;
+		case T_JavaLangFloat :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_FLOAT_FIELD;
+			break;
+		case T_JavaLangDouble :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_DOUBLE_FIELD;
+			break;
+		case T_JavaLangBoolean :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_BOOLEAN_FIELD;
+			break;
+		case T_JavaLangVoid :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.TYPE))
+				return TYPE_VOID_FIELD;
+			break;
+		case T_JavaLangSystem :
+			if (CharOperation.equals(fieldBinding.name, QualifiedNamesConstants.Out))
+				return OUT_SYSTEM_FIELD;
+	}
+	return -1;
+}
+/**
+ * Return the index of the @methodBinding.
+ *
+ * Returns -1 if the @methodBinding is not a predefined methodBinding, 
+ * the right index otherwise.
+ *
+ * @param methodBinding com.ibm.compiler.namelookup.MethodBinding
+ * @return <CODE>int</CODE>
+ */
+public int indexOfWellKnownMethodNameAndType(MethodBinding methodBinding) {
+	char firstChar = methodBinding.selector[0];
+	switch (firstChar) {
+		case 'f' :
+			if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (methodBinding.returnType.id == T_JavaLangClass) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ForName))) {
+				// This method binding is forName(java.lang.String)
+				return FORNAME_CLASS_METHOD_NAME_AND_TYPE;
+			}
+			break;
+		case '<' :
+			if (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init)) {
+				if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.StringConstructorSignature)) {
+					// This method binding is (java.lang.String)V
+					return STRING_CONSTR_METHOD_NAME_AND_TYPE;
+				} else
+					if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.DefaultConstructorSignature)) {
+						return DEFAULT_CONSTR_METHOD_NAME_AND_TYPE;
+					}
+			}
+			break;
+		case 'a' :
+			if ((methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangStringBuffer) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Append))) {
+				switch (methodBinding.parameters[0].id) {
+					case T_int :
+					case T_byte :
+					case T_short :
+						// This method binding is append(int)
+						return APPEND_INT_METHOD_NAME_AND_TYPE;
+					case T_float :
+						// This method binding is append(float)
+						return APPEND_FLOAT_METHOD_NAME_AND_TYPE;
+					case T_long :
+						// This method binding is append(long)
+						return APPEND_LONG_METHOD_NAME_AND_TYPE;
+					case T_JavaLangObject :
+						// This method binding is append(java.lang.Object)
+						return APPEND_OBJECT_METHOD_NAME_AND_TYPE;
+					case T_char :
+						// This method binding is append(char)
+						return APPEND_CHAR_METHOD_NAME_AND_TYPE;
+					case T_JavaLangString :
+						// This method binding is append(java.lang.String)
+						return APPEND_STRING_METHOD_NAME_AND_TYPE;
+					case T_boolean :
+						// This method binding is append(boolean)
+						return APPEND_BOOLEAN_METHOD_NAME_AND_TYPE;
+					case T_double :
+						// This method binding is append(double)
+						return APPEND_DOUBLE_METHOD_NAME_AND_TYPE;
+				}
+			}
+			break;
+		case 't' :
+			if ((methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ToString))) {
+				// This method binding is toString()
+				return TOSTRING_METHOD_NAME_AND_TYPE;
+			}
+			break;
+		case 'v' :
+			if ((methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ValueOf))) {
+				switch(methodBinding.parameters[0].id) {
+					case T_Object:
+						return VALUEOF_OBJECT_METHOD_NAME_AND_TYPE;
+					case T_int:
+					case T_short:
+					case T_byte:
+						return VALUEOF_INT_METHOD_NAME_AND_TYPE;
+					case T_long:
+						return VALUEOF_LONG_METHOD_NAME_AND_TYPE;
+					case T_float:
+						return VALUEOF_FLOAT_METHOD_NAME_AND_TYPE;
+					case T_double:
+						return VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE;
+					case T_boolean:
+						return VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE;
+					case T_char:
+						return VALUEOF_CHAR_METHOD_NAME_AND_TYPE;
+				}
+			}
+			break;
+		case 'e' :
+			if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_int) && (methodBinding.returnType.id == T_void) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Exit))) {
+				// This method binding is exit(int)
+				return EXIT_METHOD_NAME_AND_TYPE;
+			}
+			break;
+		case 'g' :
+			if ((methodBinding.selector.length == 10) && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetMessage))) {
+				// This method binding is getMessage()
+				return GETMESSAGE_METHOD_NAME_AND_TYPE;
+			}
+			break;
+		case 'i' :
+			if ((methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Intern))) {
+				// This method binding is toString()
+				return INTERN_METHOD_NAME_AND_TYPE;
+			}       
+	}
+	return -1;
+}
+/**
+ * Return the index of the @methodBinding.
+ *
+ * Returns -1 if the @methodBinding is not a predefined methodBinding, 
+ * the right index otherwise.
+ *
+ * @param methodBinding com.ibm.compiler.namelookup.MethodBinding
+ * @return <CODE>int</CODE>
+ */
+public int indexOfWellKnownMethods(MethodBinding methodBinding) {
+	char firstChar = methodBinding.selector[0];
+	switch (methodBinding.declaringClass.id) {
+		case T_JavaLangClass :
+			if ((firstChar == 'f') && (methodBinding.isStatic()) && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (methodBinding.returnType.id == T_JavaLangClass) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ForName))) {
+				// This method binding is forName(java.lang.String)
+				return FORNAME_CLASS_METHOD;
+			} else
+				if ((firstChar == 'g') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangReflectConstructor) && CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetConstructor) && CharOperation.equals(methodBinding.parameters[0].constantPoolName(), QualifiedNamesConstants.ArrayJavaLangClassConstantPoolName)) {
+					return GETCONSTRUCTOR_CLASS_METHOD;
+				}
+			break;
+		case T_JavaLangNoClassDefError :
+			if ((firstChar == '<') && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init))) {
+				// This method binding is NoClassDefFoundError(java.lang.String)
+				return NOCLASSDEFFOUNDERROR_CONSTR_METHOD;
+			}
+			break;
+		case T_JavaLangReflectConstructor :
+			if ((firstChar == 'n') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangObject) && CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.NewInstance) && CharOperation.equals(methodBinding.parameters[0].constantPoolName(), QualifiedNamesConstants.ArrayJavaLangObjectConstantPoolName)) {
+				return NEWINSTANCE_CONSTRUCTOR_METHOD;
+			}
+			break;
+		case T_JavaLangStringBuffer :
+			if ((firstChar == 'a') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangStringBuffer) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Append))) {
+				switch (methodBinding.parameters[0].id) {
+					case T_int :
+					case T_byte :
+					case T_short :
+						// This method binding is append(int)
+						return APPEND_INT_METHOD;
+					case T_float :
+						// This method binding is append(float)
+						return APPEND_FLOAT_METHOD;
+					case T_long :
+						// This method binding is append(long)
+						return APPEND_LONG_METHOD;
+					case T_JavaLangObject :
+						// This method binding is append(java.lang.Object)
+						return APPEND_OBJECT_METHOD;
+					case T_char :
+						// This method binding is append(char)
+						return APPEND_CHAR_METHOD;
+					case T_JavaLangString :
+						// This method binding is append(java.lang.String)
+						return APPEND_STRING_METHOD;
+					case T_boolean :
+						// This method binding is append(boolean)
+						return APPEND_BOOLEAN_METHOD;
+					case T_double :
+						// This method binding is append(double)
+						return APPEND_DOUBLE_METHOD;
+				}
+			} else
+				if ((firstChar == 't') && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ToString))) {
+					// This method binding is toString()
+					return STRINGBUFFER_TOSTRING_METHOD;
+				} else
+					if ((firstChar == '<') && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init))) {
+						if ((methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_JavaLangString)) {
+							// This method binding is <init>(String)                    
+							return STRINGBUFFER_STRING_CONSTR_METHOD;
+						} else {
+							if (methodBinding.parameters.length == 0) {
+								// This method binding is <init>()
+								return STRINGBUFFER_DEFAULT_CONSTR_METHOD;
+							}
+						}
+					}
+			break;
+		case T_JavaLangString :
+			if ((firstChar == 'v') && (methodBinding.parameters.length == 1) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.ValueOf))) {
+				// This method binding is valueOf(java.lang.Object)
+				switch (methodBinding.parameters[0].id) {
+					case T_Object :
+						return VALUEOF_OBJECT_METHOD;
+					case T_int :
+					case T_short :
+					case T_byte :
+						return VALUEOF_INT_METHOD;
+					case T_long :
+						return VALUEOF_LONG_METHOD;
+					case T_float :
+						return VALUEOF_FLOAT_METHOD;
+					case T_double :
+						return VALUEOF_DOUBLE_METHOD;
+					case T_boolean :
+						return VALUEOF_BOOLEAN_METHOD;
+					case T_char :
+						return VALUEOF_CHAR_METHOD;
+				}
+			} else
+				if ((firstChar == 'i') && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Intern))) {
+					// This method binding is valueOf(java.lang.Object)
+					return STRING_INTERN_METHOD;
+				}
+			break;
+		case T_JavaLangSystem :
+			if ((firstChar == 'e') && (methodBinding.parameters.length == 1) && (methodBinding.parameters[0].id == T_int) && (methodBinding.returnType.id == T_void) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Exit))) {
+				// This method binding is exit(int)
+				return SYSTEM_EXIT_METHOD;
+			}
+			break;
+		case T_JavaLangThrowable :
+			if ((firstChar == 'g') && (methodBinding.selector.length == 10) && (methodBinding.parameters.length == 0) && (methodBinding.returnType.id == T_JavaLangString) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.GetMessage))) {
+				// This method binding is getMessage()
+				return THROWABLE_GETMESSAGE_METHOD;
+			}
+		case T_JavaLangError :
+			if ((firstChar == '<') && (methodBinding.parameters.length == 1) && (CharOperation.equals(methodBinding.selector, QualifiedNamesConstants.Init)) && (methodBinding.parameters[0].id == T_String)) {
+				return JAVALANGERROR_CONSTR_METHOD;
+			}
+	}
+	return -1;
+}
+/**
+ * Return the index of the @typeBinding
+ *
+ * Returns -1 if the @typeBinding is not a predefined binding, the right index 
+ * otherwise.
+ *
+ * @param typeBinding com.ibm.compiler.namelookup.TypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int indexOfWellKnownTypes(TypeBinding typeBinding) {
+	switch(typeBinding.id) {
+		case T_JavaLangBoolean : return JAVA_LANG_BOOLEAN_TYPE;
+		case T_JavaLangByte : return JAVA_LANG_BYTE_TYPE;
+		case T_JavaLangCharacter : return JAVA_LANG_CHARACTER_TYPE;
+		case T_JavaLangDouble : return JAVA_LANG_DOUBLE_TYPE;
+		case T_JavaLangFloat : return JAVA_LANG_FLOAT_TYPE;
+		case T_JavaLangInteger : return JAVA_LANG_INTEGER_TYPE;
+		case T_JavaLangLong : return JAVA_LANG_LONG_TYPE;
+		case T_JavaLangShort : return JAVA_LANG_SHORT_TYPE;
+		case T_JavaLangVoid : return JAVA_LANG_VOID_TYPE;
+		case T_JavaLangClass : return JAVA_LANG_CLASS_TYPE;
+		case T_JavaLangClassNotFoundException : return JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE;
+		case T_JavaLangNoClassDefError : return JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE;
+		case T_JavaLangObject : return JAVA_LANG_OBJECT_TYPE;
+		case T_JavaLangString : return JAVA_LANG_STRING_TYPE;
+		case T_JavaLangStringBuffer : return JAVA_LANG_STRINGBUFFER_TYPE;
+		case T_JavaLangSystem : return JAVA_LANG_SYSTEM_TYPE;
+		case T_JavaLangThrowable : return JAVA_LANG_THROWABLE_TYPE;
+		case T_JavaLangError : return JAVA_LANG_ERROR_TYPE;
+		case T_JavaLangException : return JAVA_LANG_EXCEPTION_TYPE;
+		case T_JavaLangReflectConstructor : return JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE;
+	}
+	return -1;
+}
+public int literalIndex(byte[] utf8encoding, char[] stringCharArray) {
+	int index;
+	if ((index = UTF8Cache.get(stringCharArray)) < 0) {
+		// The entry doesn't exit yet
+		index = UTF8Cache.put(stringCharArray, currentIndex);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		currentIndex++;
+		// Write the tag first
+		writeU1(Utf8Tag);
+		// Then the size of the stringName array
+		//writeU2(utf8Constant.length);
+		int savedCurrentOffset = currentOffset;
+		if (currentOffset + 2 >= poolContent.length) {
+			// we need to resize the poolContent array because we won't have
+			// enough space to write the length
+			int length = poolContent.length;
+			System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		}
+		currentOffset += 2;
+		// add in once the whole byte array
+		int length = poolContent.length;
+		int utf8encodingLength = utf8encoding.length;
+		if (currentOffset + utf8encodingLength >= length) {
+			System.arraycopy(poolContent, 0, (poolContent = new byte[length + utf8encodingLength + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		}
+		System.arraycopy(utf8encoding, 0, poolContent, currentOffset, utf8encodingLength);
+		currentOffset += utf8encodingLength;
+		// Now we know the length that we have to write in the constant pool
+		// we use savedCurrentOffset to do that
+		poolContent[savedCurrentOffset] = (byte) (utf8encodingLength >> 8);
+		poolContent[savedCurrentOffset + 1] = (byte) utf8encodingLength;
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param char[] stringName
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(char[] utf8Constant) {
+	int index;
+	if ((index = UTF8Cache.get(utf8Constant)) < 0) {
+		// The entry doesn't exit yet
+		// Write the tag first
+		writeU1(Utf8Tag);
+		// Then the size of the stringName array
+		int savedCurrentOffset = currentOffset;
+		if (currentOffset + 2 >= poolContent.length) {
+			// we need to resize the poolContent array because we won't have
+			// enough space to write the length
+			int length = poolContent.length;
+			System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		}
+		currentOffset += 2;
+		int length = 0;
+		for (int i = 0; i < utf8Constant.length; i++) {
+			char current = utf8Constant[i];
+			if ((current >= 0x0001) && (current <= 0x007F)) {
+				// we only need one byte: ASCII table
+				writeU1(current);
+				length++;
+			} else
+				if (current > 0x07FF) {
+					// we need 3 bytes
+					length += 3;
+					writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+					writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+					writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+				} else {
+					// we can be 0 or between 0x0080 and 0x07FF
+					// In that case we only need 2 bytes
+					length += 2;
+					writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+					writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+				}
+		}
+		if (length >= 65535) {
+			currentOffset = savedCurrentOffset - 1;
+			return -1;
+		}
+		index = UTF8Cache.put(utf8Constant, currentIndex);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		currentIndex++;     
+		// Now we know the length that we have to write in the constant pool
+		// we use savedCurrentOffset to do that
+		poolContent[savedCurrentOffset] = (byte) (length >> 8);
+		poolContent[savedCurrentOffset + 1] = (byte) length;
+	}
+	return index;
+}
+public int literalIndex(char[] stringCharArray, byte[] utf8encoding) {
+	int index;
+	int stringIndex;
+	if ((index = stringCache.get(stringCharArray)) < 0) {
+		// The entry doesn't exit yet
+		stringIndex = literalIndex(utf8encoding, stringCharArray);
+		index = stringCache.put(stringCharArray, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the tag first
+		writeU1(StringTag);
+		// Then the string index
+		writeU2(stringIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the double
+ * value. If the double is not already present into the pool, it is added. The 
+ * double cache is updated and it returns the right index.
+ *
+ * @param <CODE>double</CODE> key
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(double key) {
+	//Retrieve the index from the cache
+	// The double constant takes two indexes into the constant pool, but we only store
+	// the first index into the long table
+	int index;
+	// lazy initialization for base type caches
+	// If it is null, initialize it, otherwise use it
+	if (doubleCache == null) {
+			doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE);
+	}
+	if ((index = doubleCache.get(key)) < 0) {
+		index = doubleCache.put(key, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		currentIndex++; // a double needs an extra place into the constant pool
+		// Write the double into the constant pool
+		// First add the tag
+		writeU1(DoubleTag);
+		// Then add the 8 bytes representing the double
+		long temp = java.lang.Double.doubleToLongBits(key);
+		for (int i = 0; i < 8; i++) {
+			try {
+				poolContent[currentOffset++] = (byte) (temp >>> (56 - (i << 3)));
+			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
+				int length = poolContent.length;
+				System.arraycopy(poolContent, 0, (poolContent = new byte[(length << 1) + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
+				poolContent[currentOffset - 1] = (byte) (temp >>> (56 - (i << 3)));
+			}
+		}
+	};
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the float
+ * value. If the float is not already present into the pool, it is added. The 
+ * int cache is updated and it returns the right index.
+ *
+ * @param <CODE>float</CODE> key
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(float key) {
+	//Retrieve the index from the cache
+	int index;
+	// lazy initialization for base type caches
+	// If it is null, initialize it, otherwise use it
+	if (floatCache == null) {
+		floatCache = new FloatCache(FLOAT_INITIAL_SIZE);
+	}
+	if ((index = floatCache.get(key)) < 0) {
+		index = floatCache.put(key, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the float constant entry into the constant pool
+		// First add the tag
+		writeU1(FloatTag);
+		// Then add the 4 bytes representing the float
+		int temp = java.lang.Float.floatToIntBits(key);
+		for (int i = 0; i < 4; i++) {
+			try {
+				poolContent[currentOffset++] = (byte) (temp >>> (24 - i * 8));
+			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
+				int length = poolContent.length;
+				System.arraycopy(poolContent, 0, (poolContent = new byte[length * 2 + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
+				poolContent[currentOffset - 1] = (byte) (temp >>> (24 - i * 8));
+			}
+		}
+	};
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the int
+ * value. If the int is not already present into the pool, it is added. The 
+ * int cache is updated and it returns the right index.
+ *
+ * @param <CODE>int</CODE> key
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(int key) {
+	//Retrieve the index from the cache
+	int index;
+	// lazy initialization for base type caches
+	// If it is null, initialize it, otherwise use it
+	if (intCache == null) {
+		intCache = new IntegerCache(INT_INITIAL_SIZE);
+	}
+	if ((index = intCache.get(key)) < 0) {
+		index = intCache.put(key, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the integer constant entry into the constant pool
+		// First add the tag
+		writeU1(IntegerTag);
+		// Then add the 4 bytes representing the int
+		for (int i = 0; i < 4; i++) {
+			try {
+				poolContent[currentOffset++] = (byte) (key >>> (24 - i * 8));
+			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
+				int length = poolContent.length;
+				System.arraycopy(poolContent, 0, (poolContent = new byte[length * 2 + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
+				poolContent[currentOffset - 1] = (byte) (key >>> (24 - i * 8));
+			}
+		}
+	};
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the long
+ * value. If the long is not already present into the pool, it is added. The 
+ * long cache is updated and it returns the right index.
+ *
+ * @param <CODE>long</CODE> key
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(long key) {
+	// Retrieve the index from the cache
+	// The long constant takes two indexes into the constant pool, but we only store
+	// the first index into the long table
+	int index;
+	// lazy initialization for base type caches
+	// If it is null, initialize it, otherwise use it
+	if (longCache == null) {
+		longCache = new LongCache(LONG_INITIAL_SIZE);
+	}
+	if ((index = longCache.get(key)) < 0) {
+		index = longCache.put(key, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		currentIndex++; // long value need an extra place into thwe constant pool
+		// Write the long into the constant pool
+		// First add the tag
+		writeU1(LongTag);
+		// Then add the 8 bytes representing the long
+		for (int i = 0; i < 8; i++) {
+			try {
+				poolContent[currentOffset++] = (byte) (key >>> (56 - (i << 3)));
+			} catch (IndexOutOfBoundsException e) { //currentOffset has been ++ already (see the -1)
+				int length = poolContent.length;
+				System.arraycopy(poolContent, 0, (poolContent = new byte[(length << 1) + CONSTANTPOOL_INITIAL_SIZE]), 0, length);
+				poolContent[currentOffset - 1] = (byte) (key >>> (56 - (i << 3)));
+			}
+		}
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param stringConstant java.lang.String
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(String stringConstant) {
+	int index;
+	char[] stringCharArray = stringConstant.toCharArray();
+	if ((index = stringCache.get(stringCharArray)) < 0) {
+		// The entry doesn't exit yet
+		int stringIndex = literalIndex(stringCharArray);
+		index = stringCache.put(stringCharArray, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the tag first
+		writeU1(StringTag);
+		// Then the string index
+		writeU2(stringIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @param FieldBinding aFieldBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(FieldBinding aFieldBinding) {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	int indexWellKnownField;
+	if ((indexWellKnownField = indexOfWellKnownFields(aFieldBinding)) == -1) {
+		if ((index = fieldCache.get(aFieldBinding)) < 0) {
+			// The entry doesn't exit yet
+			classIndex = literalIndex(aFieldBinding.declaringClass);
+			nameAndTypeIndex = literalIndexForFields(literalIndex(aFieldBinding.name), literalIndex(aFieldBinding.type.signature()), aFieldBinding);
+			index = fieldCache.put(aFieldBinding, currentIndex++);
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(FieldRefTag);
+			writeU2(classIndex);
+			writeU2(nameAndTypeIndex);
+		}
+	} else {
+		if ((index = wellKnownFields[indexWellKnownField]) == 0) {
+			// that field need to be inserted
+			classIndex = literalIndex(aFieldBinding.declaringClass);
+			nameAndTypeIndex = literalIndexForFields(literalIndex(aFieldBinding.name), literalIndex(aFieldBinding.type.signature()), aFieldBinding);
+			index = wellKnownFields[indexWellKnownField] = currentIndex++;
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(FieldRefTag);
+			writeU2(classIndex);
+			writeU2(nameAndTypeIndex);
+		}
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @param MethodBinding aMethodBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(MethodBinding aMethodBinding) {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	int nameIndex;
+	int indexWellKnownMethod;
+	if ((indexWellKnownMethod = indexOfWellKnownMethods(aMethodBinding)) == -1) {
+		if (aMethodBinding.declaringClass.isInterface()) {
+			// Lookinf into the interface method ref table
+			if ((index = interfaceMethodCache.get(aMethodBinding)) < 0) {
+				classIndex = literalIndex(aMethodBinding.declaringClass);
+				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
+				index = interfaceMethodCache.put(aMethodBinding, currentIndex++);
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the interface method ref constant into the constant pool
+				// First add the tag
+				writeU1(InterfaceMethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+		} else {
+			// Lookinf into the method ref table
+			if ((index = methodCache.get(aMethodBinding)) < 0) {
+				classIndex = literalIndex(aMethodBinding.declaringClass);
+				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
+				index = methodCache.put(aMethodBinding, currentIndex++);
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+		}
+	} else {
+		// This is a well known method
+		if ((index = wellKnownMethods[indexWellKnownMethod]) == 0) {
+			// this methods was not inserted yet
+			if (aMethodBinding.declaringClass.isInterface()) {
+				// Lookinf into the interface method ref table
+				classIndex = literalIndex(aMethodBinding.declaringClass);
+				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
+				index = wellKnownMethods[indexWellKnownMethod] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the interface method ref constant into the constant pool
+				// First add the tag
+				writeU1(InterfaceMethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			} else {
+				// Lookinf into the method ref table
+				classIndex = literalIndex(aMethodBinding.declaringClass);
+				nameAndTypeIndex = literalIndexForMethods(literalIndex(aMethodBinding.constantPoolName()), literalIndex(aMethodBinding.signature()), aMethodBinding);
+				index = wellKnownMethods[indexWellKnownMethod] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+		}
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndex(TypeBinding aTypeBinding) {
+	int index;
+	int nameIndex;
+	int indexWellKnownType;
+	if ((indexWellKnownType = indexOfWellKnownTypes(aTypeBinding)) == -1) {
+		if ((index = classCache.get(aTypeBinding)) < 0) {
+			// The entry doesn't exit yet
+			nameIndex = literalIndex(aTypeBinding.constantPoolName());
+			index = classCache.put(aTypeBinding, currentIndex++);
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(ClassTag);
+			// Then add the 8 bytes representing the long
+			writeU2(nameIndex);
+		}
+	} else {
+		if ((index = wellKnownTypes[indexWellKnownType]) == 0) {
+			// Need to insert that binding
+			nameIndex = literalIndex(aTypeBinding.constantPoolName());
+			index = wellKnownTypes[indexWellKnownType] = currentIndex++;
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(ClassTag);
+			// Then add the 8 bytes representing the long
+			writeU2(nameIndex);
+		}
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding 
+ * nameAndType constant with nameIndex, typeIndex.
+ *
+ * @param int nameIndex
+ * @param int nameIndex
+ * @param org.eclipse.jdt.internal.compiler.lookup.FieldBinding a FieldBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForFields(int nameIndex, int typeIndex, FieldBinding key) {
+	int index;
+	int indexOfWellKnownFieldNameAndType;
+	if ((indexOfWellKnownFieldNameAndType = indexOfWellKnownFieldNameAndType(key)) == -1) {
+		// check if the entry already exists
+		if ((index = nameAndTypeCacheForFields.get(key)) == -1) {
+			// The entry doesn't exit yet
+			index = nameAndTypeCacheForFields.put(key, currentIndex++);
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+	} else {
+		if ((index = wellKnownFieldNameAndTypes[indexOfWellKnownFieldNameAndType]) == 0) {
+			index = wellKnownFieldNameAndTypes[indexOfWellKnownFieldNameAndType] = currentIndex++;
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangBoolean() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_BOOLEAN_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangBooleanConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_BOOLEAN_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangBooleanTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_BOOLEAN_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangBoolean();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_BOOLEAN_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangByte() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_BYTE_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangByteConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_BYTE_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangByteTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_BYTE_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangByte();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_BYTE_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangCharacter() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_CHARACTER_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangCharacterConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_CHARACTER_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangCharacterTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_CHARACTER_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangCharacter();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_CHARACTER_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangClass() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_CLASS_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangClassConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_CLASS_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangClassForName() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[FORNAME_CLASS_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangClass();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[FORNAME_CLASS_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.ForName);
+			int typeIndex = literalIndex(QualifiedNamesConstants.ForNameSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[FORNAME_CLASS_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[FORNAME_CLASS_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangClassGetConstructor() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[GETCONSTRUCTOR_CLASS_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangClass();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[GETCONSTRUCTOR_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.GetConstructor);
+			int typeIndex = literalIndex(QualifiedNamesConstants.GetConstructorSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[GETCONSTRUCTOR_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[GETCONSTRUCTOR_CLASS_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangClassNotFoundException() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangClassNotFoundExceptionConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_CLASSNOTFOUNDEXCEPTION_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangDouble() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_DOUBLE_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangDoubleConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_DOUBLE_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangDoubleTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_DOUBLE_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangDouble();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_DOUBLE_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangError() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_ERROR_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangErrorConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_ERROR_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangErrorConstructor() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[JAVALANGERROR_CONSTR_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangError();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
+			int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[JAVALANGERROR_CONSTR_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+public int literalIndexForJavaLangException() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_EXCEPTION_TYPE]) == 0) {
+		// The entry doesn't exit yet
+		int nameIndex = literalIndex(QualifiedNamesConstants.JavaLangExceptionConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_EXCEPTION_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangFloat() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_FLOAT_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangFloatConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_FLOAT_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangFloatTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_FLOAT_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangFloat();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_FLOAT_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangInteger() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_INTEGER_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangIntegerConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_INTEGER_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangIntegerTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_INTEGER_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangInteger();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_INTEGER_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangLong() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_LONG_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangLongConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_LONG_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangLongTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_LONG_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangLong();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_LONG_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangNoClassDefFoundError() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangNoClassDefFoundErrorConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_NOCLASSDEFFOUNDERROR_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangNoClassDefFoundErrorStringConstructor() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[NOCLASSDEFFOUNDERROR_CONSTR_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangNoClassDefFoundError();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
+			int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[NOCLASSDEFFOUNDERROR_CONSTR_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangObject() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_OBJECT_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangObjectConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_OBJECT_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangReflectConstructor() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangReflectConstructor);
+		index = wellKnownTypes[JAVA_LANG_REFLECT_CONSTRUCTOR_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+public int literalIndexForJavaLangReflectConstructorNewInstance() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[NEWINSTANCE_CONSTRUCTOR_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangReflectConstructor();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[NEWINSTANCE_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.NewInstance);
+			int typeIndex = literalIndex(QualifiedNamesConstants.NewInstanceSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[NEWINSTANCE_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[NEWINSTANCE_CONSTRUCTOR_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangShort() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_SHORT_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangShortConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_SHORT_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangShortTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_SHORT_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangShort();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_SHORT_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangString() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_STRING_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangStringConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_STRING_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringBuffer() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_STRINGBUFFER_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangStringBufferConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_STRINGBUFFER_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringBufferAppend(int typeID) {
+	int index = 0;
+	int nameAndTypeIndex = 0;
+	int classIndex = 0;
+	switch (typeID) {
+		case T_int :
+		case T_byte :
+		case T_short :
+			if ((index = wellKnownMethods[APPEND_INT_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_INT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendIntSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_INT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_INT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_long :
+			if ((index = wellKnownMethods[APPEND_LONG_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_LONG_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendLongSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_LONG_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_LONG_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_float :
+			if ((index = wellKnownMethods[APPEND_FLOAT_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_FLOAT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendFloatSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_FLOAT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_FLOAT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_double :
+			if ((index = wellKnownMethods[APPEND_DOUBLE_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_DOUBLE_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendDoubleSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_DOUBLE_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_DOUBLE_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_char :
+			if ((index = wellKnownMethods[APPEND_CHAR_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_CHAR_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendCharSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_CHAR_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_CHAR_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_boolean :
+			if ((index = wellKnownMethods[APPEND_BOOLEAN_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_BOOLEAN_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendBooleanSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_BOOLEAN_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_BOOLEAN_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_Object :
+			if ((index = wellKnownMethods[APPEND_OBJECT_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_OBJECT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendObjectSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_OBJECT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_OBJECT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_String :
+		case T_null :
+			if ((index = wellKnownMethods[APPEND_STRING_METHOD]) == 0) {
+				classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_STRING_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Append);
+					int typeIndex = literalIndex(QualifiedNamesConstants.AppendStringSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[APPEND_STRING_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[APPEND_STRING_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringBufferConstructor() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[STRINGBUFFER_STRING_CONSTR_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangStringBuffer();
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.Init);
+					int typeIndex = literalIndex(QualifiedNamesConstants.StringConstructorSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[STRING_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+		index = wellKnownMethods[STRINGBUFFER_STRING_CONSTR_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringBufferDefaultConstructor() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[STRINGBUFFER_DEFAULT_CONSTR_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangStringBuffer();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[DEFAULT_CONSTR_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Init);
+			int typeIndex = literalIndex(QualifiedNamesConstants.DefaultConstructorSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[DEFAULT_CONSTR_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[STRINGBUFFER_DEFAULT_CONSTR_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringBufferToString() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[STRINGBUFFER_TOSTRING_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangStringBuffer();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[TOSTRING_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.ToString);
+			int typeIndex = literalIndex(QualifiedNamesConstants.ToStringSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[TOSTRING_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[STRINGBUFFER_TOSTRING_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringIntern() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[STRING_INTERN_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangString();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[INTERN_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Intern);
+			int typeIndex = literalIndex(QualifiedNamesConstants.InternSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[INTERN_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[STRING_INTERN_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangStringValueOf(int typeID) {
+	int index = 0;
+	int nameAndTypeIndex = 0;
+	int classIndex = literalIndexForJavaLangString();
+	switch (typeID) {
+		case T_int :
+		case T_byte :
+		case T_short :
+			if ((index = wellKnownMethods[VALUEOF_INT_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_INT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfIntSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_INT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_INT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_long :
+			if ((index = wellKnownMethods[VALUEOF_LONG_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_LONG_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfLongSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_LONG_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_LONG_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_float :
+			if ((index = wellKnownMethods[VALUEOF_FLOAT_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_FLOAT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfFloatSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_FLOAT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_FLOAT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_double :
+			if ((index = wellKnownMethods[VALUEOF_DOUBLE_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfDoubleSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_DOUBLE_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_DOUBLE_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_char :
+			if ((index = wellKnownMethods[VALUEOF_CHAR_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_CHAR_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfCharSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_CHAR_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_CHAR_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_boolean :
+			if ((index = wellKnownMethods[VALUEOF_BOOLEAN_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfBooleanSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_BOOLEAN_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_BOOLEAN_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+		case T_Object :
+			if ((index = wellKnownMethods[VALUEOF_OBJECT_METHOD]) == 0) {
+				if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_OBJECT_METHOD_NAME_AND_TYPE]) == 0) {
+					int nameIndex = literalIndex(QualifiedNamesConstants.ValueOf);
+					int typeIndex = literalIndex(QualifiedNamesConstants.ValueOfObjectSignature);
+					nameAndTypeIndex = wellKnownMethodNameAndTypes[VALUEOF_OBJECT_METHOD_NAME_AND_TYPE] = currentIndex++;
+					writeU1(NameAndTypeTag);
+					writeU2(nameIndex);
+					writeU2(typeIndex);
+				}
+				index = wellKnownMethods[VALUEOF_OBJECT_METHOD] = currentIndex++;
+				if (index > 0xFFFF){
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// Write the method ref constant into the constant pool
+				// First add the tag
+				writeU1(MethodRefTag);
+				// Then write the class index
+				writeU2(classIndex);
+				// The write the nameAndType index
+				writeU2(nameAndTypeIndex);
+			}
+			break;
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangSystem() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_SYSTEM_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangSystemConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_SYSTEM_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangSystemExitInt() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[SYSTEM_EXIT_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangSystem();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[EXIT_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Exit);
+			int typeIndex = literalIndex(QualifiedNamesConstants.ExitIntSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[EXIT_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[SYSTEM_EXIT_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangSystemOut() {
+	int index;
+	if ((index = wellKnownFields[OUT_SYSTEM_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangSystem();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[OUT_SYSTEM_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.Out);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaIoPrintStreamSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[OUT_SYSTEM_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[OUT_SYSTEM_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangThrowable() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_THROWABLE_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangThrowableConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_THROWABLE_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the 
+ * method descriptor. It can be either an interface method reference constant
+ * or a method reference constant.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangThrowableGetMessage() {
+	int index;
+	int nameAndTypeIndex;
+	int classIndex;
+	// Looking into the method ref table
+	if ((index = wellKnownMethods[THROWABLE_GETMESSAGE_METHOD]) == 0) {
+		classIndex = literalIndexForJavaLangThrowable();
+		if ((nameAndTypeIndex = wellKnownMethodNameAndTypes[GETMESSAGE_METHOD_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.GetMessage);
+			int typeIndex = literalIndex(QualifiedNamesConstants.GetMessageSignature);
+			nameAndTypeIndex = wellKnownMethodNameAndTypes[GETMESSAGE_METHOD_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownMethods[THROWABLE_GETMESSAGE_METHOD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the method ref constant into the constant pool
+		// First add the tag
+		writeU1(MethodRefTag);
+		// Then write the class index
+		writeU2(classIndex);
+		// The write the nameAndType index
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param TypeBinding aTypeBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangVoid() {
+	int index;
+	if ((index = wellKnownTypes[JAVA_LANG_VOID_TYPE]) == 0) {
+		int nameIndex;
+		// The entry doesn't exit yet
+		nameIndex = literalIndex(QualifiedNamesConstants.JavaLangVoidConstantPoolName);
+		index = wellKnownTypes[JAVA_LANG_VOID_TYPE] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(ClassTag);
+		// Then add the 8 bytes representing the long
+		writeU2(nameIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool 
+ * corresponding to the field binding aFieldBinding.
+ *
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForJavaLangVoidTYPE() {
+	int index;
+	if ((index = wellKnownFields[TYPE_VOID_FIELD]) == 0) {
+		int nameAndTypeIndex;
+		int classIndex;
+		// The entry doesn't exit yet
+		classIndex = literalIndexForJavaLangVoid();
+		if ((nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE]) == 0) {
+			int nameIndex = literalIndex(QualifiedNamesConstants.TYPE);
+			int typeIndex = literalIndex(QualifiedNamesConstants.JavaLangClassSignature);
+			nameAndTypeIndex = wellKnownFieldNameAndTypes[TYPE_JAVALANGCLASS_NAME_AND_TYPE] = currentIndex++;
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+		index = wellKnownFields[TYPE_VOID_FIELD] = currentIndex++;
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		writeU1(FieldRefTag);
+		writeU2(classIndex);
+		writeU2(nameAndTypeIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding to the type descriptor.
+ *
+ * @param char[] stringName
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForLdc(char[] stringCharArray) {
+	int index;
+	if ((index = stringCache.get(stringCharArray)) < 0) {
+		int stringIndex;
+		// The entry doesn't exit yet
+		if ((stringIndex = UTF8Cache.get(stringCharArray)) < 0) {
+			// The entry doesn't exit yet
+			// Write the tag first
+			writeU1(Utf8Tag);
+			// Then the size of the stringName array
+			int savedCurrentOffset = currentOffset;
+			if (currentOffset + 2 >= poolContent.length) {
+				// we need to resize the poolContent array because we won't have
+				// enough space to write the length
+				int length = poolContent.length;
+				System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+			}
+			currentOffset += 2;
+			int length = 0;
+			for (int i = 0; i < stringCharArray.length; i++) {
+				char current = stringCharArray[i];
+				if ((current >= 0x0001) && (current <= 0x007F)) {
+					// we only need one byte: ASCII table
+					writeU1(current);
+					length++;
+				} else
+					if (current > 0x07FF) {
+						// we need 3 bytes
+						length += 3;
+						writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+						writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					} else {
+						// we can be 0 or between 0x0080 and 0x07FF
+						// In that case we only need 2 bytes
+						length += 2;
+						writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					}
+			}
+			if (length >= 65535) {
+				currentOffset = savedCurrentOffset - 1;
+				return -1;
+			}
+			stringIndex = UTF8Cache.put(stringCharArray, currentIndex++);
+			// Now we know the length that we have to write in the constant pool
+			// we use savedCurrentOffset to do that
+			if (length > 65535) {
+				return 0;
+			}
+			poolContent[savedCurrentOffset] = (byte) (length >> 8);
+			poolContent[savedCurrentOffset + 1] = (byte) length;
+		}
+		index = stringCache.put(stringCharArray, currentIndex++);
+		if (index > 0xFFFF){
+			this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+		}
+		// Write the tag first
+		writeU1(StringTag);
+		// Then the string index
+		writeU2(stringIndex);
+	}
+	return index;
+}
+/**
+ * This method returns the index into the constantPool corresponding 
+ * nameAndType constant with nameIndex, typeIndex.
+ *
+ * @param int nameIndex
+ * @param int nameIndex
+ * @param org.eclipse.jdt.internal.compiler.lookup.MethodBinding a methodBinding
+ * @return <CODE>int</CODE>
+ */
+public int literalIndexForMethods(int nameIndex, int typeIndex, MethodBinding key) {
+	int index;
+	int indexOfWellKnownMethodNameAndType;
+	if ((indexOfWellKnownMethodNameAndType = indexOfWellKnownMethodNameAndType(key)) == -1) {
+		// check if the entry exists
+		if ((index = nameAndTypeCacheForMethods.get(key)) == -1) {
+			// The entry doesn't exit yet
+			index = nameAndTypeCacheForMethods.put(key, currentIndex++);
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+	} else {
+		if ((index = wellKnownMethodNameAndTypes[indexOfWellKnownMethodNameAndType]) == 0) {
+			index = wellKnownMethodNameAndTypes[indexOfWellKnownMethodNameAndType] = currentIndex++;
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			writeU1(NameAndTypeTag);
+			writeU2(nameIndex);
+			writeU2(typeIndex);
+		}
+	}
+	return index;
+}
+/**
+ * This method is used to clean the receiver in case of a clinit header is generated, but the 
+ * clinit has no code.
+ * This implementation assumes that the clinit is the first method to be generated.
+ * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.addClinit()
+ */
+public void resetForClinit(int constantPoolIndex, int constantPoolOffset) {
+	currentIndex = constantPoolIndex;
+	currentOffset = constantPoolOffset;
+	if (UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) {
+		UTF8Cache.remove(AttributeNamesConstants.CodeName);
+	}
+	if (UTF8Cache.get(QualifiedNamesConstants.ClinitSignature) >= constantPoolIndex) {
+		UTF8Cache.remove(QualifiedNamesConstants.ClinitSignature);
+	}
+	if (UTF8Cache.get(QualifiedNamesConstants.Clinit) >= constantPoolIndex) {
+		UTF8Cache.remove(QualifiedNamesConstants.Clinit);
+	}
+}
+/**
+ * Write a unsigned byte into the byte array
+ * 
+ * @param <CODE>int</CODE> The value to write into the byte array
+ */
+protected final void writeU1(int value) {
+	try {
+		poolContent[currentOffset++] = (byte) value;
+	} catch (IndexOutOfBoundsException e) {
+		//currentOffset has been ++ already (see the -1)
+		int length = poolContent.length;
+		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		poolContent[currentOffset - 1] = (byte) value;
+	}
+}
+/**
+ * Write a unsigned byte into the byte array
+ * 
+ * @param <CODE>int</CODE> The value to write into the byte array
+ */
+protected final void writeU2(int value) {
+	//first byte
+	try {
+		poolContent[currentOffset++] = (byte) (value >> 8);
+	} catch (IndexOutOfBoundsException e) {
+		 //currentOffset has been ++ already (see the -1)
+		int length = poolContent.length;
+		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		poolContent[currentOffset - 1] = (byte) (value >> 8);
+	}
+	try {
+		poolContent[currentOffset++] = (byte) value;
+	} catch (IndexOutOfBoundsException e) {
+		 //currentOffset has been ++ already (see the -1)
+		int length = poolContent.length;
+		System.arraycopy(poolContent, 0, (poolContent = new byte[length + CONSTANTPOOL_GROW_SIZE]), 0, length);
+		poolContent[currentOffset - 1] = (byte) value;
+	}
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
index 7711e17..708bf06 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
@@ -1,135 +1,133 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
- 
-public class DoubleCache {
-	private double keyTable[];
-	private int valueTable[]; 
-	private int elementSize;
-/**
- * Constructs a new, empty hashtable. A default capacity and
- * load factor is used. Note that the hashtable will automatically 
- * grow when it gets full.
- */
-public DoubleCache() {
-	this(13);
-}
-/**
- * Constructs a new, empty hashtable with the specified initial
- * capacity.
- * @param initialCapacity int
- *  the initial number of buckets
- */
-public DoubleCache(int initialCapacity) {
-	elementSize = 0;
-	keyTable = new double[initialCapacity];
-	valueTable = new int[initialCapacity];
-}
-/**
- * Clears the hash table so that it has no more elements in it.
- */
-public void clear() {
-	for (int i = keyTable.length; --i >= 0;) {
-		keyTable[i] = 0.0;
-		valueTable[i] = 0;
-	}
-	elementSize = 0;
-}
-/** Returns true if the collection contains an element for the key.
- *
- * @param key <CODE>double</CODE> the key that we are looking for
- * @return boolean
- * @see ConstantPoolCache#contains
- */
-public boolean containsKey(double key) {
-	if (key == 0.0) {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == 0.0) {
-				long value1 = Double.doubleToLongBits(key);
-				long value2 = Double.doubleToLongBits(keyTable[i]);
-				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
-					return true;
-				if (value1 == 0 && value2 == 0)
-					return true;
-			}
-		}
-	} else {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == key) {
-				return true;
-			}
-		}
-	}
-	return false;
-}
-/** Gets the object associated with the specified key in the
- * hashtable.
- * @param key <CODE>double</CODE> the specified key
- * @return int the element for the key or -1 if the key is not
- *  defined in the hash table.
- * @see ConstantPoolCache#put
- */
-public int get(double key) {
-	if (key == 0.0) {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == 0.0) {
-				long value1 = Double.doubleToLongBits(key);
-				long value2 = Double.doubleToLongBits(keyTable[i]);
-				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
-					return valueTable[i];
-				if (value1 == 0 && value2 == 0)
-					return valueTable[i];
-			}
-		}
-	} else {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == key) {
-				return valueTable[i];
-			}
-		}
-	}
-	return -1;
-}
-/**
- * Puts the specified element into the hashtable, using the specified
- * key.  The element may be retrieved by doing a get() with the same key.
- * 
- * @param key <CODE>double</CODE> the specified key in the hashtable
- * @param value <CODE>int</CODE> the specified element
- * @return int value
- */
-public int put(double key, int value) {
-	if (elementSize == keyTable.length) {
-		// resize
-		System.arraycopy(keyTable, 0, (keyTable = new double[elementSize * 2]), 0, elementSize);
-		System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize);
-	}
-	keyTable[elementSize] = key;
-	valueTable[elementSize] = value;
-	elementSize++;
-	return value;
-}
-/**
- * Converts to a rather lengthy String.
- *
- * return String the ascii representation of the receiver
- */
-public String toString() {
-	int max = elementSize;
-	StringBuffer buf = new StringBuffer();
-	buf.append("{"/*nonNLS*/);
-	for (int i = 0; i < max; ++i) {
-		if ((keyTable[i] != 0) || ((keyTable[i] == 0) &&(valueTable[i] != 0))) {
-			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
-		}
-		if (i < max) {
-			buf.append(", "/*nonNLS*/);
-		}
-	}
-	buf.append("}"/*nonNLS*/);
-	return buf.toString();
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class DoubleCache {
+	private double keyTable[];
+	private int valueTable[]; 
+	private int elementSize;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically 
+ * grow when it gets full.
+ */
+public DoubleCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public DoubleCache(int initialCapacity) {
+	elementSize = 0;
+	keyTable = new double[initialCapacity];
+	valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = keyTable.length; --i >= 0;) {
+		keyTable[i] = 0.0;
+		valueTable[i] = 0;
+	}
+	elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>double</CODE> the key that we are looking for
+ * @return boolean
+ * @see ConstantPoolCache#contains
+ */
+public boolean containsKey(double key) {
+	if (key == 0.0) {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == 0.0) {
+				long value1 = Double.doubleToLongBits(key);
+				long value2 = Double.doubleToLongBits(keyTable[i]);
+				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
+					return true;
+				if (value1 == 0 && value2 == 0)
+					return true;
+			}
+		}
+	} else {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == key) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>double</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ * @see ConstantPoolCache#put
+ */
+public int get(double key) {
+	if (key == 0.0) {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == 0.0) {
+				long value1 = Double.doubleToLongBits(key);
+				long value2 = Double.doubleToLongBits(keyTable[i]);
+				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
+					return valueTable[i];
+				if (value1 == 0 && value2 == 0)
+					return valueTable[i];
+			}
+		}
+	} else {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == key) {
+				return valueTable[i];
+			}
+		}
+	}
+	return -1;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * 
+ * @param key <CODE>double</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(double key, int value) {
+	if (elementSize == keyTable.length) {
+		// resize
+		System.arraycopy(keyTable, 0, (keyTable = new double[elementSize * 2]), 0, elementSize);
+		System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize);
+	}
+	keyTable[elementSize] = key;
+	valueTable[elementSize] = value;
+	elementSize++;
+	return value;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = elementSize;
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"/*nonNLS*/);
+	for (int i = 0; i < max; ++i) {
+		if ((keyTable[i] != 0) || ((keyTable[i] == 0) &&(valueTable[i] != 0))) {
+			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
+		}
+		if (i < max) {
+			buf.append(", "/*nonNLS*/);
+		}
+	}
+	buf.append("}"/*nonNLS*/);
+	return buf.toString();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
index 3480a6c..580e0be 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
@@ -1,135 +1,133 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public class FloatCache {
-	private float keyTable[];
-	private int valueTable[];
-	private int elementSize;
-/**
- * Constructs a new, empty hashtable. A default capacity and
- * load factor is used. Note that the hashtable will automatically 
- * grow when it gets full.
- */
-public FloatCache() {
-	this(13);
-}
-/**
- * Constructs a new, empty hashtable with the specified initial
- * capacity.
- * @param initialCapacity int
- *  the initial number of buckets
- */
-public FloatCache(int initialCapacity) {
-	elementSize = 0;
-	keyTable = new float[initialCapacity];
-	valueTable = new int[initialCapacity];
-}
-/**
- * Clears the hash table so that it has no more elements in it.
- */
-public void clear() {
-	for (int i = keyTable.length; --i >= 0;) {
-		keyTable[i] = 0.0f;
-		valueTable[i] = 0;
-	}
-	elementSize = 0;
-}
-/** Returns true if the collection contains an element for the key.
- *
- * @param key <CODE>float</CODE> the key that we are looking for
- * @return boolean
- * @see ConstantPoolCache#contains
- */
-public boolean containsKey(float key) {
-	if (key == 0.0f) {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == 0.0f) {
-				int value1 = Float.floatToIntBits(key);
-				int value2 = Float.floatToIntBits(keyTable[i]);
-				if (value1 == -2147483648 && value2 == -2147483648)
-					return true;
-				if (value1 == 0 && value2 == 0)
-					return true;
-			}
-		}
-	} else {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == key) {
-				return true;
-			}
-		}
-	}
-	return false;
-}
-/** Gets the object associated with the specified key in the
- * hashtable.
- * @param key <CODE>float</CODE> the specified key
- * @return int the element for the key or -1 if the key is not
- *  defined in the hash table.
- * @see ConstantPoolCache#put
- */
-public int get(float key) {
-	if (key == 0.0f) {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == 0.0f) {
-				int value1 = Float.floatToIntBits(key);
-				int value2 = Float.floatToIntBits(keyTable[i]);
-				if (value1 == -2147483648 && value2 == -2147483648)
-					return valueTable[i];
-				if (value1 == 0 && value2 == 0)
-					return valueTable[i];
-			}
-		}
-	} else {
-		for (int i = 0, max = elementSize; i < max; i++) {
-			if (keyTable[i] == key) {
-				return valueTable[i];
-			}
-		}
-	}
-	return -1;
-}
-/**
- * Puts the specified element into the hashtable, using the specified
- * key.  The element may be retrieved by doing a get() with the same key.
- * 
- * @param key <CODE>float</CODE> the specified key in the hashtable
- * @param value <CODE>int</CODE> the specified element
- * @return int value
- */
-public int put(float key, int value) {
-	if (elementSize == keyTable.length) {
-		// resize
-		System.arraycopy(keyTable, 0, (keyTable = new float[elementSize * 2]), 0, elementSize);
-		System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize);
-	}
-	keyTable[elementSize] = key;
-	valueTable[elementSize] = value;
-	elementSize++;
-	return value;
-}
-/**
- * Converts to a rather lengthy String.
- *
- * return String the ascii representation of the receiver
- */
-public String toString() {
-	int max = elementSize;
-	StringBuffer buf = new StringBuffer();
-	buf.append("{"/*nonNLS*/);
-	for (int i = 0; i < max; ++i) {
-		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
-			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
-		}
-		if (i < max) {
-			buf.append(", "/*nonNLS*/);
-		}
-	}
-	buf.append("}"/*nonNLS*/);
-	return buf.toString();
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class FloatCache {
+	private float keyTable[];
+	private int valueTable[];
+	private int elementSize;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically 
+ * grow when it gets full.
+ */
+public FloatCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public FloatCache(int initialCapacity) {
+	elementSize = 0;
+	keyTable = new float[initialCapacity];
+	valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = keyTable.length; --i >= 0;) {
+		keyTable[i] = 0.0f;
+		valueTable[i] = 0;
+	}
+	elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>float</CODE> the key that we are looking for
+ * @return boolean
+ * @see ConstantPoolCache#contains
+ */
+public boolean containsKey(float key) {
+	if (key == 0.0f) {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == 0.0f) {
+				int value1 = Float.floatToIntBits(key);
+				int value2 = Float.floatToIntBits(keyTable[i]);
+				if (value1 == -2147483648 && value2 == -2147483648)
+					return true;
+				if (value1 == 0 && value2 == 0)
+					return true;
+			}
+		}
+	} else {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == key) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>float</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ * @see ConstantPoolCache#put
+ */
+public int get(float key) {
+	if (key == 0.0f) {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == 0.0f) {
+				int value1 = Float.floatToIntBits(key);
+				int value2 = Float.floatToIntBits(keyTable[i]);
+				if (value1 == -2147483648 && value2 == -2147483648)
+					return valueTable[i];
+				if (value1 == 0 && value2 == 0)
+					return valueTable[i];
+			}
+		}
+	} else {
+		for (int i = 0, max = elementSize; i < max; i++) {
+			if (keyTable[i] == key) {
+				return valueTable[i];
+			}
+		}
+	}
+	return -1;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * 
+ * @param key <CODE>float</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(float key, int value) {
+	if (elementSize == keyTable.length) {
+		// resize
+		System.arraycopy(keyTable, 0, (keyTable = new float[elementSize * 2]), 0, elementSize);
+		System.arraycopy(valueTable, 0, (valueTable = new int[elementSize * 2]), 0, elementSize);
+	}
+	keyTable[elementSize] = key;
+	valueTable[elementSize] = value;
+	elementSize++;
+	return value;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = elementSize;
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"/*nonNLS*/);
+	for (int i = 0; i < max; ++i) {
+		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
+			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
+		}
+		if (i < max) {
+			buf.append(", "/*nonNLS*/);
+		}
+	}
+	buf.append("}"/*nonNLS*/);
+	return buf.toString();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
index d49b8b3..1db801f 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
@@ -1,153 +1,151 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public class IntegerCache {
-	public int keyTable[];
-	public int valueTable[]; 
-	int elementSize;
-	int threshold;
-/**
- * Constructs a new, empty hashtable. A default capacity and
- * load factor is used. Note that the hashtable will automatically 
- * grow when it gets full.
- */
-public IntegerCache() {
-	this(13);
-}
-/**
- * Constructs a new, empty hashtable with the specified initial
- * capacity.
- * @param initialCapacity int
- *  the initial number of buckets
- */
-public IntegerCache(int initialCapacity) {
-	elementSize = 0;
-	threshold = (int) (initialCapacity * 0.66);
-	keyTable = new int[initialCapacity];
-	valueTable = new int[initialCapacity];
-}
-/**
- * Clears the hash table so that it has no more elements in it.
- */
-public void clear() {
-	for (int i = keyTable.length; --i >= 0;) {
-		keyTable[i] = 0;
-		valueTable[i] = 0;
-	}
-	elementSize = 0;
-}
-/** Returns true if the collection contains an element for the key.
- *
- * @param key <CODE>double</CODE> the key that we are looking for
- * @return boolean
- * @see ConstantPoolCache#contains
- */
-public boolean containsKey(int key) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return true;
-		index = (index + 1) % keyTable.length;
-	}
-	return false;
-}
-/** Gets the object associated with the specified key in the
- * hashtable.
- * @param key <CODE>double</CODE> the specified key
- * @return int the element for the key or -1 if the key is not
- *  defined in the hash table.
- * @see ConstantPoolCache#put
- */
-public int get(int key) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return valueTable[index];
-		index = (index + 1) % keyTable.length;
-	}
-	return -1;
-}
-/**
- * Return a hashcode for the value of the key parameter.
- * @param key int
- * @return int the hash code corresponding to the key value
- * @see ConstantPoolCache#put
- */
-public int hash(int key) {
-	return (key & 0x7FFFFFFF) % keyTable.length;
-}
-/**
- * Puts the specified element into the hashtable, using the specified
- * key.  The element may be retrieved by doing a get() with the same key.
- * 
- * @param key <CODE>int</CODE> the specified key in the hashtable
- * @param value <CODE>int</CODE> the specified element
- * @return int value
- */
-public int put(int key, int value) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return valueTable[index] = value;
-		index = (index + 1) % keyTable.length;
-	}
-	keyTable[index] = key;
-	valueTable[index] = value;
-
-	// assumes the threshold is never equal to the size of the table
-	if (++elementSize > threshold) {
-		rehash();
-	}
-	return value;
-}
-/**
- * Rehashes the content of the table into a bigger table.
- * This method is called automatically when the hashtable's
- * size exceeds the threshold.
- */
-private void rehash() {
-	IntegerCache newHashtable = new IntegerCache(keyTable.length * 2);
-	for (int i = keyTable.length; --i >= 0;) {
-		int key = keyTable[i];
-		int value = valueTable[i];
-		if ((key != 0) || ((key == 0) && (value != 0))) {
-			newHashtable.put(key, value);
-		}
-	}
-	this.keyTable = newHashtable.keyTable;
-	this.valueTable = newHashtable.valueTable;
-	this.threshold = newHashtable.threshold;
-}
-/**
- * Returns the number of elements contained in the hashtable.
- *
- * @return <CODE>int</CODE> The size of the table
- */
-public int size() {
-	return elementSize;
-}
-/**
- * Converts to a rather lengthy String.
- *
- * return String the ascii representation of the receiver
- */
-public String toString() {
-	int max = size();
-	StringBuffer buf = new StringBuffer();
-	buf.append("{"/*nonNLS*/);
-	for (int i = 0; i < max; ++i) {
-		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
-			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
-		}
-		if (i < max) {
-			buf.append(", "/*nonNLS*/);
-		}
-	}
-	buf.append("}"/*nonNLS*/);
-	return buf.toString();
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class IntegerCache {
+	public int keyTable[];
+	public int valueTable[]; 
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically 
+ * grow when it gets full.
+ */
+public IntegerCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public IntegerCache(int initialCapacity) {
+	elementSize = 0;
+	threshold = (int) (initialCapacity * 0.66);
+	keyTable = new int[initialCapacity];
+	valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = keyTable.length; --i >= 0;) {
+		keyTable[i] = 0;
+		valueTable[i] = 0;
+	}
+	elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>double</CODE> the key that we are looking for
+ * @return boolean
+ * @see ConstantPoolCache#contains
+ */
+public boolean containsKey(int key) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return true;
+		index = (index + 1) % keyTable.length;
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>double</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ * @see ConstantPoolCache#put
+ */
+public int get(int key) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return valueTable[index];
+		index = (index + 1) % keyTable.length;
+	}
+	return -1;
+}
+/**
+ * Return a hashcode for the value of the key parameter.
+ * @param key int
+ * @return int the hash code corresponding to the key value
+ * @see ConstantPoolCache#put
+ */
+public int hash(int key) {
+	return (key & 0x7FFFFFFF) % keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * 
+ * @param key <CODE>int</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(int key, int value) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return valueTable[index] = value;
+		index = (index + 1) % keyTable.length;
+	}
+	keyTable[index] = key;
+	valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++elementSize > threshold) {
+		rehash();
+	}
+	return value;
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	IntegerCache newHashtable = new IntegerCache(keyTable.length * 2);
+	for (int i = keyTable.length; --i >= 0;) {
+		int key = keyTable[i];
+		int value = valueTable[i];
+		if ((key != 0) || ((key == 0) && (value != 0))) {
+			newHashtable.put(key, value);
+		}
+	}
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"/*nonNLS*/);
+	for (int i = 0; i < max; ++i) {
+		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
+			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
+		}
+		if (i < max) {
+			buf.append(", "/*nonNLS*/);
+		}
+	}
+	buf.append("}"/*nonNLS*/);
+	return buf.toString();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
index a59397f..da9a4cc 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
@@ -1,153 +1,151 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public class LongCache {
-	public long keyTable[];
-	public int valueTable[]; 
-	int elementSize;
-	int threshold;
-/**
- * Constructs a new, empty hashtable. A default capacity and
- * load factor is used. Note that the hashtable will automatically 
- * grow when it gets full.
- */
-public LongCache() {
-	this(13);
-}
-/**
- * Constructs a new, empty hashtable with the specified initial
- * capacity.
- * @param initialCapacity int
- *  the initial number of buckets
- */
-public LongCache(int initialCapacity) {
-	elementSize = 0;
-	threshold = (int) (initialCapacity * 0.66);
-	keyTable = new long[initialCapacity];
-	valueTable = new int[initialCapacity];
-}
-/**
- * Clears the hash table so that it has no more elements in it.
- */
-public void clear() {
-	for (int i = keyTable.length; --i >= 0;) {
-		keyTable[i] = 0;
-		valueTable[i] = 0;
-	}
-	elementSize = 0;
-}
-/** Returns true if the collection contains an element for the key.
- *
- * @param key <CODE>long</CODE> the key that we are looking for
- * @return boolean
- * @see ConstantPoolCache#contains
- */
-public boolean containsKey(long key) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return true;
-		index = (index + 1) % keyTable.length;
-	}
-	return false;
-}
-/** Gets the object associated with the specified key in the
- * hashtable.
- * @param key <CODE>long</CODE> the specified key
- * @return int the element for the key or -1 if the key is not
- *  defined in the hash table.
- * @see ConstantPoolCache#put
- */
-public int get(long key) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return valueTable[index];
-		index = (index + 1) % keyTable.length;
-	}
-	return -1;
-}
-/**
- * Return a hashcode for the value of the key parameter.
- * @param key long
- * @return int the hash code corresponding to the key value
- * @see ConstantPoolCache#put
- */
-public int hash(long key) {
-	return ((int) key & 0x7FFFFFFF) % keyTable.length;
-}
-/**
- * Puts the specified element into the hashtable, using the specified
- * key.  The element may be retrieved by doing a get() with the same key.
- * 
- * @param key <CODE>long</CODE> the specified key in the hashtable
- * @param value <CODE>int</CODE> the specified element
- * @return int value
- */
-public int put(long key, int value) {
-	int index = hash(key);
-	while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) {
-		if (keyTable[index] == key)
-			return valueTable[index] = value;
-		index = (index + 1) % keyTable.length;
-	}
-	keyTable[index] = key;
-	valueTable[index] = value;
-
-	// assumes the threshold is never equal to the size of the table
-	if (++elementSize > threshold) {
-		rehash();
-	}
-	return value;
-}
-/**
- * Rehashes the content of the table into a bigger table.
- * This method is called automatically when the hashtable's
- * size exceeds the threshold.
- */
-private void rehash() {
-	LongCache newHashtable = new LongCache(keyTable.length * 2);
-	for (int i = keyTable.length; --i >= 0;) {
-		long key = keyTable[i];
-		int value = valueTable[i];
-		if ((key != 0) || ((key == 0) && (value != 0))) {
-			newHashtable.put(key, value);
-		}
-	}
-	this.keyTable = newHashtable.keyTable;
-	this.valueTable = newHashtable.valueTable;
-	this.threshold = newHashtable.threshold;
-}
-/**
- * Returns the number of elements contained in the hashtable.
- *
- * @return <CODE>int</CODE> The size of the table
- */
-public int size() {
-	return elementSize;
-}
-/**
- * Converts to a rather lengthy String.
- *
- * return String the ascii representation of the receiver
- */
-public String toString() {
-	int max = size();
-	StringBuffer buf = new StringBuffer();
-	buf.append("{"/*nonNLS*/);
-	for (int i = 0; i < max; ++i) {
-		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
-			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
-		}
-		if (i < max) {
-			buf.append(", "/*nonNLS*/);
-		}
-	}
-	buf.append("}"/*nonNLS*/);
-	return buf.toString();
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class LongCache {
+	public long keyTable[];
+	public int valueTable[]; 
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically 
+ * grow when it gets full.
+ */
+public LongCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public LongCache(int initialCapacity) {
+	elementSize = 0;
+	threshold = (int) (initialCapacity * 0.66);
+	keyTable = new long[initialCapacity];
+	valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = keyTable.length; --i >= 0;) {
+		keyTable[i] = 0;
+		valueTable[i] = 0;
+	}
+	elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>long</CODE> the key that we are looking for
+ * @return boolean
+ * @see ConstantPoolCache#contains
+ */
+public boolean containsKey(long key) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return true;
+		index = (index + 1) % keyTable.length;
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>long</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ * @see ConstantPoolCache#put
+ */
+public int get(long key) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) &&(valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return valueTable[index];
+		index = (index + 1) % keyTable.length;
+	}
+	return -1;
+}
+/**
+ * Return a hashcode for the value of the key parameter.
+ * @param key long
+ * @return int the hash code corresponding to the key value
+ * @see ConstantPoolCache#put
+ */
+public int hash(long key) {
+	return ((int) key & 0x7FFFFFFF) % keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * 
+ * @param key <CODE>long</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(long key, int value) {
+	int index = hash(key);
+	while ((keyTable[index] != 0) || ((keyTable[index] == 0) && (valueTable[index] != 0))) {
+		if (keyTable[index] == key)
+			return valueTable[index] = value;
+		index = (index + 1) % keyTable.length;
+	}
+	keyTable[index] = key;
+	valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++elementSize > threshold) {
+		rehash();
+	}
+	return value;
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	LongCache newHashtable = new LongCache(keyTable.length * 2);
+	for (int i = keyTable.length; --i >= 0;) {
+		long key = keyTable[i];
+		int value = valueTable[i];
+		if ((key != 0) || ((key == 0) && (value != 0))) {
+			newHashtable.put(key, value);
+		}
+	}
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"/*nonNLS*/);
+	for (int i = 0; i < max; ++i) {
+		if ((keyTable[i] != 0) || ((keyTable[i] == 0) && (valueTable[i] != 0))) {
+			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
+		}
+		if (i < max) {
+			buf.append(", "/*nonNLS*/);
+		}
+	}
+	buf.append("}"/*nonNLS*/);
+	return buf.toString();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
index 63cb51f..dc427ad 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
@@ -1,150 +1,148 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public class ObjectCache {
-	public Object keyTable[];
-	public int valueTable[];
-	int elementSize;
-	int threshold;
-/**
- * Constructs a new, empty hashtable. A default capacity is used.
- * Note that the hashtable will automatically grow when it gets full.
- */
-public ObjectCache() {
-	this(13);
-}
-/**
- * Constructs a new, empty hashtable with the specified initial
- * capacity.
- * @param initialCapacity int
- *  the initial number of buckets
- */
-public ObjectCache(int initialCapacity) {
-	this.elementSize = 0;
-	this.threshold = (int) (initialCapacity * 0.66f);
-	this.keyTable = new Object[initialCapacity];
-	this.valueTable = new int[initialCapacity];
-}
-/**
- * Clears the hash table so that it has no more elements in it.
- */
-public void clear() {
-	for (int i = keyTable.length; --i >= 0;) {
-		keyTable[i] = null;
-		valueTable[i] = 0;
-	}
-	elementSize = 0;
-}
-/** Returns true if the collection contains an element for the key.
- *
- * @param char[] key the key that we are looking for
- * @return boolean
- * @see ConstantPoolCache#contains
- */
-public boolean containsKey(Object key) {
-	int index = hashCode(key);
-	while (keyTable[index] != null) {
-		if (keyTable[index] == key)
-			return true;
-		index = (index + 1) % keyTable.length;
-	}
-	return false;
-}
-/** Gets the object associated with the specified key in the
- * hashtable.
- * @param key <CODE>char[]</CODE> the specified key
- * @return int the element for the key or -1 if the key is not
- *  defined in the hash table.
- * @see ConstantPoolCache#put
- */
-public int get(Object key) {
-	int index = hashCode(key);
-	while (keyTable[index] != null) {
-		if (keyTable[index] == key)
-			return valueTable[index];
-		index = (index + 1) % keyTable.length;
-	}
-	return -1;
-}
-/**
- * Return the hashcode for the key parameter
- *
- * @param key org.eclipse.jdt.internal.compiler.lookup.MethodBinding
- * @return int
- */
-public int hashCode(Object key) {
-	return (key.hashCode() & 0x7FFFFFFF) % keyTable.length;
-}
-/**
- * Puts the specified element into the hashtable, using the specified
- * key.  The element may be retrieved by doing a get() with the same key.
- * The key and the element cannot be null. 
- * 
- * @param key <CODE>Object</CODE> the specified key in the hashtable
- * @param value <CODE>int</CODE> the specified element
- * @see ConstantPoolCache#get
- * @return int the old value of the key, or -1 if it did not have one.
- */
-public int put(Object key, int value) { 
-	int index = hashCode(key);
-	while (keyTable[index] != null) {
-		if (keyTable[index] == key)
-			return valueTable[index] = value;
-		index = (index + 1) % keyTable.length;
-	}
-	keyTable[index] = key;
-	valueTable[index] = value;
-
-	// assumes the threshold is never equal to the size of the table
-	if (++elementSize > threshold)
-		rehash();
-	return value;
-}
-/**
- * Rehashes the content of the table into a bigger table.
- * This method is called automatically when the hashtable's
- * size exceeds the threshold.
- */
-private void rehash() {
-	ObjectCache newHashtable = new ObjectCache(keyTable.length * 2);
-	for (int i = keyTable.length; --i >= 0;)
-		if (keyTable[i] != null)
-			newHashtable.put(keyTable[i], valueTable[i]);
-
-	this.keyTable = newHashtable.keyTable;
-	this.valueTable = newHashtable.valueTable;
-	this.threshold = newHashtable.threshold;
-}
-/**
- * Returns the number of elements contained in the hashtable.
- *
- * @return <CODE>int</CODE> The size of the table
- */
-public int size() {
-	return elementSize;
-}
-/**
- * Converts to a rather lengthy String.
- *
- * return String the ascii representation of the receiver
- */
-public String toString() {
-	int max = size();
-	StringBuffer buf = new StringBuffer();
-	buf.append("{"/*nonNLS*/);
-	for (int i = 0; i < max; ++i) {
-		if (keyTable[i] != null) {
-			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
-		}
-		if (i < max) {
-			buf.append(", "/*nonNLS*/);
-		}
-	}
-	buf.append("}"/*nonNLS*/);
-	return buf.toString();
-}
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public class ObjectCache {
+	public Object keyTable[];
+	public int valueTable[];
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity is used.
+ * Note that the hashtable will automatically grow when it gets full.
+ */
+public ObjectCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public ObjectCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.threshold = (int) (initialCapacity * 0.66f);
+	this.keyTable = new Object[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = keyTable.length; --i >= 0;) {
+		keyTable[i] = null;
+		valueTable[i] = 0;
+	}
+	elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param char[] key the key that we are looking for
+ * @return boolean
+ * @see ConstantPoolCache#contains
+ */
+public boolean containsKey(Object key) {
+	int index = hashCode(key);
+	while (keyTable[index] != null) {
+		if (keyTable[index] == key)
+			return true;
+		index = (index + 1) % keyTable.length;
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>char[]</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ * @see ConstantPoolCache#put
+ */
+public int get(Object key) {
+	int index = hashCode(key);
+	while (keyTable[index] != null) {
+		if (keyTable[index] == key)
+			return valueTable[index];
+		index = (index + 1) % keyTable.length;
+	}
+	return -1;
+}
+/**
+ * Return the hashcode for the key parameter
+ *
+ * @param key org.eclipse.jdt.internal.compiler.lookup.MethodBinding
+ * @return int
+ */
+public int hashCode(Object key) {
+	return (key.hashCode() & 0x7FFFFFFF) % keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * The key and the element cannot be null. 
+ * 
+ * @param key <CODE>Object</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @see ConstantPoolCache#get
+ * @return int the old value of the key, or -1 if it did not have one.
+ */
+public int put(Object key, int value) { 
+	int index = hashCode(key);
+	while (keyTable[index] != null) {
+		if (keyTable[index] == key)
+			return valueTable[index] = value;
+		index = (index + 1) % keyTable.length;
+	}
+	keyTable[index] = key;
+	valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++elementSize > threshold)
+		rehash();
+	return value;
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	ObjectCache newHashtable = new ObjectCache(keyTable.length * 2);
+	for (int i = keyTable.length; --i >= 0;)
+		if (keyTable[i] != null)
+			newHashtable.put(keyTable[i], valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"/*nonNLS*/);
+	for (int i = 0; i < max; ++i) {
+		if (keyTable[i] != null) {
+			buf.append(keyTable[i]).append("->"/*nonNLS*/).append(valueTable[i]);
+		}
+		if (i < max) {
+			buf.append(", "/*nonNLS*/);
+		}
+	}
+	buf.append("}"/*nonNLS*/);
+	return buf.toString();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
index 7e6861c..2c2cc61 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
@@ -1,211 +1,210 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface Opcodes {
-
-	public static final byte OPC_nop = 0;
-	public static final byte OPC_aconst_null = 1;
-	public static final byte OPC_iconst_m1 = 2;
-	public static final byte OPC_iconst_0 = 3;
-	public static final byte OPC_iconst_1 = 4;
-	public static final byte OPC_iconst_2 = 5;
-	public static final byte OPC_iconst_3 = 6;
-	public static final byte OPC_iconst_4 = 7;
-	public static final byte OPC_iconst_5 = 8;
-	public static final byte OPC_lconst_0 = 9;
-	public static final byte OPC_lconst_1 = 10;
-	public static final byte OPC_fconst_0 = 11;
-	public static final byte OPC_fconst_1 = 12;
-	public static final byte OPC_fconst_2 = 13;
-	public static final byte OPC_dconst_0 = 14;
-	public static final byte OPC_dconst_1 = 15;
-	public static final byte OPC_bipush = 16;
-	public static final byte OPC_sipush = 17;
-	public static final byte OPC_ldc = 18;
-	public static final byte OPC_ldc_w = 19;
-	public static final byte OPC_ldc2_w = 20;
-	public static final byte OPC_iload = 21;
-	public static final byte OPC_lload = 22;
-	public static final byte OPC_fload = 23;
-	public static final byte OPC_dload = 24;
-	public static final byte OPC_aload = 25;
-	public static final byte OPC_iload_0 = 26;
-	public static final byte OPC_iload_1 = 27;
-	public static final byte OPC_iload_2 = 28;
-	public static final byte OPC_iload_3 = 29;
-	public static final byte OPC_lload_0 = 30;
-	public static final byte OPC_lload_1 = 31;
-	public static final byte OPC_lload_2 = 32;
-	public static final byte OPC_lload_3 = 33;
-	public static final byte OPC_fload_0 = 34;
-	public static final byte OPC_fload_1 = 35;
-	public static final byte OPC_fload_2 = 36;
-	public static final byte OPC_fload_3 = 37;
-	public static final byte OPC_dload_0 = 38;
-	public static final byte OPC_dload_1 = 39;
-	public static final byte OPC_dload_2 = 40;
-	public static final byte OPC_dload_3 = 41;
-	public static final byte OPC_aload_0 = 42;
-	public static final byte OPC_aload_1 = 43;
-	public static final byte OPC_aload_2 = 44;
-	public static final byte OPC_aload_3 = 45;
-	public static final byte OPC_iaload = 46;
-	public static final byte OPC_laload = 47;
-	public static final byte OPC_faload = 48;
-	public static final byte OPC_daload = 49;
-	public static final byte OPC_aaload = 50;
-	public static final byte OPC_baload = 51;
-	public static final byte OPC_caload = 52;
-	public static final byte OPC_saload = 53;
-	public static final byte OPC_istore = 54;
-	public static final byte OPC_lstore = 55;
-	public static final byte OPC_fstore = 56;
-	public static final byte OPC_dstore = 57;
-	public static final byte OPC_astore = 58;
-	public static final byte OPC_istore_0 = 59;
-	public static final byte OPC_istore_1 = 60;
-	public static final byte OPC_istore_2 = 61;
-	public static final byte OPC_istore_3 = 62;
-	public static final byte OPC_lstore_0 = 63;
-	public static final byte OPC_lstore_1 = 64;
-	public static final byte OPC_lstore_2 = 65;
-	public static final byte OPC_lstore_3 = 66;
-	public static final byte OPC_fstore_0 = 67;
-	public static final byte OPC_fstore_1 = 68;
-	public static final byte OPC_fstore_2 = 69;
-	public static final byte OPC_fstore_3 = 70;
-	public static final byte OPC_dstore_0 = 71;
-	public static final byte OPC_dstore_1 = 72;
-	public static final byte OPC_dstore_2 = 73;
-	public static final byte OPC_dstore_3 = 74;
-	public static final byte OPC_astore_0 = 75;
-	public static final byte OPC_astore_1 = 76;
-	public static final byte OPC_astore_2 = 77;
-	public static final byte OPC_astore_3 = 78;
-	public static final byte OPC_iastore = 79;
-	public static final byte OPC_lastore = 80;
-	public static final byte OPC_fastore = 81;
-	public static final byte OPC_dastore = 82;
-	public static final byte OPC_aastore = 83;
-	public static final byte OPC_bastore = 84;
-	public static final byte OPC_castore = 85;
-	public static final byte OPC_sastore = 86;
-	public static final byte OPC_pop = 87;
-	public static final byte OPC_pop2 = 88;
-	public static final byte OPC_dup = 89;
-	public static final byte OPC_dup_x1 = 90;
-	public static final byte OPC_dup_x2 = 91;
-	public static final byte OPC_dup2 = 92;
-	public static final byte OPC_dup2_x1 = 93;
-	public static final byte OPC_dup2_x2 = 94;
-	public static final byte OPC_swap = 95;
-	public static final byte OPC_iadd = 96;
-	public static final byte OPC_ladd = 97;
-	public static final byte OPC_fadd = 98;
-	public static final byte OPC_dadd = 99;
-	public static final byte OPC_isub = 100;
-	public static final byte OPC_lsub = 101;
-	public static final byte OPC_fsub = 102;
-	public static final byte OPC_dsub = 103;
-	public static final byte OPC_imul = 104;
-	public static final byte OPC_lmul = 105;
-	public static final byte OPC_fmul = 106;
-	public static final byte OPC_dmul = 107;
-	public static final byte OPC_idiv = 108;
-	public static final byte OPC_ldiv = 109;
-	public static final byte OPC_fdiv = 110;
-	public static final byte OPC_ddiv = 111;
-	public static final byte OPC_irem = 112;
-	public static final byte OPC_lrem = 113;
-	public static final byte OPC_frem = 114;
-	public static final byte OPC_drem = 115;
-	public static final byte OPC_ineg = 116;
-	public static final byte OPC_lneg = 117;
-	public static final byte OPC_fneg = 118;
-	public static final byte OPC_dneg = 119;
-	public static final byte OPC_ishl = 120;
-	public static final byte OPC_lshl = 121;
-	public static final byte OPC_ishr = 122;
-	public static final byte OPC_lshr = 123;
-	public static final byte OPC_iushr = 124;
-	public static final byte OPC_lushr = 125;
-	public static final byte OPC_iand = 126;
-	public static final byte OPC_land = 127;
-	public static final byte OPC_ior = (byte) 128;
-	public static final byte OPC_lor = (byte) 129;
-	public static final byte OPC_ixor = (byte) 130;
-	public static final byte OPC_lxor = (byte) 131;
-	public static final byte OPC_iinc = (byte) 132;
-	public static final byte OPC_i2l = (byte) 133;
-	public static final byte OPC_i2f = (byte) 134;
-	public static final byte OPC_i2d = (byte) 135;
-	public static final byte OPC_l2i = (byte) 136;
-	public static final byte OPC_l2f = (byte) 137;
-	public static final byte OPC_l2d = (byte) 138;
-	public static final byte OPC_f2i = (byte) 139;
-	public static final byte OPC_f2l = (byte) 140;
-	public static final byte OPC_f2d = (byte) 141;
-	public static final byte OPC_d2i = (byte) 142;
-	public static final byte OPC_d2l = (byte) 143;
-	public static final byte OPC_d2f = (byte) 144;
-	public static final byte OPC_i2b = (byte) 145;
-	public static final byte OPC_i2c = (byte) 146;
-	public static final byte OPC_i2s = (byte) 147;
-	public static final byte OPC_lcmp = (byte) 148;
-	public static final byte OPC_fcmpl = (byte) 149;
-	public static final byte OPC_fcmpg = (byte) 150;
-	public static final byte OPC_dcmpl = (byte) 151;
-	public static final byte OPC_dcmpg = (byte) 152;
-	public static final byte OPC_ifeq = (byte) 153;
-	public static final byte OPC_ifne = (byte) 154;
-	public static final byte OPC_iflt = (byte) 155;
-	public static final byte OPC_ifge = (byte) 156;
-	public static final byte OPC_ifgt = (byte) 157;
-	public static final byte OPC_ifle = (byte) 158;
-	public static final byte OPC_if_icmpeq = (byte) 159;
-	public static final byte OPC_if_icmpne = (byte) 160;
-	public static final byte OPC_if_icmplt = (byte) 161;
-	public static final byte OPC_if_icmpge = (byte) 162;
-	public static final byte OPC_if_icmpgt = (byte) 163;
-	public static final byte OPC_if_icmple = (byte) 164;
-	public static final byte OPC_if_acmpeq = (byte) 165;
-	public static final byte OPC_if_acmpne = (byte) 166;
-	public static final byte OPC_goto = (byte) 167;
-	public static final byte OPC_jsr = (byte) 168;
-	public static final byte OPC_ret = (byte) 169;
-	public static final byte OPC_tableswitch = (byte) 170;
-	public static final byte OPC_lookupswitch = (byte) 171;
-	public static final byte OPC_ireturn = (byte) 172;
-	public static final byte OPC_lreturn = (byte) 173;
-	public static final byte OPC_freturn = (byte) 174;
-	public static final byte OPC_dreturn = (byte) 175;
-	public static final byte OPC_areturn = (byte) 176;
-	public static final byte OPC_return = (byte) 177;
-	public static final byte OPC_getstatic = (byte) 178;
-	public static final byte OPC_putstatic = (byte) 179;
-	public static final byte OPC_getfield = (byte) 180;
-	public static final byte OPC_putfield = (byte) 181;
-	public static final byte OPC_invokevirtual = (byte) 182;
-	public static final byte OPC_invokespecial = (byte) 183;
-	public static final byte OPC_invokestatic = (byte) 184;
-	public static final byte OPC_invokeinterface = (byte) 185;
-	public static final byte OPC_new = (byte) 187;
-	public static final byte OPC_newarray = (byte) 188;
-	public static final byte OPC_anewarray = (byte) 189;
-	public static final byte OPC_arraylength = (byte) 190;
-	public static final byte OPC_athrow = (byte) 191;
-	public static final byte OPC_checkcast = (byte) 192;
-	public static final byte OPC_instanceof = (byte) 193;
-	public static final byte OPC_monitorenter = (byte) 194;
-	public static final byte OPC_monitorexit = (byte) 195;
-	public static final byte OPC_wide = (byte) 196;
-	public static final byte OPC_multianewarray = (byte) 197;
-	public static final byte OPC_ifnull = (byte) 198;
-	public static final byte OPC_ifnonnull = (byte) 199;
-	public static final byte OPC_goto_w = (byte) 200;
-	public static final byte OPC_jsr_w = (byte) 201;
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface Opcodes {
+
+	public static final byte OPC_nop = 0;
+	public static final byte OPC_aconst_null = 1;
+	public static final byte OPC_iconst_m1 = 2;
+	public static final byte OPC_iconst_0 = 3;
+	public static final byte OPC_iconst_1 = 4;
+	public static final byte OPC_iconst_2 = 5;
+	public static final byte OPC_iconst_3 = 6;
+	public static final byte OPC_iconst_4 = 7;
+	public static final byte OPC_iconst_5 = 8;
+	public static final byte OPC_lconst_0 = 9;
+	public static final byte OPC_lconst_1 = 10;
+	public static final byte OPC_fconst_0 = 11;
+	public static final byte OPC_fconst_1 = 12;
+	public static final byte OPC_fconst_2 = 13;
+	public static final byte OPC_dconst_0 = 14;
+	public static final byte OPC_dconst_1 = 15;
+	public static final byte OPC_bipush = 16;
+	public static final byte OPC_sipush = 17;
+	public static final byte OPC_ldc = 18;
+	public static final byte OPC_ldc_w = 19;
+	public static final byte OPC_ldc2_w = 20;
+	public static final byte OPC_iload = 21;
+	public static final byte OPC_lload = 22;
+	public static final byte OPC_fload = 23;
+	public static final byte OPC_dload = 24;
+	public static final byte OPC_aload = 25;
+	public static final byte OPC_iload_0 = 26;
+	public static final byte OPC_iload_1 = 27;
+	public static final byte OPC_iload_2 = 28;
+	public static final byte OPC_iload_3 = 29;
+	public static final byte OPC_lload_0 = 30;
+	public static final byte OPC_lload_1 = 31;
+	public static final byte OPC_lload_2 = 32;
+	public static final byte OPC_lload_3 = 33;
+	public static final byte OPC_fload_0 = 34;
+	public static final byte OPC_fload_1 = 35;
+	public static final byte OPC_fload_2 = 36;
+	public static final byte OPC_fload_3 = 37;
+	public static final byte OPC_dload_0 = 38;
+	public static final byte OPC_dload_1 = 39;
+	public static final byte OPC_dload_2 = 40;
+	public static final byte OPC_dload_3 = 41;
+	public static final byte OPC_aload_0 = 42;
+	public static final byte OPC_aload_1 = 43;
+	public static final byte OPC_aload_2 = 44;
+	public static final byte OPC_aload_3 = 45;
+	public static final byte OPC_iaload = 46;
+	public static final byte OPC_laload = 47;
+	public static final byte OPC_faload = 48;
+	public static final byte OPC_daload = 49;
+	public static final byte OPC_aaload = 50;
+	public static final byte OPC_baload = 51;
+	public static final byte OPC_caload = 52;
+	public static final byte OPC_saload = 53;
+	public static final byte OPC_istore = 54;
+	public static final byte OPC_lstore = 55;
+	public static final byte OPC_fstore = 56;
+	public static final byte OPC_dstore = 57;
+	public static final byte OPC_astore = 58;
+	public static final byte OPC_istore_0 = 59;
+	public static final byte OPC_istore_1 = 60;
+	public static final byte OPC_istore_2 = 61;
+	public static final byte OPC_istore_3 = 62;
+	public static final byte OPC_lstore_0 = 63;
+	public static final byte OPC_lstore_1 = 64;
+	public static final byte OPC_lstore_2 = 65;
+	public static final byte OPC_lstore_3 = 66;
+	public static final byte OPC_fstore_0 = 67;
+	public static final byte OPC_fstore_1 = 68;
+	public static final byte OPC_fstore_2 = 69;
+	public static final byte OPC_fstore_3 = 70;
+	public static final byte OPC_dstore_0 = 71;
+	public static final byte OPC_dstore_1 = 72;
+	public static final byte OPC_dstore_2 = 73;
+	public static final byte OPC_dstore_3 = 74;
+	public static final byte OPC_astore_0 = 75;
+	public static final byte OPC_astore_1 = 76;
+	public static final byte OPC_astore_2 = 77;
+	public static final byte OPC_astore_3 = 78;
+	public static final byte OPC_iastore = 79;
+	public static final byte OPC_lastore = 80;
+	public static final byte OPC_fastore = 81;
+	public static final byte OPC_dastore = 82;
+	public static final byte OPC_aastore = 83;
+	public static final byte OPC_bastore = 84;
+	public static final byte OPC_castore = 85;
+	public static final byte OPC_sastore = 86;
+	public static final byte OPC_pop = 87;
+	public static final byte OPC_pop2 = 88;
+	public static final byte OPC_dup = 89;
+	public static final byte OPC_dup_x1 = 90;
+	public static final byte OPC_dup_x2 = 91;
+	public static final byte OPC_dup2 = 92;
+	public static final byte OPC_dup2_x1 = 93;
+	public static final byte OPC_dup2_x2 = 94;
+	public static final byte OPC_swap = 95;
+	public static final byte OPC_iadd = 96;
+	public static final byte OPC_ladd = 97;
+	public static final byte OPC_fadd = 98;
+	public static final byte OPC_dadd = 99;
+	public static final byte OPC_isub = 100;
+	public static final byte OPC_lsub = 101;
+	public static final byte OPC_fsub = 102;
+	public static final byte OPC_dsub = 103;
+	public static final byte OPC_imul = 104;
+	public static final byte OPC_lmul = 105;
+	public static final byte OPC_fmul = 106;
+	public static final byte OPC_dmul = 107;
+	public static final byte OPC_idiv = 108;
+	public static final byte OPC_ldiv = 109;
+	public static final byte OPC_fdiv = 110;
+	public static final byte OPC_ddiv = 111;
+	public static final byte OPC_irem = 112;
+	public static final byte OPC_lrem = 113;
+	public static final byte OPC_frem = 114;
+	public static final byte OPC_drem = 115;
+	public static final byte OPC_ineg = 116;
+	public static final byte OPC_lneg = 117;
+	public static final byte OPC_fneg = 118;
+	public static final byte OPC_dneg = 119;
+	public static final byte OPC_ishl = 120;
+	public static final byte OPC_lshl = 121;
+	public static final byte OPC_ishr = 122;
+	public static final byte OPC_lshr = 123;
+	public static final byte OPC_iushr = 124;
+	public static final byte OPC_lushr = 125;
+	public static final byte OPC_iand = 126;
+	public static final byte OPC_land = 127;
+	public static final byte OPC_ior = (byte) 128;
+	public static final byte OPC_lor = (byte) 129;
+	public static final byte OPC_ixor = (byte) 130;
+	public static final byte OPC_lxor = (byte) 131;
+	public static final byte OPC_iinc = (byte) 132;
+	public static final byte OPC_i2l = (byte) 133;
+	public static final byte OPC_i2f = (byte) 134;
+	public static final byte OPC_i2d = (byte) 135;
+	public static final byte OPC_l2i = (byte) 136;
+	public static final byte OPC_l2f = (byte) 137;
+	public static final byte OPC_l2d = (byte) 138;
+	public static final byte OPC_f2i = (byte) 139;
+	public static final byte OPC_f2l = (byte) 140;
+	public static final byte OPC_f2d = (byte) 141;
+	public static final byte OPC_d2i = (byte) 142;
+	public static final byte OPC_d2l = (byte) 143;
+	public static final byte OPC_d2f = (byte) 144;
+	public static final byte OPC_i2b = (byte) 145;
+	public static final byte OPC_i2c = (byte) 146;
+	public static final byte OPC_i2s = (byte) 147;
+	public static final byte OPC_lcmp = (byte) 148;
+	public static final byte OPC_fcmpl = (byte) 149;
+	public static final byte OPC_fcmpg = (byte) 150;
+	public static final byte OPC_dcmpl = (byte) 151;
+	public static final byte OPC_dcmpg = (byte) 152;
+	public static final byte OPC_ifeq = (byte) 153;
+	public static final byte OPC_ifne = (byte) 154;
+	public static final byte OPC_iflt = (byte) 155;
+	public static final byte OPC_ifge = (byte) 156;
+	public static final byte OPC_ifgt = (byte) 157;
+	public static final byte OPC_ifle = (byte) 158;
+	public static final byte OPC_if_icmpeq = (byte) 159;
+	public static final byte OPC_if_icmpne = (byte) 160;
+	public static final byte OPC_if_icmplt = (byte) 161;
+	public static final byte OPC_if_icmpge = (byte) 162;
+	public static final byte OPC_if_icmpgt = (byte) 163;
+	public static final byte OPC_if_icmple = (byte) 164;
+	public static final byte OPC_if_acmpeq = (byte) 165;
+	public static final byte OPC_if_acmpne = (byte) 166;
+	public static final byte OPC_goto = (byte) 167;
+	public static final byte OPC_jsr = (byte) 168;
+	public static final byte OPC_ret = (byte) 169;
+	public static final byte OPC_tableswitch = (byte) 170;
+	public static final byte OPC_lookupswitch = (byte) 171;
+	public static final byte OPC_ireturn = (byte) 172;
+	public static final byte OPC_lreturn = (byte) 173;
+	public static final byte OPC_freturn = (byte) 174;
+	public static final byte OPC_dreturn = (byte) 175;
+	public static final byte OPC_areturn = (byte) 176;
+	public static final byte OPC_return = (byte) 177;
+	public static final byte OPC_getstatic = (byte) 178;
+	public static final byte OPC_putstatic = (byte) 179;
+	public static final byte OPC_getfield = (byte) 180;
+	public static final byte OPC_putfield = (byte) 181;
+	public static final byte OPC_invokevirtual = (byte) 182;
+	public static final byte OPC_invokespecial = (byte) 183;
+	public static final byte OPC_invokestatic = (byte) 184;
+	public static final byte OPC_invokeinterface = (byte) 185;
+	public static final byte OPC_new = (byte) 187;
+	public static final byte OPC_newarray = (byte) 188;
+	public static final byte OPC_anewarray = (byte) 189;
+	public static final byte OPC_arraylength = (byte) 190;
+	public static final byte OPC_athrow = (byte) 191;
+	public static final byte OPC_checkcast = (byte) 192;
+	public static final byte OPC_instanceof = (byte) 193;
+	public static final byte OPC_monitorenter = (byte) 194;
+	public static final byte OPC_monitorexit = (byte) 195;
+	public static final byte OPC_wide = (byte) 196;
+	public static final byte OPC_multianewarray = (byte) 197;
+	public static final byte OPC_ifnull = (byte) 198;
+	public static final byte OPC_ifnonnull = (byte) 199;
+	public static final byte OPC_goto_w = (byte) 200;
+	public static final byte OPC_jsr_w = (byte) 201;
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java b/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
index edefbdd..097fbfc 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
@@ -1,73 +1,71 @@
-package org.eclipse.jdt.internal.compiler.codegen;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-public interface QualifiedNamesConstants {
-	char[] JavaLangObjectConstantPoolName = "java/lang/Object"/*nonNLS*/.toCharArray();
-	char[] JavaLangStringConstantPoolName = "java/lang/String"/*nonNLS*/.toCharArray();
-	char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer"/*nonNLS*/.toCharArray();
-	char[] JavaLangClassConstantPoolName = "java/lang/Class"/*nonNLS*/.toCharArray();
-	char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable"/*nonNLS*/.toCharArray();
-	char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException"/*nonNLS*/.toCharArray();
-	char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError"/*nonNLS*/.toCharArray();
-	char[] JavaLangIntegerConstantPoolName = "java/lang/Integer"/*nonNLS*/.toCharArray();
-	char[] JavaLangFloatConstantPoolName = "java/lang/Float"/*nonNLS*/.toCharArray();
-	char[] JavaLangDoubleConstantPoolName = "java/lang/Double"/*nonNLS*/.toCharArray();
-	char[] JavaLangLongConstantPoolName = "java/lang/Long"/*nonNLS*/.toCharArray();
-	char[] JavaLangShortConstantPoolName = "java/lang/Short"/*nonNLS*/.toCharArray();
-	char[] JavaLangByteConstantPoolName = "java/lang/Byte"/*nonNLS*/.toCharArray();
-	char[] JavaLangCharacterConstantPoolName = "java/lang/Character"/*nonNLS*/.toCharArray();
-	char[] JavaLangVoidConstantPoolName = "java/lang/Void"/*nonNLS*/.toCharArray();
-	char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean"/*nonNLS*/.toCharArray();
-	char[] JavaLangSystemConstantPoolName = "java/lang/System"/*nonNLS*/.toCharArray();
-	char[] JavaLangErrorConstantPoolName = "java/lang/Error"/*nonNLS*/.toCharArray();
-	char[] JavaLangExceptionConstantPoolName = "java/lang/Exception"/*nonNLS*/.toCharArray();
-	char[] JavaLangReflectConstructor = "java/lang/reflect/Constructor"/*nonNLS*/.toCharArray();  
-	char[] Append = new char[] {'a', 'p', 'p', 'e', 'n', 'd'};
-	char[] ToString = new char[] {'t', 'o', 'S', 't', 'r', 'i', 'n', 'g'};
-	char[] Init = new char[] {'<', 'i', 'n', 'i', 't', '>'};
-	char[] Clinit = new char[] {'<', 'c', 'l', 'i', 'n', 'i', 't', '>'};
-	char[] ValueOf = new char[] {'v', 'a', 'l', 'u', 'e', 'O', 'f'};
-	char[] ForName = new char[] {'f', 'o', 'r', 'N', 'a', 'm', 'e'};
-	char[] GetMessage = new char[] {'g', 'e', 't', 'M', 'e', 's', 's', 'a', 'g', 'e'};
-	char[] NewInstance = "newInstance"/*nonNLS*/.toCharArray();
-	char[] GetConstructor = "getConstructor"/*nonNLS*/.toCharArray();
-	char[] Exit = new char[] {'e', 'x', 'i', 't'};
-	char[] Intern = "intern"/*nonNLS*/.toCharArray();
-	char[] Out = new char[] {'o', 'u', 't'};
-	char[] TYPE = new char[] {'T', 'Y', 'P', 'E'};
-	char[] This = new char[] {'t', 'h', 'i', 's'};
-	char[] JavaLangClassSignature = new char[] {'L', 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'C', 'l', 'a', 's', 's', ';'};
-	char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;"/*nonNLS*/.toCharArray();
-	char[] GetMessageSignature = "()Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"/*nonNLS*/.toCharArray();
-	char[] StringConstructorSignature = "(Ljava/lang/String;)V"/*nonNLS*/.toCharArray();
-	char[] NewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;"/*nonNLS*/.toCharArray();
-	char[] DefaultConstructorSignature = {'(', ')', 'V'};
-	char[] ClinitSignature = DefaultConstructorSignature;
-	char[] ToStringSignature = GetMessageSignature;
-	char[] InternSignature = GetMessageSignature;
-	char[] AppendIntSignature = "(I)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendLongSignature = "(J)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendFloatSignature = "(F)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendDoubleSignature = "(D)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendCharSignature = "(C)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] AppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
-	char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfIntSignature = "(I)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfLongSignature = "(J)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfCharSignature = "(C)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] ValueOfFloatSignature = "(F)Ljava/lang/String;"/*nonNLS*/.toCharArray();
-	char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;"/*nonNLS*/.toCharArray();
-	char[] ExitIntSignature = new char[] {'(', 'I', ')', 'V'};
-	char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;"/*nonNLS*/.toCharArray();
-	char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;"/*nonNLS*/.toCharArray();
-
-}
+package org.eclipse.jdt.internal.compiler.codegen;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public interface QualifiedNamesConstants {
+	char[] JavaLangObjectConstantPoolName = "java/lang/Object"/*nonNLS*/.toCharArray();
+	char[] JavaLangStringConstantPoolName = "java/lang/String"/*nonNLS*/.toCharArray();
+	char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer"/*nonNLS*/.toCharArray();
+	char[] JavaLangClassConstantPoolName = "java/lang/Class"/*nonNLS*/.toCharArray();
+	char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable"/*nonNLS*/.toCharArray();
+	char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException"/*nonNLS*/.toCharArray();
+	char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError"/*nonNLS*/.toCharArray();
+	char[] JavaLangIntegerConstantPoolName = "java/lang/Integer"/*nonNLS*/.toCharArray();
+	char[] JavaLangFloatConstantPoolName = "java/lang/Float"/*nonNLS*/.toCharArray();
+	char[] JavaLangDoubleConstantPoolName = "java/lang/Double"/*nonNLS*/.toCharArray();
+	char[] JavaLangLongConstantPoolName = "java/lang/Long"/*nonNLS*/.toCharArray();
+	char[] JavaLangShortConstantPoolName = "java/lang/Short"/*nonNLS*/.toCharArray();
+	char[] JavaLangByteConstantPoolName = "java/lang/Byte"/*nonNLS*/.toCharArray();
+	char[] JavaLangCharacterConstantPoolName = "java/lang/Character"/*nonNLS*/.toCharArray();
+	char[] JavaLangVoidConstantPoolName = "java/lang/Void"/*nonNLS*/.toCharArray();
+	char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean"/*nonNLS*/.toCharArray();
+	char[] JavaLangSystemConstantPoolName = "java/lang/System"/*nonNLS*/.toCharArray();
+	char[] JavaLangErrorConstantPoolName = "java/lang/Error"/*nonNLS*/.toCharArray();
+	char[] JavaLangExceptionConstantPoolName = "java/lang/Exception"/*nonNLS*/.toCharArray();
+	char[] JavaLangReflectConstructor = "java/lang/reflect/Constructor"/*nonNLS*/.toCharArray();  
+	char[] Append = new char[] {'a', 'p', 'p', 'e', 'n', 'd'};
+	char[] ToString = new char[] {'t', 'o', 'S', 't', 'r', 'i', 'n', 'g'};
+	char[] Init = new char[] {'<', 'i', 'n', 'i', 't', '>'};
+	char[] Clinit = new char[] {'<', 'c', 'l', 'i', 'n', 'i', 't', '>'};
+	char[] ValueOf = new char[] {'v', 'a', 'l', 'u', 'e', 'O', 'f'};
+	char[] ForName = new char[] {'f', 'o', 'r', 'N', 'a', 'm', 'e'};
+	char[] GetMessage = new char[] {'g', 'e', 't', 'M', 'e', 's', 's', 'a', 'g', 'e'};
+	char[] NewInstance = "newInstance"/*nonNLS*/.toCharArray();
+	char[] GetConstructor = "getConstructor"/*nonNLS*/.toCharArray();
+	char[] Exit = new char[] {'e', 'x', 'i', 't'};
+	char[] Intern = "intern"/*nonNLS*/.toCharArray();
+	char[] Out = new char[] {'o', 'u', 't'};
+	char[] TYPE = new char[] {'T', 'Y', 'P', 'E'};
+	char[] This = new char[] {'t', 'h', 'i', 's'};
+	char[] JavaLangClassSignature = new char[] {'L', 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'C', 'l', 'a', 's', 's', ';'};
+	char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;"/*nonNLS*/.toCharArray();
+	char[] GetMessageSignature = "()Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"/*nonNLS*/.toCharArray();
+	char[] StringConstructorSignature = "(Ljava/lang/String;)V"/*nonNLS*/.toCharArray();
+	char[] NewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;"/*nonNLS*/.toCharArray();
+	char[] DefaultConstructorSignature = {'(', ')', 'V'};
+	char[] ClinitSignature = DefaultConstructorSignature;
+	char[] ToStringSignature = GetMessageSignature;
+	char[] InternSignature = GetMessageSignature;
+	char[] AppendIntSignature = "(I)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendLongSignature = "(J)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendFloatSignature = "(F)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendDoubleSignature = "(D)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendCharSignature = "(C)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] AppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;"/*nonNLS*/.toCharArray();
+	char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfIntSignature = "(I)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfLongSignature = "(J)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfCharSignature = "(C)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] ValueOfFloatSignature = "(F)Ljava/lang/String;"/*nonNLS*/.toCharArray();
+	char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;"/*nonNLS*/.toCharArray();
+	char[] ExitIntSignature = new char[] {'(', 'I', ')', 'V'};
+	char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;"/*nonNLS*/.toCharArray();
+	char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;"/*nonNLS*/.toCharArray();
+
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
index e1b24ec..f552454 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
@@ -1,39 +1,37 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-// clinit methods (synthetics too?) can be returned from IBinaryType>>getMethods()
-// BUT do not have to be... the compiler will ignore them when building the binding.
-// The synthetic argument of a member type's constructor (ie. the first arg of a non-static
-// member type) is also ignored by the compiler, BUT in this case it must be included
-// in the constructor's signature.
-
-public interface IBinaryMethod extends IGenericMethod {
-/**
- * Answer the resolved names of the exception types in the
- * class file format as specified in section 4.2 of the Java 2 VM spec
- * or null if the array is empty.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[][] getExceptionTypeNames();
-/**
- * Answer the receiver's method descriptor which describes the parameter &
- * return types as specified in section 4.3.3 of the Java 2 VM spec.
- *
- * For example:
- *   - int foo(String) is (Ljava/lang/String;)I
- *   - Object[] foo(int) is (I)[Ljava/lang/Object;
- */
-
-char[] getMethodDescriptor();
-/**
- * Answer whether the receiver represents a class initializer method.
- */
-
-boolean isClinit();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+// clinit methods (synthetics too?) can be returned from IBinaryType>>getMethods()
+// BUT do not have to be... the compiler will ignore them when building the binding.
+// The synthetic argument of a member type's constructor (ie. the first arg of a non-static
+// member type) is also ignored by the compiler, BUT in this case it must be included
+// in the constructor's signature.
+
+public interface IBinaryMethod extends IGenericMethod {
+/**
+ * Answer the resolved names of the exception types in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[][] getExceptionTypeNames();
+/**
+ * Answer the receiver's method descriptor which describes the parameter &
+ * return types as specified in section 4.3.3 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - int foo(String) is (Ljava/lang/String;)I
+ *   - Object[] foo(int) is (I)[Ljava/lang/Object;
+ */
+
+char[] getMethodDescriptor();
+/**
+ * Answer whether the receiver represents a class initializer method.
+ */
+
+boolean isClinit();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
index 0bc363b..51d6cee 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
@@ -1,33 +1,31 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface IBinaryNestedType {
-/**
- * Answer the resolved name of the enclosing type in the
- * class file format as specified in section 4.2 of the Java 2 VM spec.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[] getEnclosingTypeName();
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- */
-
-// We have added AccDeprecated & AccSynthetic.
-
-int getModifiers();
-/**
- * Answer the resolved name of the member type in the
- * class file format as specified in section 4.2 of the Java 2 VM spec.
- *
- * For example, p1.p2.A.M is p1/p2/A$M.
- */
-
-char[] getName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public interface IBinaryNestedType {
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getEnclosingTypeName();
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+int getModifiers();
+/**
+ * Answer the resolved name of the member type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, p1.p2.A.M is p1/p2/A$M.
+ */
+
+char[] getName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
index 1b201af..95bc80f 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
@@ -1,71 +1,69 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface IBinaryType extends IGenericType {
-
-	char[][] NoInterface = new char[0][];
-	IBinaryNestedType[] NoNestedType = new IBinaryNestedType[0];
-	IBinaryField[] NoField = new IBinaryField[0];
-	IBinaryMethod[] NoMethod = new IBinaryMethod[0];
-/**
- * Answer the resolved name of the enclosing type in the
- * class file format as specified in section 4.2 of the Java 2 VM spec
- * or null if the receiver is a top level type.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[] getEnclosingTypeName();
-/**
- * Answer the receiver's fields or null if the array is empty.
- */
-
-IBinaryField[] getFields();
-/**
- * Answer the resolved names of the receiver's interfaces in the
- * class file format as specified in section 4.2 of the Java 2 VM spec
- * or null if the array is empty.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[][] getInterfaceNames();
-/**
- * Answer the receiver's nested types or null if the array is empty.
- *
- * This nested type info is extracted from the inner class attributes.
- * Ask the name environment to find a member type using its compound name.
- */
-
-// NOTE: The compiler examines the nested type info & ignores the local types
-// so the local types do not have to be included.
-
-IBinaryNestedType[] getMemberTypes();
-/**
- * Answer the receiver's methods or null if the array is empty.
- */
-
-IBinaryMethod[] getMethods();
-/**
- * Answer the resolved name of the type in the
- * class file format as specified in section 4.2 of the Java 2 VM spec.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[] getName();
-/**
- * Answer the resolved name of the receiver's superclass in the
- * class file format as specified in section 4.2 of the Java 2 VM spec
- * or null if it does not have one.
- *
- * For example, java.lang.String is java/lang/String.
- */
-
-char[] getSuperclassName();
-
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public interface IBinaryType extends IGenericType {
+
+	char[][] NoInterface = new char[0][];
+	IBinaryNestedType[] NoNestedType = new IBinaryNestedType[0];
+	IBinaryField[] NoField = new IBinaryField[0];
+	IBinaryMethod[] NoMethod = new IBinaryMethod[0];
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the receiver is a top level type.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getEnclosingTypeName();
+/**
+ * Answer the receiver's fields or null if the array is empty.
+ */
+
+IBinaryField[] getFields();
+/**
+ * Answer the resolved names of the receiver's interfaces in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[][] getInterfaceNames();
+/**
+ * Answer the receiver's nested types or null if the array is empty.
+ *
+ * This nested type info is extracted from the inner class attributes.
+ * Ask the name environment to find a member type using its compound name.
+ */
+
+// NOTE: The compiler examines the nested type info & ignores the local types
+// so the local types do not have to be included.
+
+IBinaryNestedType[] getMemberTypes();
+/**
+ * Answer the receiver's methods or null if the array is empty.
+ */
+
+IBinaryMethod[] getMethods();
+/**
+ * Answer the resolved name of the type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getName();
+/**
+ * Answer the resolved name of the receiver's superclass in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if it does not have one.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getSuperclassName();
+
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java b/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
index 1ce4eec..17b80dd 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
@@ -1,27 +1,25 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-/**
- * This interface denotes a compilation unit, providing its name and content.
- */
-public interface ICompilationUnit extends IDependent {
-/**
- * Answer the contents of the compilation unit.
- *
- * In normal use, the contents are requested twice.
- * Once during the initial lite parsing step, then again for the
- * more detailed parsing step.
- */
-
-char[] getContents();
-/**
- * Answer the name of the top level public type.
- * For example, {Hashtable}.
- */
-
-char[] getMainTypeName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+/**
+ * This interface denotes a compilation unit, providing its name and content.
+ */
+public interface ICompilationUnit extends IDependent {
+/**
+ * Answer the contents of the compilation unit.
+ *
+ * In normal use, the contents are requested twice.
+ * Once during the initial lite parsing step, then again for the
+ * more detailed parsing step.
+ */
+
+char[] getContents();
+/**
+ * Answer the name of the top level public type.
+ * For example, {Hashtable}.
+ */
+
+char[] getMainTypeName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java b/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
index 48efe75..e18bc04 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
@@ -1,39 +1,38 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-/**
- * This interface defines constants for use by the builder / compiler interface.
- */
-public interface IConstants {
-
-	/*
-	 * Modifiers
-	 */
-	int AccPublic = 0x0001;
-	int AccPrivate = 0x0002;
-	int AccProtected = 0x0004;
-	int AccStatic = 0x0008;
-	int AccFinal = 0x0010;
-	int AccSynchronized = 0x0020;
-	int AccVolatile = 0x0040;
-	int AccTransient = 0x0080;
-	int AccNative = 0x0100;
-	int AccInterface = 0x0200;
-	int AccAbstract = 0x0400;
-	int AccStrictfp = 0x0800;
-
-	/*
-	 * Other VM flags.
-	 */
-	int AccSuper = 0x0020;
-
-	/**
-	 * Extra flags for types and members.
-	 */
-	int AccSynthetic = 0x20000;
-	int AccDeprecated = 0x100000;
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * This interface defines constants for use by the builder / compiler interface.
+ */
+public interface IConstants {
+
+	/*
+	 * Modifiers
+	 */
+	int AccPublic = 0x0001;
+	int AccPrivate = 0x0002;
+	int AccProtected = 0x0004;
+	int AccStatic = 0x0008;
+	int AccFinal = 0x0010;
+	int AccSynchronized = 0x0020;
+	int AccVolatile = 0x0040;
+	int AccTransient = 0x0080;
+	int AccNative = 0x0100;
+	int AccInterface = 0x0200;
+	int AccAbstract = 0x0400;
+	int AccStrictfp = 0x0800;
+
+	/*
+	 * Other VM flags.
+	 */
+	int AccSuper = 0x0020;
+
+	/**
+	 * Extra flags for types and members.
+	 */
+	int AccSynthetic = 0x20000;
+	int AccDeprecated = 0x100000;
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java b/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
index 5663ff6..09ac635 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
@@ -1,29 +1,28 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-/**
- * This represents the target (ie. the file) of a type dependency.
- *
- * All implementors of this interface are containers for types or types
- * themselves which must be able to identify their source file name
- * when file dependencies are collected.
- * @see IDependencyInfo
- */
-public interface IDependent {
-/**
- * Answer the file name which defines the type.
- *
- * The path part (optional) must be separated from the actual
- * file proper name by a java.io.File.separator.
- *
- * The proper file name includes the suffix extension (e.g. ".java")
- *
- * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" 
- */
-
-char[] getFileName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * This represents the target (ie. the file) of a type dependency.
+ *
+ * All implementors of this interface are containers for types or types
+ * themselves which must be able to identify their source file name
+ * when file dependencies are collected.
+ * @see IDependencyInfo
+ */
+public interface IDependent {
+/**
+ * Answer the file name which defines the type.
+ *
+ * The path part (optional) must be separated from the actual
+ * file proper name by a java.io.File.separator.
+ *
+ * The proper file name includes the suffix extension (e.g. ".java")
+ *
+ * e.g. "c:/com/ibm/compiler/java/api/Compiler.java" 
+ */
+
+char[] getFileName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
index 7b22b39..5e0ed12 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
@@ -1,22 +1,21 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface IGenericField {
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- */
-
-// We have added AccDeprecated & AccSynthetic.
-
-int getModifiers();
-/**
- * Answer the name of the field.
- */
-
-char[] getName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface IGenericField {
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+int getModifiers();
+/**
+ * Answer the name of the field.
+ */
+
+char[] getName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
index 52b385d..1986585 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
@@ -1,25 +1,23 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface IGenericMethod {
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- */
-
-// We have added AccDeprecated & AccSynthetic.
-
-int getModifiers();
-/**
- * Answer the name of the method.
- *
- * For a constructor, answer <init> & <clinit> for a clinit method.
- */
-
-char[] getSelector();
-boolean isConstructor();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+public interface IGenericMethod {
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+int getModifiers();
+/**
+ * Answer the name of the method.
+ *
+ * For a constructor, answer <init> & <clinit> for a clinit method.
+ */
+
+char[] getSelector();
+boolean isConstructor();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
index 3050ede..5bc687c 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
@@ -1,27 +1,26 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface IGenericType extends IDependent {
-/**
- * Answer an int whose bits are set according the access constants
- * defined by the VM spec.
- */
-
-// We have added AccDeprecated & AccSynthetic.
-
-// NOTE: If the receiver represents a member type, the modifiers are extracted from its inner class attributes.
-
-int getModifiers();
-/**
- * Answer whether the receiver contains the resolved binary form
- * or the unresolved source form of the type.
- */
-
-boolean isBinaryType();
-boolean isClass();
-boolean isInterface();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface IGenericType extends IDependent {
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+// NOTE: If the receiver represents a member type, the modifiers are extracted from its inner class attributes.
+
+int getModifiers();
+/**
+ * Answer whether the receiver contains the resolved binary form
+ * or the unresolved source form of the type.
+ */
+
+boolean isBinaryType();
+boolean isClass();
+boolean isInterface();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java b/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
index a58d100..8499998 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
@@ -1,56 +1,55 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-/**
- * The name environment provides a callback API that the compiler
- * can use to look up types, compilation units, and packages in the
- * current environment.  The name environment is passed to the compiler
- * on creation.
- */
-public interface INameEnvironment {
-/**
- * Find a type with the given compound name.
- * Answer the binary form of the type if it is known to be consistent.
- * Otherwise, answer the compilation unit which defines the type
- * or null if the type does not exist.
- * Types in the default package are specified as {{typeName}}.
- *
- * It is unknown whether the package containing the type actually exists.
- *
- * NOTE: This method can be used to find a member type using its
- * internal name A$B, but the source file for A is answered if the binary
- * file is inconsistent.
- */
-
-NameEnvironmentAnswer findType(char[][] compoundTypeName);
-/**
- * Find a type named <typeName> in the package <packageName>.
- * Answer the binary form of the type if it is known to be consistent.
- * Otherwise, answer the compilation unit which defines the type
- * or null if the type does not exist.
- * The default package is indicated by char[0][].
- *
- * It is known that the package containing the type exists.
- *
- * NOTE: This method can be used to find a member type using its
- * internal name A$B, but the source file for A is answered if the binary
- * file is inconsistent.
- */
-
-NameEnvironmentAnswer findType(char[] typeName, char[][] packageName);
-/**
- * Answer whether packageName is the name of a known subpackage inside
- * the package parentPackageName. A top level package is found relative to null.
- * The default package is always assumed to exist.
- *
- * For example:
- *      isPackage({{java}, {awt}}, {event});
- *      isPackage(null, {java});
- */
-
-boolean isPackage(char[][] parentPackageName, char[] packageName);
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * The name environment provides a callback API that the compiler
+ * can use to look up types, compilation units, and packages in the
+ * current environment.  The name environment is passed to the compiler
+ * on creation.
+ */
+public interface INameEnvironment {
+/**
+ * Find a type with the given compound name.
+ * Answer the binary form of the type if it is known to be consistent.
+ * Otherwise, answer the compilation unit which defines the type
+ * or null if the type does not exist.
+ * Types in the default package are specified as {{typeName}}.
+ *
+ * It is unknown whether the package containing the type actually exists.
+ *
+ * NOTE: This method can be used to find a member type using its
+ * internal name A$B, but the source file for A is answered if the binary
+ * file is inconsistent.
+ */
+
+NameEnvironmentAnswer findType(char[][] compoundTypeName);
+/**
+ * Find a type named <typeName> in the package <packageName>.
+ * Answer the binary form of the type if it is known to be consistent.
+ * Otherwise, answer the compilation unit which defines the type
+ * or null if the type does not exist.
+ * The default package is indicated by char[0][].
+ *
+ * It is known that the package containing the type exists.
+ *
+ * NOTE: This method can be used to find a member type using its
+ * internal name A$B, but the source file for A is answered if the binary
+ * file is inconsistent.
+ */
+
+NameEnvironmentAnswer findType(char[] typeName, char[][] packageName);
+/**
+ * Answer whether packageName is the name of a known subpackage inside
+ * the package parentPackageName. A top level package is found relative to null.
+ * The default package is always assumed to exist.
+ *
+ * For example:
+ *      isPackage({{java}, {awt}}, {event});
+ *      isPackage(null, {java});
+ */
+
+boolean isPackage(char[][] parentPackageName, char[] packageName);
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
index 5dfd047..283689d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
@@ -1,37 +1,36 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface ISourceField extends IGenericField {
-/**
- * Answer the source end position of the field's declaration.
- */
-
-int getDeclarationSourceEnd();
-/**
- * Answer the source start position of the field's declaration.
- */
-
-int getDeclarationSourceStart();
-/**
- * Answer the source end position of the field's name.
- */
-
-int getNameSourceEnd();
-/**
- * Answer the source start position of the field's name.
- */
-
-int getNameSourceStart();
-/**
- * Answer the type name of the field.
- *
- * The name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[] getTypeName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface ISourceField extends IGenericField {
+/**
+ * Answer the source end position of the field's declaration.
+ */
+
+int getDeclarationSourceEnd();
+/**
+ * Answer the source start position of the field's declaration.
+ */
+
+int getDeclarationSourceStart();
+/**
+ * Answer the source end position of the field's name.
+ */
+
+int getNameSourceEnd();
+/**
+ * Answer the source start position of the field's name.
+ */
+
+int getNameSourceStart();
+/**
+ * Answer the type name of the field.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[] getTypeName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
index a83406e..d7ffcab 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
@@ -1,62 +1,61 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface ISourceMethod extends IGenericMethod {
-/**
- * Answer the names of the argument
- * or null if the array is empty.
- */
-
-char[][] getArgumentNames();
-/**
- * Answer the unresolved names of the argument types
- * or null if the array is empty.
- *
- * A name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[][] getArgumentTypeNames();
-/**
- * Answer the source end position of the method's declaration.
- */
-
-int getDeclarationSourceEnd();
-/**
- * Answer the source start position of the method's declaration.
- */
-
-int getDeclarationSourceStart();
-/**
- * Answer the unresolved names of the exception types
- * or null if the array is empty.
- *
- * A name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[][] getExceptionTypeNames();
-/**
- * Answer the source end position of the method's selector.
- */
-
-int getNameSourceEnd();
-/**
- * Answer the source start position of the method's selector.
- */
-
-int getNameSourceStart();
-/**
- * Answer the unresolved name of the return type
- * or null if receiver is a constructor or clinit.
- *
- * The name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[] getReturnTypeName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface ISourceMethod extends IGenericMethod {
+/**
+ * Answer the names of the argument
+ * or null if the array is empty.
+ */
+
+char[][] getArgumentNames();
+/**
+ * Answer the unresolved names of the argument types
+ * or null if the array is empty.
+ *
+ * A name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[][] getArgumentTypeNames();
+/**
+ * Answer the source end position of the method's declaration.
+ */
+
+int getDeclarationSourceEnd();
+/**
+ * Answer the source start position of the method's declaration.
+ */
+
+int getDeclarationSourceStart();
+/**
+ * Answer the unresolved names of the exception types
+ * or null if the array is empty.
+ *
+ * A name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[][] getExceptionTypeNames();
+/**
+ * Answer the source end position of the method's selector.
+ */
+
+int getNameSourceEnd();
+/**
+ * Answer the source start position of the method's selector.
+ */
+
+int getNameSourceStart();
+/**
+ * Answer the unresolved name of the return type
+ * or null if receiver is a constructor or clinit.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[] getReturnTypeName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
index 3e2790d..4e71c21 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
@@ -1,103 +1,102 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public interface ISourceType extends IGenericType {
-/**
- * Answer the source end position of the type's declaration.
- */
-
-int getDeclarationSourceEnd();
-/**
- * Answer the source start position of the type's declaration.
- */
-
-int getDeclarationSourceStart();
-/**
- * Answer the enclosing type
- * or null if the receiver is a top level type.
- */
-
-ISourceType getEnclosingType();
-/**
- * Answer the receiver's fields or null if the array is empty.
- *
- * NOTE: Multiple fields with the same name can exist in the result.
- */
-
-ISourceField[] getFields();
-/**
- * Answer the unresolved names of the receiver's imports
- * or null if the array is empty.
- *
- * An import is a qualified, dot separated name.
- * For example, java.util.Hashtable or java.lang.*.
- */
-
-char[][] getImports();
-/**
- * Answer the unresolved names of the receiver's interfaces
- * or null if the array is empty.
- *
- * A name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[][] getInterfaceNames();
-/**
- * Answer the receiver's member types
- * or null if the array is empty.
- */
-
-ISourceType[] getMemberTypes();
-/**
- * Answer the receiver's methods or null if the array is empty.
- *
- * NOTE: Multiple methods with the same name & parameter types can exist in the result.
- */
-
-ISourceMethod[] getMethods();
-/**
- * Answer the simple source name of the receiver.
- */
-
-char[] getName();
-/**
- * Answer the source end position of the type's name.
- */
-
-int getNameSourceEnd();
-/**
- * Answer the source start position of the type's name.
- */
-
-int getNameSourceStart();
-/**
- * Answer the qualified name of the receiver's package separated by periods
- * or null if its the default package.
- *
- * For example, {java.util.Hashtable}.
- */
-
-char[] getPackageName();
-/**
- * Answer the qualified name of the receiver.
- *
- * The name is a qualified, dot separated name.
- * For example, java.util.Hashtable.
- */
-
-char[] getQualifiedName();
-/**
- * Answer the unresolved name of the receiver's superclass
- * or null if it does not have one.
- *
- * The name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[] getSuperclassName();
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public interface ISourceType extends IGenericType {
+/**
+ * Answer the source end position of the type's declaration.
+ */
+
+int getDeclarationSourceEnd();
+/**
+ * Answer the source start position of the type's declaration.
+ */
+
+int getDeclarationSourceStart();
+/**
+ * Answer the enclosing type
+ * or null if the receiver is a top level type.
+ */
+
+ISourceType getEnclosingType();
+/**
+ * Answer the receiver's fields or null if the array is empty.
+ *
+ * NOTE: Multiple fields with the same name can exist in the result.
+ */
+
+ISourceField[] getFields();
+/**
+ * Answer the unresolved names of the receiver's imports
+ * or null if the array is empty.
+ *
+ * An import is a qualified, dot separated name.
+ * For example, java.util.Hashtable or java.lang.*.
+ */
+
+char[][] getImports();
+/**
+ * Answer the unresolved names of the receiver's interfaces
+ * or null if the array is empty.
+ *
+ * A name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[][] getInterfaceNames();
+/**
+ * Answer the receiver's member types
+ * or null if the array is empty.
+ */
+
+ISourceType[] getMemberTypes();
+/**
+ * Answer the receiver's methods or null if the array is empty.
+ *
+ * NOTE: Multiple methods with the same name & parameter types can exist in the result.
+ */
+
+ISourceMethod[] getMethods();
+/**
+ * Answer the simple source name of the receiver.
+ */
+
+char[] getName();
+/**
+ * Answer the source end position of the type's name.
+ */
+
+int getNameSourceEnd();
+/**
+ * Answer the source start position of the type's name.
+ */
+
+int getNameSourceStart();
+/**
+ * Answer the qualified name of the receiver's package separated by periods
+ * or null if its the default package.
+ *
+ * For example, {java.util.Hashtable}.
+ */
+
+char[] getPackageName();
+/**
+ * Answer the qualified name of the receiver.
+ *
+ * The name is a qualified, dot separated name.
+ * For example, java.util.Hashtable.
+ */
+
+char[] getQualifiedName();
+/**
+ * Answer the unresolved name of the receiver's superclass
+ * or null if it does not have one.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[] getSuperclassName();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java b/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
index ecfee24..4c11d8b 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
@@ -1,67 +1,66 @@
-package org.eclipse.jdt.internal.compiler.env;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-
-public class NameEnvironmentAnswer {
-	// only one of the three can be set
-	IBinaryType binaryType;
-	ICompilationUnit compilationUnit;
-	ISourceType sourceType;
-public NameEnvironmentAnswer(IBinaryType binaryType) {
-	this.binaryType = binaryType;
-}
-public NameEnvironmentAnswer(ICompilationUnit compilationUnit) {
-	this.compilationUnit = compilationUnit;
-}
-public NameEnvironmentAnswer(ISourceType sourceType) {
-	this.sourceType = sourceType;
-}
-/**
- * Answer the resolved binary form for the type or null if the
- * receiver represents a compilation unit or source type.
- */
-
-public IBinaryType getBinaryType() {
-	return binaryType;
-}
-/**
- * Answer the compilation unit or null if the
- * receiver represents a binary or source type.
- */
-
-public ICompilationUnit getCompilationUnit() {
-	return compilationUnit;
-}
-/**
- * Answer the unresolved source form for the type or null if the
- * receiver represents a compilation unit or binary type.
- */
-
-public ISourceType getSourceType() {
-	return sourceType;
-}
-/**
- * Answer whether the receiver contains the resolved binary form of the type.
- */
-
-public boolean isBinaryType() {
-	return binaryType != null;
-}
-/**
- * Answer whether the receiver contains the compilation unit which defines the type.
- */
-
-public boolean isCompilationUnit() {
-	return compilationUnit != null;
-}
-/**
- * Answer whether the receiver contains the unresolved source form of the type.
- */
-
-public  boolean isSourceType() {
-	return sourceType != null;
-}
-}
+package org.eclipse.jdt.internal.compiler.env;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+public class NameEnvironmentAnswer {
+	// only one of the three can be set
+	IBinaryType binaryType;
+	ICompilationUnit compilationUnit;
+	ISourceType sourceType;
+public NameEnvironmentAnswer(IBinaryType binaryType) {
+	this.binaryType = binaryType;
+}
+public NameEnvironmentAnswer(ICompilationUnit compilationUnit) {
+	this.compilationUnit = compilationUnit;
+}
+public NameEnvironmentAnswer(ISourceType sourceType) {
+	this.sourceType = sourceType;
+}
+/**
+ * Answer the resolved binary form for the type or null if the
+ * receiver represents a compilation unit or source type.
+ */
+
+public IBinaryType getBinaryType() {
+	return binaryType;
+}
+/**
+ * Answer the compilation unit or null if the
+ * receiver represents a binary or source type.
+ */
+
+public ICompilationUnit getCompilationUnit() {
+	return compilationUnit;
+}
+/**
+ * Answer the unresolved source form for the type or null if the
+ * receiver represents a compilation unit or binary type.
+ */
+
+public ISourceType getSourceType() {
+	return sourceType;
+}
+/**
+ * Answer whether the receiver contains the resolved binary form of the type.
+ */
+
+public boolean isBinaryType() {
+	return binaryType != null;
+}
+/**
+ * Answer whether the receiver contains the compilation unit which defines the type.
+ */
+
+public boolean isCompilationUnit() {
+	return compilationUnit != null;
+}
+/**
+ * Answer whether the receiver contains the unresolved source form of the type.
+ */
+
+public  boolean isSourceType() {
+	return sourceType != null;
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index 307d43a..ef19627 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -1,123 +1,121 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-/**
- * Record conditional initialization status during definite assignment analysis
- *
- */
-public class ConditionalFlowInfo extends FlowInfo {
-	public FlowInfo initsWhenTrue;
-	public FlowInfo initsWhenFalse;
-ConditionalFlowInfo(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
-	this.initsWhenTrue = initsWhenTrue;
-	this.initsWhenFalse = initsWhenFalse; 
-}
-public UnconditionalFlowInfo addInitializationsFrom(UnconditionalFlowInfo otherInits) {
-	return unconditionalInits().addInitializationsFrom(otherInits);
-}
-public UnconditionalFlowInfo addPotentialInitializationsFrom(UnconditionalFlowInfo otherInits) {
-	return unconditionalInits().addPotentialInitializationsFrom(otherInits);
-}
-public FlowInfo asNegatedCondition() {
-	FlowInfo extra = initsWhenTrue;
-	initsWhenTrue = initsWhenFalse;
-	initsWhenFalse = extra;
-	return this;
-}
-public FlowInfo copy() {
-	return new ConditionalFlowInfo(initsWhenTrue.copy(), initsWhenFalse.copy());
-}
-public FlowInfo initsWhenFalse() {
-	return initsWhenFalse;
-}
-public FlowInfo initsWhenTrue() {
-	return initsWhenTrue;
-}
-/**
- * Check status of definite assignment for a field.
- */
-public boolean isDefinitelyAssigned(FieldBinding field) {
-	return initsWhenTrue.isDefinitelyAssigned(field) 
-			&& initsWhenFalse.isDefinitelyAssigned(field);
-	
-}
-/**
- * Check status of definite assignment for a local variable.
- */
-public boolean isDefinitelyAssigned(LocalVariableBinding local) {
-	return initsWhenTrue.isDefinitelyAssigned(local) 
-			&& initsWhenFalse.isDefinitelyAssigned(local);
-	
-}
-public boolean isFakeReachable(){
-	return unconditionalInits().isFakeReachable();	
-	//should maybe directly be: false
-}
-/**
- * Check status of potential assignment for a field.
- */
-public boolean isPotentiallyAssigned(FieldBinding field) {
-	return initsWhenTrue.isPotentiallyAssigned(field) 
-			|| initsWhenFalse.isPotentiallyAssigned(field);
-	
-}
-/**
- * Check status of potential assignment for a local variable.
- */
-public boolean isPotentiallyAssigned(LocalVariableBinding local) {
-	return initsWhenTrue.isPotentiallyAssigned(local) 
-			|| initsWhenFalse.isPotentiallyAssigned(local);
-	
-}
-/**
- * Record a field got definitely assigned.
- */
-public void markAsDefinitelyAssigned(FieldBinding field) {
-	initsWhenTrue.markAsDefinitelyAssigned(field);
-	initsWhenFalse.markAsDefinitelyAssigned(field);	
-}
-/**
- * Record a field got definitely assigned.
- */
-public void markAsDefinitelyAssigned(LocalVariableBinding local) {
-	initsWhenTrue.markAsDefinitelyAssigned(local);
-	initsWhenFalse.markAsDefinitelyAssigned(local);	
-}
-/**
- * Clear the initialization info for a field
- */
-public void markAsDefinitelyNotAssigned(FieldBinding field) {
-	initsWhenTrue.markAsDefinitelyNotAssigned(field);
-	initsWhenFalse.markAsDefinitelyNotAssigned(field);	
-}
-/**
- * Clear the initialization info for a local variable
- */
-public void markAsDefinitelyNotAssigned(LocalVariableBinding local) {
-	initsWhenTrue.markAsDefinitelyNotAssigned(local);
-	initsWhenFalse.markAsDefinitelyNotAssigned(local);	
-}
-public FlowInfo markAsFakeReachable(boolean isFakeReachable) {
-	initsWhenTrue.markAsFakeReachable(isFakeReachable);
-	initsWhenFalse.markAsFakeReachable(isFakeReachable);
-	return this;
-}
-public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
-	return unconditionalInits().mergedWith(otherInits);
-}
-public String toString() {
-	return "FlowInfo<true: "/*nonNLS*/ + initsWhenTrue.toString() + ", false: "/*nonNLS*/ + initsWhenFalse.toString() + ">"/*nonNLS*/;
-}
-public UnconditionalFlowInfo unconditionalInits() {
-	return initsWhenTrue.unconditionalInits().copy()
-			.mergedWith(initsWhenFalse.unconditionalInits());
-}
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+/**
+ * Record conditional initialization status during definite assignment analysis
+ *
+ */
+public class ConditionalFlowInfo extends FlowInfo {
+	public FlowInfo initsWhenTrue;
+	public FlowInfo initsWhenFalse;
+ConditionalFlowInfo(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
+	this.initsWhenTrue = initsWhenTrue;
+	this.initsWhenFalse = initsWhenFalse; 
+}
+public UnconditionalFlowInfo addInitializationsFrom(UnconditionalFlowInfo otherInits) {
+	return unconditionalInits().addInitializationsFrom(otherInits);
+}
+public UnconditionalFlowInfo addPotentialInitializationsFrom(UnconditionalFlowInfo otherInits) {
+	return unconditionalInits().addPotentialInitializationsFrom(otherInits);
+}
+public FlowInfo asNegatedCondition() {
+	FlowInfo extra = initsWhenTrue;
+	initsWhenTrue = initsWhenFalse;
+	initsWhenFalse = extra;
+	return this;
+}
+public FlowInfo copy() {
+	return new ConditionalFlowInfo(initsWhenTrue.copy(), initsWhenFalse.copy());
+}
+public FlowInfo initsWhenFalse() {
+	return initsWhenFalse;
+}
+public FlowInfo initsWhenTrue() {
+	return initsWhenTrue;
+}
+/**
+ * Check status of definite assignment for a field.
+ */
+public boolean isDefinitelyAssigned(FieldBinding field) {
+	return initsWhenTrue.isDefinitelyAssigned(field) 
+			&& initsWhenFalse.isDefinitelyAssigned(field);
+	
+}
+/**
+ * Check status of definite assignment for a local variable.
+ */
+public boolean isDefinitelyAssigned(LocalVariableBinding local) {
+	return initsWhenTrue.isDefinitelyAssigned(local) 
+			&& initsWhenFalse.isDefinitelyAssigned(local);
+	
+}
+public boolean isFakeReachable(){
+	return unconditionalInits().isFakeReachable();	
+	//should maybe directly be: false
+}
+/**
+ * Check status of potential assignment for a field.
+ */
+public boolean isPotentiallyAssigned(FieldBinding field) {
+	return initsWhenTrue.isPotentiallyAssigned(field) 
+			|| initsWhenFalse.isPotentiallyAssigned(field);
+	
+}
+/**
+ * Check status of potential assignment for a local variable.
+ */
+public boolean isPotentiallyAssigned(LocalVariableBinding local) {
+	return initsWhenTrue.isPotentiallyAssigned(local) 
+			|| initsWhenFalse.isPotentiallyAssigned(local);
+	
+}
+/**
+ * Record a field got definitely assigned.
+ */
+public void markAsDefinitelyAssigned(FieldBinding field) {
+	initsWhenTrue.markAsDefinitelyAssigned(field);
+	initsWhenFalse.markAsDefinitelyAssigned(field);	
+}
+/**
+ * Record a field got definitely assigned.
+ */
+public void markAsDefinitelyAssigned(LocalVariableBinding local) {
+	initsWhenTrue.markAsDefinitelyAssigned(local);
+	initsWhenFalse.markAsDefinitelyAssigned(local);	
+}
+/**
+ * Clear the initialization info for a field
+ */
+public void markAsDefinitelyNotAssigned(FieldBinding field) {
+	initsWhenTrue.markAsDefinitelyNotAssigned(field);
+	initsWhenFalse.markAsDefinitelyNotAssigned(field);	
+}
+/**
+ * Clear the initialization info for a local variable
+ */
+public void markAsDefinitelyNotAssigned(LocalVariableBinding local) {
+	initsWhenTrue.markAsDefinitelyNotAssigned(local);
+	initsWhenFalse.markAsDefinitelyNotAssigned(local);	
+}
+public FlowInfo markAsFakeReachable(boolean isFakeReachable) {
+	initsWhenTrue.markAsFakeReachable(isFakeReachable);
+	initsWhenFalse.markAsFakeReachable(isFakeReachable);
+	return this;
+}
+public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
+	return unconditionalInits().mergedWith(otherInits);
+}
+public String toString() {
+	return "FlowInfo<true: "/*nonNLS*/ + initsWhenTrue.toString() + ", false: "/*nonNLS*/ + initsWhenFalse.toString() + ">"/*nonNLS*/;
+}
+public UnconditionalFlowInfo unconditionalInits() {
+	return initsWhenTrue.unconditionalInits().copy()
+			.mergedWith(initsWhenFalse.unconditionalInits());
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index 426698c..e39c62a 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -1,136 +1,134 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-
-/**
- * Reflects the context of code analysis, keeping track of enclosing
- *	try statements, exception handlers, etc...
- */
-public class ExceptionHandlingFlowContext extends FlowContext {
-	ReferenceBinding[] handledExceptions;
-
-	public final static int BitCacheSize = 32; // 32 bits per int
-	int[] isReached;
-	int[] isNeeded;
-	UnconditionalFlowInfo[] initsOnExceptions;
-	ObjectCache indexes = new ObjectCache();
-	boolean isMethodContext;
-public ExceptionHandlingFlowContext(
-	FlowContext parent, 
-	AstNode associatedNode, 
-	ReferenceBinding[] handledExceptions, 
-	BlockScope scope, 
-	UnconditionalFlowInfo flowInfo) {
-
-	super(parent, associatedNode);
-	isMethodContext = scope == scope.methodScope();
-/*	
-	// for a method, append the unchecked exceptions to the handled exceptions collection
-
-	if (scope.methodScope() == scope) {
-		int length;
-		System.arraycopy(
-			handledExceptions, 
-			0, 
-			(handledExceptions = 
-				new ReferenceBinding[(length = handledExceptions.length) + 2]), 
-			0, 
-			length); 
-		handledExceptions[length] = scope.getJavaLangRuntimeException();
-		handledExceptions[length + 1] = scope.getJavaLangError();
-	}
-*/	
-	this.handledExceptions = handledExceptions;
-	int count = handledExceptions.length, cacheSize = (count / BitCacheSize) + 1;
-	isReached = new int[cacheSize]; // none is reached by default
-	isNeeded = new int[cacheSize]; // none is needed by default
-	initsOnExceptions = new UnconditionalFlowInfo[count];
-	for (int i = 0; i < count; i++) {
-		indexes.put(handledExceptions[i], i); // key type  -> value index
-		boolean isUnchecked = 
-			(scope.compareUncheckedException(handledExceptions[i]) != NotRelated); 
-		int cacheIndex = i / BitCacheSize, bitMask = 1 << (i % BitCacheSize);
-		if (isUnchecked) {
-			isReached[cacheIndex] |= bitMask;
-			initsOnExceptions[i] = flowInfo.copy().unconditionalInits();
-		} else {
-			initsOnExceptions[i] = FlowInfo.DeadEnd;
-		}
-	}
-	System.arraycopy(isReached, 0, isNeeded, 0, cacheSize);
-}
-public void complainIfUnusedExceptionHandlers(AstNode[] exceptionHandlers, BlockScope scope, TryStatement tryStatement) {
-
-	// report errors for unreachable exception handlers
-
-	for (int i = 0, count = handledExceptions.length; i < count; i++) {
-		int index = indexes.get(handledExceptions[i]);
-		int cacheIndex = index / BitCacheSize;
-		int bitMask	= 1 << (index % BitCacheSize);
-		if ((isReached[cacheIndex] & bitMask) == 0) {
-			scope.problemReporter().unreachableExceptionHandler(
-				handledExceptions[index], 
-				exceptionHandlers[index]); 
-		} else {
-			if ((isNeeded[cacheIndex] & bitMask) == 0) {
-				scope.problemReporter().maskedExceptionHandler(
-					handledExceptions[index], 
-					exceptionHandlers[index]); 
-			}
-		}
-	}
-	// will optimized out unnecessary catch block during code gen
-	tryStatement.preserveExceptionHandler = isNeeded;
-}
-public String individualToString() {
-	StringBuffer buffer = new StringBuffer("Exception flow context"/*nonNLS*/);
-	int length = handledExceptions.length;
-	for (int i = 0; i < length; i++) {
-		int cacheIndex = i / BitCacheSize;
-		int bitMask = 1 << (i % BitCacheSize);		
-		buffer.append('[').append(handledExceptions[i].readableName());
-		if ((isReached[cacheIndex] & bitMask) != 0) {
-			if ((isNeeded[cacheIndex] & bitMask) == 0) {
-				buffer.append("-masked"/*nonNLS*/);
-			} else {
-				buffer.append("-reached"/*nonNLS*/);
-			}
-		} else {
-			buffer.append("-not reached"/*nonNLS*/);
-		}
-		buffer.append('-').append(initsOnExceptions[i].toString()).append(']');
-	}
-	return buffer.toString();
-}
-public UnconditionalFlowInfo initsOnException(ReferenceBinding exceptionType) {
-
-	int index;
-	if ((index = indexes.get(exceptionType)) < 0) {
-		return FlowInfo.DeadEnd;
-	}
-	return initsOnExceptions[index];
-}
-public void recordHandlingException(ReferenceBinding exceptionType, UnconditionalFlowInfo flowInfo, TypeBinding raisedException, AstNode invocationSite, boolean wasAlreadyDefinitelyCaught) {
-		
-	int index = indexes.get(exceptionType);
-	// if already flagged as being reached (unchecked exception handler)
-	int cacheIndex = index / BitCacheSize;
-	int bitMask = 1 << (index % BitCacheSize);
-	if (!wasAlreadyDefinitelyCaught) {
-		this.isNeeded[cacheIndex] |= bitMask;
-	}
-	this.isReached[cacheIndex] |= bitMask;
-	initsOnExceptions[index] = 
-		initsOnExceptions[index] == FlowInfo.DeadEnd
-			? flowInfo.copy().unconditionalInits()
-			: initsOnExceptions[index].mergedWith(flowInfo); 
-}
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class ExceptionHandlingFlowContext extends FlowContext {
+	ReferenceBinding[] handledExceptions;
+
+	public final static int BitCacheSize = 32; // 32 bits per int
+	int[] isReached;
+	int[] isNeeded;
+	UnconditionalFlowInfo[] initsOnExceptions;
+	ObjectCache indexes = new ObjectCache();
+	boolean isMethodContext;
+public ExceptionHandlingFlowContext(
+	FlowContext parent, 
+	AstNode associatedNode, 
+	ReferenceBinding[] handledExceptions, 
+	BlockScope scope, 
+	UnconditionalFlowInfo flowInfo) {
+
+	super(parent, associatedNode);
+	isMethodContext = scope == scope.methodScope();
+/*	
+	// for a method, append the unchecked exceptions to the handled exceptions collection
+
+	if (scope.methodScope() == scope) {
+		int length;
+		System.arraycopy(
+			handledExceptions, 
+			0, 
+			(handledExceptions = 
+				new ReferenceBinding[(length = handledExceptions.length) + 2]), 
+			0, 
+			length); 
+		handledExceptions[length] = scope.getJavaLangRuntimeException();
+		handledExceptions[length + 1] = scope.getJavaLangError();
+	}
+*/	
+	this.handledExceptions = handledExceptions;
+	int count = handledExceptions.length, cacheSize = (count / BitCacheSize) + 1;
+	isReached = new int[cacheSize]; // none is reached by default
+	isNeeded = new int[cacheSize]; // none is needed by default
+	initsOnExceptions = new UnconditionalFlowInfo[count];
+	for (int i = 0; i < count; i++) {
+		indexes.put(handledExceptions[i], i); // key type  -> value index
+		boolean isUnchecked = 
+			(scope.compareUncheckedException(handledExceptions[i]) != NotRelated); 
+		int cacheIndex = i / BitCacheSize, bitMask = 1 << (i % BitCacheSize);
+		if (isUnchecked) {
+			isReached[cacheIndex] |= bitMask;
+			initsOnExceptions[i] = flowInfo.copy().unconditionalInits();
+		} else {
+			initsOnExceptions[i] = FlowInfo.DeadEnd;
+		}
+	}
+	System.arraycopy(isReached, 0, isNeeded, 0, cacheSize);
+}
+public void complainIfUnusedExceptionHandlers(AstNode[] exceptionHandlers, BlockScope scope, TryStatement tryStatement) {
+
+	// report errors for unreachable exception handlers
+
+	for (int i = 0, count = handledExceptions.length; i < count; i++) {
+		int index = indexes.get(handledExceptions[i]);
+		int cacheIndex = index / BitCacheSize;
+		int bitMask	= 1 << (index % BitCacheSize);
+		if ((isReached[cacheIndex] & bitMask) == 0) {
+			scope.problemReporter().unreachableExceptionHandler(
+				handledExceptions[index], 
+				exceptionHandlers[index]); 
+		} else {
+			if ((isNeeded[cacheIndex] & bitMask) == 0) {
+				scope.problemReporter().maskedExceptionHandler(
+					handledExceptions[index], 
+					exceptionHandlers[index]); 
+			}
+		}
+	}
+	// will optimized out unnecessary catch block during code gen
+	tryStatement.preserveExceptionHandler = isNeeded;
+}
+public String individualToString() {
+	StringBuffer buffer = new StringBuffer("Exception flow context"/*nonNLS*/);
+	int length = handledExceptions.length;
+	for (int i = 0; i < length; i++) {
+		int cacheIndex = i / BitCacheSize;
+		int bitMask = 1 << (i % BitCacheSize);		
+		buffer.append('[').append(handledExceptions[i].readableName());
+		if ((isReached[cacheIndex] & bitMask) != 0) {
+			if ((isNeeded[cacheIndex] & bitMask) == 0) {
+				buffer.append("-masked"/*nonNLS*/);
+			} else {
+				buffer.append("-reached"/*nonNLS*/);
+			}
+		} else {
+			buffer.append("-not reached"/*nonNLS*/);
+		}
+		buffer.append('-').append(initsOnExceptions[i].toString()).append(']');
+	}
+	return buffer.toString();
+}
+public UnconditionalFlowInfo initsOnException(ReferenceBinding exceptionType) {
+
+	int index;
+	if ((index = indexes.get(exceptionType)) < 0) {
+		return FlowInfo.DeadEnd;
+	}
+	return initsOnExceptions[index];
+}
+public void recordHandlingException(ReferenceBinding exceptionType, UnconditionalFlowInfo flowInfo, TypeBinding raisedException, AstNode invocationSite, boolean wasAlreadyDefinitelyCaught) {
+		
+	int index = indexes.get(exceptionType);
+	// if already flagged as being reached (unchecked exception handler)
+	int cacheIndex = index / BitCacheSize;
+	int bitMask = 1 << (index % BitCacheSize);
+	if (!wasAlreadyDefinitelyCaught) {
+		this.isNeeded[cacheIndex] |= bitMask;
+	}
+	this.isReached[cacheIndex] |= bitMask;
+	initsOnExceptions[index] = 
+		initsOnExceptions[index] == FlowInfo.DeadEnd
+			? flowInfo.copy().unconditionalInits()
+			: initsOnExceptions[index].mergedWith(flowInfo); 
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
index a082af7..ce00676 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -1,66 +1,64 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-
-/**
- * Reflects the context of code analysis, keeping track of enclosing
- *	try statements, exception handlers, etc...
- */
-public class FinallyFlowContext extends FlowContext {
-	Reference finalAssignments[];
-	int assignCount;
-public FinallyFlowContext(FlowContext parent, AstNode associatedNode) {
-	super(parent, associatedNode);
-}
-/**
- * Given some contextual initialization info (derived from a try block or a catch block), this 
- * code will check that the subroutine context does not also initialize a final variable potentially set
- * redundantly.
- */
-
-public void complainOnRedundantFinalAssignments(FlowInfo flowInfo, BlockScope scope) {
-	for (int i = 0; i < assignCount; i++) {
-		Reference ref;
-		if (((ref = finalAssignments[i]).bits & BindingIds.FIELD) != 0) {
-			// final field
-			if (flowInfo.isPotentiallyAssigned(ref.fieldBinding())) {
-				scope.problemReporter().duplicateInitializationOfBlankFinalField(ref.fieldBinding(), ref);
-			}
-		} else {
-			// final local variable
-			if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)((NameReference)ref).binding)) {
-				scope.problemReporter().duplicateInitializationOfFinalLocal((LocalVariableBinding)((NameReference)ref).binding,(NameReference)ref);
-			}
-		}
-		// any reference reported at this level is removed from the parent context 
-		// where it could also be reported again
-		FlowContext currentContext = parent;
-		while (currentContext != null) {
-			if (currentContext.isSubRoutine()) {
-				currentContext.removeFinalAssignmentIfAny(ref);
-			}
-			currentContext = currentContext.parent;
-		}
-	}
-}
-public boolean isSubRoutine() {
-	return true;
-}
-boolean recordFinalAssignment(VariableBinding binding, Reference finalAssignment) {
-	if (assignCount == 0) {
-		finalAssignments = new Reference[5];
-	} else {
-		if (assignCount == finalAssignments.length)
-			System.arraycopy(finalAssignments, 0, (finalAssignments = new Reference[assignCount * 2]), 0, assignCount);
-	};
-	finalAssignments[assignCount++] = finalAssignment;
-	return true;
-}
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class FinallyFlowContext extends FlowContext {
+	Reference finalAssignments[];
+	int assignCount;
+public FinallyFlowContext(FlowContext parent, AstNode associatedNode) {
+	super(parent, associatedNode);
+}
+/**
+ * Given some contextual initialization info (derived from a try block or a catch block), this 
+ * code will check that the subroutine context does not also initialize a final variable potentially set
+ * redundantly.
+ */
+
+public void complainOnRedundantFinalAssignments(FlowInfo flowInfo, BlockScope scope) {
+	for (int i = 0; i < assignCount; i++) {
+		Reference ref;
+		if (((ref = finalAssignments[i]).bits & BindingIds.FIELD) != 0) {
+			// final field
+			if (flowInfo.isPotentiallyAssigned(ref.fieldBinding())) {
+				scope.problemReporter().duplicateInitializationOfBlankFinalField(ref.fieldBinding(), ref);
+			}
+		} else {
+			// final local variable
+			if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)((NameReference)ref).binding)) {
+				scope.problemReporter().duplicateInitializationOfFinalLocal((LocalVariableBinding)((NameReference)ref).binding,(NameReference)ref);
+			}
+		}
+		// any reference reported at this level is removed from the parent context 
+		// where it could also be reported again
+		FlowContext currentContext = parent;
+		while (currentContext != null) {
+			if (currentContext.isSubRoutine()) {
+				currentContext.removeFinalAssignmentIfAny(ref);
+			}
+			currentContext = currentContext.parent;
+		}
+	}
+}
+public boolean isSubRoutine() {
+	return true;
+}
+boolean recordFinalAssignment(VariableBinding binding, Reference finalAssignment) {
+	if (assignCount == 0) {
+		finalAssignments = new Reference[5];
+	} else {
+		if (assignCount == finalAssignments.length)
+			System.arraycopy(finalAssignments, 0, (finalAssignments = new Reference[assignCount * 2]), 0, assignCount);
+	};
+	finalAssignments[assignCount++] = finalAssignment;
+	return true;
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 329ccbf..d76194c 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -1,399 +1,395 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import java.util.*;
-
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-/**
- * Reflects the context of code analysis, keeping track of enclosing
- *	try statements, exception handlers, etc...
- */
-public class FlowContext implements TypeConstants {
-	public AstNode associatedNode;
-	public FlowContext parent;
-
-	public final static FlowContext NotContinuableContext = new FlowContext(null,null);
-public FlowContext(FlowContext parent, AstNode associatedNode) {
-	this.parent = parent;
-	this.associatedNode = associatedNode;
-}
-public Label breakLabel() {
-	return null;
-}
-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;
-	while (traversedContext != null) {
-		AstNode sub;
-		if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) {
-			// traversing a non-returning subroutine means that all unhandled 
-			// exceptions will actually never get sent...
-			return;
-		}
-
-		// filter exceptions that are locally caught from the most enclosing 
-		// try statement to the outer ones.
-		if (traversedContext instanceof ExceptionHandlingFlowContext) {
-			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
-			ReferenceBinding[] caughtExceptions;
-			if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
-				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) {
-							switch (scope.compareTypes(raisedException, caughtException)) {
-								case EqualOrMoreSpecific :
-									exceptionContext.recordHandlingException(caughtException, flowInfo.unconditionalInits(), raisedException, location, locallyCaught[raisedIndex]); // was already definitely caught ?
-									if (!locallyCaught[raisedIndex]){
-										locallyCaught[raisedIndex] = true; // remember that this exception has been definitely caught
-										remainingCount--;
-									}
-									break;
-								case MoreGeneric :
-									exceptionContext.recordHandlingException(caughtException, flowInfo.unconditionalInits(), raisedException, 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 (scope.areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
-							|| scope.areTypesCompatible(raisedException, scope.getJavaLangError())){
-							remainingCount --;
-							raisedExceptions[i] = null;
-						}
-					}			
-				}
-			}
-		}
-		if (remainingCount == 0)
-			return;
-		traversedContext = traversedContext.parent;
-	}
-
-	// if reaches this point, then there are some remaining unhandled exception types.	
-	for (int i = 0; i < raisedCount; i++) {
-		TypeBinding exception;
-		if ((exception = raisedExceptions[i]) != null) {
-			scope.problemReporter().unhandledException(exception, location, scope);
-		}
-	}
-}
-/* 
-"	- SMARTER VERSION -
-| unhandledExceptionTypes nameEnv traversedContext |
-
-someExceptionTypes isEmpty ifTrue: [^self].
-
-unhandledExceptionTypes := someExceptionTypes asOrderedCollection.
-nameEnv := scope enclosingMethod nameEnvironment.
-
-traversedContext := self.
-[traversedContext isNil] whileFalse: [| caughtExceptions sub |
-
-((sub := traversedContext subRoutine) notNil and: [sub cannotReturn])
-ifTrue: [
-" "Traversing a non-returning subroutine means that all unhandled exceptions will actually
-never get sent..." "
-^self].
-" "Filter exceptions that are locally caught from the most enclosing try statement to the outer ones." "
-(caughtExceptions := traversedContext handledExceptions) isNil
-ifFalse: [
-caughtExceptions do: [:handledExceptionAssoc | | handledException |
-handledException := handledExceptionAssoc key.
-unhandledExceptionTypes copy do: [:raisedException | | safe |
-" "Any exception recognized as being caught is removed from the exceptions list" "
-((safe := raisedException isCompatibleWith: handledException in: nameEnv)
-or: [handledException isCompatibleWith: raisedException in: nameEnv])
-ifTrue: [
-traversedContext
-recordInitializationInfo: initInfo
-onException: handledException.
-handledExceptionAssoc value: true.
-safe ifTrue: [unhandledExceptionTypes remove: raisedException]]]]].
-unhandledExceptionTypes isEmpty ifTrue: [^self].
-traversedContext := traversedContext parent].
-
-scope enclosingMethod errorInterface
-unexpectedExceptionsError: unhandledExceptionTypes
-from: invocationSite
-
-*/
-public void checkExceptionHandlers(TypeBinding raisedException, AstNode location, FlowInfo flowInfo, BlockScope scope) {
-
-	// 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;
-	while (traversedContext != null) {
-		AstNode sub;
-		if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) {
-			// traversing a non-returning subroutine means that all unhandled 
-			// exceptions will actually never get sent...
-			return;
-		}
-
-		// filter exceptions that are locally caught from the most enclosing 
-		// try statement to the outer ones.
-		if (traversedContext instanceof ExceptionHandlingFlowContext) {
-			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
-			ReferenceBinding[] caughtExceptions;
-			if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
-				boolean definitelyCaught = false;
-				for (int caughtIndex = 0, caughtCount = caughtExceptions.length; caughtIndex < caughtCount; caughtIndex++) {
-					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
-					switch (scope.compareTypes(raisedException, caughtException)) {
-						case EqualOrMoreSpecific :
-							exceptionContext.recordHandlingException(
-								caughtException, 
-								flowInfo.unconditionalInits(), 
-								raisedException, 
-								location, 
-								definitelyCaught); // was it already definitely caught ?
-							definitelyCaught = true;
-							break;
-						case MoreGeneric :
-							exceptionContext.recordHandlingException(
-								caughtException, 
-								flowInfo.unconditionalInits(), 
-								raisedException, 
-								location, 
-								false); // was not caught already per construction
-					}
-				}
-				if (definitelyCaught) return;
-			}
-			// method treatment for unchecked exceptions
-			if (exceptionContext.isMethodContext){
-				if (scope.areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
-					|| scope.areTypesCompatible(raisedException, scope.getJavaLangError()))
-					return;
-				break; // not handled anywhere, thus jump to error handling
-			}
-		}
-		traversedContext = traversedContext.parent;
-	}
-
-	// if reaches this point, then there are some remaining unhandled exception types.
-	scope.problemReporter().unhandledException(raisedException, location, scope);
-}
-public Label continueLabel() {
-	return null;
-}
-public FlowContext getTargetContextForBreakLabel(char[] labelName) {
-
-	// lookup through break labels
-
-	FlowContext current = this, lastNonReturningSubRoutine = null;
-	while (current != null) {
-		if (current.isNonReturningContext()) {
-			lastNonReturningSubRoutine = current;
-		}
-		char[] currentLabelName;
-		if (((currentLabelName = current.labelName()) != null) 
-			&& CharOperation.equals(currentLabelName, labelName)) {
-			if (lastNonReturningSubRoutine == null) {
-				return current;
-			} else {
-				return lastNonReturningSubRoutine;
-			}
-		}
-		current = current.parent;
-	}
-
-	// not found
-	return null;
-}
-public FlowContext getTargetContextForContinueLabel(char[] labelName) {
-
-	// lookup through continue labels
-
-	FlowContext current = this, lastContinuable = null, 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)) {
-			if ((lastContinuable != null) && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) {
-				if (lastNonReturningSubRoutine == null) {
-					return lastContinuable;
-				} else {
-					return lastNonReturningSubRoutine;
-				}
-			} else {
-				// label is found, but not a continuable location
-				return NotContinuableContext;
-			}
-		}
-		current = current.parent;
-	}
-
-	// not found
-	return null;
-}
-public FlowContext getTargetContextForDefaultBreak() {
-
-	// lookup through break labels
-
-	FlowContext current = this, lastNonReturningSubRoutine = null;
-	while (current != null) {
-		if (current.isNonReturningContext()) {
-			lastNonReturningSubRoutine = current;
-		}
-		if (current.isBreakable()) {
-			if (lastNonReturningSubRoutine == null) {
-				return current;
-			} else {
-				return lastNonReturningSubRoutine;
-			}
-		}
-		current = current.parent;
-	}
-
-	// not found
-	return null;
-}
-public FlowContext getTargetContextForDefaultContinue() {
-
-	// lookup through continue labels
-
-
-	FlowContext current = this, lastNonReturningSubRoutine = null;
-	while (current != null) {
-		if (current.isNonReturningContext()) {
-			lastNonReturningSubRoutine = current;
-		}
-		if (current.isContinuable()) {
-			if (lastNonReturningSubRoutine == null) {
-				return current;
-			} else {
-				return lastNonReturningSubRoutine;
-			}
-		}
-		current = current.parent;
-	}
-
-	// not found
-	return null;
-}
-public String individualToString(){
-	return "Flow context"/*nonNLS*/;
-}
-public FlowInfo initsOnBreak() {
-	return FlowInfo.DeadEnd;
-}
-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;
-}
-public void recordBreakFrom(FlowInfo flowInfo) {
-}
-public void recordContinueFrom(FlowInfo flowInfo) {
-}
-boolean recordFinalAssignment(VariableBinding variable, Reference finalReference) {
-	return true; // keep going
-}
-public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
-}
-public void recordSettingFinal(VariableBinding variable, Reference finalReference) {
-
-	// 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.parent;
-	}
-}
-void removeFinalAssignmentIfAny(Reference reference) {
-}
-public AstNode subRoutine() {
-	return null;
-}
-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();
-}
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class FlowContext implements TypeConstants {
+	public AstNode associatedNode;
+	public FlowContext parent;
+
+	public final static FlowContext NotContinuableContext = new FlowContext(null,null);
+public FlowContext(FlowContext parent, AstNode associatedNode) {
+	this.parent = parent;
+	this.associatedNode = associatedNode;
+}
+public Label breakLabel() {
+	return null;
+}
+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;
+	while (traversedContext != null) {
+		AstNode sub;
+		if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) {
+			// traversing a non-returning subroutine means that all unhandled 
+			// exceptions will actually never get sent...
+			return;
+		}
+
+		// filter exceptions that are locally caught from the most enclosing 
+		// try statement to the outer ones.
+		if (traversedContext instanceof ExceptionHandlingFlowContext) {
+			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
+			ReferenceBinding[] caughtExceptions;
+			if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
+				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) {
+							switch (scope.compareTypes(raisedException, caughtException)) {
+								case EqualOrMoreSpecific :
+									exceptionContext.recordHandlingException(caughtException, flowInfo.unconditionalInits(), raisedException, location, locallyCaught[raisedIndex]); // was already definitely caught ?
+									if (!locallyCaught[raisedIndex]){
+										locallyCaught[raisedIndex] = true; // remember that this exception has been definitely caught
+										remainingCount--;
+									}
+									break;
+								case MoreGeneric :
+									exceptionContext.recordHandlingException(caughtException, flowInfo.unconditionalInits(), raisedException, 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 (scope.areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
+							|| scope.areTypesCompatible(raisedException, scope.getJavaLangError())){
+							remainingCount --;
+							raisedExceptions[i] = null;
+						}
+					}			
+				}
+			}
+		}
+		if (remainingCount == 0)
+			return;
+		traversedContext = traversedContext.parent;
+	}
+
+	// if reaches this point, then there are some remaining unhandled exception types.	
+	for (int i = 0; i < raisedCount; i++) {
+		TypeBinding exception;
+		if ((exception = raisedExceptions[i]) != null) {
+			scope.problemReporter().unhandledException(exception, location, scope);
+		}
+	}
+}
+/* 
+"	- SMARTER VERSION -
+| unhandledExceptionTypes nameEnv traversedContext |
+
+someExceptionTypes isEmpty ifTrue: [^self].
+
+unhandledExceptionTypes := someExceptionTypes asOrderedCollection.
+nameEnv := scope enclosingMethod nameEnvironment.
+
+traversedContext := self.
+[traversedContext isNil] whileFalse: [| caughtExceptions sub |
+
+((sub := traversedContext subRoutine) notNil and: [sub cannotReturn])
+ifTrue: [
+" "Traversing a non-returning subroutine means that all unhandled exceptions will actually
+never get sent..." "
+^self].
+" "Filter exceptions that are locally caught from the most enclosing try statement to the outer ones." "
+(caughtExceptions := traversedContext handledExceptions) isNil
+ifFalse: [
+caughtExceptions do: [:handledExceptionAssoc | | handledException |
+handledException := handledExceptionAssoc key.
+unhandledExceptionTypes copy do: [:raisedException | | safe |
+" "Any exception recognized as being caught is removed from the exceptions list" "
+((safe := raisedException isCompatibleWith: handledException in: nameEnv)
+or: [handledException isCompatibleWith: raisedException in: nameEnv])
+ifTrue: [
+traversedContext
+recordInitializationInfo: initInfo
+onException: handledException.
+handledExceptionAssoc value: true.
+safe ifTrue: [unhandledExceptionTypes remove: raisedException]]]]].
+unhandledExceptionTypes isEmpty ifTrue: [^self].
+traversedContext := traversedContext parent].
+
+scope enclosingMethod errorInterface
+unexpectedExceptionsError: unhandledExceptionTypes
+from: invocationSite
+
+*/
+public void checkExceptionHandlers(TypeBinding raisedException, AstNode location, FlowInfo flowInfo, BlockScope scope) {
+
+	// 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;
+	while (traversedContext != null) {
+		AstNode sub;
+		if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) {
+			// traversing a non-returning subroutine means that all unhandled 
+			// exceptions will actually never get sent...
+			return;
+		}
+
+		// filter exceptions that are locally caught from the most enclosing 
+		// try statement to the outer ones.
+		if (traversedContext instanceof ExceptionHandlingFlowContext) {
+			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext;
+			ReferenceBinding[] caughtExceptions;
+			if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
+				boolean definitelyCaught = false;
+				for (int caughtIndex = 0, caughtCount = caughtExceptions.length; caughtIndex < caughtCount; caughtIndex++) {
+					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
+					switch (scope.compareTypes(raisedException, caughtException)) {
+						case EqualOrMoreSpecific :
+							exceptionContext.recordHandlingException(
+								caughtException, 
+								flowInfo.unconditionalInits(), 
+								raisedException, 
+								location, 
+								definitelyCaught); // was it already definitely caught ?
+							definitelyCaught = true;
+							break;
+						case MoreGeneric :
+							exceptionContext.recordHandlingException(
+								caughtException, 
+								flowInfo.unconditionalInits(), 
+								raisedException, 
+								location, 
+								false); // was not caught already per construction
+					}
+				}
+				if (definitelyCaught) return;
+			}
+			// method treatment for unchecked exceptions
+			if (exceptionContext.isMethodContext){
+				if (scope.areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
+					|| scope.areTypesCompatible(raisedException, scope.getJavaLangError()))
+					return;
+				break; // not handled anywhere, thus jump to error handling
+			}
+		}
+		traversedContext = traversedContext.parent;
+	}
+
+	// if reaches this point, then there are some remaining unhandled exception types.
+	scope.problemReporter().unhandledException(raisedException, location, scope);
+}
+public Label continueLabel() {
+	return null;
+}
+public FlowContext getTargetContextForBreakLabel(char[] labelName) {
+
+	// lookup through break labels
+
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		char[] currentLabelName;
+		if (((currentLabelName = current.labelName()) != null) 
+			&& CharOperation.equals(currentLabelName, labelName)) {
+			if (lastNonReturningSubRoutine == null) {
+				return current;
+			} else {
+				return lastNonReturningSubRoutine;
+			}
+		}
+		current = current.parent;
+	}
+
+	// not found
+	return null;
+}
+public FlowContext getTargetContextForContinueLabel(char[] labelName) {
+
+	// lookup through continue labels
+
+	FlowContext current = this, lastContinuable = null, 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)) {
+			if ((lastContinuable != null) && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) {
+				if (lastNonReturningSubRoutine == null) {
+					return lastContinuable;
+				} else {
+					return lastNonReturningSubRoutine;
+				}
+			} else {
+				// label is found, but not a continuable location
+				return NotContinuableContext;
+			}
+		}
+		current = current.parent;
+	}
+
+	// not found
+	return null;
+}
+public FlowContext getTargetContextForDefaultBreak() {
+
+	// lookup through break labels
+
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		if (current.isBreakable()) {
+			if (lastNonReturningSubRoutine == null) {
+				return current;
+			} else {
+				return lastNonReturningSubRoutine;
+			}
+		}
+		current = current.parent;
+	}
+
+	// not found
+	return null;
+}
+public FlowContext getTargetContextForDefaultContinue() {
+
+	// lookup through continue labels
+
+
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		if (current.isContinuable()) {
+			if (lastNonReturningSubRoutine == null) {
+				return current;
+			} else {
+				return lastNonReturningSubRoutine;
+			}
+		}
+		current = current.parent;
+	}
+
+	// not found
+	return null;
+}
+public String individualToString(){
+	return "Flow context"/*nonNLS*/;
+}
+public FlowInfo initsOnBreak() {
+	return FlowInfo.DeadEnd;
+}
+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;
+}
+public void recordBreakFrom(FlowInfo flowInfo) {
+}
+public void recordContinueFrom(FlowInfo flowInfo) {
+}
+boolean recordFinalAssignment(VariableBinding variable, Reference finalReference) {
+	return true; // keep going
+}
+public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
+}
+public void recordSettingFinal(VariableBinding variable, Reference finalReference) {
+
+	// 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.parent;
+	}
+}
+void removeFinalAssignmentIfAny(Reference reference) {
+}
+public AstNode subRoutine() {
+	return null;
+}
+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();
+}
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 74ef42c..c2eb347 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,79 +1,78 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-
-public abstract class FlowInfo {
-	public static final UnconditionalFlowInfo DeadEnd = new UnconditionalFlowInfo(); // Represents a dead branch status of initialization
-abstract public UnconditionalFlowInfo addInitializationsFrom(UnconditionalFlowInfo otherInits);
-abstract public UnconditionalFlowInfo addPotentialInitializationsFrom(UnconditionalFlowInfo otherInits);
-public FlowInfo asNegatedCondition() {
-	return this;
-}
-public boolean complainIfUnreachable(Statement statement, BlockScope scope) {
-	// Report an error if necessary
-
-	return false;
-}
-public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
-	return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
-}
-abstract public FlowInfo copy();
-public static UnconditionalFlowInfo initial(int maxFieldCount) {
-	UnconditionalFlowInfo info = new UnconditionalFlowInfo();
-	info.maxFieldCount = maxFieldCount;
-	return info;
-}
-abstract public FlowInfo initsWhenFalse();
-abstract public FlowInfo initsWhenTrue();
-final public boolean isDeadEnd() {
-	return this == DeadEnd;
-}
-/**
- * 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);
-abstract public boolean isFakeReachable();
-/**
- * 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);   
-/**
- * Record a field got definitely assigned.
- */
-abstract public void markAsDefinitelyAssigned(FieldBinding field);
-/**
- * Record a local got definitely assigned.
- */
-abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
-/**
- * Clear the initialization info for a field
- */
-abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
-/**
- * Clear the initialization info for a local variable
- */
-abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
-abstract public FlowInfo markAsFakeReachable(boolean isFakeReachable);
-abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
-public String toString(){
-	if (this == DeadEnd){
-		return "FlowInfo.DeadEnd"/*nonNLS*/;
-	}
-	return super.toString();
-}
-abstract public UnconditionalFlowInfo unconditionalInits();
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class FlowInfo {
+	public static final UnconditionalFlowInfo DeadEnd = new UnconditionalFlowInfo(); // Represents a dead branch status of initialization
+abstract public UnconditionalFlowInfo addInitializationsFrom(UnconditionalFlowInfo otherInits);
+abstract public UnconditionalFlowInfo addPotentialInitializationsFrom(UnconditionalFlowInfo otherInits);
+public FlowInfo asNegatedCondition() {
+	return this;
+}
+public boolean complainIfUnreachable(Statement statement, BlockScope scope) {
+	// Report an error if necessary
+
+	return false;
+}
+public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
+	return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
+}
+abstract public FlowInfo copy();
+public static UnconditionalFlowInfo initial(int maxFieldCount) {
+	UnconditionalFlowInfo info = new UnconditionalFlowInfo();
+	info.maxFieldCount = maxFieldCount;
+	return info;
+}
+abstract public FlowInfo initsWhenFalse();
+abstract public FlowInfo initsWhenTrue();
+final public boolean isDeadEnd() {
+	return this == DeadEnd;
+}
+/**
+ * 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);
+abstract public boolean isFakeReachable();
+/**
+ * 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);   
+/**
+ * Record a field got definitely assigned.
+ */
+abstract public void markAsDefinitelyAssigned(FieldBinding field);
+/**
+ * Record a local got definitely assigned.
+ */
+abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
+/**
+ * Clear the initialization info for a field
+ */
+abstract public void markAsDefinitelyNotAssigned(FieldBinding field);
+/**
+ * Clear the initialization info for a local variable
+ */
+abstract public void markAsDefinitelyNotAssigned(LocalVariableBinding local);
+abstract public FlowInfo markAsFakeReachable(boolean isFakeReachable);
+abstract public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits);
+public String toString(){
+	if (this == DeadEnd){
+		return "FlowInfo.DeadEnd"/*nonNLS*/;
+	}
+	return super.toString();
+}
+abstract public UnconditionalFlowInfo unconditionalInits();
+}
diff --git a/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java b/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
index dc29f9f..13bb5ab 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
@@ -1,55 +1,50 @@
-package org.eclipse.jdt.internal.compiler.flow;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jdt.internal.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.*;
-
-import java.util.*;
-
-/**
- * Reflects the context of code analysis, keeping track of enclosing
- *	try statements, exception handlers, etc...
- */
-public class InitializationFlowContext extends ExceptionHandlingFlowContext {
-	public UnconditionalFlowInfo initsOnReturn;
-
-	public int exceptionCount;
-	public TypeBinding[] thrownExceptions = new TypeBinding[5];
-	public AstNode[] exceptionThrowers = new AstNode[5];
-public InitializationFlowContext(FlowContext parent, AstNode associatedNode, BlockScope scope) {
-	super(
-		parent, 
-		associatedNode, 
-		new ReferenceBinding[] {scope.getJavaLangThrowable()}, // tolerate any kind of exception, but record them
-		scope,
-		FlowInfo.DeadEnd);
-	
-	this.initsOnReturn = FlowInfo.DeadEnd;
-}
-public void checkInitializerExceptions(BlockScope currentScope, FlowContext initializerContext, FlowInfo flowInfo) {
-	for(int i = 0; i < exceptionCount; i++){
-		initializerContext.checkExceptionHandlers(thrownExceptions[i], exceptionThrowers[i], flowInfo, currentScope);
-	}
-}
-public void recordHandlingException(ReferenceBinding exceptionType, UnconditionalFlowInfo flowInfo, TypeBinding raisedException, AstNode invocationSite, boolean wasMasked) {
-
-	int size = thrownExceptions.length;
-	if (exceptionCount == size){
-		System.arraycopy(thrownExceptions, 0, (thrownExceptions = new TypeBinding[size*2]),0, size);
-		System.arraycopy(exceptionThrowers, 0, (exceptionThrowers = new AstNode[size*2]),0, size);
-	}
-	thrownExceptions[exceptionCount] = raisedException;
-	exceptionThrowers[exceptionCount++ ] = invocationSite;
-}
-public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
-
-	// record initializations which were performed at the return point
-	initsOnReturn = initsOnReturn.mergedWith(flowInfo);
-}
-}
+package org.eclipse.jdt.internal.compiler.flow;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class InitializationFlowContext extends ExceptionHandlingFlowContext {
+	public UnconditionalFlowInfo initsOnReturn;
+
+	public int exceptionCount;
+	public TypeBinding[] thrownExceptions = new TypeBinding[5];
+	public AstNode[] exceptionThrowers = new AstNode[5];
+public InitializationFlowContext(FlowContext parent, AstNode associatedNode, BlockScope scope) {
+	super(
+		parent, 
+		associatedNode, 
+		new ReferenceBinding[] {scope.getJavaLangThrowable()}, // tolerate any kind of exception, but record them
+		scope,
+		FlowInfo.DeadEnd);
+	
+	this.initsOnReturn = FlowInfo.DeadEnd;
+}
+public void checkInitializerExceptions(BlockScope currentScope, FlowContext initializerContext, FlowInfo flowInfo) {
+	for(int i = 0; i < exceptionCount; i++){
+		initializerContext.checkExceptionHandlers(thrownExceptions[i], exceptionThrowers[i], flowInfo, currentScope);
+	}
+}
+public void recordHandlingException(ReferenceBinding exceptionType, UnconditionalFlowInfo flowInfo, TypeBinding raisedException, AstNode invocationSite, boolean wasMasked) {
+
+	int size = thrownExceptions.length;
+	if (exceptionCount == size){
+		System.arraycopy(thrownExceptions, 0, (thrownExceptions = new TypeBinding[size*2]),0, size);
+		System.arraycopy(exceptionThrowers, 0, (exceptionThrowers = new AstNode[size*2]),0, size);
+	}
+	thrownExceptions[exceptionCount] = raisedException;
+	exceptionThrowers[exceptionCount++ ] = invocationSite;
+}
+public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
+
+	// record initializations which were performed at the return point
+	initsOnReturn = initsOnReturn.mergedWith(flowInfo);
+}
+}
