Adds regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=173526.  Also improves tracing support in the MockValidationReporter.
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/MockValidationReporter.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/MockValidationReporter.java
index f2e7b2e..a948679 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/MockValidationReporter.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/MockValidationReporter.java
@@ -68,8 +68,18 @@
     {
         List<ReportedProblem>  messages = _messagesByOffset.get(offset);
 
-        if (messages == null)
+        if (messages == null || messages.size() == 0)
         {
+            for (final Map.Entry<Integer, List<ReportedProblem>> entry : _messagesByOffset.entrySet())
+            {
+                int entryOffset = entry.getKey().intValue();
+                // if the offset looked for is within +/-5 of an entry,
+                // dump it to stderr for debugging slightly off offsets
+                if (offset >= entryOffset - 5 && offset <= entryOffset+5)
+                {
+                    System.err.printf("Offset %d requested not found but close is: %d", offset, entryOffset);
+                }
+            }
             messages = new ArrayList<ReportedProblem>();
             _messagesByOffset.put(offset, messages);
         }
@@ -80,8 +90,13 @@
     public void assertExpectedMessage(
             final int offset, final int length, final int severity)
     {
+        assertExpectedMessage(offset, length, severity, null);
+    }
+
+    public void assertExpectedMessage(
+            final int offset, final int length, final int severity, final Integer code)
+    {
         final List<ReportedProblem> reportedProblems = getMessageListForOffset(offset);
-        final List<ReportedProblem> reportedProblemsNotMatching = new ArrayList<ReportedProblem>();
 
         Assert.assertTrue(reportedProblems.size() > 0);
 
@@ -89,12 +104,11 @@
         {
             if (problem.getLength() == length && problem.getSeverity() == severity)
             {
-                // we found the expected message
-                return;
-            }
-            else
-            {
-                reportedProblemsNotMatching.add(problem);
+                if (code == null || code == Integer.valueOf(problem.getErrorCode()))
+                {
+                    // we found the expected message
+                    return;
+                }
             }
         }
 
@@ -102,11 +116,16 @@
 
         for (final ReportedProblem problem : reportedProblems)
         {
-            failMessage += "\n" + problem.getText();
+            failMessage += 
+                String.format("\n at offset offset %d, code=%d, length=%d, message=%s", problem.getOffset(), 
+                        problem.getErrorCode(), problem.getLength(), problem.getText());
         }
-        Assert.fail(String.format("Failed to find expected message at offset %d, found instead %s", offset, failMessage));
+        Assert.fail(String.format(
+                "Failed to find expected message at offset %d%s, length %d, found instead %s"
+                , offset, length, (code == null ? "" : ", with errorCode "+code), failMessage));
+
     }
-    
+
     public static class ReportedProblem
     {
         private final int _offset;
diff --git a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/TestJSPSemanticsValidator_AttributeValues.java b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/TestJSPSemanticsValidator_AttributeValues.java
index 6d8f472..1ee0dc0 100644
--- a/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/TestJSPSemanticsValidator_AttributeValues.java
+++ b/jsf/tests/org.eclipse.jst.jsf.core.tests/src/org/eclipse/jst/jsf/core/tests/validation/TestJSPSemanticsValidator_AttributeValues.java
@@ -18,6 +18,7 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jst.common.project.facet.JavaFacetUtils;
+import org.eclipse.jst.jsf.common.internal.types.TypeComparatorDiagnosticFactory;
 import org.eclipse.jst.jsf.core.tests.TestsPlugin;
 import org.eclipse.jst.jsf.test.util.JSFTestUtil;
 import org.eclipse.jst.jsf.test.util.WebProjectTestEnvironment;
@@ -111,7 +112,7 @@
         // in the path, we trigger a containment warning on the loadBundle
         // since the f:view in the doc can't be fully resolved.
         // at 845 we also get two, one for syntax error and one for missing bracket
-        assertEquals(9, mockReporter.getReportedProblems().size());
+        assertEquals(10, mockReporter.getReportedProblems().size());
 
         mockReporter.assertExpectedMessage(603, 2, IMessage.NORMAL_SEVERITY);
         mockReporter.assertExpectedMessage(648, 4, IMessage.NORMAL_SEVERITY);
@@ -123,7 +124,9 @@
         mockReporter.assertExpectedMessage(846, 5, IMessage.HIGH_SEVERITY);
         mockReporter.assertExpectedMessage(847, 3, IMessage.NORMAL_SEVERITY);
 
-        mockReporter.assertExpectedMessage(963, 40, IMessage.HIGH_SEVERITY);
+        mockReporter.assertExpectedMessage(946, 24, IMessage.NORMAL_SEVERITY, TypeComparatorDiagnosticFactory.PROPERTY_NOT_WRITABLE_ID);
+
+        mockReporter.assertExpectedMessage(1015, 40, IMessage.HIGH_SEVERITY);
     }