*** empty log message ***
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
index d92b27b..fb6ce8f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
@@ -41,7 +41,6 @@
 		this.endPosition = endPosition;
 		this.line = line;
 	}
-	//TODO should use StringBuffer.append(char[], int, int) instead of creating subarrays
 	public String errorReportSource(char[] unitSource) {
 		//extra from the source the innacurate     token
 		//and "highlight" it using some underneath ^^^^^
@@ -54,6 +53,11 @@
 			|| ((startPosition < 0) && (endPosition < 0)))
 			return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
 
+		StringBuffer errorBuffer = new StringBuffer(" "); //$NON-NLS-1$
+		errorBuffer.append(Util.bind("problem.atLine", String.valueOf(line))); //$NON-NLS-1$
+		errorBuffer.append("\n\t"); //$NON-NLS-1$
+		
+		char c;
 		final char SPACE = '\u0020';
 		final char MARK = '^';
 		final char TAB = '\t';
@@ -62,60 +66,31 @@
 		//contain any \r \n. This is false on statements ! 
 		//(the code still works but the display is not optimal !)
 
-		//compute the how-much-char we are displaying around the inaccurate token
-		int begin = startPosition >= unitSource.length ? unitSource.length - 1 : startPosition;
-		int relativeStart = 0;
-		int end = endPosition >= unitSource.length ? unitSource.length - 1 : endPosition;
-		int relativeEnd = 0;
-		label : for (relativeStart = 0;; relativeStart++) {
-			if (begin == 0)
-				break label;
-			if ((unitSource[begin - 1] == '\n') || (unitSource[begin - 1] == '\r'))
-				break label;
-			begin--;
+		// expand to line limits
+		int length = unitSource.length, begin, end;
+		for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+			if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
 		}
-		label : for (relativeEnd = 0;; relativeEnd++) {
-			if ((end + 1) >= unitSource.length)
-				break label;
-			if ((unitSource[end + 1] == '\r') || (unitSource[end + 1] == '\n')) {
-				break label;
-			}
-			end++;
+		for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+			if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
 		}
-		//extract the message form the source
-		char[] extract = new char[end - begin + 1];
-		System.arraycopy(unitSource, begin, extract, 0, extract.length);
-		char c;
-		//remove all SPACE and TAB that begin the error message...
-		int trimLeftIndex = 0;
-		while (((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE));
-		System.arraycopy(
-			extract,
-			trimLeftIndex - 1,
-			extract = new char[extract.length - trimLeftIndex + 1],
-			0,
-			extract.length);
-		relativeStart -= trimLeftIndex;
-		//buffer spaces and tabs in order to reach the error position
-		int pos = 0;
-		char[] underneath = new char[extract.length]; // can't be bigger
-		for (int i = 0; i <= relativeStart; i++) {
-			if (extract[i] == TAB) {
-				underneath[pos++] = TAB;
-			} else {
-				underneath[pos++] = SPACE;
-			}
+		
+		// trim left and right spaces/tabs
+		while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+		//while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated
+		
+		// copy source
+		errorBuffer.append(unitSource, begin, end-begin+1);
+		errorBuffer.append("\n\t"); //$NON-NLS-1$
+		
+		// compute underline
+		for (int i = begin; i <startPosition; i++) {
+			errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
 		}
-		//mark the error position
-		for (int i = startPosition;
-			i <= (endPosition >= unitSource.length ? unitSource.length - 1 : endPosition);
-			i++)
-			underneath[pos++] = MARK;
-		//resize underneathto remove 'null' chars
-		System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
-
-		return " " + Util.bind("problem.atLine", String.valueOf(line)) 	//$NON-NLS-2$ //$NON-NLS-1$
-			+ "\n\t" + new String(extract) + "\n\t" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
+		for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) {
+			errorBuffer.append(MARK);
+		}
+		return errorBuffer.toString();
 	}
 
 	/**