Update after Philippe's review
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index e53723a..87afbee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -15,7 +15,6 @@
 

 	// for local variable attribute

 	int preAssertInitStateIndex = -1;

-	private boolean activateCodeGeneration = false;

 	private FieldBinding assertionSyntheticFieldBinding;

 	

 	public AssertStatement(

@@ -62,29 +61,7 @@
 		if (constant != NotAConstant && constant.booleanValue() == true) {

 			return flowInfo;

 		}

-		activateCodeGeneration = true;

-		SourceTypeBinding sourceTypeBinding = currentScope.outerMostMethodScope().enclosingSourceType();

-		assertionSyntheticFieldBinding = sourceTypeBinding.addSyntheticField(this, currentScope);

-		TypeDeclaration typeDeclaration = currentScope.outerMostClassScope().referenceType();

-		typeDeclaration.emulationAssertionSupport = true;

-		AbstractMethodDeclaration[] methods = typeDeclaration.methods;

-		Clinit clinit = null;

-		for (int i = 0, max = methods.length; i < max; i++) {

-			AbstractMethodDeclaration method = methods[i];

-			if (method.isClinit()) {

-				// this is the clinit

-				clinit = (Clinit) method;

-			}

-		}

-		if (clinit == null) {

-			typeDeclaration.addClinit();

-			methods = typeDeclaration.methods;

-			clinit = (Clinit) methods[0];

-			// need to initialize the scope of the clinit

-			clinit.resolve(currentScope.outerMostClassScope());

-			clinit.needFreeReturn = true;

-		}

-		clinit.addSupportForAssertion(assertionSyntheticFieldBinding);

+		manageSyntheticAccessIfNecessary(currentScope);

 		return flowInfo;

 	}

 

@@ -95,7 +72,7 @@
 		int pc = codeStream.position, divergePC;

 	

 		//  codegen here

-		if (activateCodeGeneration) {

+		if (this.assertionSyntheticFieldBinding != null) {

 			Label assertionActivationLabel = new Label(codeStream);

 			codeStream.getstatic(this.assertionSyntheticFieldBinding);

 			codeStream.ifne(assertionActivationLabel);

@@ -142,4 +119,24 @@
 		}

 		visitor.endVisit(this, scope);

 	}	

+	

+	public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {

+		ClassScope outerMostClassScope = currentScope.outerMostClassScope();

+		SourceTypeBinding sourceTypeBinding = outerMostClassScope.enclosingSourceType();

+		this.assertionSyntheticFieldBinding = sourceTypeBinding.addSyntheticField(this, currentScope);

+		TypeDeclaration typeDeclaration = outerMostClassScope.referenceType();

+		AbstractMethodDeclaration[] methods = typeDeclaration.methods;

+		Clinit clinit = null;

+		for (int i = 0, max = methods.length; i < max; i++) {

+			AbstractMethodDeclaration method = methods[i];

+			if (method.isClinit()) {

+				// this is the clinit

+				clinit = (Clinit) method;

+			}

+		}

+		if (clinit != null) {

+			// should always be the case

+			clinit.addSupportForAssertion(assertionSyntheticFieldBinding);

+		}

+	}

 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index bf3a84a..e062786 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -16,7 +16,6 @@
 public class Clinit extends AbstractMethodDeclaration {

 	public final static char[] ConstantPoolName = "<clinit>"/*nonNLS*/.toCharArray();

 	

-	private boolean activateAssertionEmulation = false;

 	private FieldBinding assertionSyntheticFieldBinding = null;

 	private FieldBinding classLiteralSyntheticField = null;

 	

@@ -89,7 +88,7 @@
 

 		// 1.4 feature

 		// This has to be done before any other initialization

-		if (this.activateAssertionEmulation) {

+		if (this.assertionSyntheticFieldBinding != null) {

 			// generate code related to the activation of assertion for this class

 			codeStream.generateClassLiteralAccessForType(classScope.enclosingSourceType(), classLiteralSyntheticField);

 			codeStream.invokeJavaLangClassDesiredAssertionStatus();

@@ -173,12 +172,11 @@
 }

 

 public void addSupportForAssertion(FieldBinding assertionSyntheticFieldBinding) {

-	this.activateAssertionEmulation = true;

 	this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding;

 	// 1.4 feature

 	// we need to add the field right now, because the field infos are generated before the methods

 	SourceTypeBinding sourceType = this.scope.outerMostMethodScope().enclosingSourceType();

-	classLiteralSyntheticField = sourceType.addSyntheticField(sourceType, scope);

+	this.classLiteralSyntheticField = sourceType.addSyntheticField(sourceType, scope);

 }

 

 }

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 5060063..3c76018 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -33,6 +33,9 @@
 

 	// for statements only

 	public static final int IsReachableMASK = 0x80000000; // highest bit

+	

+	// for type declaration only

+	public static final int AddAssertionMASK = 1; // highest bit

 

 	/*

 	public final static int BitMask1= 0x1; // decimal 1

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index d496c26..c3be7fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -33,7 +33,7 @@
 	public int declarationSourceStart ;

 	public int declarationSourceEnd ;

 	public int bodyStart;

-	public boolean emulationAssertionSupport = false;

+	

 /*

  *	We cause the compilation task to abort to a given extent.

  */

@@ -651,7 +651,7 @@
 	

 	return false ;}

 	----------------------------------------------------*/

-	if (emulationAssertionSupport) {

+	if ((this.bits & AddAssertionMASK) != 0) {

 		return true;

 	}

 	if (fields == null)

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index bc4fd85..6dd312a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -276,23 +276,57 @@
 					case 1:

 						switch(methodBinding.parameters[0].id) {

 							case T_String :

-								return CONSTR_STRING_METHOD_NAME_AND_TYPE;	

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.StringConstructorSignature)) {

+									return CONSTR_STRING_METHOD_NAME_AND_TYPE;	

+								} else {

+									return -1;

+								}

 							case T_Object :

-								return CONSTR_OBJECT_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorObjectConstrSignature)) {

+									return CONSTR_OBJECT_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_int :

 							case T_byte :

 							case T_short :

-								return CONSTR_INT_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorIntConstrSignature)

+									|| CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.ShortConstrSignature)

+									|| CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.ByteConstrSignature)) {

+									return CONSTR_INT_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_char :

-								return CONSTR_CHAR_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorCharConstrSignature)) {

+									return CONSTR_CHAR_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_boolean :

-								return CONSTR_BOOLEAN_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorBooleanConstrSignature)) {

+									return CONSTR_BOOLEAN_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_float :

-								return CONSTR_FLOAT_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorFloatConstrSignature)) {

+									return CONSTR_FLOAT_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_double :

-								return CONSTR_DOUBLE_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorDoubleConstrSignature)) {

+									return CONSTR_DOUBLE_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 							case T_long :

-								return CONSTR_LONG_METHOD_NAME_AND_TYPE;

+								if (CharOperation.equals(methodBinding.signature(), QualifiedNamesConstants.AssertionErrorLongConstrSignature)) {

+									return CONSTR_LONG_METHOD_NAME_AND_TYPE;

+								} else {

+									return -1;

+								}

 						}

 					case 0:

 						if (methodBinding.signature().length == 3) {

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
index 64f4318..994e3c6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/QualifiedNamesConstants.java
@@ -79,4 +79,6 @@
 	char[] AssertionErrorObjectConstrSignature = "(Ljava/lang/Object;)V"/*nonNLS*/.toCharArray();

 	char[] DesiredAssertionStatus = "desiredAssertionStatus"/*nonNLS*/.toCharArray();

 	char[] DesiredAssertionStatusSignature = "()Z"/*nonNLS*/.toCharArray();

+	char[] ShortConstrSignature = "(S)V"/*nonNLS*/.toCharArray();

+	char[] ByteConstrSignature = "(B)V"/*nonNLS*/.toCharArray();

 }

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
index 4482fd9..ca927af 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ConfigurableProblems.java
@@ -20,4 +20,5 @@
 	final int TemporaryWarning = 0x40000;

 	final int AccessEmulation = 0x80000;

 	final int NonExternalizedString = 0x100000;

+	final int AssertUsedAsAnIdentifier = 0x200000;

 }

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index b783f44..e292896 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -199,17 +199,16 @@
 	return synthField;

 }

 

-/* Add a new synthetic field for a class literal access.

+/* Add a new synthetic field for the emulation of the assert statement.

 *	Answer the new field or the existing field if one already existed.

 */

-

 public FieldBinding addSyntheticField(AssertStatement assertStatement, BlockScope blockScope) {

 	if (synthetics == null) {

 		synthetics = new Hashtable[] { new Hashtable(5), new Hashtable(5), new Hashtable(5) };

 	}

 

 	// use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.

-	FieldBinding synthField = (FieldBinding) synthetics[FIELD].get(BooleanBinding);

+	FieldBinding synthField = (FieldBinding) synthetics[FIELD].get("assertionEmulation"/*nonNLS*/);

 	if (synthField == null) {

 		synthField = new SyntheticFieldBinding(

 			"$assertionsDisabled"/*nonNLS*/.toCharArray(),

@@ -218,7 +217,7 @@
 			this,

 			Constant.NotAConstant,

 			0);

-		synthetics[FIELD].put(BooleanBinding, synthField);

+		synthetics[FIELD].put("assertionEmulation"/*nonNLS*/, synthField);

 	}

 	// ensure there is not already such a field defined by the user

 	// ensure there is not already such a field defined by the user

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index 3ff5545..61b6336 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -41,7 +41,6 @@
 	final int T_JavaLangClassNotFoundException = 23;

 	final int T_JavaIoPrintStream = 24;

 	final int T_JavaLangException = 25;

-	final int T_JavaLangAssertionError = 35; // 1.4 feature

 

 	// wrapper types

 	final int T_JavaLangByte = 26;

@@ -53,6 +52,9 @@
 	final int T_JavaLangDouble = 32;

 	final int T_JavaLangBoolean = 33;

 	final int T_JavaLangVoid = 34;

+

+	// 1.4 feature

+	final int T_JavaLangAssertionError = 35;

 	final int NoId = Integer.MAX_VALUE;

 

 	// implicit conversions: <compileType> to <runtimeType>  (note: booleans are integers at runtime)

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 0b5496a..2cda38c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -1389,6 +1389,9 @@
 	}

 

 	//always add <clinit> (will be remove at code gen time if empty)

+	if (this.scanner.containsAssertKeyword) {

+		typeDecl.bits |= Statement.AddAssertionMASK;

+	}

 	typeDecl.addClinit();

 	typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 

 }

@@ -2127,6 +2130,9 @@
 	typeDecl.checkConstructors(this);

 	

 	//always add <clinit> (will be remove at code gen time if empty)

+	if (this.scanner.containsAssertKeyword) {

+		typeDecl.bits |= Statement.AddAssertionMASK;

+	}

 	typeDecl.addClinit();

 	typeDecl.declarationSourceEnd = flushAnnotationsDefinedPriorTo(endStatementPosition); 

 }

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 7ef2d07..c91fa27 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -21,6 +21,7 @@
 	// 1.4 feature

 	public boolean assertMode;

 	public boolean useAssertAsAnIndentifier = false;

+	public boolean containsAssertKeyword = false;

 	

 	public boolean recordLineSeparator;

 	public char currentCharacter;

@@ -1988,6 +1989,7 @@
 						&& (data[++index] == 'r')

 						&& (data[++index] == 't')) {

 							if (assertMode) {

+								containsAssertKeyword = true;

 								return TokenNameassert;

 							} else {

 								useAssertAsAnIndentifier = true;

@@ -2670,6 +2672,7 @@
 	source = sourceString;

 	startPosition = -1;

 	initialPosition = currentPosition = 0;

+	containsAssertKeyword = false;

 	if (source == null) {

 		source = new char[0];

 	}

diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 9e3ebf6..1f1af06 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -428,7 +428,14 @@
 				return Warning;

 			}

 			return Ignore;

-		

+		case UseAssertAsAnIdentifier :

+			if ((errorThreshold & AssertUsedAsAnIdentifier) != 0){

+				return Error;

+			}

+			if ((warningThreshold & AssertUsedAsAnIdentifier) != 0){

+				return Warning;

+			}

+			return Ignore;		

 		default:

 			return Error;

 	}

@@ -2160,7 +2167,6 @@
 	this.handle(

 		UseAssertAsAnIdentifier,

 		new String[0],

-		Warning,

 		sourceStart,

 		sourceEnd);	

 }