testing: improve ITestRunListener2 API
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/ITestRunListener2.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/ITestRunListener2.java
index a27a75a..65916ff 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/ITestRunListener2.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/ITestRunListener2.java
@@ -71,8 +71,9 @@
 	public void testRunTerminated();
 		
 	/**
-	 * Information about a member of the test suite that is about to be run. The
-	 * format of the string is:
+	 * Information about a member of the test suite that is about to be run.
+	 * This method is part of the JUnit runner socket protocol. 
+	 * The format of the string is:
 	 * 
 	 * <pre>
 	 *  testId,testName,isSuite,testcount
@@ -92,6 +93,21 @@
 	public void testTreeEntry(String description);
 
 	/**
+	 * Information about a member of the test suite that is about to be run
+	 * (this method is not related to the JUnit runner socket protocol).
+	 * 
+	 * @param testId
+	 *            a unique id for the test
+	 * @param testName
+	 *            the name of the test
+	 * @param isSuite
+	 *            if the test is suite
+	 * @param testCount
+	 *            an integer indicating the number of tests
+	 */
+	public void testTreeEntry(String testId, String testName, boolean isSuite, int testCount);
+
+	/**
 	 * An individual test has failed with a stack trace.
 	 * 
 	 * @param status the outcome of the test; one of
@@ -100,8 +116,8 @@
 	 * @param testId a unique Id identifying the test
 	 * @param testName the name of the test that failed
 	 * @param trace the stack trace
-	 * @param expected the expected value
-	 * @param actual the actual value
+	 * @param expected the expected value or empty string/null if none
+	 * @param actual the actual value or empty string/null if none
 	 */
 	public void testFailed(int status, String testId, String testName, String trace, String expected, String actual, int failedCode);
 
@@ -117,9 +133,9 @@
 	 * @param trace the stack trace in the case of abnormal termination, or the
 	 *        empty string if none
 	 * @param expected the expected value in case of abnormal termination, or
-	 *        the empty string if none
+	 *        the empty string/null if none
 	 * @param actual the actual value in case of abnormal termination, or the
-	 *        empty string if none
+	 *        empty string/null if none
 	 */
 	public void testReran(String testId, String testClass, String testName, int status, String trace, String expected, String actual);
 	
diff --git a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
index 42737f5..649c3af 100755
--- a/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
+++ b/core/plugins/org.eclipse.dltk.testing/src/org/eclipse/dltk/internal/testing/model/TestRunSession.java
@@ -583,6 +583,11 @@
 		
 		int testCount= Integer.parseInt(treeEntry.substring(index2 + 1));
 		
+		return addTreeEntry(id, testName, isSuite, testCount);
+	}
+
+	private TestElement addTreeEntry(String id, String testName,
+			boolean isSuite, int testCount) {
 		if (isSuite && testCount > 1) {
 			adjustTotalCount(fStartedCount + testCount);
 		}
@@ -711,6 +716,17 @@
 				((ITestSessionListener) listeners[i]).testAdded(testElement);
 			}
 		}
+
+		public void testTreeEntry(String testId, String testName,
+				boolean isSuite, int testCount) {
+			TestElement testElement = addTreeEntry(testId, testName, isSuite,
+					testCount);
+
+			Object[] listeners = fSessionListeners.getListeners();
+			for (int i = 0; i < listeners.length; ++i) {
+				((ITestSessionListener) listeners[i]).testAdded(testElement);
+			}
+		}
 	
 		private TestElement createUnrootedTestElement(String testId, String testName) {
 			TestSuiteElement unrootedSuite= getUnrootedSuite();
@@ -808,13 +824,14 @@
 		}
 
 		private String nullifyEmpty(String string) {
-			int length= string.length();
-			if (length == 0)
-				return null;
-			else if (string.charAt(length - 1) == '\n')
-				return string.substring(0, length - 1);
-			else
-				return string;
+			if (string != null) {
+				int length = string.length();
+				if (length == 0)
+					return null;
+				else if (string.charAt(length - 1) == '\n')
+					return string.substring(0, length - 1);
+			}
+			return string;
 		}
 	
 		public void testReran(String testId, String testClass, String testName, int status, String trace) {