[maven-scm] copy for tag surefire-2.5

git-svn-id: https://svn.apache.org/repos/asf/maven/surefire/tags/surefire-2.5@898285 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
index 7e37b7a..a1ba58f 100644
--- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
+++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
@@ -19,10 +19,15 @@
  * under the License.
  */
 
+import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;               
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -52,6 +57,8 @@
 import org.apache.maven.surefire.booter.SurefireBooter;
 import org.apache.maven.surefire.booter.SurefireBooterForkException;
 import org.apache.maven.surefire.booter.SurefireExecutionException;
+import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
+import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Writer;
 import org.apache.maven.surefire.report.BriefConsoleReporter;
 import org.apache.maven.surefire.report.BriefFileReporter;
 import org.apache.maven.surefire.report.ConsoleReporter;
@@ -59,32 +66,10 @@
 import org.apache.maven.surefire.report.FileReporter;
 import org.apache.maven.surefire.report.ForkingConsoleReporter;
 import org.apache.maven.surefire.report.XMLReporter;
-import org.codehaus.plexus.util.StringUtils;
-import org.codehaus.plexus.util.ReaderFactory;
-import org.codehaus.plexus.util.FileUtils;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.FileOutputStream;
-import java.io.Writer;
-import java.io.OutputStreamWriter;
-import java.io.BufferedOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.apache.maven.execution.MavenSession;
 import org.apache.maven.toolchain.Toolchain;
 import org.apache.maven.toolchain.ToolchainManager;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Writer;
-import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.StringUtils;
 
 /**
  * Run integration tests using Surefire.
@@ -119,12 +104,11 @@
     private boolean skipITs;
 
     /**
-     * DEPRECATED This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
-     * Use -DskipTests instead; it's shorter.
+     * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
      *
      * @parameter expression="${maven.test.skip.exec}"
      * @since 2.3
-     * @deprecated
+     * @deprecated Use -DskipTests instead.
      */
     private boolean skipExec;
 
@@ -249,8 +233,9 @@
 
     /**
      * List of System properties to pass to the JUnit tests.
-     * @deprecated use systemPropertyVariables instead
+     *
      * @parameter
+     * @deprecated Use systemPropertyVariables instead.
      */
     private Properties systemProperties;
 
@@ -291,6 +276,7 @@
 
     /**
      * The summary file to write integration test results to.
+     *
      * @parameter expression="${project.build.directory}/failsafe-reports/failsafe-summary.xml"
      * @required
      */
@@ -468,19 +454,20 @@
     private String perCoreThreadCount;
 
     /**
-     * (junitcore only) Indicates that the thread pool will be unlimited. paralell setting and the actual number of classes/methods
-     * will decide. Setting this to true effectively disables perCoreThreadCount and  threadCount
+     * (junitcore only) Indicates that the thread pool will be unlimited. The parallel parameter and the actual number of classes/methods
+     * will decide. Setting this to true effectively disables perCoreThreadCount and threadCount.
      *
      * @parameter expression="${useUnlimitedThreads}"
      * @since 2.5
      */
     private String useUnlimitedThreads;
+
     /**
      * (TestNG only) When you use the parallel attribute, TestNG will try to run all your test methods in separate threads, except for
      * methods that depend on each other, which will be run in the same thread in order to respect their order of
      * execution.
-     *
-     * JUNIT4.6 Values are classes/methods/both to run in separate threads, as controlled by threadCount.
+     * <p/>
+     * In JUnit 4.7 the values are classes/methods/both to run in separate threads, as controlled by threadCount.
      *
      * @parameter expression="${parallel}"
      * @todo test how this works with forking, and console/file output parallelism
@@ -511,7 +498,7 @@
     private ArtifactFactory artifactFactory;
 
     /**
-     * The plugin remote repositories declared in the pom.
+     * The plugin remote repositories declared in the POM.
      *
      * @parameter expression="${project.pluginArtifactRepositories}"
      * @since 2.2
@@ -525,8 +512,6 @@
      */
     private ArtifactMetadataSource metadataSource;
 
-    
-    
     private static final String BRIEF_REPORT_FORMAT = "brief";
 
     private static final String PLAIN_REPORT_FORMAT = "plain";
@@ -557,12 +542,12 @@
     private Boolean useSystemClassLoader;
 
     /**
-     * By default, Surefire forks your tests using a manifest-only jar; set this parameter
+     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter
      * to "false" to force it to launch your tests with a plain old Java classpath.
      * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
-     * for a more detailed explanation of manifest-only jars and their benefits.)
-     *
-     * Default value is "true".  Beware, setting this to "false" may cause your tests to
+     * for a more detailed explanation of manifest-only JARs and their benefits.)
+     * <p/>
+     * Beware, setting this to "false" may cause your tests to
      * fail on Windows if your classpath is too long.
      *
      * @parameter expression="${failsafe.useManifestOnlyJar}" default-value="true"
@@ -603,10 +588,12 @@
      */
     protected String encoding;
 
-    /** @component */
+    /**
+     * @component
+     */
     private ToolchainManager toolchainManager;
-    
-    
+
+
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
@@ -619,7 +606,7 @@
             FailsafeSummary result = new FailsafeSummary();
             try
             {
-                result.setResult(surefireBooter.run());
+                result.setResult( surefireBooter.run() );
             }
             catch ( SurefireBooterForkException e )
             {
@@ -636,11 +623,13 @@
                 System.setProperties( originalSystemProperties );
             }
 
-            if (!summaryFile.getParentFile().isDirectory()) {
+            if ( !summaryFile.getParentFile().isDirectory() )
+            {
                 summaryFile.getParentFile().mkdirs();
             }
 
-            try {
+            try
+            {
                 String encoding;
                 if ( StringUtils.isEmpty( this.encoding ) )
                 {
@@ -648,19 +637,23 @@
                         "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                             + ", i.e. build is platform dependent!" );
                     encoding = ReaderFactory.FILE_ENCODING;
-                } else {
+                }
+                else
+                {
                     encoding = this.encoding;
                 }
 
                 FileOutputStream fileOutputStream = new FileOutputStream( summaryFile );
-                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( fileOutputStream);
+                BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( fileOutputStream );
                 Writer writer = new OutputStreamWriter( bufferedOutputStream, encoding );
                 FailsafeSummaryXpp3Writer xpp3Writer = new FailsafeSummaryXpp3Writer();
                 xpp3Writer.write( writer, result );
                 writer.close();
                 bufferedOutputStream.close();
                 fileOutputStream.close();
-            } catch ( IOException e ) {
+            }
+            catch ( IOException e )
+            {
                 throw new MojoExecutionException( e.getMessage(), e );
             }
         }
@@ -727,6 +720,11 @@
         }
     }
 
+    private boolean isAnyConcurrencySelected()
+    {
+        return this.parallel != null && this.parallel.trim().length() > 0;
+    }
+
     /**
      * Converts old TestNG configuration parameters over to new properties based configuration
      * method. (if any are defined the old way)
@@ -748,26 +746,34 @@
         }
         if ( this.perCoreThreadCount != null )
         {
-            properties.setProperty( "perCoreThreadCount", perCoreThreadCount);
+            properties.setProperty( "perCoreThreadCount", perCoreThreadCount );
         }
         if ( this.useUnlimitedThreads != null )
         {
-            properties.setProperty( "useUnlimitedThreads", useUnlimitedThreads);
+            properties.setProperty( "useUnlimitedThreads", useUnlimitedThreads );
         }
-        Artifact configurableParallelComputer = (Artifact) projectArtifactMap.get("org.jdogma.junit:configurable-parallel-computer");
-        properties.setProperty("configurableParallelComputerPresent", Boolean.toString(configurableParallelComputer != null));
+        Artifact configurableParallelComputer =
+            (Artifact) projectArtifactMap.get( "org.jdogma.junit:configurable-parallel-computer" );
+        properties.setProperty( "configurableParallelComputerPresent",
+                                Boolean.toString( configurableParallelComputer != null ) );
 
     }
 
-    private boolean isJunit47Compatible(Artifact artifact) throws MojoExecutionException {
-        return isWithinVersionSpec(artifact, "[4.7,)");
-    }
-    
-    private boolean isJunit40to46(Artifact artifact)  throws MojoExecutionException {
-        return isWithinVersionSpec(artifact, "[4.0,4.7)");
+    private boolean isJunit47Compatible( Artifact artifact )
+        throws MojoExecutionException
+    {
+        return isWithinVersionSpec( artifact, "[4.7,)" );
     }
 
-    private boolean isWithinVersionSpec(Artifact artifact, String versionSpec) throws MojoExecutionException {
+    private boolean isAnyJunit4( Artifact artifact )
+        throws MojoExecutionException
+    {
+        return isWithinVersionSpec( artifact, "[4.0,)" );
+    }
+
+    private boolean isWithinVersionSpec( Artifact artifact, String versionSpec )
+        throws MojoExecutionException
+    {
         if ( artifact == null )
         {
             return false;
@@ -827,11 +833,11 @@
             if ( testNgArtifact != null )
             {
                 VersionRange range = VersionRange.createFromVersionSpec( "[4.7,)" );
-                if ( !range.containsVersion( new DefaultArtifactVersion(testNgArtifact.getVersion()) ) )
+                if ( !range.containsVersion( new DefaultArtifactVersion( testNgArtifact.getVersion() ) ) )
                 {
                     throw new MojoFailureException(
-                                                    "TestNG support requires version 4.7 or above. You have declared version " +
-                                                        testNgArtifact.getVersion() );
+                        "TestNG support requires version 4.7 or above. You have declared version "
+                            + testNgArtifact.getVersion() );
                 }
 
                 convertTestNGParameters();
@@ -847,14 +853,17 @@
                 // different one since its based on the source level, not the JVM. Prune using the filter.
                 addProvider( surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact );
             }
-            else if ( junitArtifact != null && isJunit47Compatible( junitArtifact ) )
+            else if ( junitArtifact != null && isAnyJunit4( junitArtifact ) )
             {
-                convertJunitCoreParameters();
-                addProvider( surefireBooter, "surefire-junit47", surefireArtifact.getBaseVersion(), null );
-            }
-            else if ( junitArtifact != null && isJunit40to46( junitArtifact ) )
-            {
-                addProvider( surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null );
+                if ( isAnyConcurrencySelected() && isJunit47Compatible( junitArtifact ) )
+                {
+                    convertJunitCoreParameters();
+                    addProvider( surefireBooter, "surefire-junit47", surefireArtifact.getBaseVersion(), null );
+                }
+                else
+                {
+                    addProvider( surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null );
+                }
             }
             else
             {
@@ -865,8 +874,8 @@
         }
         catch ( ArtifactNotFoundException e )
         {
-            throw new MojoExecutionException( "Unable to locate required surefire provider dependency: " +
-                e.getMessage(), e );
+            throw new MojoExecutionException(
+                "Unable to locate required surefire provider dependency: " + e.getMessage(), e );
         }
         catch ( InvalidVersionSpecificationException e )
         {
@@ -885,8 +894,10 @@
             }
 
             // TODO: properties should be passed in here too
-            surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite", new Object[]{
-                suiteXmlFiles, testSourceDirectory.getAbsolutePath(), testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties, reportsDirectory} );
+            surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite",
+                                         new Object[]{suiteXmlFiles, testSourceDirectory.getAbsolutePath(),
+                                             testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties,
+                                             reportsDirectory} );
         }
         else
         {
@@ -933,8 +944,8 @@
                 // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
                 if ( includes == null || includes.size() == 0 )
                 {
-                    includes = new ArrayList( Arrays.asList( new String[]{"**/IT*.java", "**/*IT.java",
-                        "**/*ITCase.java"} ) );
+                    includes =
+                        new ArrayList( Arrays.asList( new String[]{"**/IT*.java", "**/*IT.java", "**/*ITCase.java"} ) );
                 }
                 if ( excludes == null || excludes.size() == 0 )
                 {
@@ -944,23 +955,24 @@
 
             if ( testNgArtifact != null )
             {
-                surefireBooter.addTestSuite("org.apache.maven.surefire.testng.TestNGDirectoryTestSuite", new Object[]{
-                        testClassesDirectory, includes, excludes, testSourceDirectory.getAbsolutePath(),
-                        testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties, reportsDirectory});
+                surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite",
+                                             new Object[]{testClassesDirectory, includes, excludes,
+                                                 testSourceDirectory.getAbsolutePath(), testNgArtifact.getVersion(),
+                                                 testNgArtifact.getClassifier(), properties, reportsDirectory} );
             }
             else
             {
                 String junitDirectoryTestSuite;
-                if ( isJunit47Compatible( junitArtifact ) )
+                if ( isAnyConcurrencySelected() && isJunit47Compatible( junitArtifact ) )
                 {
                     junitDirectoryTestSuite = "org.apache.maven.surefire.junitcore.JUnitCoreDirectoryTestSuite";
-                    getLog().warn( "Props are" + properties.toString() );
+                    getLog().info( "Concurrency config is " + properties.toString() );
                     surefireBooter.addTestSuite( junitDirectoryTestSuite,
                                                  new Object[]{testClassesDirectory, includes, excludes, properties} );
                 }
                 else
                 {
-                    if ( isJunit40to46( junitArtifact ) )
+                    if ( isAnyJunit4( junitArtifact ) )
                     {
                         junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
                     }
@@ -969,7 +981,6 @@
                         // fall back to JUnit, which also contains POJO support. Also it can run
                         // classes compiled against JUnit since it has a dependency on JUnit itself.
                         junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite";
-                        junitDirectoryTestSuite = "org.apache.maven.surefire.junit.JUnitDirectoryTestSuite";
                     }
                     surefireBooter.addTestSuite( junitDirectoryTestSuite,
                                                  new Object[]{testClassesDirectory, includes, excludes} );
@@ -983,8 +994,8 @@
 
         // Check if we need to add configured classes/test classes directories here.
         // If they are configured, we should remove the default to avoid conflicts.
-        File projectClassesDirectory = new File ( project.getBuild().getOutputDirectory() );
-        if ( ! projectClassesDirectory.equals( classesDirectory ) )
+        File projectClassesDirectory = new File( project.getBuild().getOutputDirectory() );
+        if ( !projectClassesDirectory.equals( classesDirectory ) )
         {
             int indexToReplace = classpathElements.indexOf( project.getBuild().getOutputDirectory() );
             if ( indexToReplace != -1 )
@@ -1080,7 +1091,8 @@
 
             if ( "true".equals( debugForkedProcess ) )
             {
-                debugForkedProcess = "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
+                debugForkedProcess =
+                    "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
             }
 
             fork.setDebugLine( debugForkedProcess );
@@ -1142,7 +1154,7 @@
 
         return surefireBooter;
     }
-    
+
     private void showMap( Map map, String setting )
     {
         for ( Iterator i = map.keySet().iterator(); i.hasNext(); )
@@ -1153,7 +1165,8 @@
         }
     }
 
-    private void addProvider( SurefireBooter surefireBooter, String provider, String version, Artifact filteredArtifact )
+    private void addProvider( SurefireBooter surefireBooter, String provider, String version,
+                              Artifact filteredArtifact )
         throws ArtifactNotFoundException, ArtifactResolutionException
     {
         Artifact providerArtifact = artifactFactory.createDependencyArtifact( "org.apache.maven.surefire", provider,
@@ -1177,9 +1190,8 @@
         ArtifactFilter filter = null;
         if ( filteredArtifact != null )
         {
-            filter =
-                new ExcludesArtifactFilter( Collections.singletonList( filteredArtifact.getGroupId() + ":" +
-                    filteredArtifact.getArtifactId() ) );
+            filter = new ExcludesArtifactFilter(
+                Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) );
         }
 
         Artifact originatingArtifact = artifactFactory.createBuildArtifact( "dummy", "dummy", "1.0", "jar" );
@@ -1263,9 +1275,9 @@
     }
 
     /**
-     * <p>
+     * <p/>
      * Adds Reporters that will generate reports with different formatting.
-     * <p>
+     * <p/>
      * The Reporter that will be added will be based on the value of the parameter useFile, reportFormat, and
      * printSummary.
      *
@@ -1281,40 +1293,40 @@
             {
                 if ( forking )
                 {
-                    surefireBooter.addReport( ForkingConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                    surefireBooter.addReport( ForkingConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
                 }
                 else
                 {
-                    surefireBooter.addReport( ConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                    surefireBooter.addReport( ConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
                 }
             }
 
             if ( BRIEF_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( BriefFileReporter.class.getName(), new Object[] { reportsDirectory,
-                    trimStackTrace } );
+                surefireBooter.addReport( BriefFileReporter.class.getName(),
+                                          new Object[]{reportsDirectory, trimStackTrace} );
             }
             else if ( PLAIN_REPORT_FORMAT.equals( reportFormat ) )
             {
                 surefireBooter.addReport( FileReporter.class.getName(),
-                                          new Object[] { reportsDirectory, trimStackTrace } );
+                                          new Object[]{reportsDirectory, trimStackTrace} );
             }
         }
         else
         {
             if ( BRIEF_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( BriefConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                surefireBooter.addReport( BriefConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
             }
             else if ( PLAIN_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( DetailedConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                surefireBooter.addReport( DetailedConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
             }
         }
 
         if ( !disableXmlReport )
         {
-            surefireBooter.addReport( XMLReporter.class.getName(), new Object[] { reportsDirectory, trimStackTrace } );
+            surefireBooter.addReport( XMLReporter.class.getName(), new Object[]{reportsDirectory, trimStackTrace} );
         }
     }
 
@@ -1334,17 +1346,15 @@
         this.skipTests = skipExec;
     }
 
-    //TODO remove the part with ToolchainManager lookup once we depend on
-    //2.0.9 (have it as prerequisite). Define as regular component field then.
     private Toolchain getToolchain()
     {
         Toolchain tc = null;
-        
+
         if ( toolchainManager != null )
         {
             tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
         }
-        
+
         return tc;
     }
 }
diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
index e96ba4c..432af15 100644
--- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
+++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/VerifyMojo.java
@@ -19,67 +19,23 @@
  * under the License.
  */
 
+import java.io.BufferedInputStream;
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.factory.ArtifactFactory;
-import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
-import org.apache.maven.artifact.resolver.ArtifactResolutionException;
-import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
-import org.apache.maven.artifact.resolver.ArtifactResolver;
-import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
-import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
-import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
-import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
-import org.apache.maven.artifact.versioning.VersionRange;
-import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.ArtifactResolver;
-import org.apache.maven.artifact.factory.ArtifactFactory;
-import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.surefire.booter.ForkConfiguration;
 import org.apache.maven.surefire.booter.SurefireBooter;
-import org.apache.maven.surefire.booter.SurefireBooterForkException;
-import org.apache.maven.surefire.booter.SurefireExecutionException;
-import org.apache.maven.surefire.report.BriefConsoleReporter;
-import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Writer;
-import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Reader;
 import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
-import org.codehaus.plexus.util.StringUtils;
+import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Reader;
 import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.BufferedOutputStream;
-import java.io.Writer;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.BufferedInputStream;
-import java.io.Reader;
-import java.io.InputStreamReader;
-import java.util.List;
-import java.util.Properties;
-import java.util.Map;
-import java.util.HashMap;
-
 /**
  * Verify integration tests ran using Surefire.
  *
@@ -112,12 +68,11 @@
     private boolean skipITs;
 
     /**
-     * DEPRECATED This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
-     * Use -DskipTests instead; it's shorter.
+     * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
      *
      * @parameter expression="${maven.test.skip.exec}"
      * @since 2.3
-     * @deprecated
+     * @deprecated Use -DskipTests instead.
      */
     private boolean skipExec;
 
@@ -171,7 +126,7 @@
     private File summaryFile;
 
     /**
-     * Set this to "true" to cause a failure if there are no tests to run. Defaults to false.
+     * Set this to "true" to cause a failure if there are no tests to run.
      *
      * @parameter expression="${failIfNoTests}"
      * @since 2.4
diff --git a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
index 4b40d12..c55aca5 100644
--- a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
+++ b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
@@ -39,7 +39,6 @@
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
-import org.apache.maven.artifact.versioning.ArtifactVersion;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
@@ -66,7 +65,7 @@
 
 /**
  * Run tests using Surefire.
- * 
+ *
  * @author Jason van Zyl
  * @version $Id$
  * @requiresDependencyResolution test
@@ -87,12 +86,11 @@
     private boolean skipTests;
 
     /**
-     * DEPRECATED This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
-     * Use -DskipTests instead; it's shorter.
+     * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
      *
-     * @deprecated
      * @parameter expression="${maven.test.skip.exec}"
      * @since 2.3
+     * @deprecated Use -DskipTests instead.
      */
     private boolean skipExec;
 
@@ -222,8 +220,9 @@
 
     /**
      * List of System properties to pass to the JUnit tests.
-     * @deprecated use systemPropertyVariables instead
+     *
      * @parameter
+     * @deprecated Use systemPropertyVariables instead.
      */
     private Properties systemProperties;
 
@@ -293,7 +292,7 @@
     private boolean redirectTestOutputToFile;
 
     /**
-     * Set this to "true" to cause a failure if there are no tests to run. Defaults to false.
+     * Set this to "true" to cause a failure if there are no tests to run.
      *
      * @parameter expression="${failIfNoTests}"
      * @since 2.4
@@ -434,19 +433,20 @@
     private String perCoreThreadCount;
 
     /**
-     * (junitcore only) Indicates that the thread pool will be unlimited. paralell setting and the actual number of classes/methods
-     * will decide. Setting this to true effectively disables perCoreThreadCount and  threadCount
+     * (junitcore only) Indicates that the thread pool will be unlimited. The parallel parameter and the actual number of classes/methods
+     * will decide. Setting this to true effectively disables perCoreThreadCount and threadCount.
      *
      * @parameter expression="${useUnlimitedThreads}"
      * @since 2.5
      */
     private String useUnlimitedThreads;
+
     /**
      * (TestNG only) When you use the parallel attribute, TestNG will try to run all your test methods in separate threads, except for
      * methods that depend on each other, which will be run in the same thread in order to respect their order of
      * execution.
-     *
-     * JUNIT4.6 Values are classes/methods/both to run in separate threads, as controlled by threadCount.
+     * <p/>
+     * In JUnit 4.7 the values are classes/methods/both to run in separate threads, as controlled by threadCount.
      *
      * @parameter expression="${parallel}"
      * @todo test how this works with forking, and console/file output parallelism
@@ -477,7 +477,7 @@
     private ArtifactFactory artifactFactory;
 
     /**
-     * The plugin remote repositories declared in the pom.
+     * The plugin remote repositories declared in the POM.
      *
      * @parameter expression="${project.pluginArtifactRepositories}"
      * @since 2.2
@@ -491,8 +491,6 @@
      */
     private ArtifactMetadataSource metadataSource;
 
-    
-    
     private static final String BRIEF_REPORT_FORMAT = "brief";
 
     private static final String PLAIN_REPORT_FORMAT = "plain";
@@ -523,12 +521,12 @@
     private Boolean useSystemClassLoader;
 
     /**
-     * By default, Surefire forks your tests using a manifest-only jar; set this parameter
+     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter
      * to "false" to force it to launch your tests with a plain old Java classpath.
      * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
-     * for a more detailed explanation of manifest-only jars and their benefits.)
-     *
-     * Default value is "true".  Beware, setting this to "false" may cause your tests to
+     * for a more detailed explanation of manifest-only JARs and their benefits.)
+     * <p/>
+     * Beware, setting this to "false" may cause your tests to
      * fail on Windows if your classpath is too long.
      *
      * @parameter expression="${surefire.useManifestOnlyJar}" default-value="true"
@@ -562,10 +560,12 @@
      */
     private String objectFactory;
 
-    /** @component */
+    /**
+     * @component
+     */
     private ToolchainManager toolchainManager;
-    
-    
+
+
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
@@ -595,18 +595,28 @@
                 System.setProperties( originalSystemProperties );
             }
 
-            if ( result == 0 ) return;
+            if ( result == 0 )
+            {
+                return;
+            }
 
             String msg;
 
             if ( result == SurefireBooter.NO_TESTS_EXIT_CODE )
             {
-                if ( ( failIfNoTests == null ) || !failIfNoTests.booleanValue() ) return;
+                if ( ( failIfNoTests == null ) || !failIfNoTests.booleanValue() )
+                {
+                    return;
+                }
                 // TODO: i18n
-                throw new MojoFailureException( "No tests were executed!  (Set -DfailIfNoTests=false to ignore this error.)" );
-            } else {
+                throw new MojoFailureException(
+                    "No tests were executed!  (Set -DfailIfNoTests=false to ignore this error.)" );
+            }
+            else
+            {
                 // TODO: i18n
-                msg = "There are test failures.\n\nPlease refer to " + reportsDirectory + " for the individual test results.";
+                msg = "There are test failures.\n\nPlease refer to " + reportsDirectory
+                    + " for the individual test results.";
 
             }
 
@@ -682,6 +692,11 @@
         }
     }
 
+    private boolean isAnyConcurrencySelected()
+    {
+        return this.parallel != null && this.parallel.trim().length() > 0;
+    }
+
     /**
      * Converts old TestNG configuration parameters over to new properties based configuration
      * method. (if any are defined the old way)
@@ -703,26 +718,34 @@
         }
         if ( this.perCoreThreadCount != null )
         {
-            properties.setProperty( "perCoreThreadCount", perCoreThreadCount);
+            properties.setProperty( "perCoreThreadCount", perCoreThreadCount );
         }
         if ( this.useUnlimitedThreads != null )
         {
-            properties.setProperty( "useUnlimitedThreads", useUnlimitedThreads);
+            properties.setProperty( "useUnlimitedThreads", useUnlimitedThreads );
         }
-        Artifact configurableParallelComputer = (Artifact) projectArtifactMap.get("org.jdogma.junit:configurable-parallel-computer");
-        properties.setProperty("configurableParallelComputerPresent", Boolean.toString(configurableParallelComputer != null));
+        Artifact configurableParallelComputer =
+            (Artifact) projectArtifactMap.get( "org.jdogma.junit:configurable-parallel-computer" );
+        properties.setProperty( "configurableParallelComputerPresent",
+                                Boolean.toString( configurableParallelComputer != null ) );
 
     }
 
-    private boolean isJunit47Compatible(Artifact artifact) throws MojoExecutionException {
-        return isWithinVersionSpec(artifact, "[4.7,)");
-    }
-    
-    private boolean isJunit40to46(Artifact artifact)  throws MojoExecutionException {
-        return isWithinVersionSpec(artifact, "[4.0,4.7)");
+    private boolean isJunit47Compatible( Artifact artifact )
+        throws MojoExecutionException
+    {
+        return isWithinVersionSpec( artifact, "[4.7,)" );
     }
 
-    private boolean isWithinVersionSpec(Artifact artifact, String versionSpec) throws MojoExecutionException {
+    private boolean isAnyJunit4( Artifact artifact )
+        throws MojoExecutionException
+    {
+        return isWithinVersionSpec( artifact, "[4.0,)" );
+    }
+
+    private boolean isWithinVersionSpec( Artifact artifact, String versionSpec )
+        throws MojoExecutionException
+    {
         if ( artifact == null )
         {
             return false;
@@ -782,11 +805,11 @@
             if ( testNgArtifact != null )
             {
                 VersionRange range = VersionRange.createFromVersionSpec( "[4.7,)" );
-                if ( !range.containsVersion( new DefaultArtifactVersion(testNgArtifact.getVersion()) ) )
+                if ( !range.containsVersion( new DefaultArtifactVersion( testNgArtifact.getVersion() ) ) )
                 {
                     throw new MojoFailureException(
-                                                    "TestNG support requires version 4.7 or above. You have declared version " +
-                                                        testNgArtifact.getVersion() );
+                        "TestNG support requires version 4.7 or above. You have declared version "
+                            + testNgArtifact.getVersion() );
                 }
 
                 convertTestNGParameters();
@@ -802,14 +825,17 @@
                 // different one since its based on the source level, not the JVM. Prune using the filter.
                 addProvider( surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact );
             }
-            else if ( junitArtifact != null && isJunit47Compatible( junitArtifact ) )
+            else if ( junitArtifact != null && isAnyJunit4( junitArtifact ) )
             {
-                convertJunitCoreParameters();
-                addProvider( surefireBooter, "surefire-junit47", surefireArtifact.getBaseVersion(), null );
-            }
-            else if ( junitArtifact != null && isJunit40to46( junitArtifact ) )
-            {
-                addProvider( surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null );
+                if ( isAnyConcurrencySelected() && isJunit47Compatible( junitArtifact ) )
+                {
+                    convertJunitCoreParameters();
+                    addProvider( surefireBooter, "surefire-junit47", surefireArtifact.getBaseVersion(), null );
+                }
+                else
+                {
+                    addProvider( surefireBooter, "surefire-junit4", surefireArtifact.getBaseVersion(), null );
+                }
             }
             else
             {
@@ -820,8 +846,8 @@
         }
         catch ( ArtifactNotFoundException e )
         {
-            throw new MojoExecutionException( "Unable to locate required surefire provider dependency: " +
-                e.getMessage(), e );
+            throw new MojoExecutionException(
+                "Unable to locate required surefire provider dependency: " + e.getMessage(), e );
         }
         catch ( InvalidVersionSpecificationException e )
         {
@@ -840,8 +866,10 @@
             }
 
             // TODO: properties should be passed in here too
-            surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite", new Object[]{
-                suiteXmlFiles, testSourceDirectory.getAbsolutePath(), testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties, reportsDirectory} );
+            surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite",
+                                         new Object[]{suiteXmlFiles, testSourceDirectory.getAbsolutePath(),
+                                             testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties,
+                                             reportsDirectory} );
         }
         else
         {
@@ -888,36 +916,35 @@
                 // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
                 if ( includes == null || includes.size() == 0 )
                 {
-                    includes =
-                        new ArrayList( Arrays.asList( new String[] { "**/Test*.java", "**/*Test.java",
-                            "**/*TestCase.java" } ) );
+                    includes = new ArrayList(
+                        Arrays.asList( new String[]{"**/Test*.java", "**/*Test.java", "**/*TestCase.java"} ) );
                 }
                 if ( excludes == null || excludes.size() == 0 )
                 {
-                    excludes =
-                        new ArrayList( Arrays.asList( new String[] { "**/*$*" } ) );
+                    excludes = new ArrayList( Arrays.asList( new String[]{"**/*$*"} ) );
                 }
             }
 
             if ( testNgArtifact != null )
             {
-                surefireBooter.addTestSuite("org.apache.maven.surefire.testng.TestNGDirectoryTestSuite", new Object[]{
-                        testClassesDirectory, includes, excludes, testSourceDirectory.getAbsolutePath(),
-                        testNgArtifact.getVersion(), testNgArtifact.getClassifier(), properties, reportsDirectory});
+                surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite",
+                                             new Object[]{testClassesDirectory, includes, excludes,
+                                                 testSourceDirectory.getAbsolutePath(), testNgArtifact.getVersion(),
+                                                 testNgArtifact.getClassifier(), properties, reportsDirectory} );
             }
             else
             {
                 String junitDirectoryTestSuite;
-                if ( isJunit47Compatible( junitArtifact ) )
+                if ( isAnyConcurrencySelected() && isJunit47Compatible( junitArtifact ) )
                 {
                     junitDirectoryTestSuite = "org.apache.maven.surefire.junitcore.JUnitCoreDirectoryTestSuite";
-                    getLog().warn( "Props are" + properties.toString() );
+                    getLog().info( "Concurrency config is " + properties.toString() );
                     surefireBooter.addTestSuite( junitDirectoryTestSuite,
                                                  new Object[]{testClassesDirectory, includes, excludes, properties} );
                 }
                 else
                 {
-                    if ( isJunit40to46( junitArtifact ) )
+                    if ( isAnyJunit4( junitArtifact ) )
                     {
                         junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
                     }
@@ -939,8 +966,8 @@
 
         // Check if we need to add configured classes/test classes directories here.
         // If they are configured, we should remove the default to avoid conflicts.
-        File projectClassesDirectory = new File ( project.getBuild().getOutputDirectory() );
-        if ( ! projectClassesDirectory.equals( classesDirectory ) )
+        File projectClassesDirectory = new File( project.getBuild().getOutputDirectory() );
+        if ( !projectClassesDirectory.equals( classesDirectory ) )
         {
             int indexToReplace = classpathElements.indexOf( project.getBuild().getOutputDirectory() );
             if ( indexToReplace != -1 )
@@ -1036,7 +1063,8 @@
 
             if ( "true".equals( debugForkedProcess ) )
             {
-                debugForkedProcess = "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
+                debugForkedProcess =
+                    "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
             }
 
             fork.setDebugLine( debugForkedProcess );
@@ -1098,7 +1126,7 @@
 
         return surefireBooter;
     }
-    
+
     private void showMap( Map map, String setting )
     {
         for ( Iterator i = map.keySet().iterator(); i.hasNext(); )
@@ -1109,7 +1137,8 @@
         }
     }
 
-    private void addProvider( SurefireBooter surefireBooter, String provider, String version, Artifact filteredArtifact )
+    private void addProvider( SurefireBooter surefireBooter, String provider, String version,
+                              Artifact filteredArtifact )
         throws ArtifactNotFoundException, ArtifactResolutionException
     {
         Artifact providerArtifact = artifactFactory.createDependencyArtifact( "org.apache.maven.surefire", provider,
@@ -1133,9 +1162,8 @@
         ArtifactFilter filter = null;
         if ( filteredArtifact != null )
         {
-            filter =
-                new ExcludesArtifactFilter( Collections.singletonList( filteredArtifact.getGroupId() + ":" +
-                    filteredArtifact.getArtifactId() ) );
+            filter = new ExcludesArtifactFilter(
+                Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) );
         }
 
         Artifact originatingArtifact = artifactFactory.createBuildArtifact( "dummy", "dummy", "1.0", "jar" );
@@ -1219,9 +1247,9 @@
     }
 
     /**
-     * <p>
+     * <p/>
      * Adds Reporters that will generate reports with different formatting.
-     * <p>
+     * <p/>
      * The Reporter that will be added will be based on the value of the parameter useFile, reportFormat, and
      * printSummary.
      *
@@ -1237,40 +1265,40 @@
             {
                 if ( forking )
                 {
-                    surefireBooter.addReport( ForkingConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                    surefireBooter.addReport( ForkingConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
                 }
                 else
                 {
-                    surefireBooter.addReport( ConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                    surefireBooter.addReport( ConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
                 }
             }
 
             if ( BRIEF_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( BriefFileReporter.class.getName(), new Object[] { reportsDirectory,
-                    trimStackTrace } );
+                surefireBooter.addReport( BriefFileReporter.class.getName(),
+                                          new Object[]{reportsDirectory, trimStackTrace} );
             }
             else if ( PLAIN_REPORT_FORMAT.equals( reportFormat ) )
             {
                 surefireBooter.addReport( FileReporter.class.getName(),
-                                          new Object[] { reportsDirectory, trimStackTrace } );
+                                          new Object[]{reportsDirectory, trimStackTrace} );
             }
         }
         else
         {
             if ( BRIEF_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( BriefConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                surefireBooter.addReport( BriefConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
             }
             else if ( PLAIN_REPORT_FORMAT.equals( reportFormat ) )
             {
-                surefireBooter.addReport( DetailedConsoleReporter.class.getName(), new Object[] { trimStackTrace } );
+                surefireBooter.addReport( DetailedConsoleReporter.class.getName(), new Object[]{trimStackTrace} );
             }
         }
 
         if ( !disableXmlReport )
         {
-            surefireBooter.addReport( XMLReporter.class.getName(), new Object[] { reportsDirectory, trimStackTrace } );
+            surefireBooter.addReport( XMLReporter.class.getName(), new Object[]{reportsDirectory, trimStackTrace} );
         }
     }
 
@@ -1290,17 +1318,15 @@
         this.skipTests = skipExec;
     }
 
-    //TODO remove the part with ToolchainManager lookup once we depend on
-    //2.0.9 (have it as prerequisite). Define as regular component field then.
     private Toolchain getToolchain()
     {
         Toolchain tc = null;
-        
+
         if ( toolchainManager != null )
         {
             tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
         }
-        
+
         return tc;
     }
 }
diff --git a/maven-surefire-plugin/src/site/apt/examples/additional-classpath.apt.vm b/maven-surefire-plugin/src/site/apt/examples/additional-classpath.apt.vm
index f072a92..43f2698 100644
--- a/maven-surefire-plugin/src/site/apt/examples/additional-classpath.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/additional-classpath.apt.vm
@@ -3,18 +3,18 @@
   ------
   Pascal Lambert
   ------
-  March 2008
+  2010-01-09
   ------
 
 Additional Classpath Elements
 
-  If you need to put more stuff in your classpath when Surefire executes (e.g some funky resources or a container special jar),
+  If you need to put more stuff in your classpath when Surefire executes (e.g some funky resources or a container specific JAR),
   we normally recommend you add it to your classpath as a dependency.  Consider deploying shared jars to a private remote repository for your
   organization.
-  
+
   But, if you must, you can use the <<<additionalClasspathElements>>> element to add custom resources/jars to your classpath.
-  This will be treated as an absolute file system path, so you may want use ${basedir} or another property combined with a relative path.
-  Note that additional classpath elements are added to the end of the classpath, so you cannot use these to 
+  This will be treated as an absolute file system path, so you may want use $\{basedir\} or another property combined with a relative path.
+  Note that additional classpath elements are added to the end of the classpath, so you cannot use these to
   override project dependencies or resources.
 
 +---+
diff --git a/maven-surefire-plugin/src/site/apt/examples/class-loading.apt.vm b/maven-surefire-plugin/src/site/apt/examples/class-loading.apt.vm
index ad66480..e786354 100644
--- a/maven-surefire-plugin/src/site/apt/examples/class-loading.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/class-loading.apt.vm
@@ -3,7 +3,7 @@
   ------
   Dan Fabulich
   ------
-  May 2008
+  2010-01-09
   ------
 
 Classloading and Forking in Maven Surefire
@@ -13,7 +13,7 @@
 
 * Executive Summary
 
- If you're having problems, you'll probably want to tinker with these three settings: forkMode, useSystemClassLoader, and useManifestOnlyJar.
+ If you're having problems, you'll probably want to tinker with these three settings: <<<forkMode>>>, <<<useSystemClassLoader>>>, and <<<useManifestOnlyJar>>>.
 
 * What problem does Surefire solve?
 
@@ -30,7 +30,7 @@
  
 * How do people solve this problem in general?
 
- There are two "tricks" you can use to workaround this problem; both of them are can cause other problems in some cases.
+ There are two "tricks" you can use to workaround this problem; both of them can cause other problems in some cases.
 
  1. <<Isolated Classloader>>: One workaround is to use an isolated classloader.
  Instead of launching MyApp directly, we can launch some other app (a "booter")
@@ -41,18 +41,18 @@
  
  The problem with using an isolated classloader is that your classpath isn't
  <really> correct, and some apps can detect this and object. For example, the
- system property "java.class.path" won't include your jars; if your app notices
+ system property <<<java.class.path>>> won't include your jars; if your app notices
  this, it could cause a problem.
  
  There's another similar problem with using an isolated classloader: any class
- may call the static method ClassLoader.getSystemClassLoader() and attempt to
+ may call the static method <<<ClassLoader.getSystemClassLoader()>>> and attempt to
  load classes out of that classloader, instead of using the default classloader.
- Classes often do this if they need to create classloaders of their own....
+ Classes often do this if they need to create classloaders of their own.
  Unfortunately, Java-based web application servers like Jetty, Tomcat, BEA
  WebLogic and IBM WebSphere are very likely to try to escape the confines of an
  isolated classloader.
  
- 2. <<Manifest-Only Jar>>: Another workaround is to use a "manifest-only jar." In
+ 2. <<Manifest-Only JAR>>: Another workaround is to use a "manifest-only jar." In
  this case, you create a temporary jar that's almost completely empty, except for
  a META-INF/MANIFEST.MF file. Java manifests can contain attributes that the Java
  VM will honor as directives; for example, you can have a "Class-Path" attribute,
@@ -67,10 +67,10 @@
  thread context classloader and the default classloader are all the same; there's
  no possibility of "escaping" the classloader. But this is still a weird
  simulation of a "normal" classpath, and it's still possible for apps to notice
- this. Again, java.class.path may not be what you'd expect ("why does it contain
+ this. Again, <<<java.class.path>>> may not be what you'd expect ("why does it contain
  only one jar?"). Additionally, it's possible to query the system classloader to
  get the list of jars back out of it; your app may be confused if it finds only
- our booter.jar there!
+ our <<<booter.jar>>> there!
 
 * Advantages/Disadvantages of each solution
 
@@ -95,27 +95,27 @@
 * What does Surefire do?
 
  Surefire provides a mechanism for using multiple strategies.  The main parameter that
- determines this is called "useSystemClassLoader".  If useSystemClassLoader is
- true, then we use a manifest-only jar; otherwise, we use an isolated
+ determines this is called <<<useSystemClassLoader>>>.  If <<<useSystemClassLoader>>> is
+ <<<true>>>, then we use a manifest-only JAR; otherwise, we use an isolated
  classloader.  If you want to use a basic plain old Java classpath, you can set
- useManifestOnlyJar=false which only has an effect when useSystemClassLoader=true.
- 
- (The default value for useSystemClassLoader changed between Surefire 2.3 and
+ <<<useManifestOnlyJar=false>>> which only has an effect when <<<useSystemClassLoader=true>>>.
+
+ The default value for <<<useSystemClassLoader>>> changed between Surefire 2.3 and
  Surefire 2.4, which was a pretty significant change.  In Surefire 2.3,
- useSystemClassLoader was false by default, and we used an isolated classloader. 
- In Surefire 2.4, useSystemClassLoader is true by default.  No value works for
+ <<<useSystemClassLoader>>> was <<<false>>> by default, and we used an isolated classloader.
+ In Surefire 2.4, <<<useSystemClassLoader>>> is <<<true>>> by default.  No value works for
  everyone, but we think this default is an improvement; a bunch of
- hard-to-diagnose bugs get better when we useSystemClassLoader=true.)
- 
- Unfortunately, if useSystemClassLoader is set incorrectly for your app, you're going to
+ hard-to-diagnose bugs get better when we <<<useSystemClassLoader=true>>>.
+
+ Unfortunately, if <<<useSystemClassLoader>>> is set incorrectly for your app, you're going to
  have a problem on your hands that can be quite difficult to diagnose.  You might
  even be forced to read a long doc page like this one.  ;-)
- 
- If you're having problems loading classes, try setting useSystemClassLoader=false
+
+ If you're having problems loading classes, try setting <<<useSystemClassLoader=false>>>
  to see if that helps.  You can do that with the POM snippet below, or by setting
- "-Dsurefire.useSystemClassLoader=false".  If that doesn't work, try setting
- useSystemClassLoader back to true and setting useManifestOnlyJar to false.
- 
+ <<<-Dsurefire.useSystemClassLoader=false>>>.  If that doesn't work, try setting
+ <<<useSystemClassLoader>>> back to <<<true>>> and setting <<<useManifestOnlyJar>>> to <<<false>>>.
+
 +---+
 <project>
   [...]
@@ -141,8 +141,8 @@
 
  * Run mvn with --debug (aka -X) to get more detailed output
 
- * Check your forkMode.  If forkMode=never, it's impossible to use the system classloader or a plain old Java classpath; we have to use an isolated classloader.
+ * Check your <<<forkMode>>>.  If <<<forkMode=never>>>, it's impossible to use the system classloader or a plain old Java classpath; we have to use an isolated classloader.
 
- * If you're using the defaults, useSystemClassLoader=true and useManifestOnlyJar=false.  In that case, look at the generated manifest-only surefire booter jar.  Open it up (it's just a zip) and read its manifest.
+ * If you're using the defaults, <<<useSystemClassLoader=true>>> and <<<useManifestOnlyJar=false>>>.  In that case, look at the generated manifest-only Surefire booter JAR.  Open it up (it's just a zip) and read its manifest.
 
- * Run mvn with -Dmaven.surefire.debug, and attach to the running process with a debugger.
+ * Run mvn with <<<-Dmaven.surefire.debug>>>, and attach to the running process with a debugger.
diff --git a/maven-surefire-plugin/src/site/apt/examples/debugging.apt b/maven-surefire-plugin/src/site/apt/examples/debugging.apt
index 5cea253..e294d41 100644
--- a/maven-surefire-plugin/src/site/apt/examples/debugging.apt
+++ b/maven-surefire-plugin/src/site/apt/examples/debugging.apt
@@ -3,13 +3,13 @@
   ------
   Dan Fabulich
   ------
-  January 2008
+  2010-01-09
   ------
 
 Debugging Tests
 
   Sometimes you need to debug the tests exactly as Maven ran them.  Here's how!
-  
+
 Forked Tests
 
   By default, Maven runs your tests in a separate ("forked") process.  You can use the <<<maven.surefire.debug>>> property
@@ -23,7 +23,7 @@
   using Eclipse.  You can setup a "Remote Java Application" launch configuration via the menu
   command "Run" > "Open Debug Dialog..."
 
-  If you need to configure a different port, you may pass a more detailed value.  For example, the value below will use port 8000
+  If you need to configure a different port, you may pass a more detailed value.  For example, the command below will use port 8000
   instead of port 5005.
 
 +---+
@@ -40,7 +40,7 @@
 
   Then all you need to do is debug Maven itself.  Since Maven 2.0.8, Maven has shipped with a "mvnDebug" shell script that you can
   use to launch Maven with convenient debugging options:
-  
+
 +---+
 mvnDebug -DforkMode=never test
 +---+
diff --git a/maven-surefire-plugin/src/site/apt/examples/inclusion-exclusion.apt.vm b/maven-surefire-plugin/src/site/apt/examples/inclusion-exclusion.apt.vm
index 1b62fb1..1a070ec 100644
--- a/maven-surefire-plugin/src/site/apt/examples/inclusion-exclusion.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/inclusion-exclusion.apt.vm
@@ -3,7 +3,7 @@
   ------
   Allan Ramirez
   ------
-  July 2006
+  2010-01-09
   ------
 
 Inclusions and Exclusions of Tests
@@ -13,13 +13,13 @@
   By default, the Surefire Plugin will automatically include all test classes
   with the following wildcard patterns:
 
-   * <"**/Test*.java"> - includes all of its subdirectory and all java
+   * <"**/Test*.java"> - includes all of its subdirectories and all java
    filenames that start with "Test".
 
-   * <"**/*Test.java"> - includes all of its subdirectory and all java
+   * <"**/*Test.java"> - includes all of its subdirectories and all java
    filenames that end with "Test".
 
-   * <"**/*TestCase.java"> - includes all of its subdirectory and all java
+   * <"**/*TestCase.java"> - includes all of its subdirectories and all java
    filenames that end with "TestCase".
 
    []
@@ -75,4 +75,4 @@
   </build>
   [...]
 </project>
-+---+
\ No newline at end of file
++---+
diff --git a/maven-surefire-plugin/src/site/apt/examples/system-properties.apt.vm b/maven-surefire-plugin/src/site/apt/examples/system-properties.apt.vm
index b50226d..82d8dc3 100644
--- a/maven-surefire-plugin/src/site/apt/examples/system-properties.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/system-properties.apt.vm
@@ -4,17 +4,17 @@
   Allan Ramirez
   Dan Tran
   ------
-  July 2006
+  2010-01-09
   ------
 
 Using System Properties
 
   There are two ways to add a list of system properties to Surefire:
 
-* systemProperyVariable
+* systemPropertyVariables
 
-  This configuration is the replacement of the deprecated <systemProperies>.  It can accept any value
-  from Maven's properties that can be converted <<to String value>>
+  This configuration is the replacement of the deprecated <<<systemProperties>>>.  It can accept any value
+  from Maven's properties that can be converted <<to String value>>.
 
 +---+
 <project>
@@ -40,7 +40,7 @@
 +---+
 
 
-* systemProperties ( deprecated ) 
+* systemProperties ( deprecated )
 
 +---+
 <project>
@@ -67,10 +67,10 @@
 </project>
 +---+
 
-  Take note that <<String valued>> properties can only be passed as system
+  Take note that only <<String valued>> properties can be passed as system
   properties. Any attempt to pass any other Maven variable type (i.e. <<<List>>>
   or a <<<URL>>> variable) will cause the variable expression to be passed
-  literally (unevaluated). So having an example below:
+  literally (unevaluated). So having the example below:
 
 +---+
 <project>
diff --git a/maven-surefire-plugin/src/site/apt/examples/testng.apt.vm b/maven-surefire-plugin/src/site/apt/examples/testng.apt.vm
index b2ac67a..2a04d35 100644
--- a/maven-surefire-plugin/src/site/apt/examples/testng.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/testng.apt.vm
@@ -3,7 +3,7 @@
  ------
  Brett Porter <brett@apache.org>
  ------
- 2 May 2006
+ 2010-01-09
  ------
 
 Using TestNG
@@ -13,21 +13,21 @@
   To get started with TestNG, include the following dependency in your project:
 
 +---+
-[...]
-  <dependency>
-    <groupId>org.testng</groupId>
-    <artifactId>testng</artifactId>
-    <version>5.8</version>
-    <scope>test</scope>
-    <classifier>jdk15</classifier>
-  </dependency>
-[...]
+  [...]
+    <dependency>
+      <groupId>org.testng</groupId>
+      <artifactId>testng</artifactId>
+      <version>5.8</version>
+      <scope>test</scope>
+      <classifier>jdk15</classifier>
+    </dependency>
+  [...]
 +---+
 
-  <<Note:>> if you are using JDK 1.4 Javadoc annotations for your TestNG tests, replace jdk15 with jdk14 above.
+  <<Note:>> if you are using JDK 1.4 Javadoc annotations for your TestNG tests, replace the classifier <<<jdk15>>> with <<<jdk14>>> above.
 
   This is the only step that is required to get started - you can now create tests in your test source directory
-  (eg, <<<src/test/java>>>, and as long as they are named using the defaults such as *Test.java they will be run
+  (eg, <<<src/test/java>>>. As long as they are named using the defaults such as <<<*Test.java>>> they will be run
   by Surefire as TestNG tests.
 
   If you'd like to use a different naming scheme, you can change the <<<includes>>> parameter, as discussed in the
@@ -36,21 +36,21 @@
 * Using Suite XML Files
 
   Another alternative is to use TestNG suite XML files. This allows flexible configuration of the tests to be run.
-  These files are created as normal, and then added to the Surefire Plugin configuration:
+  These files are created in the normal way, and then added to the Surefire Plugin configuration:
 
 +---+
-[...]
-  <plugin>
-    <groupId>org.apache.maven.plugins</groupId>
-    <artifactId>maven-surefire-plugin</artifactId>
-    <version>${project.version}</version>
-    <configuration>
-      <suiteXmlFiles>
-        <suiteXmlFile>testng.xml</suiteXmlFile>
-      </suiteXmlFiles>
-    </configuration>
-  </plugin>
-[...]
+    [...]
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <suiteXmlFiles>
+            <suiteXmlFile>testng.xml</suiteXmlFile>
+          </suiteXmlFiles>
+        </configuration>
+      </plugin>
+    [...]
 +---+
 
   This configuration will override the includes and excludes patterns and run all tests in the suite files.
@@ -61,41 +61,38 @@
   into your TestNG test, by specifying them as system properties, like this:
 
 +---+
-[...]
-  <plugin>
-    <groupId>org.apache.maven.plugins</groupId>
-    <artifactId>maven-surefire-plugin</artifactId>
-    <version>${project.version}</version>
-    <configuration>
-      <systemProperties>
-        <property>
-          <name>browser</name>
-          <value>firefox</value>
-        </property>
-      </systemProperties>
-    </configuration>
-  </plugin>
-[...]
+    [...]
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <systemPropertyVariables>
+            <propertyName>firefox</propertyName>
+          </systemPropertyVariables>
+        </configuration>
+      </plugin>
+    [...]
 +---+
 
   For more information about setting system properties in Surefire tests, see {{{system-properties.html}System Properties}}.
 
 * Using Groups
 
-  TestNG allows you to group your tests. You can then execute a specific group or groups. To do this with Surefire,
+  TestNG allows you to group your tests. You can then execute one or more specific groups. To do this with Surefire,
   use the <<<groups>>> parameter, for example:
 
 +---+
-[...]
-  <plugin>
-    <groupId>org.apache.maven.plugins</groupId>
-    <artifactId>maven-surefire-plugin</artifactId>
-    <version>${project.version}</version>
-    <configuration>
-      <groups>functest,perftest</groups>
-    </configuration>
-  </plugin>
-[...]
+    [...]
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <groups>functest,perftest</groups>
+        </configuration>
+      </plugin>
+    [...]
 +---+
 
   Likewise, the <<<excludedGroups>>> parameter can be used to run all but a certain set of groups.
@@ -107,17 +104,17 @@
   For example:
 
 +---+
-[...]
-  <plugin>
-    <groupId>org.apache.maven.plugins</groupId>
-    <artifactId>maven-surefire-plugin</artifactId>
-    <version>${project.version}</version>
-    <configuration>
-      <parallel>methods</parallel>
-      <threadCount>10</threadCount>
-    </configuration>
-  </plugin>
-[...]
+    [...]
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <parallel>methods</parallel>
+          <threadCount>10</threadCount>
+        </configuration>
+      </plugin>
+    [...]
 +---+
 
   This is particularly useful for slow tests that can have high concurrency, or to quickly and roughly assess the independance
@@ -127,35 +124,33 @@
 
   TestNG provides support for attaching custom listeners, reporters, annotation transformers and method interceptors to your tests.
   By default, TestNG attaches a few basic listeners to generate HTML and XML reports.
-  
+
   You can configure multiple custom listeners like this:
 
 +---+
-[...]
-  <plugin>
-    <groupId>org.apache.maven.plugins</groupId>
-    <artifactId>maven-surefire-plugin</artifactId>
-    <version>${project.version}</version>
-    <configuration>
-      <properties>
-        <property>
-          <name>usedefaultlisteners</name>
-          <value>false</value> <!-- disabling default listeners is optional -->
-        </property>
-        <property>
-          <name>listener</name>
-          <value>com.mycompany.MyResultListener,com.mycompany.MyAnnotationTransformer,com.mycompany.MyMethodInterceptor</value>
-        </property>
-        <property>
-          <name>reporter</name>
-          <value>listenReport.Reporter</value>
-        </property>
-      </properties>
-    </configuration>
-  </plugin>
-[...]
+    [...]
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <properties>
+            <property>
+              <name>usedefaultlisteners</name>
+              <value>false</value> <!-- disabling default listeners is optional -->
+            </property>
+            <property>
+              <name>listener</name>
+              <value>com.mycompany.MyResultListener,com.mycompany.MyAnnotationTransformer,com.mycompany.MyMethodInterceptor</value>
+            </property>
+            <property>
+              <name>reporter</name>
+              <value>listenReport.Reporter</value>
+            </property>
+          </properties>
+        </configuration>
+      </plugin>
+    [...]
 +---+
 
   For more information on TestNG, see the {{{http://www.testng.org}TestNG web site}}.
-
-
diff --git a/maven-surefire-plugin/src/site/apt/usage.apt b/maven-surefire-plugin/src/site/apt/usage.apt
index ffb9992..2886eb1 100644
--- a/maven-surefire-plugin/src/site/apt/usage.apt
+++ b/maven-surefire-plugin/src/site/apt/usage.apt
@@ -4,7 +4,7 @@
   Brett Porter
   Allan Ramirez
   ------
-  July 2006
+  2010-01-09
   ------
 
 ~~ Licensed to the Apache Software Foundation (ASF) under one
@@ -53,7 +53,7 @@
 
   Note that any normal Surefire integration works identically no matter which
   providers are in use - so you can still produce a Cobertura report and a
-  Surefire results report on your project web site for your TestNG tests,
+  Surefire report on your project web site for your TestNG tests,
   for example.
 
   The POJO provider above allows you to write tests that do not depend on
diff --git a/maven-surefire-plugin/src/site/site.xml b/maven-surefire-plugin/src/site/site.xml
index 735eabe..87869e6 100644
--- a/maven-surefire-plugin/src/site/site.xml
+++ b/maven-surefire-plugin/src/site/site.xml
@@ -21,8 +21,7 @@
 
 <project xmlns="http://maven.apache.org/DECORATION/1.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd"
-  name="Maven Surefire plugin">
+  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
   <body>
     <menu name="Overview">
       <item name="Introduction" href="index.html"/>
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractSurefireIntegrationTestClass.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractSurefireIntegrationTestClass.java
index f25daa6..b508708 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractSurefireIntegrationTestClass.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractSurefireIntegrationTestClass.java
@@ -32,8 +32,13 @@
         goals.add( goal );
         if ( !verifier.getCliOptions().contains( "-s" ) )
         {
+            String settingsPath = System.getProperty( "maven.settings.file" ) + ".staged";
+            if ( settingsPath.indexOf( ' ' ) >= 0 )
+            {
+                settingsPath = '"' + settingsPath + '"';
+            }
             verifier.getCliOptions().add( "-s" );
-            verifier.getCliOptions().add( System.getProperty( "maven.settings.file" ) + ".staged" );
+            verifier.getCliOptions().add( settingsPath );
         }
         verifier.executeGoals( goals );
     }
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/ChekcTestNgVersionsIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgVersionsIT.java
similarity index 98%
rename from surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/ChekcTestNgVersionsIT.java
rename to surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgVersionsIT.java
index cfd829b..308b0a3 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/ChekcTestNgVersionsIT.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/CheckTestNgVersionsIT.java
@@ -13,7 +13,7 @@
  * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
  * 
  */
-public class ChekcTestNgVersionsIT
+public class CheckTestNgVersionsIT
     extends AbstractSurefireIntegrationTestClass
 {
     
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit47concurrencyIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit47concurrencyIT.java
new file mode 100755
index 0000000..352c55b
--- /dev/null
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit47concurrencyIT.java
@@ -0,0 +1,46 @@
+package org.apache.maven.surefire.its;
+
+
+import org.apache.maven.it.Verifier;
+import org.apache.maven.it.util.ResourceExtractor;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Basic suite test using all known versions of JUnit 4.x
+ *
+ * @author <a href="mailto:kristian.rosenvold@gmail.com">Kristian Rosenvold</a>
+ *
+ */
+public class Junit47concurrencyIT
+    extends AbstractSurefireIntegrationTestClass
+{
+
+
+    public void test47 () throws Exception
+    {
+        runJUnitTest();
+    }
+
+
+    public void runJUnitTest ()
+        throws Exception
+    {
+        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/concurrentjunit47" );
+
+        Verifier verifier = new Verifier( testDir.getAbsolutePath() );
+        List arguments = this.getInitialGoals();
+        arguments.add( "test" );
+        // DGF we have to pass in the version as a command line argument
+        // and NOT as a system property; otherwise our setting will be ignored
+        arguments.add( "-DjunitVersion=4.7");
+        verifier.executeGoals( arguments );
+
+        verifier.verifyErrorFreeLog();
+        verifier.resetStreams();
+
+        IntegrationTestSuiteResults suite = HelperAssertions.parseTestResults( new File[] { testDir } );
+        HelperAssertions.assertTestSuiteResults( 1, 0, 0, 0, suite );
+    }
+}
\ No newline at end of file
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit4VersionsIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit4VersionsIT.java
index b9ba6b5..1e79f77 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit4VersionsIT.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Junit4VersionsIT.java
@@ -46,6 +46,22 @@
     {
         runJUnitTest( "4.4" );
     }
+
+    public void test45 () throws Exception
+    {
+        runJUnitTest( "4.5" );
+    }
+
+    public void test46 () throws Exception
+    {
+        runJUnitTest( "4.6" );
+    }
+
+    public void test47 () throws Exception
+    {
+        runJUnitTest( "4.7" );
+    }
+
     
     public void runJUnitTest (String version)
         throws Exception
diff --git a/surefire-integration-tests/src/test/resources/concurrentjunit47/pom.xml b/surefire-integration-tests/src/test/resources/concurrentjunit47/pom.xml
new file mode 100755
index 0000000..bbc65d0
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/concurrentjunit47/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.plugins.surefire</groupId>
+  <artifactId>junit47</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <name>Test for JUnit 4.7</name>
+
+
+  <properties>
+    <junitVersion>4.7</junitVersion>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junitVersion}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>${surefire.version}</version>
+          <configuration>
+              <parallel>methods</parallel>
+              <threadCount>2</threadCount>
+          </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/surefire-integration-tests/src/test/resources/concurrentjunit47/src/test/java/junit47/BasicTest.java b/surefire-integration-tests/src/test/resources/concurrentjunit47/src/test/java/junit47/BasicTest.java
new file mode 100755
index 0000000..f4a4180
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/concurrentjunit47/src/test/java/junit47/BasicTest.java
@@ -0,0 +1,41 @@
+package concurrentjunit47.src.test.java.junit47;
+
+import org.junit.*;
+
+
+public class BasicTest
+{
+
+    private boolean setUpCalled = false;
+
+    private static boolean tearDownCalled = false;
+
+    @Before
+    public void setUp()
+    {
+        setUpCalled = true;
+        tearDownCalled = false;
+        System.out.println( "Called setUp" );
+    }
+
+    @After
+    public void tearDown()
+    {
+        setUpCalled = false;
+        tearDownCalled = true;
+        System.out.println( "Called tearDown" );
+    }
+
+    @Test
+    public void testSetUp()
+    {
+        Assert.assertTrue( "setUp was not called", setUpCalled );
+    }
+
+    @AfterClass
+    public static void oneTimeTearDown()
+    {
+
+    }
+
+}
\ No newline at end of file
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSet.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSet.java
index e1cd4db..f722e77 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSet.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSet.java
@@ -79,10 +79,8 @@
 
     public static void execute(Class[] classes, ReporterManager reportManager, JUnitCoreParameters jUnitCoreParameters)
             throws TestSetFailedException {
-        RunListener listener = new JUnitCoreTestSetReporter(reportManager);
-        if (jUnitCoreParameters.isAnyParallelitySelected()) {
-            listener = createRunListener(listener, jUnitCoreParameters.isConfigurableParallelComputerPresent());
-        }
+        RunListener realTarget = new JUnitCoreTestSetReporter(reportManager);
+        RunListener listener = createRunListener(realTarget, jUnitCoreParameters.isConfigurableParallelComputerPresent());
         Computer computer = getComputer(jUnitCoreParameters);
         try {
             runJunitCore(classes, computer, listener);
@@ -94,7 +92,9 @@
 
     private static RunListener createRunListener(RunListener realTarget, boolean configurableParallelComputerPresent)
             throws TestSetFailedException {
-        if (!configurableParallelComputerPresent) return new DemultiplexingRunListener(realTarget);
+        if (!configurableParallelComputerPresent) {
+            return new DemultiplexingRunListener(realTarget);
+        }
         try {
             Class<?> cpcClass = Class.forName(demuxerClassName);
             Constructor constructor = cpcClass.getConstructor(RunListener.class);
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSetReporter.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSetReporter.java
index feec1ff..fbb0408 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSetReporter.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreTestSetReporter.java
@@ -21,6 +21,8 @@
 
 
 import java.util.ResourceBundle;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.maven.surefire.Surefire;
 import org.apache.maven.surefire.report.ReportEntry;
@@ -33,10 +35,21 @@
 class JUnitCoreTestSetReporter
     extends RunListener
 {
+
+    private static final Pattern PARENS = Pattern.compile(
+            "^" +
+            "[^\\(\\)]+" + //non-parens
+            "\\((" + // then an open-paren (start matching a group)
+            "[^\\\\(\\\\)]+" + //non-parens
+            ")\\)" +
+            "$" ); // then a close-paren (end group match)
+
     // Constants
     private static ResourceBundle bundle = ResourceBundle.getBundle( Surefire.SUREFIRE_BUNDLE_NAME );
 
 
+    private Description currentRunStart;
+    private String currentClassName;
     private ReporterManager reportMgr;
 
     /**
@@ -63,8 +76,10 @@
         throws Exception
     {
         String rawString = bundle.getString( "testSetStarting" );
-        ReportEntry report = new ReportEntry( description.getClassName(), description.getDisplayName(), rawString );
+        currentClassName = extractClassName(description);
+        currentRunStart = description;
 
+        ReportEntry report = new ReportEntry( description.getClassName(), currentClassName, rawString );
         this.reportMgr.testSetStarting( report );
     }
 
@@ -77,7 +92,7 @@
         throws Exception
     {
         String rawString = bundle.getString( "testSetCompletedNormally" );
-        ReportEntry report = new ReportEntry( result.getClass().getCanonicalName(), result.getClass().getName(), rawString );
+        ReportEntry report = new ReportEntry( currentRunStart.getClassName(), currentClassName, rawString );
         this.reportMgr.testSetCompleted( report );
         this.reportMgr.reset();
     }
@@ -152,4 +167,13 @@
             this.reportMgr.testSucceeded( report );
         }
     }
+
+    private String extractClassName( Description description )
+    {
+        String displayName = description.getDisplayName();
+        Matcher m = PARENS.matcher( displayName );
+        if (!m.find()) return displayName;
+        return m.group( 1 );
+    }
+
 }