Index: src/org/testng/internal/Invoker.java
===================================================================
--- src/org/testng/internal/Invoker.java	(revision 924)
+++ src/org/testng/internal/Invoker.java	(working copy)
@@ -55,7 +55,25 @@
   private SuiteRunState m_suiteState;
   private boolean m_skipFailedInvocationCounts;
   private List<IInvokedMethodListener> m_invokedMethodListeners;
+  private boolean m_continueOnFailedConfiguration;
+  
+  /** Group failures must be synched as the Invoker is accessed concurrently */
+  private Map<String, Boolean> m_beforegroupsFailures= new Hashtable<String, Boolean>();
+  
+  /** Class failures must be synched as the Invoker is accessed concurrently */
+  private Map<Class<?>, Boolean> m_classInvocationResults= new Hashtable<Class<?>, Boolean>();
+  
+  /** Test methods whose configuration methods have failed. */
+  private Map<ITestNGMethod, Boolean> m_methodInvocationResults = new Hashtable<ITestNGMethod, Boolean>();
 
+  private void setClassInvocationFailure(Class<?> clazz, boolean flag) {
+    m_classInvocationResults.put(clazz, flag);
+  }
+  
+  private void setMethodInvocationFailure(ITestNGMethod method, boolean flag) {
+      m_methodInvocationResults.put(method, flag);
+  }
+
   public Invoker(ITestContext testContext,
                  ITestResultNotifier notifier,
                  SuiteRunState state,
@@ -68,6 +86,7 @@
     m_annotationFinder= annotationFinder;
     m_skipFailedInvocationCounts = skipFailedInvocationCounts;
     m_invokedMethodListeners = invokedMethodListeners;
+    m_continueOnFailedConfiguration = XmlSuite.CONTINUE.equals(testContext.getSuite().getXmlSuite().getConfigFailurePolicy());
   }
 
   /**
@@ -138,8 +157,8 @@
             boolean isSuiteConfiguration = isSuiteConfiguration(configurationAnnotation); 
             boolean alwaysRun= isAlwaysRun(configurationAnnotation);
   
-            if(!confInvocationPassed(tm) && !alwaysRun) {
-              handleConfigurationSkip(tm, testResult, configurationAnnotation, suite);
+            if(!confInvocationPassed(tm, currentTestMethod, testClass) && !alwaysRun) {
+              handleConfigurationSkip(tm, testResult, configurationAnnotation, currentTestMethod, suite);
               continue;
             }
   
@@ -181,24 +200,28 @@
         }
       }
       catch(InvocationTargetException ex) {
-        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite);
+        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, currentTestMethod, suite);
       }
       catch(TestNGException ex) {
         // Don't wrap TestNGExceptions, it could be a missing parameter on a
         // @Configuration method
-        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite);
+        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, currentTestMethod, suite);
       }
       catch(Throwable ex) { // covers the non-wrapper exceptions
-        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, suite);
+        handleConfigurationFailure(ex, tm, testResult, configurationAnnotation, currentTestMethod, suite);
       }
     } // for methods
   }
   
   /**
-   * Marks the currect <code>TestResult</code> as skipped and invokes the listeners.
+   * Marks the current <code>TestResult</code> as skipped and invokes the listeners.
    */
-  private void handleConfigurationSkip(ITestNGMethod tm, ITestResult testResult, IConfigurationAnnotation annotation, XmlSuite suite) {
-    recordConfigurationInvocationFailed(tm, annotation, suite);
+  private void handleConfigurationSkip(ITestNGMethod tm, 
+                                       ITestResult testResult, 
+                                       IConfigurationAnnotation annotation, 
+                                       ITestNGMethod currentTestMethod, 
+                                       XmlSuite suite) {
+    recordConfigurationInvocationFailed(tm, testResult.getTestClass(), annotation, currentTestMethod, suite);
     testResult.setStatus(ITestResult.SKIP);
     runConfigurationListeners(testResult);
   }
@@ -266,6 +289,7 @@
                                           ITestNGMethod tm,
                                           ITestResult testResult,
                                           IConfigurationAnnotation annotation,
+                                          ITestNGMethod currentTestMethod,
                                           XmlSuite suite) 
   {
     Throwable cause= ite.getCause() != null ? ite.getCause() : ite;
@@ -274,7 +298,7 @@
       SkipException skipEx= (SkipException) cause;
       if(skipEx.isSkip()) {
         testResult.setThrowable(skipEx);
-        handleConfigurationSkip(tm, testResult, annotation, suite);
+        handleConfigurationSkip(tm, testResult, annotation, currentTestMethod, suite);
         return;
       }
     }
@@ -288,7 +312,7 @@
     // what kind of @Configuration method we're dealing with
     //
     if (null != annotation) {
-      recordConfigurationInvocationFailed(tm, annotation, suite);
+      recordConfigurationInvocationFailed(tm, testResult.getTestClass(), annotation, currentTestMethod, suite);
     }
   }
 
@@ -321,18 +345,34 @@
    * Record internally the failure of a Configuration, so that we can determine
    * later if @Test should be skipped.
    */
-  private void recordConfigurationInvocationFailed(ITestNGMethod tm, IConfigurationAnnotation annotation, XmlSuite suite) {
-    // If beforeTestClass/beforeTestMethod or afterTestClass/afterTestMethod 
-    // failed, mark this entire class as failed, but only this class (the other 
-    // classes should keep running normally)
-    if (annotation.getBeforeTestClass()
-      || annotation.getAfterTestClass()
-      || annotation.getBeforeTestMethod()
-      || annotation.getAfterTestMethod()) 
+  private void recordConfigurationInvocationFailed(ITestNGMethod tm, 
+                                                   IClass testClass, 
+                                                   IConfigurationAnnotation annotation, 
+                                                   ITestNGMethod currentTestMethod, 
+                                                   XmlSuite suite) {
+    // If beforeTestClass or afterTestClass failed, mark either the config method's
+    // entire class as failed, or the class under tests as failed, depending on
+    // the configuration failure policy
+    if (annotation.getBeforeTestClass() || annotation.getAfterTestClass()) 
     {
-      setClassInvocationFailure(tm.getRealClass(), false);
+        // tm is the configuration method, and currentTestMethod is null for BeforeClass
+        // methods, so we need testClass
+        if (m_continueOnFailedConfiguration)
+          setClassInvocationFailure(testClass.getRealClass(), false);
+        else
+          setClassInvocationFailure(tm.getRealClass(), false);
     }
 
+    // If before/afterTestMethod failed, mark either the config method's entire
+    // class as failed, or just the current test method as failed, depending on
+    // the configuration failure policy
+    else if (annotation.getBeforeTestMethod() || annotation.getAfterTestMethod()) {
+        if (m_continueOnFailedConfiguration)
+            setMethodInvocationFailure(currentTestMethod, false);
+        else
+            setClassInvocationFailure(tm.getRealClass(), false);
+    }
+
     // If beforeSuite or afterSuite failed, mark *all* the classes as failed
     // for configurations.  At this point, the entire Suite is screwed
     else if (annotation.getBeforeSuite() || annotation.getAfterSuite()) {
@@ -360,10 +400,14 @@
    * @return true if this class has successfully run all its @Configuration
    * method or false if at least one of these methods failed.
    */
-  private boolean confInvocationPassed(ITestNGMethod method) {
+  private boolean confInvocationPassed(ITestNGMethod method, ITestNGMethod currentTestMethod, IClass testClass) {
     boolean result= true;
 
-    Class<?> cls= method.getMethod().getDeclaringClass();
+    // If continuing on config failure, check invocation results for the class
+    // under test, otherwise use the method's declaring class
+    Class<?> cls = m_continueOnFailedConfiguration ? 
+            testClass.getRealClass() :
+                method.getMethod().getDeclaringClass();
     
     if(m_suiteState.isFailed()) {
       result= false;
@@ -372,7 +416,13 @@
       if(m_classInvocationResults.containsKey(cls)) {
         result= m_classInvocationResults.get(cls);
       }
-      else {
+      // if method is BeforeClass, currentTestMethod will be null
+      else if (m_continueOnFailedConfiguration && 
+              currentTestMethod != null && 
+              m_methodInvocationResults.containsKey(currentTestMethod)) {
+          result = m_methodInvocationResults.get(currentTestMethod);
+      }
+      else if (!m_continueOnFailedConfiguration) {
         for(Class<?> clazz: m_classInvocationResults.keySet()) {
 //          if (clazz == cls) {
           if(clazz.isAssignableFrom(cls)) {
@@ -396,16 +446,6 @@
     return result;
   }
 
-  /** Group failures must be synched as the Invoker is accessed concurrently */
-  private Map<String, Boolean> m_beforegroupsFailures= new Hashtable<String, Boolean>();
-  
-  /** Class failures must be synched as the Invoker is accessed concurrently */
-  private Map<Class<?>, Boolean> m_classInvocationResults= new Hashtable<Class<?>, Boolean>();
-
-  private void setClassInvocationFailure(Class<?> clazz, boolean flag) {
-    m_classInvocationResults.put(clazz, flag);
-  }
-
   /**
    * Effectively invokes a configuration method on all passed in instances.
    * TODO: Should change this method to be more like invokeMethod() so that we can
@@ -547,7 +587,7 @@
       
       Method thisMethod= tm.getMethod();
       
-      if(confInvocationPassed(tm)) {
+      if(confInvocationPassed(tm, tm, testClass)) {
         log(3, "Invoking " + thisMethod.getDeclaringClass().getName() + "." +
             thisMethod.getName());
 
@@ -1537,8 +1577,6 @@
     }
 
     Class<?>[] exceptions = exceptionHolder.expectedClasses;
-    String messageRegExp = exceptionHolder.messageRegExp;
-
     Class<?> realExceptionClass= ite.getClass();
 
     for(int i= 0; i < exceptions.length; i++) {
Index: src/org/testng/TestNGCommandLineArgs.java
===================================================================
--- src/org/testng/TestNGCommandLineArgs.java	(revision 924)
+++ src/org/testng/TestNGCommandLineArgs.java	(working copy)
@@ -12,7 +12,6 @@
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -73,6 +72,7 @@
   public static final String DATA_PROVIDER_THREAD_COUNT = "-dataproviderthreadcount";
   public static final String USE_DEFAULT_LISTENERS = "-usedefaultlisteners";
   public static final String SUITE_DEF_OPT = "testng.suite.definitions";
+  public static final String CONFIG_FAILURE_POLICY = "-configfailurepolicy";
 
 
   /** 
@@ -360,6 +360,12 @@
       else if (SKIP_FAILED_INVOCATION_COUNT_OPT.equalsIgnoreCase(argv[i])) {
         arguments.put(SKIP_FAILED_INVOCATION_COUNT_OPT, Boolean.TRUE);
       }
+      else if (CONFIG_FAILURE_POLICY.equalsIgnoreCase(argv[i])) {
+          if ((i + 1) < argv.length) {
+              arguments.put(CONFIG_FAILURE_POLICY, trim(argv[i + 1]));
+              i++;
+          }
+      }
       //
       // Unknown option
       //
@@ -747,6 +753,8 @@
     System.out.println("\t\trun tests in parallel using the specified mode");
     System.out.println("[" + THREAD_COUNT
             + " number of threads to use when running tests in parallel]");
+    System.out.println("[" + CONFIG_FAILURE_POLICY + "skip|continue]");
+    System.out.println("\t\twhether to ever invoke a config method again after is has failed once");
     System.out.println("[" + SUITE_NAME_OPT + " name]");
     System.out.println("\t\tDefault name of test suite, if not specified in suite definition file or source code");
     System.out.println("[" + TEST_NAME_OPT + " Name]");
Index: src/org/testng/TestNGAntTask.java
===================================================================
--- src/org/testng/TestNGAntTask.java	(revision 924)
+++ src/org/testng/TestNGAntTask.java	(working copy)
@@ -61,6 +61,7 @@
  * <li>dataproviderthreadcount (attribute)</li>
  * <li>verbose (attribute)</li>
  * <li>testrunfactory (attribute)</li>
+ * <li>configFailurepolicy (attribute)</li>
  * 
  * </ul>
  *
@@ -139,6 +140,7 @@
   protected String m_parallelMode;
   protected String m_threadCount;
   protected String m_dataproviderthreadCount;
+  protected String m_configFailurePolicy;
   public String m_useDefaultListeners;
   private String m_suiteName="Ant suite";
   private String m_testName="Ant test";
@@ -469,6 +471,10 @@
       m_listeners.add(st.nextToken());
     }
   }
+  
+  public void setConfigFailurePolicy(String failurePolicy) {
+    m_configFailurePolicy = failurePolicy;
+  }
 
   /**
    * Launches TestNG in a new JVM.
@@ -592,6 +598,11 @@
       argv.add(m_parallelMode);
     }
 
+    if (m_configFailurePolicy != null) {
+      argv.add(TestNGCommandLineArgs.CONFIG_FAILURE_POLICY);
+      argv.add(m_configFailurePolicy);
+    }
+    
     if(m_threadCount != null) {
       argv.add(TestNGCommandLineArgs.THREAD_COUNT);
       argv.add(m_threadCount);
Index: src/org/testng/TestNG.java
===================================================================
--- src/org/testng/TestNG.java	(revision 924)
+++ src/org/testng/TestNG.java	(working copy)
@@ -154,6 +154,7 @@
   private boolean m_useThreadCount;
   private String m_parallelMode;
   private boolean m_useParallelMode;
+  private String m_configFailurePolicy = null;
   private Class[] m_commandLineTestClasses;
   
   private String m_defaultSuiteName=DEFAULT_COMMAND_LINE_SUITE_NAME;
@@ -723,6 +724,9 @@
       if(m_useParallelMode) {
         s.setParallel(m_parallelMode);
       }
+      if(m_configFailurePolicy != null) {
+        s.setConfigFailurePolicy(m_configFailurePolicy.toString());
+      }
     }
 
   }
@@ -876,6 +880,10 @@
           xmlSuite.setVerbose(m_verbose);
         }
         
+        if (null != m_configFailurePolicy) {
+            xmlSuite.setConfigFailurePolicy(m_configFailurePolicy);
+        }
+        
         PoolService.initialize(xmlSuite.getDataProviderThreadCount());
         result.add(createAndRunSuiteRunners(xmlSuite));
         PoolService.getInstance().shutdown();
@@ -1062,6 +1070,11 @@
         addReporter(reporterConfig);
       }
     }
+    
+    String failurePolicy = (String)cmdLineArgs.get(TestNGCommandLineArgs.CONFIG_FAILURE_POLICY);
+    if (failurePolicy != null) {
+        setConfigFailurePolicy(failurePolicy);
+    }
   }
 
   private void setSkipFailedInvocationCounts(Boolean skip) {
@@ -1251,6 +1264,24 @@
   public void setDefaultTestName(String defaultTestName) {
     m_defaultTestName = defaultTestName;
   }
+
+  /**
+   * Sets the policy for whether or not to ever invoke a configuration method again after
+   * it has failed once. Possible values are defined in {@link XmlSuite}.  The default
+   * value is {@link XmlSuite#SKIP}.
+   * @param failurePolicy the configuration failure policy
+   */
+  public void setConfigFailurePolicy(String failurePolicy) {
+    m_configFailurePolicy = failurePolicy;
+  }
+
+  /**
+   * Returns the configuration failure policy.
+   * @return config failure policy
+   */
+  public String getConfigFailurePolicy() {
+    return m_configFailurePolicy;
+  }
   
   // DEPRECATED: to be removed after a major version change
   /**
Index: src/org/testng/xml/XmlSuite.java
===================================================================
--- src/org/testng/xml/XmlSuite.java	(revision 924)
+++ src/org/testng/xml/XmlSuite.java	(working copy)
@@ -8,7 +8,6 @@
 import org.testng.reporters.XMLStringBuffer;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -40,6 +39,10 @@
   public static final String PARALLEL_CLASSES = "classes";
   public static final String PARALLEL_NONE = "none";
   
+  /** Configuration failure policy options */
+  public static final String SKIP = "skip";
+  public static final String CONTINUE = "continue";
+  
   private String m_test;
   
   /** The default suite name TODO CQ is this OK as a default name. */
@@ -53,6 +56,9 @@
   
   private String m_parallel = null;
   
+  /** Whether to SKIP or CONTINUE to re-attempt failed configuration methods. */
+  private String m_configFailurePolicy = SKIP;
+  
   /** JUnit compatibility flag. */
   private Boolean m_isJUnit = Boolean.FALSE;
   
@@ -137,8 +143,24 @@
   public void setParallel(String parallel) {
     m_parallel = parallel;
   }
+  
+  /**
+   * Sets the configuration failure policy.
+   * @param configFailurePolicy the config failure policy
+   */
+  public void setConfigFailurePolicy(String configFailurePolicy) {
+    m_configFailurePolicy = configFailurePolicy;
+  }
 
   /**
+   * Returns the configuration failure policy.
+   * @return the configuration failure policy
+   */
+  public String getConfigFailurePolicy() {
+    return m_configFailurePolicy;
+  }
+
+  /**
    * Returns the verbose.
    * @return the verbose.
    */
@@ -389,6 +411,7 @@
     if(null != parallel && !"".equals(parallel)) {
       p.setProperty("parallel", parallel);
     }
+    p.setProperty("configfailurepolicy", getConfigFailurePolicy());
     p.setProperty("thread-count", String.valueOf(getThreadCount()));
     p.setProperty("data-provider-thread-count", String.valueOf(getDataProviderThreadCount()));
     p.setProperty("annotations", getAnnotations());
@@ -483,6 +506,7 @@
     result.setListeners(getListeners());
     result.setAnnotations(getAnnotations());
     result.setParallel(getParallel());
+    result.setConfigFailurePolicy(getConfigFailurePolicy());
     result.setThreadCount(getThreadCount());
     result.setDataProviderThreadCount(getDataProviderThreadCount());
     result.setParameters(getAllParameters());
Index: src/org/testng/xml/TestNGContentHandler.java
===================================================================
--- src/org/testng/xml/TestNGContentHandler.java	(revision 924)
+++ src/org/testng/xml/TestNGContentHandler.java	(working copy)
@@ -142,6 +142,12 @@
           Utils.log("Parser", 1, "[WARN] Unknown value of attribute 'parallel' at suite level: '" + parallel + "'.");
         }
       }
+      String configFailurePolicy = attributes.getValue("configfailurepolicy");
+      if (null != configFailurePolicy) {
+        if (XmlSuite.SKIP.equals(configFailurePolicy) || XmlSuite.CONTINUE.equals(configFailurePolicy)) {
+          m_currentSuite.setConfigFailurePolicy(configFailurePolicy);
+        }
+      }
       String skip = attributes.getValue("skipfailedinvocationcounts");
       if (skip != null) {
         m_currentSuite.setSkipFailedInvocationCounts(Boolean.valueOf(skip));
Index: src/testng-1.0.dtd
===================================================================
--- src/testng-1.0.dtd	(revision 924)
+++ src/testng-1.0.dtd	(working copy)
@@ -40,6 +40,8 @@
                 This setting has no impact on the HTML reports.
 @attr  parallel   Whether TestNG should use different threads
                 to run your tests (might speed up the process)
+@attr  configfailurepolicy  Whether to continue attempting Before/After
+                Class/Methods after they've failed once or just skip remaining.                
 @attr  thread-count An integer giving the size of the thread pool to use
                 if you set parallel.
 @attr  annotations  If "javadoc", TestNG will look for
@@ -58,6 +60,7 @@
     junit (true | false) "false"
     verbose CDATA #IMPLIED
     parallel (false | methods | tests | classes) "false"
+    configfailurepolicy (skip | continue) "skip"
     thread-count CDATA "5"
     annotations CDATA #IMPLIED
     time-out CDATA #IMPLIED
Index: src/testng-1.0.dtd.html
===================================================================
--- src/testng-1.0.dtd.html	(revision 924)
+++ src/testng-1.0.dtd.html	(working copy)
@@ -54,6 +54,8 @@
                 This setting has no impact on the HTML reports.
 @attr  parallel   Whether TestNG should use different threads
                 to run your tests (might speed up the process)
+@attr  configfailurepolicy  Whether to continue attempting Before/After
+                Class/Methods after they've failed once or just skip remaining.
 @attr  thread-count An integer giving the size of the thread pool to use
                 if you set parallel.
 @attr  annotations  If "javadoc", TestNG will look for
@@ -72,6 +74,7 @@
     junit (true | false) "false"
     verbose CDATA #IMPLIED
     parallel (false | methods | tests | classes) "false"
+    configfailurepolicy (skip | continue) "skip"
     thread-count CDATA "5"
     annotations CDATA #IMPLIED
     time-out CDATA #IMPLIED
Index: test/src/test/configurationFailurePolicy/ClassWithFailedBeforeClassMethod.java
===================================================================
--- test/src/test/configurationFailurePolicy/ClassWithFailedBeforeClassMethod.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ClassWithFailedBeforeClassMethod.java	(revision 0)
@@ -0,0 +1,23 @@
+package test.configurationFailurePolicy;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ClassWithFailedBeforeClassMethod {
+
+  @BeforeClass
+  public void setupClassFails() {
+    throw new RuntimeException( "setup class fail" );
+  }
+    
+  @BeforeMethod
+  public void setupMethod() {
+
+  }
+    
+  @Test
+  public void test1() {
+
+  }
+}
Index: test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeMethod.java
===================================================================
--- test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeMethod.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeMethod.java	(revision 0)
@@ -0,0 +1,17 @@
+package test.configurationFailurePolicy;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ExtendsClassWithFailedBeforeMethod extends ClassWithFailedBeforeMethod {
+    
+  @BeforeMethod
+  public void setupExtension() {
+        
+  }
+    
+  @Test
+  public void test2() {
+
+  }
+}
Index: test/src/test/configurationFailurePolicy/FailurePolicyTest.java
===================================================================
--- test/src/test/configurationFailurePolicy/FailurePolicyTest.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/FailurePolicyTest.java	(revision 0)
@@ -0,0 +1,81 @@
+package test.configurationFailurePolicy;
+
+import org.testng.ITestContext;
+import org.testng.TestListenerAdapter;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.testng.xml.XmlSuite;
+
+import testhelper.OutputDirectoryPatch;
+
+import static org.testng.Assert.*;
+
+public class FailurePolicyTest {
+
+  // only if this is run from an xml file that sets this on the suite
+  @BeforeClass(enabled=false)
+  public void setupClass( ITestContext testContext) {
+    assertEquals(testContext.getSuite().getXmlSuite().getConfigFailurePolicy(), XmlSuite.CONTINUE);
+  }
+
+  @DataProvider( name="dp" )
+  public Object[][] getData() {
+    Object[][] data = new Object[][] {
+      // params - confFail, confSkip, skipedTests
+      new Object[] { new Class[] { ClassWithFailedBeforeClassMethod.class }, 1, 1, 1 },
+      new Object[] { new Class[] { ClassWithFailedBeforeMethodAndMultipleTests.class }, 2, 0, 2 },
+      new Object[] { new Class[] { ExtendsClassWithFailedBeforeMethod.class }, 2, 2, 2 },
+      new Object[] { new Class[] { ClassWithFailedBeforeClassMethod.class }, 1, 1, 1 },
+      new Object[] { new Class[] { ExtendsClassWithFailedBeforeClassMethod.class }, 1, 2, 2 },
+      new Object[] { new Class[] { ClassWithFailedBeforeClassMethod.class, ExtendsClassWithFailedBeforeClassMethod.class }, 2, 3, 3 },
+      new Object[] { new Class[] { ClassWithSkippingBeforeMethod.class }, 0, 1, 1 },
+    };
+    return data;
+  }
+    
+  @Test( dataProvider = "dp" )
+  public void confFailureTest(Class[] classesUnderTest, int configurationFailures, int configurationSkips, int skippedTests) {
+
+    TestListenerAdapter tla = new TestListenerAdapter();
+    TestNG testng = new TestNG();
+    testng.setOutputDirectory(OutputDirectoryPatch.getOutputDirectory());
+    testng.setTestClasses(classesUnderTest);
+    testng.addListener(tla);
+    testng.setVerbose(0);
+    testng.setConfigFailurePolicy(XmlSuite.CONTINUE);
+    testng.run();
+
+    verify(tla, configurationFailures, configurationSkips, skippedTests);
+  }
+
+  @Test
+  public void commandLineTest() {
+    String[] argv = new String[] { "-log", "0", "-d", OutputDirectoryPatch.getOutputDirectory(),
+            "-configfailurepolicy", "continue", 
+            "-testclass", "test.configurationFailurePolicy.ClassWithFailedBeforeMethodAndMultipleTests" };
+    TestListenerAdapter tla = new TestListenerAdapter();
+    TestNG.privateMain(argv, tla);
+
+    verify(tla, 2, 0, 2);
+  }
+  
+  @Test
+  public void commandLineTestWithXMLFile() {
+    String[] argv = new String[] { "-log", "0", "-d", OutputDirectoryPatch.getOutputDirectory(),
+            "-configfailurepolicy", "continue", 
+            "test/testng-configfailure.xml" };
+    TestListenerAdapter tla = new TestListenerAdapter();
+    TestNG.privateMain(argv, tla);
+
+    verify(tla, 2, 0, 2);
+  }
+
+  private void verify( TestListenerAdapter tla, int configurationFailures, int configurationSkips, int skippedTests ) {
+      assertEquals(tla.getConfigurationFailures().size(), configurationFailures, "wrong number of configuration failures");
+      assertEquals(tla.getConfigurationSkips().size(), configurationSkips, "wrong number of configuration skips");
+      assertEquals(tla.getSkippedTests().size(), skippedTests, "wrong number of skipped tests");      
+  }
+  
+}
Index: test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethod.java
===================================================================
--- test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethod.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethod.java	(revision 0)
@@ -0,0 +1,17 @@
+package test.configurationFailurePolicy;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ClassWithFailedBeforeMethod {
+
+  @BeforeMethod
+  public void setupShouldFail() {
+    throw new RuntimeException("Failing in setUp");
+  }
+    
+  @Test
+  public void test1() {
+
+  }
+}
Index: test/src/test/configurationFailurePolicy/ClassWithSkippingBeforeMethod.java
===================================================================
--- test/src/test/configurationFailurePolicy/ClassWithSkippingBeforeMethod.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ClassWithSkippingBeforeMethod.java	(revision 0)
@@ -0,0 +1,23 @@
+package test.configurationFailurePolicy;
+
+import org.testng.SkipException;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ClassWithSkippingBeforeMethod {
+
+  private int invocations = 0;
+    
+  @BeforeMethod
+  public void beforeMethod() {
+      invocations++;
+      if (invocations ==2)
+        throw new SkipException("skipping");
+  }
+  
+  @Test
+  public void test1() {}
+  
+  @Test
+  public void test2() {}
+}
Index: test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeClassMethod.java
===================================================================
--- test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeClassMethod.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ExtendsClassWithFailedBeforeClassMethod.java	(revision 0)
@@ -0,0 +1,11 @@
+package test.configurationFailurePolicy;
+
+import org.testng.annotations.Test;
+
+public class ExtendsClassWithFailedBeforeClassMethod extends ClassWithFailedBeforeClassMethod {
+
+  @Test
+  public void test2() {
+        // should be skipped, but BeforeClass method attempted again
+  }
+}
Index: test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethodAndMultipleTests.java
===================================================================
--- test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethodAndMultipleTests.java	(revision 0)
+++ test/src/test/configurationFailurePolicy/ClassWithFailedBeforeMethodAndMultipleTests.java	(revision 0)
@@ -0,0 +1,22 @@
+package test.configurationFailurePolicy;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ClassWithFailedBeforeMethodAndMultipleTests {
+
+  @BeforeMethod
+  public void setupShouldFail() {
+    throw new RuntimeException("Failing in setUp");
+  }
+    
+  @Test
+  public void test1() {
+
+  }
+    
+  @Test
+  public void test2() {
+
+  }
+}
Index: test/testng.xml
===================================================================
--- test/testng.xml	(revision 924)
+++ test/testng.xml	(working copy)
@@ -566,4 +566,10 @@
     </classes>
   </test>
 
+  <test name="ConfigFailurePolicy">
+    <classes>
+      <class name="test.configurationFailurePolicy.FailurePolicyTest" />
+    </classes>
+  </test>
+
 </suite>
Index: test/testng-configfailure.xml
===================================================================
--- test/testng-configfailure.xml	(revision 0)
+++ test/testng-configfailure.xml	(revision 0)
@@ -0,0 +1,9 @@
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+
+<suite name="TestNG" verbose="0">
+    <test name="Config Failure Policy">
+        <classes>
+            <class name="test.configurationFailurePolicy.ClassWithFailedBeforeMethodAndMultipleTests" />
+        </classes>
+    </test>
+</suite>
