You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2015/03/26 01:15:52 UTC

[10/19] maven-surefire git commit: improved filters

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/FilterFactoryTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/FilterFactoryTest.java b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/FilterFactoryTest.java
index f44ee0a..91a00e3 100644
--- a/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/FilterFactoryTest.java
+++ b/surefire-providers/common-junit48/src/test/java/org/apache/maven/surefire/common/junit48/FilterFactoryTest.java
@@ -19,125 +19,591 @@ package org.apache.maven.surefire.common.junit48;
  * under the License.
  */
 
+import junit.framework.TestCase;
 import org.junit.Test;
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.runner.Computer;
 import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.Runner;
 import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.junit.runner.Description.createTestDescription;
 
 public class FilterFactoryTest
+    extends TestCase
 {
-    static class Suite
+    @RunWith( org.junit.runners.Suite.class )
+    @org.junit.runners.Suite.SuiteClasses( { FirstClass.class, SecondClass.class } )
+    static public class Suite
     {
 
     }
 
-    static class FirstClass
+    static public class FirstClass
     {
-
+        @Test
+        public void testMethod()
+        {
+            System.out.println( "FirstClass#testMethod" );
+        }
+
+        @Test
+        public void secondTestMethod()
+        {
+            System.out.println( "FirstClass#secondTestMethod" );
+        }
+
+        @Test
+        public void otherMethod()
+        {
+            System.out.println( "FirstClass#otherMethod" );
+        }
     }
 
-    static class SecondClass {
+    static public class SecondClass
+    {
+        @Test
+        public void testMethod()
+        {
+            System.out.println( "SecondClass#testMethod" );
+        }
+
+        @Test
+        public void secondTestMethod()
+        {
+            System.out.println( "SecondClass#secondTestMethod" );
+        }
+    }
 
+    static public class ThirdClass
+    {
+        @Test
+        public void testMethod()
+        {
+            System.out.println( "ThirdClass#testMethod" );
+        }
+
+        @Test
+        public void secondTestMethod()
+        {
+            System.out.println( "ThirdClass#secondTestMethod" );
+        }
     }
 
-    private final Description testMethod = createTestDescription( FirstClass.class, "testMethod" );
-    private final Description secondTestMethod = createTestDescription( FirstClass.class, "secondTestMethod" );
-    private final Description otherMethod = createTestDescription( FirstClass.class, "otherMethod" );
-    private final Description testMethodInSecondClass = createTestDescription( SecondClass.class, "testMethod" );
-    private final Description secondTestMethodInSecondClass = createTestDescription( SecondClass.class,
-            "secondTestMethod" );
+    private static final Description testMethod = createTestDescription( FirstClass.class, "testMethod" );
+
+    private static final Description secondTestMethod = createTestDescription( FirstClass.class, "secondTestMethod" );
+
+    private static final Description otherMethod = createTestDescription( FirstClass.class, "otherMethod" );
 
-    private final String firstClassName = FirstClass.class.getName();
-    private final String secondClassName = SecondClass.class.getName();
+    private static final Description testMethodInSecondClass = createTestDescription( SecondClass.class, "testMethod" );
+
+    private static final Description secondTestMethodInSecondClass =
+        createTestDescription( SecondClass.class, "secondTestMethod" );
+
+    private static final String firstClassName = FirstClass.class.getName();
+
+    private static final String secondClassName = SecondClass.class.getName();
 
     private Filter createMethodFilter( String requestString )
     {
         return new FilterFactory( getClass().getClassLoader() ).createMethodFilter( requestString );
     }
 
-    @Test
-    public void shouldMatchExactMethodName()
+    public void testBackwardsCompatibilityNullMethodFilter()
+    {
+        Filter filter = createMethodFilter( null );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityEmptyMethodFilter()
+    {
+        Filter filter = createMethodFilter( "" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityBlankMethodFilter()
     {
-        Filter exactFilter = createMethodFilter( "testMethod" );
+        Filter filter = createMethodFilter( "    \n" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityTestParameterClass() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityTestParameterJavaClass() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + ".java" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityTestParameterMethod1() {
+        Filter filter = createMethodFilter( FirstClass.class.getName().replace( '.', '/' ) + ".java#testMethod"  );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityTestParameterMethod2() {
+        Filter filter = createMethodFilter( FirstClass.class.getName().replace( '.', '/' ) + "#testMethod"  );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testBackwardsCompatibilityTestParameterMethod3() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#testMethod"  );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithWildcard() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithWildcardClass() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*.class]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithExactClass() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".class]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithWildcardJavaClassNegativeTest() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName().replace( '.', '/' ) + ".*.java]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class ).filterWith( filter ) );
+        assertFalse( result.wasSuccessful() );
+    }
+
+    public void testRegexWithTwoClasses() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndOneMethod() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#otherMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndOneMethodComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#otherMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 6, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndWildcardMethod() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#test*" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndWildcardMethodComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#test*" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndRegexMethod() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#%regex[test.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndRegexMethodComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#%regex[test.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndRegexMethods() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#%regex[test.*|other.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndRegexMethodsComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]#%regex[test.*|other.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 4, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndMultipleRegexMethods() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]"
+                                                + "#%regex[test.*]+%regex[other.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testRegexWithTwoClassesAndMultipleRegexMethodsComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*"
+                                                + "|" + SecondClass.class.getName() + ".*]"
+                                                + "#%regex[test.*]+%regex[other.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 4, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleRegexClasses() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*],"
+                                                + "%regex[" + SecondClass.class.getName() + ".*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleRegexClassesComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*],"
+                                                + "!%regex[" + SecondClass.class.getName() + ".*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClasses() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "," + SecondClass.class.getName() );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 5, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesMethods() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#other*,"
+                                                + SecondClass.class.getName() + "#*TestMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesAndMultipleMethodsWithWildcards() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#other*+second*Method,"
+                                                + SecondClass.class.getName() + "#*TestMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesAndMultipleMethodsWithRegex() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#%regex[other.*|second.*Method],"
+                                                + SecondClass.class.getName() + "#%regex[.*TestMethod]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesAndMultipleMethodsMix() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#%regex[other.*|second.*Method],"
+                                                + SecondClass.class.getName() + "#*TestMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesAndMultipleMethods() {
+        Filter filter = createMethodFilter( FirstClass.class.getName() + "#other*+secondTestMethod,"
+                                                + SecondClass.class.getName() + "#*TestMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleClassesComplement() {
+        Filter filter = createMethodFilter( "!" + FirstClass.class.getName() + ",!" + SecondClass.class.getName() );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleRegexClassesMethods() {
+        Filter filter = createMethodFilter( "%regex[" + FirstClass.class.getName() + ".*]#%regex[test.*]+%regex[other.*],"
+                                                + "%regex[" + SecondClass.class.getName() + ".*]#%regex[second.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 3, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testMultipleRegexClassesMethodsComplement() {
+        Filter filter = createMethodFilter( "!%regex[" + FirstClass.class.getName() + ".*]#%regex[test.*]+%regex[other.*],"
+                                                + "!%regex[" + SecondClass.class.getName() + ".*]#%regex[second.*]" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class, SecondClass.class, ThirdClass.class )
+                                      .filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 4, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testShouldMatchExactMethodName()
+    {
+        Filter exactFilter = createMethodFilter( "#testMethod" );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
     }
 
-    @Test
-    public void shouldMatchExactMethodNameWithHash()
+    public void testShouldMatchExactMethodNameComplement()
+    {
+        Filter exactFilter = createMethodFilter( "!#testMethod" );
+        assertFalse( "should not run testMethod", exactFilter.shouldRun( testMethod ) );
+        assertTrue( "should run other than testMethod", exactFilter.shouldRun( secondTestMethod ) );
+        assertFalse( "should not run testMethod", exactFilter.shouldRun( testMethodInSecondClass ) );
+        assertTrue( "should run other than testMethod", exactFilter.shouldRun( secondTestMethodInSecondClass ) );
+    }
+
+    public void testShouldMatchExactMethodNameWithHash()
     {
         Filter exactFilter = createMethodFilter( "#testMethod" );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
     }
 
-    @Test
-    public void shouldNotMatchExactOnOtherMethod()
+    public void testShouldNotRunExactMethodWithoutClass()
+    {
+        Filter exactFilter = createMethodFilter( "#testMethod" );
+        assertFalse( "should run containing matching method", exactFilter.shouldRun( secondTestMethod ) );
+    }
+
+    public void testShouldNotMatchExactOnOtherMethod()
     {
-        Filter exactFilter = createMethodFilter( "testMethod" );
+        Filter exactFilter = createMethodFilter( "#testMethod" );
         assertFalse( "should not run other methods", exactFilter.shouldRun( otherMethod ) );
     }
 
-    @Test
-    public void shouldMatchWildCardsInMethodName()
+    public void testShouldMatchWildCardsInMethodName()
     {
-        Filter starAtEnd = createMethodFilter( "test*" );
+        Filter starAtEnd = createMethodFilter( "#test*" );
         assertTrue( "match ending with star should run", starAtEnd.shouldRun( testMethod ) );
 
-        Filter starAtBeginning = createMethodFilter( "*Method" );
+        Filter starAtBeginning = createMethodFilter( "#*Method" );
         assertTrue( "match starting with star should run", starAtBeginning.shouldRun( testMethod ) );
 
-        Filter starInMiddle = createMethodFilter( "test*thod" );
+        Filter starInMiddle = createMethodFilter( "#test*thod" );
         assertTrue( "match containing star should run", starInMiddle.shouldRun( testMethod ) );
 
-        Filter questionAtEnd = createMethodFilter( "testMetho?" );
+        Filter questionAtEnd = createMethodFilter( "#testMetho?" );
         assertTrue( "match ending with question mark should run", questionAtEnd.shouldRun( testMethod ) );
 
-        Filter questionAtBeginning = createMethodFilter( "????Method" );
+        Filter questionAtBeginning = createMethodFilter( "#????Method" );
         assertTrue( "match starting with question mark should run", questionAtBeginning.shouldRun( testMethod ) );
 
-        Filter questionInMiddle = createMethodFilter( "testM?thod" );
+        Filter questionInMiddle = createMethodFilter( "#testM?thod" );
         assertTrue( "match containing question mark should run", questionInMiddle.shouldRun( testMethod ) );
 
-        Filter starAndQuestion = createMethodFilter( "t?st*thod" );
+        Filter starAndQuestion = createMethodFilter( "#t?st*thod" );
         assertTrue( "match containing star and question mark should run", starAndQuestion.shouldRun( testMethod ) );
     }
 
-    @Test
-    public void shouldMatchExactClassAndMethod()
+    public void testShouldMatchExactClassAndMethod()
     {
         Filter exactFilter = createMethodFilter( firstClassName + "#testMethod" );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
     }
 
-    @Test
-    public void shouldMatchSimpleClassNameWithMethod()
+    public void testShouldMatchSimpleClassNameWithMethod()
     {
         Filter exactFilter = createMethodFilter( "FilterFactoryTest$FirstClass#testMethod" );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
         assertFalse( "other method should not match", exactFilter.shouldRun( otherMethod ) );
     }
 
-    @Test
-    public void shouldMatchClassNameWithWildcardAndMethod()
+    public void testShouldMatchClassNameWithWildcardAndMethod()
     {
         Filter exactFilter = createMethodFilter( "*First*#testMethod" );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
         assertFalse( "other method should not match", exactFilter.shouldRun( otherMethod ) );
     }
 
-    @Test
-    public void shouldMatchClassNameWithWildcardCompletely()
+    public void testShouldMatchClassNameWithWildcardCompletely()
     {
         Filter exactFilter = createMethodFilter( "First*#testMethod" );
         assertFalse( "other method should not match", exactFilter.shouldRun( testMethod ) );
         assertFalse( "other method should not match", exactFilter.shouldRun( otherMethod ) );
     }
 
-
-    @Test
-    public void shouldMatchMultipleMethodsSeparatedByComman()
+    public void testShouldMatchMultipleMethodsSeparatedByComma()
     {
         Filter exactFilter = createMethodFilter( firstClassName + "#testMethod,#secondTestMethod" );
 
@@ -148,20 +614,21 @@ public class FilterFactoryTest
         assertFalse( "other method should not match", exactFilter.shouldRun( otherMethod ) );
     }
 
-    @Test
-    public void shouldMatchMultipleMethodsInSameClassSeparatedByPlus() {
+    public void testShouldMatchMultipleMethodsInSameClassSeparatedByPlus()
+    {
         Filter exactFilter = createMethodFilter( FirstClass.class.getName() + "#testMethod+secondTestMethod" );
 
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
         assertTrue( "exact match on name should run", exactFilter.shouldRun( secondTestMethod ) );
 
-        assertFalse( "method in another class should not match", exactFilter.shouldRun( secondTestMethodInSecondClass ) );
+        assertFalse( "method in another class should not match",
+                     exactFilter.shouldRun( secondTestMethodInSecondClass ) );
 
         assertFalse( "other method should not match", exactFilter.shouldRun( otherMethod ) );
     }
 
-    @Test
-    public void shouldRunCompleteClassWhenSeparatedByCommaWithoutHash() {
+    public void testShouldRunCompleteClassWhenSeparatedByCommaWithoutHash()
+    {
         Filter exactFilter = createMethodFilter( firstClassName + "#testMethod," + secondClassName );
 
         assertTrue( "exact match on name should run", exactFilter.shouldRun( testMethod ) );
@@ -173,28 +640,118 @@ public class FilterFactoryTest
         assertTrue( "should run complete second class", exactFilter.shouldRun( secondTestMethodInSecondClass ) );
     }
 
-    @Test
-    public void shouldRunSuitesContainingExactMethodName()
+    public void testShouldRunSuitesContainingExactMethodName()
     {
         Description suite = Description.createSuiteDescription( Suite.class );
         suite.addChild( testMethod );
         suite.addChild( secondTestMethod );
 
-        Filter exactFilter = createMethodFilter( "testMethod" );
+        Filter exactFilter = createMethodFilter( "#testMethod" );
         assertTrue( "should run suites containing matching method", exactFilter.shouldRun( suite ) );
     }
 
-    @Test
-    public void shouldSkipSuitesNotContainingExactMethodName()
+    public void testShouldSkipSuitesNotContainingExactMethodName()
     {
+        Filter exactFilter = createMethodFilter( "#otherMethod" );
+        assertFalse( "should not run method", exactFilter.shouldRun( testMethod ) );
+        assertFalse( "should not run method", exactFilter.shouldRun( secondTestMethod ) );
         Description suite = Description.createSuiteDescription( Suite.class );
         suite.addChild( testMethod );
         suite.addChild( secondTestMethod );
-
-        Filter exactFilter = createMethodFilter( "otherMethod" );
-        assertFalse( "should not run method", exactFilter.shouldRun( testMethod ) );
-        assertFalse( "should not run method", exactFilter.shouldRun( secondTestMethod ) );
         assertFalse( "should not run suites containing no matches", exactFilter.shouldRun( suite ) );
     }
 
+    public void testSingleMethodWithJUnitCoreSuite()
+    {
+        Filter filter = createMethodFilter( "#testMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( Suite.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    /*public void testSuiteAggregator()
+        throws InitializationError
+    {
+
+        class FilteringRequest
+            extends Request
+        {
+            private Runner filteredRunner;
+
+            public FilteringRequest( Request req, Filter filter )
+            {
+                try
+                {
+                    Runner runner = req.getRunner();
+                    filter.apply( runner );
+                    filteredRunner = runner;
+                }
+                catch ( NoTestsRemainException e )
+                {
+                    filteredRunner = null;
+                }
+            }
+
+            @Override
+            public Runner getRunner()
+            {
+                return filteredRunner;
+            }
+        }
+
+        Request req = Request.classes( new Computer()
+        {
+            private final List<Runner> runners = new ArrayList<Runner>();
+
+            @Override
+            public Runner getSuite( RunnerBuilder builder, Class<?>[] classes )
+                throws InitializationError
+            {
+                super.getSuite( builder, classes );
+                return new org.junit.runners.Suite( (Class<?>) null, runners ) {};
+            }
+
+            @Override
+            protected Runner getRunner( RunnerBuilder builder, Class<?> testClass )
+                throws Throwable
+            {
+                Runner runner = new org.junit.runners.Suite( (Class<?>) null, Arrays.asList( super.getRunner( builder, testClass ) ) ) {};
+                runners.add( runner );
+                return runner;
+            }
+        }, Suite.class );
+        Filter filter = createMethodFilter( "FilterFactoryTest$Suite" );
+        Request request = new FilteringRequest( req, filter );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( request );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 2, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }*/
+
+    public void testSingleMethodWithJUnitCoreFirstClass()
+    {
+        Filter filter = createMethodFilter( "#testMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
+
+    public void testWithJUnitCoreFirstClassAndSingleMethod()
+    {
+        Filter filter = createMethodFilter( "FilterFactoryTest$FirstClass#testMethod" );
+        JUnitCore core = new JUnitCore();
+        Result result = core.run( Request.classes( FirstClass.class ).filterWith( filter ) );
+        assertTrue( result.wasSuccessful() );
+        assertEquals( 1, result.getRunCount() );
+        assertEquals( 0, result.getFailureCount() );
+        assertEquals( 0, result.getIgnoreCount() );
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/Filter.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/Filter.java b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/Filter.java
new file mode 100644
index 0000000..2dae870
--- /dev/null
+++ b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/Filter.java
@@ -0,0 +1,27 @@
+package org.apache.maven.surefire.junit4;
+
+/*
+ * 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.
+ */
+
+import java.lang.reflect.Method;
+
+interface Filter
+{
+    boolean shouldRun( Class<?> clazz, Method method );
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
index 93922e1..9957d1e 100644
--- a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
+++ b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
@@ -20,7 +20,9 @@ package org.apache.maven.surefire.junit4;
  */
 
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -42,11 +44,11 @@ import org.apache.maven.surefire.report.ReporterFactory;
 import org.apache.maven.surefire.report.RunListener;
 import org.apache.maven.surefire.report.SimpleReportEntry;
 import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.testset.TestListResolver;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.RunOrderCalculator;
 import org.apache.maven.surefire.util.ScanResult;
 import org.apache.maven.surefire.util.TestsToRun;
-import org.apache.maven.surefire.util.internal.StringUtils;
 import org.junit.runner.Description;
 import org.junit.runner.Request;
 import org.junit.runner.Result;
@@ -58,13 +60,15 @@ import org.junit.runner.notification.RunNotifier;
 public class JUnit4Provider
     extends AbstractProvider
 {
+    private static final Collection<Method> JAVA_LANG_OBJECT_METHODS = Arrays.asList( Object.class.getMethods() );
+
     private final ClassLoader testClassLoader;
 
     private final List<org.junit.runner.notification.RunListener> customRunListeners;
 
     private final JUnit4TestChecker jUnit4TestChecker;
 
-    private final String requestedTestMethod;
+    private final TestListResolver testResolver;
 
     private final ProviderParameters providerParameters;
 
@@ -85,7 +89,7 @@ public class JUnit4Provider
         customRunListeners = JUnit4RunListenerFactory.
             createCustomListeners( booterParameters.getProviderProperties().getProperty( "listener" ) );
         jUnit4TestChecker = new JUnit4TestChecker( testClassLoader );
-        requestedTestMethod = booterParameters.getTestRequest().getRequestedTestMethod();
+        testResolver = booterParameters.getTestRequest().getTestListResolver();
         rerunFailingTestsCount = booterParameters.getTestRequest().getRerunFailingTestsCount();
     }
 
@@ -142,16 +146,7 @@ public class JUnit4Provider
         reporter.testSetStarting( report );
         try
         {
-            if ( !StringUtils.isBlank( requestedTestMethod ) )
-            {
-                String actualTestMethod = getMethod( clazz, requestedTestMethod );
-                String[] testMethods = StringUtils.split( actualTestMethod, "+" );
-                executeWithRerun( clazz, listeners, testMethods );
-            }
-            else
-            {
-                executeWithRerun( clazz, listeners, null );
-            }
+            executeWithRerun( clazz, listeners );
         }
         catch ( Throwable e )
         {
@@ -165,12 +160,11 @@ public class JUnit4Provider
         }
     }
 
-    private void executeWithRerun( Class<?> clazz, RunNotifier listeners, String[] testMethods )
+    private void executeWithRerun( Class<?> clazz, RunNotifier listeners )
     {
         JUnitTestFailureListener failureListener = new JUnitTestFailureListener();
         listeners.addListener( failureListener );
-
-        execute( clazz, listeners, testMethods );
+        execute( clazz, listeners, testResolver.isEmpty() ? null : new TestResolverFilter() );
 
         // Rerun failing tests if rerunFailingTestsCount is larger than 0
         if ( rerunFailingTestsCount > 0 )
@@ -180,7 +174,10 @@ public class JUnit4Provider
                 Set<String> methodsSet = JUnit4ProviderUtil.generateFailingTests( failureListener.getAllFailures() );
                 String[] methods = methodsSet.toArray( new String[ methodsSet.size() ] );
                 failureListener.reset();
-                execute( clazz, listeners, methods );
+                if ( methods.length != 0 )
+                {
+                    execute( clazz, listeners, new FailedMethodFilter( methods ) );
+                }
             }
         }
     }
@@ -262,52 +259,63 @@ public class JUnit4Provider
         return System.getProperty( "surefire.junit4.upgradecheck" ) != null;
     }
 
-    private static void execute( Class<?> testClass, RunNotifier fNotifier, String[] testMethods )
+    private void execute( Class<?> testClass, RunNotifier fNotifier, Filter filter )
     {
-        if ( testMethods != null )
+        if ( !Modifier.isInterface( testClass.getModifiers() ) )
         {
-            for ( final Method method : testClass.getMethods() )
+            if ( filter != null )
             {
-                for ( final String testMethod : testMethods )
+                for ( Method testMethod : testClass.getMethods() )
                 {
-                    if ( SelectorUtils.match( testMethod, method.getName() ) )
+                    if ( !JAVA_LANG_OBJECT_METHODS.contains( testMethod ) )
                     {
-                        Request.method( testClass, method.getName() ).getRunner().run( fNotifier );
+                        String methodName = testMethod.getName();
+                        boolean accessible = !Modifier.isStatic( testMethod.getModifiers() );
+                        if ( accessible && filter.shouldRun( testClass, testMethod ) )
+                        {
+                            Request.method( testClass, methodName ).getRunner().run( fNotifier );
+                        }
                     }
-
                 }
             }
+            else
+            {
+                Request.aClass( testClass ).getRunner().run( fNotifier );
+            }
         }
-        else
+    }
+
+    private final class TestResolverFilter
+        implements Filter
+    {
+
+        public boolean shouldRun( Class<?> testClass, Method testMethod )
         {
-            Request.aClass( testClass ).getRunner().run( fNotifier );
+            return testResolver.shouldRun( testClass, testMethod.getName() );
         }
     }
 
-    /**
-     * this method retrive testMethods from String like
-     * "com.xx.ImmutablePairTest#testBasic,com.xx.StopWatchTest#testLang315+testStopWatchSimpleGet" <br>
-     * and we need to think about cases that 2 or more method in 1 class. we should choose the correct method
-     *
-     * @param testClass the testclass
-     * @param testMethodStr the test method string
-     * @return a string ;)
-     */
-    private static String getMethod( Class testClass, String testMethodStr )
+    private static class FailedMethodFilter
+        implements Filter
     {
-        final String className = testClass.getName();
 
-        if ( !testMethodStr.contains( "#" ) && !testMethodStr.contains( "," ) )
+        private final String[] methodPatterns;
+
+        private FailedMethodFilter( String[] methodPatterns )
+        {
+            this.methodPatterns = methodPatterns;
+        }
+
+        public boolean shouldRun( Class<?> clazz, Method method )
         {
-            return testMethodStr;
+            for ( String methodPattern : methodPatterns )
+            {
+                if ( SelectorUtils.match( methodPattern, method.getName() ) )
+                {
+                    return true;
+                }
+            }
+            return false;
         }
-        testMethodStr += ","; // for the bellow  split code
-        final int beginIndex = testMethodStr.indexOf( className );
-        final int endIndex = testMethodStr.indexOf( ",", beginIndex );
-        final String classMethodStr =
-            testMethodStr.substring( beginIndex, endIndex ); // String like "StopWatchTest#testLang315"
-
-        final int index = classMethodStr.indexOf( '#' );
-        return index >= 0 ? classMethodStr.substring( index + 1, classMethodStr.length() ) : null;
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java b/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
index bbca2d3..a888162 100644
--- a/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
+++ b/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
@@ -47,7 +47,7 @@ public class JUnit4ProviderTest
     {
         BaseProviderFactory providerParameters = new BaseProviderFactory( null, Boolean.TRUE );
         providerParameters.setProviderProperties( new Properties() );
-        providerParameters.setClassLoaders( this.getClass().getClassLoader() );
+        providerParameters.setClassLoaders( getClass().getClassLoader() );
         providerParameters.setTestRequest( new TestRequest( null, null, null ) );
         return new JUnit4Provider( providerParameters );
     }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
index 7895993..9cf8e34 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
@@ -39,12 +39,12 @@ import org.apache.maven.surefire.report.ConsoleOutputReceiver;
 import org.apache.maven.surefire.report.ReporterFactory;
 import org.apache.maven.surefire.report.RunListener;
 import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.testset.TestListResolver;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.RunOrderCalculator;
 import org.apache.maven.surefire.util.ScanResult;
 import org.apache.maven.surefire.util.ScannerFilter;
 import org.apache.maven.surefire.util.TestsToRun;
-import org.apache.maven.surefire.util.internal.StringUtils;
 import org.junit.runner.manipulation.Filter;
 
 /**
@@ -74,7 +74,7 @@ public class JUnitCoreProvider
 
     private RunOrderCalculator runOrderCalculator;
 
-    private String requestedTestMethod;
+    private TestListResolver testResolver;
 
     public JUnitCoreProvider( ProviderParameters providerParameters )
     {
@@ -84,7 +84,18 @@ public class JUnitCoreProvider
         runOrderCalculator = providerParameters.getRunOrderCalculator();
         jUnitCoreParameters = new JUnitCoreParameters( providerParameters.getProviderProperties() );
         scannerFilter = new JUnit48TestChecker( testClassLoader );
-        requestedTestMethod = providerParameters.getTestRequest().getRequestedTestMethod();
+        System.out.println( "TIBOR providerParameters=" + providerParameters );
+        System.out.println( "TIBOR providerParameters.getTestRequest()=" + providerParameters.getTestRequest() );
+        System.out.println( "TIBOR providerParameters.getTestRequest().getTestListResolver().getPluginParameterTest()="
+                                + providerParameters.getTestRequest().getTestListResolver().getPluginParameterTest() );
+        System.out.println( "TIBOR includes: "
+                                + providerParameters.getTestRequest().getTestListResolver().getIncludedFilters() );
+        System.out.println( "TIBOR excludes: "
+                                + providerParameters.getTestRequest().getTestListResolver().getExcludedFilters() );
+        System.out.println( "TIBOR includes: "
+                                + providerParameters.getTestRequest().getTestListResolver().getIncludedFilters()
+            .iterator().next() );
+        testResolver = providerParameters.getTestRequest().getTestListResolver();
         rerunFailingTestsCount = providerParameters.getTestRequest().getRerunFailingTestsCount();
 
         customRunListeners =
@@ -198,21 +209,15 @@ public class JUnitCoreProvider
 
     private Filter createJUnit48Filter()
     {
-        final FilterFactory filterFactory = new FilterFactory( testClassLoader );
-        Filter groupFilter = filterFactory.createGroupFilter( providerParameters.getProviderProperties() );
-        return isMethodFilterSpecified() ? filterFactory.and( groupFilter,
-                                                              filterFactory.createMethodFilter( requestedTestMethod ) )
-                        : groupFilter;
+        final FilterFactory factory = new FilterFactory( testClassLoader );
+        Filter groupFilter = factory.createGroupFilter( providerParameters.getProviderProperties() );
+        boolean onlyGroups = testResolver.isEmpty();
+        return onlyGroups ? groupFilter : factory.and( groupFilter, factory.createMethodFilter( testResolver ) );
     }
 
     private TestsToRun scanClassPath()
     {
-        final TestsToRun scanned = scanResult.applyFilter( scannerFilter, testClassLoader );
+        TestsToRun scanned = scanResult.applyFilter( scannerFilter, testClassLoader );
         return runOrderCalculator.orderTestClasses( scanned );
     }
-
-    private boolean isMethodFilterSpecified()
-    {
-        return !StringUtils.isBlank( requestedTestMethod );
-    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/GroupMatcherMethodSelector.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/GroupMatcherMethodSelector.java b/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/GroupMatcherMethodSelector.java
index 7f5d347..ffc8ad7 100644
--- a/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/GroupMatcherMethodSelector.java
+++ b/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/GroupMatcherMethodSelector.java
@@ -48,26 +48,20 @@ public class GroupMatcherMethodSelector
 
     public boolean includeMethod( IMethodSelectorContext context, ITestNGMethod method, boolean isTestMethod )
     {
-        // System.out.println( "Checking: " + method + " vs. matcher: " + matcher );
         Boolean result = (Boolean) answers.get( method );
         if ( result != null )
         {
-            // System.out.println( "Enabled? " + result );
             return result;
         }
 
         if ( matcher == null )
         {
-            // System.out.println( "No matcher, enable by default" );
             return true;
         }
 
         String[] groups = method.getGroups();
-        result = Boolean.valueOf( matcher.enabled( groups ) );
-
+        result = matcher.enabled( groups );
         answers.put( method, result );
-
-        // System.out.println( "Enabled? " + result );
         return result;
     }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/MethodSelector.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/MethodSelector.java b/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/MethodSelector.java
index bf42daa..bfbc495 100644
--- a/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/MethodSelector.java
+++ b/surefire-providers/surefire-testng-utils/src/main/java/org/apache/maven/surefire/testng/utils/MethodSelector.java
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.testng.utils;
  */
 
 import java.util.List;
-import org.apache.maven.shared.utils.io.SelectorUtils;
 
+import org.apache.maven.surefire.testset.TestListResolver;
 import org.testng.IMethodSelector;
 import org.testng.IMethodSelectorContext;
 import org.testng.ITestNGMethod;
@@ -37,33 +37,31 @@ public class MethodSelector
     implements IMethodSelector
 {
 
-    private static String methodName = null;
+    private static TestListResolver testListResolver = null;
 
     public void setTestMethods( List arg0 )
     {
-        // noop
     }
 
     public boolean includeMethod( IMethodSelectorContext context, ITestNGMethod testngMethod, boolean isTestMethod )
     {
-        if ( testngMethod.isBeforeClassConfiguration() || testngMethod.isBeforeGroupsConfiguration()
+        return testngMethod.isBeforeClassConfiguration() || testngMethod.isBeforeGroupsConfiguration()
             || testngMethod.isBeforeMethodConfiguration() || testngMethod.isBeforeSuiteConfiguration()
-            || testngMethod.isBeforeTestConfiguration() )
-        {
-            return true;
-        }
-        if ( testngMethod.isAfterClassConfiguration() || testngMethod.isAfterGroupsConfiguration()
-            || testngMethod.isAfterMethodConfiguration() || testngMethod.isAfterSuiteConfiguration()
-            || testngMethod.isAfterTestConfiguration() )
-        {
-            return true;
-        }
+            || testngMethod.isBeforeTestConfiguration() || testngMethod.isAfterClassConfiguration()
+            || testngMethod.isAfterGroupsConfiguration() || testngMethod.isAfterMethodConfiguration()
+            || testngMethod.isAfterSuiteConfiguration() || testngMethod.isAfterTestConfiguration()
+            || shouldRun( testngMethod );
 
-        return SelectorUtils.match( methodName, testngMethod.getMethodName() );
     }
 
-    public static void setMethodName( String methodName )
+    public static void setTestListResolver( TestListResolver testListResolver )
     {
-        MethodSelector.methodName = methodName;
+        MethodSelector.testListResolver = testListResolver;
+    }
+
+    private static boolean shouldRun( ITestNGMethod test )
+    {
+        TestListResolver resolver = MethodSelector.testListResolver;
+        return resolver != null && resolver.shouldRun( test.getRealClass(), test.getMethodName() );
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
index d30ad3c..d7f6678 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
@@ -39,6 +39,7 @@ import org.apache.maven.surefire.report.ReporterException;
 import org.apache.maven.surefire.report.ReporterFactory;
 import org.apache.maven.surefire.report.RunListener;
 import org.apache.maven.surefire.report.SimpleReportEntry;
+import org.apache.maven.surefire.testset.TestListResolver;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.RunOrderCalculator;
 import org.apache.maven.surefire.util.ScanResult;
@@ -66,7 +67,7 @@ public class TestNGDirectoryTestSuite
 
     private final ScanResult scanResult;
 
-    private final String testMethodPattern;
+    private final TestListResolver testListResolver;
 
     private final RunOrderCalculator runOrderCalculator;
 
@@ -77,7 +78,7 @@ public class TestNGDirectoryTestSuite
     private Class<? extends Annotation> junitTestAnnotation;
 
     public TestNGDirectoryTestSuite( String testSourceDirectory, Properties confOptions, File reportsDirectory,
-                                     String testMethodPattern, RunOrderCalculator runOrderCalculator,
+                                     TestListResolver testListResolver, RunOrderCalculator runOrderCalculator,
                                      ScanResult scanResult )
     {
 
@@ -88,7 +89,7 @@ public class TestNGDirectoryTestSuite
         this.testSourceDirectory = testSourceDirectory;
         this.reportsDirectory = reportsDirectory;
         this.scanResult = scanResult;
-        this.testMethodPattern = testMethodPattern;
+        this.testListResolver = testListResolver;
         this.junitTestClass = findJUnitTestClass();
         this.junitRunWithAnnotation = findJUnitRunWithAnnotation();
         this.junitTestAnnotation = findJUnitTestAnnotation();
@@ -127,7 +128,7 @@ public class TestNGDirectoryTestSuite
         final Map optionsToUse = isJUnitTest( testClass ) ? junitOptions : options;
 
         TestNGExecutor.run( new Class[]{ testClass }, testSourceDirectory, optionsToUse, reporter, this,
-                            reportsDirectory, testMethodPattern );
+                            reportsDirectory, testListResolver );
 
         finishTestSuite( reporter, this );
     }
@@ -203,14 +204,14 @@ public class TestNGDirectoryTestSuite
         Class[] testClasses = testNgTestClasses.toArray( new Class[testNgTestClasses.size()] );
 
         TestNGExecutor.run( testClasses, this.testSourceDirectory, options, reporterManager, this,
-                            testNgReportsDirectory, testMethodPattern );
+                            testNgReportsDirectory, testListResolver );
 
         if ( junitTestClasses.size() > 0 )
         {
             testClasses = junitTestClasses.toArray( new Class[junitTestClasses.size()] );
 
             TestNGExecutor.run( testClasses, testSourceDirectory, junitOptions, reporterManager, this,
-                                junitReportsDirectory, testMethodPattern );
+                                junitReportsDirectory, testListResolver );
         }
 
         finishTestSuite( reporterManager, this );
@@ -280,7 +281,7 @@ public class TestNGDirectoryTestSuite
         startTestSuite( reporter, this );
 
         TestNGExecutor.run( new Class[] { testSet.getTestClass() }, this.testSourceDirectory, this.options, reporter,
-                            this, reportsDirectory, testMethodPattern );
+                            this, reportsDirectory, testListResolver );
 
         finishTestSuite( reporter, this );
     }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
index b3801fe..e50d643 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
@@ -22,6 +22,7 @@ package org.apache.maven.surefire.testng;
 import org.apache.maven.surefire.booter.ProviderParameterNames;
 import org.apache.maven.surefire.report.RunListener;
 import org.apache.maven.surefire.testng.conf.Configurator;
+import org.apache.maven.surefire.testset.TestListResolver;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.ReflectionUtils;
 import org.apache.maven.surefire.util.internal.StringUtils;
@@ -35,7 +36,6 @@ import org.testng.xml.XmlTest;
 import java.io.File;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -65,7 +65,7 @@ public class TestNGExecutor
     }
 
     public static void run( Class[] testClasses, String testSourceDirectory, Map options, RunListener reportManager,
-                            TestNgTestSuite suite, File reportsDirectory, final String methodNamePattern )
+                            TestNgTestSuite suite, File reportsDirectory, TestListResolver testListResolver )
         throws TestSetFailedException
     {
         TestNG testng = new TestNG( true );
@@ -73,8 +73,8 @@ public class TestNGExecutor
         Configurator configurator = getConfigurator( (String) options.get( "testng.configurator" ) );
         System.out.println( "Configuring TestNG with: " + configurator.getClass().getSimpleName() );
 
-        XmlMethodSelector groupMatchingSelector = getGroupMatchingSelector( options );
-        XmlMethodSelector methodNameFilteringSelector = getMethodNameFilteringSelector( methodNamePattern );
+        XmlMethodSelector groupMatchingSelector = createGroupMatchingSelector( options );
+        XmlMethodSelector methodNameFilteringSelector = createMethodNameFilteringSelector( testListResolver );
 
         Map<String, SuiteAndNamedTests> suitesNames = new HashMap<String, SuiteAndNamedTests>();
 
@@ -176,59 +176,40 @@ public class TestNGExecutor
     }
 
     @SuppressWarnings( "checkstyle:magicnumber" )
-    private static XmlMethodSelector getMethodNameFilteringSelector( String methodNamePattern )
+    private static XmlMethodSelector createMethodNameFilteringSelector( TestListResolver testListResolver )
         throws TestSetFailedException
     {
-        if ( StringUtils.isBlank( methodNamePattern ) )
+        if ( testListResolver != null && !testListResolver.isEmpty() )
         {
-            return null;
-        }
+            // the class is available in the testClassPath
+            String clazzName = "org.apache.maven.surefire.testng.utils.MethodSelector";
+            try
+            {
+                Class<?> clazz = Class.forName( clazzName );
+                Method method = clazz.getMethod( "setTestListResolver", TestListResolver.class );
+                method.invoke( null, testListResolver );
+            }
+            catch ( Exception e )
+            {
+                throw new TestSetFailedException( e.getMessage(), e );
+            }
 
-        // the class is available in the testClassPath
-        String clazzName = "org.apache.maven.surefire.testng.utils.MethodSelector";
-        try
-        {
-            Class clazz = Class.forName( clazzName );
+            XmlMethodSelector xms = new XmlMethodSelector();
 
-            Method method = clazz.getMethod( "setMethodName", new Class[] { String.class } );
-            method.invoke( null, methodNamePattern );
-        }
-        catch ( ClassNotFoundException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( SecurityException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( NoSuchMethodException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( IllegalArgumentException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( IllegalAccessException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
+            xms.setName( clazzName );
+            // looks to need a high value
+            xms.setPriority( 10000 );
+
+            return xms;
         }
-        catch ( InvocationTargetException e )
+        else
         {
-            throw new TestSetFailedException( e.getMessage(), e );
+            return null;
         }
-
-        XmlMethodSelector xms = new XmlMethodSelector();
-
-        xms.setName( clazzName );
-        // looks to need a high value
-        xms.setPriority( 10000 );
-
-        return xms;
     }
 
     @SuppressWarnings( "checkstyle:magicnumber" )
-    private static XmlMethodSelector getGroupMatchingSelector( Map options )
+    private static XmlMethodSelector createGroupMatchingSelector( Map options )
         throws TestSetFailedException
     {
         String groups = (String) options.get( ProviderParameterNames.TESTNG_GROUPS_PROP );
@@ -249,27 +230,7 @@ public class TestNGExecutor
             Method method = clazz.getMethod( "setGroups", new Class[] { String.class, String.class } );
             method.invoke( null, groups, excludedGroups );
         }
-        catch ( ClassNotFoundException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( SecurityException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( NoSuchMethodException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( IllegalArgumentException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( IllegalAccessException e )
-        {
-            throw new TestSetFailedException( e.getMessage(), e );
-        }
-        catch ( InvocationTargetException e )
+        catch ( Exception e )
         {
             throw new TestSetFailedException( e.getMessage(), e );
         }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/889caca8/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
index 5d89d35..1e91fa6 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
@@ -117,7 +117,7 @@ public class TestNGProvider
     boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
     {
         return testSuiteDefinition.getSuiteXmlFiles() != null && testSuiteDefinition.getSuiteXmlFiles().size() > 0
-                        && testSuiteDefinition.getRequestedTest() == null;
+                        && testSuiteDefinition.getTestListResolver() == null;
 
     }
 
@@ -126,7 +126,7 @@ public class TestNGProvider
     {
         return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
                                              reporterConfiguration.getReportsDirectory(),
-                                             testRequest.getRequestedTestMethod(), runOrderCalculator, scanResult );
+                                             testRequest.getTestListResolver(), runOrderCalculator, scanResult );
     }
 
     private TestNGXmlTestSuite getXmlSuite()