JUnitReports now include the stack trace in case of failure.

Also fix for base classes.
diff --git a/src/main/java/org/testng/reporters/JUnitReportReporter.java b/src/main/java/org/testng/reporters/JUnitReportReporter.java
index b32f33e..a26ceb4 100644
--- a/src/main/java/org/testng/reporters/JUnitReportReporter.java
+++ b/src/main/java/org/testng/reporters/JUnitReportReporter.java
@@ -12,6 +12,8 @@
 import org.testng.xml.XmlSuite;
 
 import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Calendar;
@@ -46,25 +48,40 @@
       Date timeStamp = Calendar.getInstance().getTime();
       p1.setProperty(XMLConstants.ATTR_TIMESTAMP, timeStamp.toGMTString());
 
-      List<Properties> testCases = Lists.newArrayList();
+      List<TestTag> testCases = Lists.newArrayList();
       int failures = 0;
+      int errors = 0;
       int testCount = 0;
       int totalTime = 0;
 
       for (ITestResult tr: entry.getValue()) {
+        TestTag testTag = new TestTag();
+
         if (tr.getStatus() != ITestResult.SUCCESS) failures++;
         Properties p2 = new Properties();
         p2.setProperty("classname", tr.getMethod().getMethod().getDeclaringClass().getName());
         p2.setProperty("name", tr.getMethod().getMethodName());
         long time = tr.getEndMillis() - tr.getStartMillis();
         p2.setProperty("time", "" + time);
+        Throwable t = tr.getThrowable();
+        if (t != null) {
+          t.fillInStackTrace();
+          StringWriter sw = new StringWriter();
+          PrintWriter pw = new PrintWriter(sw);
+          t.printStackTrace(pw);
+          testTag.message = t.getMessage();
+          testTag.type = t.getClass().getName();
+          testTag.stackTrace = sw.toString();
+          errors++;
+        }
         totalTime += time;
         testCount++;
-        testCases.add(p2);
+        testTag.properties = p2;
+        testCases.add(testTag);
       }
 
       p1.setProperty("failures", "" + failures);
-      p1.setProperty("errors", "" + 0);
+      p1.setProperty("errors", "" + errors);
       p1.setProperty("name", cls.getName());
       p1.setProperty("tests", "" + testCount);
       p1.setProperty("time", "" + totalTime);
@@ -82,8 +99,20 @@
       xsb.addComment("Generated by " + getClass().getName());
 
       xsb.push("testsuite", p1);
-      for (Properties p : testCases) {
-        xsb.addEmptyElement("testcase", p);
+      for (TestTag testTag : testCases) {
+        if (testTag.stackTrace == null) xsb.addEmptyElement("testcase", testTag.properties);
+        else {
+          xsb.push("testcase", testTag.properties);
+
+          Properties p = new Properties();
+          p.setProperty("message", testTag.message);
+          p.setProperty("type", testTag.type);
+          xsb.push("error", p);
+          xsb.addCDATA(testTag.stackTrace);
+          xsb.pop("error");
+
+          xsb.pop("testcase");
+        }
       }
       xsb.pop("testsuite");
 
@@ -96,9 +125,16 @@
 
   }
 
+  class TestTag {
+    public Properties properties;
+    public String message;
+    public String type;
+    public String stackTrace;
+  }
+
   private void addResults(Set<ITestResult> allResults, Map<Class<?>, Set<ITestResult>> out) {
     for (ITestResult tr : allResults) {
-      Class<?> cls = tr.getMethod().getMethod().getDeclaringClass();
+      Class<?> cls = tr.getMethod().getTestClass().getRealClass();
       Set<ITestResult> l = out.get(cls);
       if (l == null) {
         l = Sets.newHashSet();