← Back to team overview

nunit-core team mailing list archive

[Merge] lp:~jterrell/nunitv2/action-attributes into lp:nunitv2

 

Jordan Terrell has proposed merging lp:~jterrell/nunitv2/action-attributes into lp:nunitv2.

Requested reviews:
  NUnit Core Developers (nunit-core)

For more details, see:
https://code.launchpad.net/~jterrell/nunitv2/action-attributes/+merge/90591

Final action attribute design implemented...
-- 
https://code.launchpad.net/~jterrell/nunitv2/action-attributes/+merge/90591
Your team NUnit Core Developers is requested to review the proposed merge of lp:~jterrell/nunitv2/action-attributes into lp:nunitv2.
=== modified file 'src/NUnitCore/core/ActionsHelper.cs'
--- src/NUnitCore/core/ActionsHelper.cs	2011-11-20 06:12:04 +0000
+++ src/NUnitCore/core/ActionsHelper.cs	2012-01-29 01:29:26 +0000
@@ -6,122 +6,103 @@
 
 #if CLR_2_0 || CLR_4_0
 using System;
-using System.Collections;
+using System.Collections;
+using System.Collections.Generic;
 using System.Reflection;
 
 namespace NUnit.Core
 {
     internal class ActionsHelper
     {
-        private static Type _ActionInterfaceType = null;
-        private static Hashtable _ActionTypes = null;
+        private static Type _ActionInterfaceType = null;
 
         static ActionsHelper()
         {
-            _ActionInterfaceType = Type.GetType(NUnitFramework.TestActionInterface);
-            _ActionTypes = new Hashtable();
-
-            Type suiteActionInterface = Type.GetType(NUnitFramework.TestSuiteActionInterface);
-            if(suiteActionInterface != null)
-                _ActionTypes.Add(ActionLevel.Suite, suiteActionInterface);
-
-            Type caseActionInterface = Type.GetType(NUnitFramework.TestCaseActionInterface);
-            if(caseActionInterface != null)
-                _ActionTypes.Add(ActionLevel.Test, caseActionInterface);
-        }
-
-        public static object[] GetActionsFromTypeAttributes(Type type)
+            _ActionInterfaceType = Type.GetType(NUnitFramework.TestActionInterface);
+        }
+
+        public static void ExecuteActions(ActionPhase phase, IEnumerable<TestAction> actions, ITest test)
+        {
+            if (actions == null)
+                return;
+
+            TestAction[] filteredActions = GetFilteredAndSortedActions(actions, phase);
+
+            foreach (TestAction action in filteredActions)
+            {
+                if(phase == ActionPhase.Before)
+                    action.ExecuteBefore(test);
+                else
+                    action.ExecuteAfter(test);
+            }
+        }
+
+        public static TestAction[] GetActionsFromAttributeProvider(ICustomAttributeProvider attributeProvider)
+        {
+            if (attributeProvider == null || _ActionInterfaceType == null)
+                return new TestAction[0];
+
+            object[] targets = attributeProvider.GetCustomAttributes(_ActionInterfaceType, false);
+
+            List<TestAction> actions = new List<TestAction>();
+
+            foreach (var target in targets)
+                actions.Add(new TestAction(target));
+
+            actions.Sort(SortByTargetDescending);
+
+            return actions.ToArray();
+        }
+
+        public static TestAction[] GetActionsFromTypesAttributes(Type type)
         {
-            if(type == null)
-                return new object[0];
-
-            if(type == typeof(object))
-                return new object[0];
-
-            ArrayList actions = new ArrayList();
-
-            actions.AddRange(GetActionsFromTypeAttributes(type.BaseType));
+            if(type == null)
+                return new TestAction[0];
+
+            if(type == typeof(object))
+                return new TestAction[0];
+
+            List<TestAction> actions = new List<TestAction>();
+
+            actions.AddRange(GetActionsFromTypesAttributes(type.BaseType));
 
             Type[] declaredInterfaces = GetDeclaredInterfaces(type);
 
-            foreach(Type interfaceType in declaredInterfaces)
-                actions.AddRange(GetActionsFromAttributes(interfaceType));
-
-            actions.AddRange(GetActionsFromAttributes(type));
+            foreach(Type interfaceType in declaredInterfaces)
+                actions.AddRange(GetActionsFromAttributeProvider(interfaceType));
+
+            actions.AddRange(GetActionsFromAttributeProvider(type));
 
             return actions.ToArray();
         }
 
         private static Type[] GetDeclaredInterfaces(Type type)
         {
-            Type[] interfaces = type.GetInterfaces();
-            Type[] baseInterfaces = new Type[0];
-
-            if (type.BaseType != typeof(object))
-                return interfaces;
-
-            ArrayList declaredInterfaces = new ArrayList();
+            List<Type> interfaces = new List<Type>(type.GetInterfaces());
+
+            if (type.BaseType == typeof(object))
+                return interfaces.ToArray();
+
+            List<Type> baseInterfaces = new List<Type>(type.BaseType.GetInterfaces());
+            List<Type> declaredInterfaces = new List<Type>();
+
             foreach (Type interfaceType in interfaces)
             {
-                if (Array.IndexOf(baseInterfaces, interfaceType) < 0)
+                if (!baseInterfaces.Contains(interfaceType))
                     declaredInterfaces.Add(interfaceType);
             }
 
-            return (Type[])declaredInterfaces.ToArray(typeof(Type));
-        }
-
-        public static object[] GetActionsFromAttributes(ICustomAttributeProvider attributeProvider)
-        {
-            if(attributeProvider == null || _ActionInterfaceType == null)
-                return new object[0];
-
-            return attributeProvider.GetCustomAttributes(_ActionInterfaceType, false);
-        }
-
-        public static void ExecuteActions(ActionLevel level, ActionPhase phase, IEnumerable actions, object fixture, MethodInfo method)
-        {
-            if (actions == null)
-                return;
-
-            Type actionType = GetActionType(level);
-            if(actionType == null)
-                return;
-
-            MethodInfo actionMethod = GetActionMethod(actionType, level, phase);
-
-            object[] filteredActions = GetFilteredAndSortedActions(actions, phase, actionType);
-
-            foreach (object action in filteredActions)
-            {
-                if (action == null)
-                    continue;
-
-                Reflect.InvokeMethod(actionMethod, action, fixture, method);
-            }
-        }
-
-        private static object[] GetFilteredAndSortedActions(IEnumerable actions, ActionPhase phase, Type actionType)
-        {
-            ArrayList filteredActions = new ArrayList();
-            foreach(object actionItem in actions)
-            {
-                if(actionItem == null)
-                    continue;
-
-                if(actionItem is IEnumerable)
-                {
-                    foreach(object nestedItem in ((IEnumerable)actionItem))
-                    {
-                        if(nestedItem == null)
-                            continue;
-
-                        if (actionType.IsAssignableFrom(nestedItem.GetType()) && filteredActions.Contains(nestedItem) != true)
-                            filteredActions.Add(nestedItem);
-                    }
-                }
-                else if(actionType.IsAssignableFrom(actionItem.GetType()) && filteredActions.Contains(actionItem) != true)
+            return declaredInterfaces.ToArray();
+        }
+
+        private static TestAction[] GetFilteredAndSortedActions(IEnumerable<TestAction> actions, ActionPhase phase)
+        {
+            List<TestAction> filteredActions = new List<TestAction>();
+            foreach (TestAction actionItem in actions)
+            {
+                if (filteredActions.Contains(actionItem) != true)
                     filteredActions.Add(actionItem);
-            }
+            }
 
             if(phase == ActionPhase.After)
                 filteredActions.Reverse();
@@ -129,32 +110,10 @@
             return filteredActions.ToArray();
         }
 
-        private static Type GetActionType(ActionLevel level)
-        {
-            return (Type) _ActionTypes[level];
-        }
-
-        private static MethodInfo GetActionMethod(Type actionType, ActionLevel level, ActionPhase phase)
-        {
-            if (phase == ActionPhase.Before)
-            {
-                if (level == ActionLevel.Suite)
-                    return Reflect.GetNamedMethod(actionType, "BeforeTestSuite");
-
-                return Reflect.GetNamedMethod(actionType, "BeforeTestCase");
-            }
-
-            if (level == ActionLevel.Suite)
-                return Reflect.GetNamedMethod(actionType, "AfterTestSuite");
-
-            return Reflect.GetNamedMethod(actionType, "AfterTestCase");
-        }
-    }
-
-    public enum ActionLevel
-    {
-        Suite,
-        Test
+        private static int SortByTargetDescending(TestAction x, TestAction y)
+        {
+            return y.Targets.CompareTo(x.Targets);
+        }
     }
 
     public enum ActionPhase

=== modified file 'src/NUnitCore/core/NUnitFramework.cs'
--- src/NUnitCore/core/NUnitFramework.cs	2011-12-02 05:50:49 +0000
+++ src/NUnitCore/core/NUnitFramework.cs	2012-01-29 01:29:26 +0000
@@ -35,7 +35,7 @@
 		public const string DescriptionAttribute = "NUnit.Framework.DescriptionAttribute";
         public const string RequiredAddinAttribute = "NUnit.Framework.RequiredAddinAttribute";
 
-        // Attributes that apply only to Classes
+        // Attributes that apply only to Classes
         public const string TestFixtureAttribute = "NUnit.Framework.TestFixtureAttribute";
         public const string SetUpFixtureAttribute = "NUnit.Framework.SetUpFixtureAttribute";
 
@@ -56,9 +56,9 @@
 
         #region Other Framework Types
 
-        public static readonly string TestSuiteActionInterface = "NUnit.Framework.ITestSuiteAction, nunit.framework";
-        public static readonly string TestCaseActionInterface = "NUnit.Framework.ITestCaseAction, nunit.framework";
-        public static readonly string TestActionInterface = "NUnit.Framework.ITestAction, nunit.framework";
+        public static readonly string TestActionInterface = "NUnit.Framework.ITestAction, nunit.framework";
+
+	    public static readonly string TestDetailsClass = "NUnit.Framework.TestDetails, nunit.framework";
 
         public static readonly string AssertException = "NUnit.Framework.AssertionException";
         public static readonly string IgnoreException = "NUnit.Framework.IgnoreException";

=== modified file 'src/NUnitCore/core/NUnitTestFixture.cs'
--- src/NUnitCore/core/NUnitTestFixture.cs	2011-08-28 19:58:58 +0000
+++ src/NUnitCore/core/NUnitTestFixture.cs	2012-01-29 01:29:26 +0000
@@ -31,7 +31,7 @@
                 Reflect.GetMethodsWithAttribute(this.FixtureType, NUnitFramework.TearDownAttribute, true);
 
 #if CLR_2_0 || CLR_4_0
-            this.actions = ActionsHelper.GetActionsFromTypeAttributes(fixtureType);
+            this.actions = ActionsHelper.GetActionsFromTypesAttributes(fixtureType);
 #endif
         }
 

=== modified file 'src/NUnitCore/core/ParameterizedTestMethodSuite.cs'
--- src/NUnitCore/core/ParameterizedTestMethodSuite.cs	2011-08-26 23:38:44 +0000
+++ src/NUnitCore/core/ParameterizedTestMethodSuite.cs	2012-01-29 01:29:26 +0000
@@ -3,7 +3,10 @@
 // This is free software licensed under the NUnit license. You may
 // obtain a copy of the license at http://nunit.org.
 // ****************************************************************
-using System.Collections;
+using System.Collections;
+#if CLR_2_0 || CLR_4_0
+using System.Collections.Generic;
+#endif
 using System.Reflection;
 using System.Text;
 
@@ -64,7 +67,7 @@
             }
 
 #if CLR_2_0 || CLR_4_0
-            this.actions = ActionsHelper.GetActionsFromAttributes(this.method);
+            this.actions = ActionsHelper.GetActionsFromAttributeProvider(this.method);
 #endif
 
             // DYNAMIC: Get the parameters, and add the methods here.
@@ -105,16 +108,24 @@
         /// <param name="suiteResult"></param>
         protected override void DoOneTimeTearDown(TestResult suiteResult)
         {
-        }
-
-        #if CLR_2_0 || CLR_4_0
-
-        protected override void ExecuteActions(ActionLevel level, ActionPhase phase)
-        {
-            ActionsHelper.ExecuteActions(level, phase, this.actions, this.Fixture, method);
-        }
-
-        #endif
-
+        }
+
+#if CLR_2_0 || CLR_4_0
+        protected override void ExecuteActions(ActionPhase phase)
+        {
+            List<TestAction> targetActions = new List<TestAction>();
+
+            if (this.actions != null)
+            {
+                foreach (var action in this.actions)
+                {
+                    if (action.DoesTarget(TestAction.TargetsSuite))
+                        targetActions.Add(action);
+                }
+            }
+
+            ActionsHelper.ExecuteActions(phase, targetActions, this);
+        }
+#endif
     }
 }

=== modified file 'src/NUnitCore/core/SetUpFixture.cs'
--- src/NUnitCore/core/SetUpFixture.cs	2011-03-30 20:37:44 +0000
+++ src/NUnitCore/core/SetUpFixture.cs	2012-01-29 01:29:26 +0000
@@ -30,7 +30,7 @@
 			this.fixtureTearDownMethods = Reflect.GetMethodsWithAttribute( type, NUnitFramework.TearDownAttribute, true );
 
 #if CLR_2_0 || CLR_4_0
-		    this.actions = ActionsHelper.GetActionsFromTypeAttributes(type);
+		    this.actions = ActionsHelper.GetActionsFromTypesAttributes(type);
 #endif
 		}
 		#endregion

=== added file 'src/NUnitCore/core/TestAction.cs'
--- src/NUnitCore/core/TestAction.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitCore/core/TestAction.cs	2012-01-29 01:29:26 +0000
@@ -0,0 +1,83 @@
+#if CLR_2_0 || CLR_4_0
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace NUnit.Core
+{
+    public class TestAction
+    {
+        public static readonly ushort TargetsSite = 1;
+        public static readonly ushort TargetsTest = 2;
+        public static readonly ushort TargetsSuite = 4;
+
+        private static readonly Type _ActionInterfaceType = null;
+        private static readonly Type _TestDetailsClassType = null;
+
+        static TestAction()
+        {
+            _ActionInterfaceType = Type.GetType(NUnitFramework.TestActionInterface);
+            _TestDetailsClassType = Type.GetType(NUnitFramework.TestDetailsClass);
+        }
+
+        private readonly object _Target;
+        private readonly ushort _Targets;
+
+        public TestAction(object target)
+        {
+            if(target == null)
+                throw new ArgumentNullException("target");
+
+            _Target = target;
+            _Targets = (ushort) Reflect.GetPropertyValue(target, "Targets");
+        }
+
+        public void ExecuteBefore(ITest test)
+        {
+            Execute(test, "Before");
+        }
+
+        public void ExecuteAfter(ITest test)
+        {
+            Execute(test, "After");
+        }
+
+        private void Execute(ITest test, string methodPrefix)
+        {
+            var method = Reflect.GetNamedMethod(_ActionInterfaceType, methodPrefix + "Test");
+            var details = CreateTestDetails(test);
+
+            Reflect.InvokeMethod(method, _Target, details);
+        }
+
+        private static object CreateTestDetails(ITest test)
+        {
+            object fixture = null;
+            MethodInfo method = null;
+
+            var testMethod = test as TestMethod;
+            if (testMethod != null)
+                method = testMethod.Method;
+
+            var testObject = test as Test;
+            if(testObject != null)
+                fixture = testObject.Fixture;
+
+            return Activator.CreateInstance(_TestDetailsClassType,
+                                            fixture,
+                                            method,
+                                            test.TestName.FullName,
+                                            test.TestType,
+                                            test.IsSuite);
+        }
+
+        public bool DoesTarget(ushort target)
+        {
+            return (_Targets & target) == target && _Targets != 0;
+        }
+
+        public int Targets { get { return _Targets; } }
+    }
+}
+#endif
\ No newline at end of file

=== modified file 'src/NUnitCore/core/TestAssembly.cs'
--- src/NUnitCore/core/TestAssembly.cs	2011-03-30 20:37:44 +0000
+++ src/NUnitCore/core/TestAssembly.cs	2012-01-29 01:29:26 +0000
@@ -21,8 +21,8 @@
         /// <param name="path">The path.</param>
         public TestAssembly(Assembly assembly, string path) : base(path)
         {
-#if CLR_2_0 || CLR_4_0
-            this.actions = ActionsHelper.GetActionsFromAttributes(assembly);
+#if CLR_2_0 || CLR_4_0
+            this.actions = ActionsHelper.GetActionsFromAttributeProvider(assembly);
 #endif
         }
 

=== modified file 'src/NUnitCore/core/TestMethod.cs'
--- src/NUnitCore/core/TestMethod.cs	2011-12-26 18:36:39 +0000
+++ src/NUnitCore/core/TestMethod.cs	2012-01-29 01:29:26 +0000
@@ -2,7 +2,8 @@
 // This is free software licensed under the NUnit license. You
 // may obtain a copy of the license as well as information regarding
 // copyright ownership at http://nunit.org.
-// ****************************************************************
+// ****************************************************************
+
 namespace NUnit.Core
 {
 	using System;
@@ -13,6 +14,10 @@
 	using System.Text.RegularExpressions;
 	using System.Reflection;
 
+#if CLR_2_0 || CLR_4_0
+    using System.Collections.Generic;
+#endif
+
 	/// <summary>
 	/// The TestMethod class represents a Test implemented as a method.
 	/// 
@@ -47,12 +52,12 @@
         /// <summary>
         /// The actions
         /// </summary>
-	    protected object[] actions;
+	    protected TestAction[] actions;
 
         /// <summary>
         /// The parent suite's actions
-        /// </summary>
-	    protected object[] suiteActions;
+        /// </summary>
+        protected TestAction[] suiteActions;
 #endif
 
         /// <summary>
@@ -239,8 +244,8 @@
 
             try
             {
-#if CLR_2_0 || CLR_4_0
-                this.actions = ActionsHelper.GetActionsFromAttributes(method);
+#if CLR_2_0 || CLR_4_0
+                this.actions = ActionsHelper.GetActionsFromAttributeProvider(method);
 #endif
 
                 // Temporary... to allow for tests that directly execute a test case);
@@ -379,22 +384,42 @@
 
 #if CLR_2_0 || CLR_4_0
 
-        protected virtual void ExecuteActions(ActionLevel level, ActionPhase phase)
-        {
-            object[][] targetActions = new object[][] { this.suiteActions, this.actions };
-            ActionsHelper.ExecuteActions(level, phase, targetActions, this.Fixture, this.Method);
+        protected virtual void ExecuteActions(ActionPhase phase)
+        {
+            List<TestAction> targetActions = new List<TestAction>();
+
+            if (this.suiteActions != null)
+            {
+                foreach (var action in this.suiteActions)
+                {
+                    if(action.DoesTarget(TestAction.TargetsTest))
+                        targetActions.Add(action);
+                }
+            }
+
+            if (this.actions != null)
+            {
+                foreach (var action in this.actions)
+                {
+                    
+                    if (action.DoesTarget(TestAction.TargetsSite) || (!(Parent is ParameterizedMethodSuite) && action.DoesTarget(TestAction.TargetsTest)))
+                        targetActions.Add(action);
+                }
+            }
+
+            ActionsHelper.ExecuteActions(phase, targetActions, this);
         }
 
         private void RunBeforeActions(TestResult testResult)
         {
-            ExecuteActions(ActionLevel.Test, ActionPhase.Before);
+            ExecuteActions(ActionPhase.Before);
         }
 
         private void RunAfterActions(TestResult testResult)
         {
             try
             {
-                ExecuteActions(ActionLevel.Test, ActionPhase.After);
+                ExecuteActions(ActionPhase.After);
             }
             catch (Exception ex)
             {

=== modified file 'src/NUnitCore/core/TestSuite.cs'
--- src/NUnitCore/core/TestSuite.cs	2011-12-28 03:44:23 +0000
+++ src/NUnitCore/core/TestSuite.cs	2012-01-29 01:29:26 +0000
@@ -2,8 +2,9 @@
 // This is free software licensed under the NUnit license. You
 // may obtain a copy of the license as well as information regarding
 // copyright ownership at http://nunit.org.
-// ****************************************************************
-
+// ****************************************************************
+
+
 namespace NUnit.Core
 {
 	using System;
@@ -13,6 +14,10 @@
 	using System.Reflection;
 	using NUnit.Core.Filters;
 
+#if CLR_2_0 || CLR_4_0
+    using System.Collections.Generic;
+#endif
+
 	/// <summary>
 	/// Summary description for TestSuite.
 	/// </summary>
@@ -52,7 +57,7 @@
         /// <summary>
         /// The actions for this suite
         /// </summary>
-	    protected object[] actions;
+	    protected TestAction[] actions;
 #endif
 
         /// <summary>
@@ -196,13 +201,13 @@
         }
 
 #if CLR_2_0 || CLR_4_0
-        internal virtual object[] GetTestActions()
-        {
-            ArrayList allActions = new ArrayList();
+        internal virtual TestAction[] GetTestActions()
+        {
+            List<TestAction> allActions = new List<TestAction>();
 
             if (this.Parent != null && this.Parent is TestSuite)
             {
-                object[] parentActions = ((TestSuite)this.Parent).GetTestActions();
+                TestAction[] parentActions = ((TestSuite)this.Parent).GetTestActions();
 
                 if (parentActions != null)
                     allActions.AddRange(parentActions);
@@ -378,16 +383,27 @@
 
 #if CLR_2_0 || CLR_4_0
 
-        protected virtual void ExecuteActions(ActionLevel level, ActionPhase phase)
-        {
-            ActionsHelper.ExecuteActions(level, phase, this.actions, this.Fixture, null);
+        protected virtual void ExecuteActions(ActionPhase phase)
+        {
+            List<TestAction> targetActions = new List<TestAction>();
+
+            if (this.actions != null)
+            {
+                foreach (var action in this.actions)
+                {
+                    if (action.DoesTarget(TestAction.TargetsSite) || action.DoesTarget(TestAction.TargetsSuite))
+                        targetActions.Add(action);
+                }
+            }
+
+            ActionsHelper.ExecuteActions(phase, targetActions, this);
         }
 
         protected virtual void DoOneTimeBeforeTestSuiteActions(TestResult suiteResult)
         {
             try
             {
-                ExecuteActions(ActionLevel.Suite, ActionPhase.Before);
+                ExecuteActions(ActionPhase.Before);
                 TestExecutionContext.CurrentContext.Update();
             }
             catch (Exception ex)
@@ -462,7 +478,7 @@
         {
             try
             {
-                ExecuteActions(ActionLevel.Suite, ActionPhase.After);
+                ExecuteActions(ActionPhase.After);
             }
             catch (Exception ex)
             {

=== modified file 'src/NUnitCore/core/nunit.core.dll.csproj'
--- src/NUnitCore/core/nunit.core.dll.csproj	2012-01-10 23:03:38 +0000
+++ src/NUnitCore/core/nunit.core.dll.csproj	2012-01-29 01:29:26 +0000
@@ -1,3 +1,4 @@
+<<<<<<< TREE
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
   <PropertyGroup>
@@ -210,4 +211,220 @@
     <PostBuildEvent>
     </PostBuildEvent>
   </PropertyGroup>
+=======
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EBD43A7F-AFCA-4281-BB53-5CDD91F966A3}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>nunit.core</AssemblyName>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Library</OutputType>
+    <RootNamespace>NUnit.Core</RootNamespace>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <PublishUrl>http://localhost/nunit.core/</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Web</InstallFrom>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>true</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>..\..\..\bin\Debug\lib\</OutputPath>
+    <BaseAddress>285212672</BaseAddress>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;DEBUG;CLR_2_0,NET_2_0,CS_3_0</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoWarn>1699</NoWarn>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>..\..\..\bin\Release\lib\</OutputPath>
+    <BaseAddress>285212672</BaseAddress>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;CLR_2_0,NET_2_0,CS_3_0</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <FileAlignment>4096</FileAlignment>
+    <NoWarn>1699</NoWarn>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+    <ProjectReference Include="..\interfaces\nunit.core.interfaces.dll.csproj">
+      <Name>nunit.core.interfaces.dll</Name>
+      <Project>{435428F8-5995-4CE4-8022-93D595A8CC0F}</Project>
+      <Private>False</Private>
+    </ProjectReference>
+    <Reference Include="System.Configuration" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\CommonAssemblyInfo.cs">
+      <Link>CommonAssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="AbstractTestCaseDecoration.cs" />
+    <Compile Include="AssemblyHelper.cs" />
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="AssemblyReader.cs" />
+    <Compile Include="AssemblyResolver.cs" />
+    <Compile Include="ActionsHelper.cs" />
+    <Compile Include="Builders\CombinatorialStrategy.cs" />
+    <Compile Include="Builders\CombinatorialTestCaseProvider.cs" />
+    <Compile Include="Builders\CombiningStrategy.cs" />
+    <Compile Include="Builders\DatapointProvider.cs" />
+    <Compile Include="Builders\InlineDataPointProvider.cs" />
+    <Compile Include="Builders\LegacySuiteBuilder.cs" />
+    <Compile Include="Builders\NUnitTestCaseBuilder.cs" />
+    <Compile Include="Builders\NUnitTestFixtureBuilder.cs" />
+    <Compile Include="Builders\PairwiseStrategy.cs" />
+    <Compile Include="Builders\ProviderCache.cs" />
+    <Compile Include="Builders\ProviderInfo.cs" />
+    <Compile Include="Builders\SequentialStrategy.cs" />
+    <Compile Include="Builders\SetUpFixtureBuilder.cs" />
+    <Compile Include="Builders\TestAssemblyBuilder.cs" />
+    <Compile Include="Builders\TestCaseParameterProvider.cs" />
+    <Compile Include="Builders\TestCaseSourceProvider.cs" />
+    <Compile Include="Builders\ValueSourceProvider.cs" />
+    <Compile Include="ContextDictionary.cs" />
+    <Compile Include="CoreExtensions.cs" />
+    <Compile Include="CultureDetector.cs" />
+    <Compile Include="DirectorySwapper.cs" />
+    <Compile Include="DomainAgent.cs" />
+    <Compile Include="EventListenerTextWriter.cs" />
+    <Compile Include="EventPump.cs" />
+    <Compile Include="EventQueue.cs" />
+    <Compile Include="ExpectedExceptionProcessor.cs" />
+    <Compile Include="Extensibility\DataPointProviders.cs" />
+    <Compile Include="Extensibility\EventListenerCollection.cs" />
+    <Compile Include="Extensibility\FrameworkRegistry.cs" />
+    <Compile Include="Extensibility\SuiteBuilderCollection.cs" />
+    <Compile Include="Extensibility\TestCaseBuilderCollection.cs" />
+    <Compile Include="Extensibility\TestCaseProviders.cs" />
+    <Compile Include="Extensibility\TestDecoratorCollection.cs" />
+    <Compile Include="ExtensionHost.cs" />
+    <Compile Include="ExtensionPoint.cs" />
+    <Compile Include="IgnoreDecorator.cs" />
+    <Compile Include="InternalTrace.cs" />
+    <Compile Include="InternalTraceWriter.cs" />
+    <Compile Include="InvalidSuiteException.cs" />
+    <Compile Include="InvalidTestFixtureException.cs" />
+    <Compile Include="LegacySuite.cs" />
+    <Compile Include="Log4NetCapture.cs" />
+    <Compile Include="LogCapture.cs" />
+    <Compile Include="Logger.cs" />
+    <Compile Include="MethodHelper.cs" />
+    <Compile Include="NamespaceSuite.cs" />
+    <Compile Include="NamespaceTreeBuilder.cs" />
+    <Compile Include="NoTestFixturesException.cs" />
+    <Compile Include="NullListener.cs" />
+    <Compile Include="NUnitConfiguration.cs" />
+    <Compile Include="NUnitException.cs" />
+    <Compile Include="NUnitFramework.cs" />
+    <Compile Include="NUnitTestFixture.cs" />
+    <Compile Include="NUnitTestMethod.cs" />
+    <Compile Include="ParameterizedFixtureSuite.cs" />
+    <Compile Include="ParameterizedTestMethodSuite.cs" />
+    <Compile Include="PlatformHelper.cs" />
+    <Compile Include="ProjectRootSuite.cs" />
+    <Compile Include="ProxyTestRunner.cs" />
+    <Compile Include="QueuingEventListener.cs" />
+    <Compile Include="Reflect.cs" />
+    <Compile Include="RemoteTestRunner.cs" />
+    <Compile Include="SetUpFixture.cs" />
+    <Compile Include="SimpleTestRunner.cs" />
+    <Compile Include="StringTextWriter.cs" />
+    <Compile Include="SuiteBuilderAttribute.cs" />
+    <Compile Include="TestAction.cs" />
+    <Compile Include="TestAssembly.cs" />
+    <Compile Include="TestBuilderAttribute.cs" />
+    <Compile Include="TestCaseBuilderAttribute.cs" />
+    <Compile Include="TestDecoratorAttribute.cs" />
+    <Compile Include="TestExecutionContext.cs" />
+    <Compile Include="TestFixture.cs" />
+    <Compile Include="TestFixtureBuilder.cs" />
+    <Compile Include="TestMethod.cs" />
+    <Compile Include="TestRunnerThread.cs" />
+    <Compile Include="TestSuite.cs" />
+    <Compile Include="TestSuiteBuilder.cs" />
+    <Compile Include="TestThread.cs" />
+    <Compile Include="TextCapture.cs" />
+    <Compile Include="ThreadedTestRunner.cs" />
+    <Compile Include="ThreadUtility.cs" />
+    <Compile Include="TypeHelper.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="nunit.core.build" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+>>>>>>> MERGE-SOURCE
 </Project>
\ No newline at end of file

=== modified file 'src/NUnitCore/tests/ActionAttributeExceptionTests.cs'
--- src/NUnitCore/tests/ActionAttributeExceptionTests.cs	2011-03-30 20:37:44 +0000
+++ src/NUnitCore/tests/ActionAttributeExceptionTests.cs	2012-01-29 01:29:26 +0000
@@ -42,52 +42,24 @@
         }
 
         [Test]
-        public void BeforeTestSuiteException()
-        {
-            ExceptionThrowingActionAttribute.Reset();
-            ExceptionThrowingActionAttribute.ThrowBeforeSuiteException = true;
-
-            ActionAttributeExceptionFixture.Reset();
-
-            TestResult result = FindFailureTestResult(RunTest());
-
-            Assert.IsTrue(result.FailureSite == FailureSite.SetUp);
-            Assert.IsFalse(ActionAttributeExceptionFixture.TestRun);
-        }
-
-        [Test]
-        public void AfterTestSuiteException()
-        {
-            ExceptionThrowingActionAttribute.Reset();
-            ExceptionThrowingActionAttribute.ThrowAfterSuiteException = true;
-
-            ActionAttributeExceptionFixture.Reset();
-
-            TestResult result = FindFailureTestResult(RunTest());
-
-            Assert.IsTrue(result.FailureSite == FailureSite.TearDown);
-            Assert.IsTrue(ActionAttributeExceptionFixture.TestRun);
-        }
-
-        [Test]
-        public void BeforeTestCaseException()
-        {
-            ExceptionThrowingActionAttribute.Reset();
-            ExceptionThrowingActionAttribute.ThrowBeforeCaseException = true;
-
-            ActionAttributeExceptionFixture.Reset();
-
-            TestResult result = FindFailureTestResult(RunTest());
-
-            Assert.IsTrue(result.FailureSite == FailureSite.SetUp);
-            Assert.IsFalse(ActionAttributeExceptionFixture.TestRun);
-        }
-
-        [Test]
-        public void AfterTestCaseException()
-        {
-            ExceptionThrowingActionAttribute.Reset();
-            ExceptionThrowingActionAttribute.ThrowAfterCaseException = true;
+        public void BeforeTestException()
+        {
+            ExceptionThrowingActionAttribute.Reset();
+            ExceptionThrowingActionAttribute.ThrowBeforeException = true;
+
+            ActionAttributeExceptionFixture.Reset();
+
+            TestResult result = FindFailureTestResult(RunTest());
+
+            Assert.IsTrue(result.FailureSite == FailureSite.SetUp);
+            Assert.IsFalse(ActionAttributeExceptionFixture.TestRun);
+        }
+
+        [Test]
+        public void AfterTestException()
+        {
+            ExceptionThrowingActionAttribute.Reset();
+            ExceptionThrowingActionAttribute.ThrowAfterException = true;
 
             ActionAttributeExceptionFixture.Reset();
 

=== modified file 'src/NUnitCore/tests/ActionAttributeTests.cs'
--- src/NUnitCore/tests/ActionAttributeTests.cs	2011-08-26 23:38:44 +0000
+++ src/NUnitCore/tests/ActionAttributeTests.cs	2012-01-29 01:29:26 +0000
@@ -1,7 +1,7 @@
 #if CLR_2_0 || CLR_4_0
 using System;
 using System.Collections;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 using NUnit.Framework;
 using NUnit.TestData.ActionAttributeTests;
 
@@ -19,22 +19,32 @@
         }
 
         private TestResult _result = null;
-        private readonly string[] _definitionSites = new string[]
+        private readonly string[] _suiteSites = new string[]
         {
             "Assembly",
-            "BaseSetUpFixture",
-            "SetUpFixture",
+            "BaseSetupFixture",
+            "SetupFixture",
             "BaseInterface",
             "BaseFixture",
             "Interface",
-            "Fixture",
-            "Method"
+            "Fixture"
+        };
+
+        private readonly string[] _parameterizedTestOutput = new string[]
+        {
+            "SomeTest-Case1",
+            "SomeTest-Case2"
+        };
+
+        private readonly string[] _testOutput = new string[]
+        {
+            "SomeTestNotParameterized",
         };
 
         [TestFixtureSetUp]
         public void Setup()
         {
-            ActionAttributeFixture.Results = new StringCollection();
+            ActionAttributeFixture.Results = new List<string>();
 
             TestSuiteBuilder builder = new TestSuiteBuilder();
             TestPackage package = new TestPackage(AssemblyHelper.GetAssemblyPath(typeof(ActionAttributeFixture)));
@@ -47,173 +57,114 @@
         [Test]
         public void TestsRunsSuccessfully()
         {
-            Assert.IsTrue(_result.IsSuccess, "Test run was not successful.");
-            Assert.Contains("SomeTest-Case1", ActionAttributeFixture.Results, "Test Case 1 was not run.");
-            Assert.Contains("SomeTest-Case2", ActionAttributeFixture.Results, "Test Case 2 was not run.");
-            Assert.Contains("SomeOtherTest", ActionAttributeFixture.Results, "SomeOtherTest was not run.");
-
+            Assert.IsTrue(_result.IsSuccess, "Test run was not successful.");
+
+            Console.WriteLine("{prefix}.{phase}.{hasFixture}.{hasMethod}");            
             foreach(string message in ActionAttributeFixture.Results)
                 Console.WriteLine(message);
         }
 
-        [Test]
-        public void DefinitionSites_BeforeSuite_ExecuteFirst_InOrder()
-        {
-            for (int i = 0; i < _definitionSites.Length - 1; i++)
-            {
-                string prefix = string.Format("{0}.BeforeTestSuite-", _definitionSites[i]);
-                
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-
-        [Test]
-        public void DefinitionSites_AfterSuite_ExecuteLast_InOrder()
-        {
-            int lastIndex = ActionAttributeFixture.Results.Count - 1;
-            for (int i = lastIndex; i > lastIndex - _definitionSites.Length; i--)
-            {
-                string prefix = string.Format("{0}.AfterTestSuite-", _definitionSites[lastIndex - i]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void DefinitionSites_BeforeTest_ExecuteInOrder_ForSomeOtherTest()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeOtherTest") - _definitionSites.Length - 1;
-            for (int i = startIndex; i < startIndex; i++)
-            {
-                string prefix = string.Format("{0}.BeforeTestCase-", _definitionSites[i - startIndex]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void DefinitionSites_AfterTest_ExecuteInOrder_ForSomeOtherTest()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeOtherTest");
-            for (int i = 1; i <= _definitionSites.Length - 1; i++)
-            {
-                string prefix = string.Format("{0}.AfterTestCase-", _definitionSites[_definitionSites.Length - 1 - i]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void AllDefinitionSites_BeforeTest_ExecuteInOrder_ForSomeTestCase1()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1") - _definitionSites.Length;
-            for (int i = startIndex; i < startIndex; i++)
-            {
-                string prefix = string.Format("{0}.BeforeTestCase-", _definitionSites[i - startIndex]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void AllDefinitionSites_AfterTest_ExecuteInOrder_ForSomeTestCase1()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1");
-            for (int i = 1; i <= _definitionSites.Length; i++)
-            {
-                string prefix = string.Format("{0}.AfterTestCase-", _definitionSites[_definitionSites.Length - i]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void AllDefinitionSites_BeforeTest_ExecuteInOrder_ForSomeTestCase2()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2") - _definitionSites.Length;
-            for (int i = startIndex; i < startIndex; i++)
-            {
-                string prefix = string.Format("{0}.BeforeTestCase-", _definitionSites[i - startIndex]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void AllDefinitionSites_AfterTest_ExecuteInOrder_ForSomeTestCase2()
-        {
-            int startIndex = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2");
-            for (int i = 1; i <= _definitionSites.Length; i++)
-            {
-                string prefix = string.Format("{0}.AfterTestCase-", _definitionSites[_definitionSites.Length - i]);
-
-                Assert.IsTrue(
-                    ActionAttributeFixture.Results[startIndex + i].StartsWith(prefix),
-                    string.Format("Did not find prefix '{0}' at index {1}", prefix, i));
-            }
-        }
-
-        [Test]
-        public void MethodDefinedSite_BeforeSuite_BeforeSomeTestCase1()
-        {
-            int testCase = ActionAttributeFixture.Results.IndexOf("SomeTest-Case1");
-            int index = ActionAttributeFixture.Results.IndexOf("Method.BeforeTestSuite-ActionAttributeFixture-SomeTest");
-            
-            Assert.IsTrue(index >= 0);
-            Assert.IsTrue(testCase > index);
-        }
-
-        [Test]
-        public void MethodDefinedSite_AfterSuite_BeforeSomeTestCase2()
-        {
-            int testCase = ActionAttributeFixture.Results.IndexOf("SomeTest-Case2");
-            int index = ActionAttributeFixture.Results.IndexOf("Method.AfterTestSuite-ActionAttributeFixture-SomeTest");
-
-            Assert.IsTrue(index >= 0);
-            Assert.IsTrue(testCase < index);
-        }
-
-        [Test]
-        public void AllActions_BeforeAndAfterTest_HasAccessToFixture()
-        {
-            foreach(string message in ActionAttributeFixture.Results)
-            {
-                if (message.Contains("BeforeTestCase") || message.Contains("AfterTestCase"))
-                    Assert.IsTrue(message.Contains(typeof(ActionAttributeFixture).Name), string.Format("'{0}' shows action does not have access to fixture.", message));
-            }
-        }
-
-        [Test]
-        public void AllActions_BeforeAndAfterTest_HasAccessToMethodInfo()
-        {
-            StringCollection validEndSegments = new StringCollection();
-            validEndSegments.AddRange(new string[] {"SomeOtherTest", "SomeTest"});
-
-            foreach (string message in ActionAttributeFixture.Results)
-            {
-                if (message.Contains("BeforeTestCase") || message.Contains("AfterTestCase"))
-                {
-                    string endSegment = message.Substring(message.LastIndexOf('-') + 1);
-
-                    Assert.IsTrue(validEndSegments.Contains(endSegment),
-                                  string.Format("'{0}' shows action does not have access to method info.", message));
-                }
-            }
+        private void AssertResultEquals(List<string> input, int index, string expected)
+        {
+            Assert.IsTrue(input[index].Equals(expected), string.Format("Did not find '{0}' at index {1}; instead '{2}'", expected, index, input[index]));
+        }
+
+        [Test]
+        public void ExpectedOutput_InCorrectOrder()
+        {
+            List<string> expectedResults = new List<string>(@"AssemblySuite.Before.false.false
+AssemblySite.Before.false.false
+BaseSetupFixtureSuite.Before.true.false
+BaseSetupFixtureSite.Before.true.false
+SetupFixtureSuite.Before.true.false
+SetupFixtureSite.Before.true.false
+BaseInterfaceSuite.Before.true.false
+BaseInterfaceSite.Before.true.false
+BaseFixtureSuite.Before.true.false
+BaseFixtureSite.Before.true.false
+InterfaceSuite.Before.true.false
+InterfaceSite.Before.true.false
+FixtureSuite.Before.true.false
+FixtureSite.Before.true.false
+ParameterizedSuite.Before.true.false
+AssemblyTest.Before.true.true
+BaseSetupFixtureTest.Before.true.true
+SetupFixtureTest.Before.true.true
+BaseInterfaceTest.Before.true.true
+BaseFixtureTest.Before.true.true
+InterfaceTest.Before.true.true
+FixtureTest.Before.true.true
+ParameterizedTest.Before.true.true
+ParameterizedSite.Before.true.true
+SomeTest-Case1
+ParameterizedSite.After.true.true
+ParameterizedTest.After.true.true
+FixtureTest.After.true.true
+InterfaceTest.After.true.true
+BaseFixtureTest.After.true.true
+BaseInterfaceTest.After.true.true
+SetupFixtureTest.After.true.true
+BaseSetupFixtureTest.After.true.true
+AssemblyTest.After.true.true
+AssemblyTest.Before.true.true
+BaseSetupFixtureTest.Before.true.true
+SetupFixtureTest.Before.true.true
+BaseInterfaceTest.Before.true.true
+BaseFixtureTest.Before.true.true
+InterfaceTest.Before.true.true
+FixtureTest.Before.true.true
+ParameterizedTest.Before.true.true
+ParameterizedSite.Before.true.true
+SomeTest-Case2
+ParameterizedSite.After.true.true
+ParameterizedTest.After.true.true
+FixtureTest.After.true.true
+InterfaceTest.After.true.true
+BaseFixtureTest.After.true.true
+BaseInterfaceTest.After.true.true
+SetupFixtureTest.After.true.true
+BaseSetupFixtureTest.After.true.true
+AssemblyTest.After.true.true
+ParameterizedSuite.After.true.false
+AssemblyTest.Before.true.true
+BaseSetupFixtureTest.Before.true.true
+SetupFixtureTest.Before.true.true
+BaseInterfaceTest.Before.true.true
+BaseFixtureTest.Before.true.true
+InterfaceTest.Before.true.true
+FixtureTest.Before.true.true
+MethodTest.Before.true.true
+MethodSite.Before.true.true
+SomeTestNotParameterized
+MethodSite.After.true.true
+MethodTest.After.true.true
+FixtureTest.After.true.true
+InterfaceTest.After.true.true
+BaseFixtureTest.After.true.true
+BaseInterfaceTest.After.true.true
+SetupFixtureTest.After.true.true
+BaseSetupFixtureTest.After.true.true
+AssemblyTest.After.true.true
+FixtureSite.After.true.false
+FixtureSuite.After.true.false
+InterfaceSite.After.true.false
+InterfaceSuite.After.true.false
+BaseFixtureSite.After.true.false
+BaseFixtureSuite.After.true.false
+BaseInterfaceSite.After.true.false
+BaseInterfaceSuite.After.true.false
+SetupFixtureSite.After.true.false
+SetupFixtureSuite.After.true.false
+BaseSetupFixtureSite.After.true.false
+BaseSetupFixtureSuite.After.true.false
+AssemblySite.After.false.false
+AssemblySuite.After.false.false".Split(new[]{"\r\n"}, StringSplitOptions.RemoveEmptyEntries));
+
+
+            Assert.AreEqual(expectedResults.Count, ActionAttributeFixture.Results.Count);
+
+            for(int i = 0; i < expectedResults.Count; i++)
+                Assert.IsTrue(expectedResults[i] == ActionAttributeFixture.Results[i]);
         }
     }
 }

=== added file 'src/NUnitFramework/framework/ActionTargets.cs'
--- src/NUnitFramework/framework/ActionTargets.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/ActionTargets.cs	2012-01-29 01:29:26 +0000
@@ -0,0 +1,28 @@
+#if CLR_2_0 || CLR_4_0
+using System;
+
+namespace NUnit.Framework
+{
+    /// <summary>
+    /// The different targets a test action attribute can be applied to
+    /// </summary>
+    [Flags]
+    public enum ActionTargets : ushort
+    {
+        /// <summary>
+        /// Target is defined by where the action attribute is attached
+        /// </summary>
+        Site = 1,
+
+        /// <summary>
+        /// Target a individual test case
+        /// </summary>
+        Test = 2,
+
+        /// <summary>
+        /// Target a suite of test cases
+        /// </summary>
+        Suite = 4
+    }
+}
+#endif

=== added file 'src/NUnitFramework/framework/Attributes/TestActionAttribute.cs'
--- src/NUnitFramework/framework/Attributes/TestActionAttribute.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Attributes/TestActionAttribute.cs	2012-01-29 01:29:26 +0000
@@ -0,0 +1,23 @@
+#if CLR_2_0 || CLR_4_0
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NUnit.Framework
+{
+    /// <summary>
+    /// Provide actions to execute before and after tests.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
+    public abstract class TestActionAttribute : Attribute, ITestAction
+    {
+        public virtual void BeforeTest(TestDetails testDetails) { }
+        public virtual void AfterTest(TestDetails testDetails) { }
+        
+        public virtual ActionTargets Targets
+        {
+            get { return ActionTargets.Site; }
+        }
+    }
+}
+#endif
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Interfaces/ITestAction.cs'
--- src/NUnitFramework/framework/Interfaces/ITestAction.cs	2011-03-30 20:37:44 +0000
+++ src/NUnitFramework/framework/Interfaces/ITestAction.cs	2012-01-29 01:29:26 +0000
@@ -5,15 +5,34 @@
 // ****************************************************************
 
 #if CLR_2_0 || CLR_4_0
-using System;
-
+using System;
+using System.Reflection;
+
 namespace NUnit.Framework
-{
-    /// <summary>
-    /// The base interface for test actions
-    /// </summary>
+{
+    /// <summary>
+    /// When implemented by an attribute, this interface implemented to provide actions to execute before and after tests.
+    /// </summary>
     public interface ITestAction
-    {
+    {
+        /// <summary>
+        /// Executed before each test is run
+        /// </summary>
+        /// <param name="testDetails">Provides details about the test that is going to be run.</param>
+        void BeforeTest(TestDetails testDetails);
+
+        /// <summary>
+        /// Executed after each test is run
+        /// </summary>
+        /// <param name="testDetails">Provides details about the test that has just been run.</param>
+        void AfterTest(TestDetails testDetails);
+
+
+        /// <summary>
+        /// Provides the target for the action attribute
+        /// </summary>
+        /// <returns>The target for the action attribute</returns>
+        ActionTargets Targets { get; }
     }
 }
 #endif

=== removed file 'src/NUnitFramework/framework/Interfaces/ITestCaseAction.cs'
--- src/NUnitFramework/framework/Interfaces/ITestCaseAction.cs	2011-08-26 23:38:44 +0000
+++ src/NUnitFramework/framework/Interfaces/ITestCaseAction.cs	1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
-// ****************************************************************
-// Copyright 2011, Charlie Poole
-// This is free software licensed under the NUnit license. You may
-// obtain a copy of the license at http://nunit.org
-// ****************************************************************
-
-#if CLR_2_0 || CLR_4_0
-using System;
-using System.Reflection;
-
-namespace NUnit.Framework
-{
-    /// <summary>
-    /// The interface implemented to provide actions to execute before and after tests.
-    /// </summary>
-    public interface ITestCaseAction : ITestAction
-    {
-        /// <summary>
-        /// Executed before each test case is run
-        /// </summary>
-        /// <param name="fixture">The fixture the test is part of, if available.</param>
-        /// <param name="method">The method that implements the test case, if available.</param>
-        void BeforeTestCase(object fixture, MethodInfo method);
-
-        /// <summary>
-        /// Executed after each test case is run
-        /// </summary>
-        /// <param name="fixture">The fixture the test is part of, if available.</param>
-        /// <param name="method">The method that implements the test case, if available.</param>
-        void AfterTestCase(object fixture, MethodInfo method);
-    }
-}
-#endif

=== removed file 'src/NUnitFramework/framework/Interfaces/ITestSuiteAction.cs'
--- src/NUnitFramework/framework/Interfaces/ITestSuiteAction.cs	2011-08-26 23:38:44 +0000
+++ src/NUnitFramework/framework/Interfaces/ITestSuiteAction.cs	1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
-// ****************************************************************
-// Copyright 2011, Charlie Poole
-// This is free software licensed under the NUnit license. You may
-// obtain a copy of the license at http://nunit.org
-// ****************************************************************
-
-#if CLR_2_0 || CLR_4_0
-using System;
-using System.Reflection;
-
-namespace NUnit.Framework
-{
-    /// <summary>
-    /// The interface implemented to provide actions to execute before and after suites.
-    /// </summary>
-    public interface ITestSuiteAction : ITestAction
-    {
-        /// <summary>
-        /// Executed before each suite is run
-        /// </summary>
-        /// <param name="fixture">The fixture that defines the test suite, if available.</param>
-        /// <param name="method">The method that defines the test suite, if available.</param>
-        void BeforeTestSuite(object fixture, MethodInfo method);
-
-        /// <summary>
-        /// Executed after each suite is run
-        /// </summary>
-        /// <param name="fixture">The fixture that defines the test suite, if available.</param>
-        /// <param name="method">The method that defines the test suite, if available.</param>
-        void AfterTestSuite(object fixture, MethodInfo method);
-    }
-}
-#endif

=== added file 'src/NUnitFramework/framework/TestDetails.cs'
--- src/NUnitFramework/framework/TestDetails.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/TestDetails.cs	2012-01-29 01:29:26 +0000
@@ -0,0 +1,60 @@
+#if CLR_2_0 || CLR_4_0
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace NUnit.Framework
+{
+    /// <summary>
+    /// Provides details about a test
+    /// </summary>
+    public class TestDetails
+    {
+        ///<summary>
+        /// Creates an instance of TestDetails
+        ///</summary>
+        ///<param name="fixture">The fixture that the test is a member of, if available.</param>
+        ///<param name="method">The method that implements the test, if available.</param>
+        ///<param name="fullName">The full name of the test.</param>
+        ///<param name="type">A string representing the type of test, e.g. "Test Case".</param>
+        ///<param name="isSuite">Indicates if the test represents a suite of tests.</param>
+        public TestDetails(object fixture, MethodInfo method, string fullName, string type, bool isSuite)
+        {
+            Fixture = fixture;
+            Method = method;
+
+            FullName = fullName;
+            Type = type;
+            IsSuite = isSuite;
+        }
+        
+        ///<summary>
+        /// The fixture that the test is a member of, if available.
+        ///</summary>
+        public object Fixture { get; private set; }
+
+        /// <summary>
+        /// The method that implements the test, if available.
+        /// </summary>
+        public MethodInfo Method { get; private set; }
+
+        /// <summary>
+        /// The full name of the test.
+        /// </summary>
+        public string FullName { get; private set; }
+
+        /// <summary>
+        /// A string representing the type of test, e.g. "Test Case".
+        /// </summary>
+        public string Type { get; private set; }
+
+        /// <summary>
+        /// Indicates if the test represents a suite of tests.
+        /// </summary>
+        public bool IsSuite { get; private set; }
+    }
+}
+
+#endif
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/nunit.framework.dll.csproj'
--- src/NUnitFramework/framework/nunit.framework.dll.csproj	2011-06-11 23:59:16 +0000
+++ src/NUnitFramework/framework/nunit.framework.dll.csproj	2012-01-29 01:29:26 +0000
@@ -1,193 +1,194 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
-  <PropertyGroup>
-    <ProjectType>Local</ProjectType>
-    <ProductVersion>9.0.21022</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{83DD7E12-A705-4DBA-9D71-09C8973D9382}</ProjectGuid>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <AssemblyKeyContainerName>
-    </AssemblyKeyContainerName>
-    <AssemblyName>nunit.framework</AssemblyName>
-    <DefaultClientScript>JScript</DefaultClientScript>
-    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
-    <DefaultTargetSchema>IE50</DefaultTargetSchema>
-    <DelaySign>false</DelaySign>
-    <OutputType>Library</OutputType>
-    <RootNamespace>NUnit.Framework</RootNamespace>
-    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <UpgradeBackupLocation>
-    </UpgradeBackupLocation>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <OutputPath>..\..\..\bin\Debug\framework\</OutputPath>
-    <BaseAddress>285212672</BaseAddress>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>TRACE;DEBUG;CLR_2_0</DefineConstants>
-    <DocumentationFile>..\..\..\bin\Debug\framework\nunit.framework.xml</DocumentationFile>
-    <DebugSymbols>true</DebugSymbols>
-    <FileAlignment>4096</FileAlignment>
-    <NoWarn>1699</NoWarn>
-    <Optimize>false</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>full</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <OutputPath>..\..\..\bin\Release\framework\</OutputPath>
-    <BaseAddress>285212672</BaseAddress>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>TRACE;CLR_2_0</DefineConstants>
-    <DocumentationFile>..\..\..\bin\Release\framework\nunit.framework.xml</DocumentationFile>
-    <FileAlignment>4096</FileAlignment>
-    <NoWarn>1699</NoWarn>
-    <Optimize>true</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>none</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System">
-      <Name>System</Name>
-    </Reference>
-    <Reference Include="System.Data">
-      <Name>System.Data</Name>
-    </Reference>
-    <Reference Include="System.Xml">
-      <Name>System.XML</Name>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="..\..\CommonAssemblyInfo.cs">
-      <Link>CommonAssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="AssemblyInfo.cs" />
-    <Compile Include="Assert.cs" />
-    <Compile Include="AssertionHelper.cs" />
-    <Compile Include="Assume.cs" />
-    <Compile Include="Attributes\CategoryAttribute.cs" />
-    <Compile Include="Attributes\DatapointAttributes.cs" />
-    <Compile Include="Attributes\DescriptionAttribute.cs" />
-    <Compile Include="Attributes\ExpectedExceptionAttribute.cs" />
-    <Compile Include="Attributes\ExplicitAttribute.cs" />
-    <Compile Include="Attributes\IgnoreAttribute.cs" />
-    <Compile Include="Attributes\IncludeExcludeAttributes.cs" />
-    <Compile Include="Attributes\JoinTypeAttributes.cs" />
-    <Compile Include="Attributes\MaxTimeAttribute.cs" />
-    <Compile Include="Attributes\PropertyAttribute.cs" />
-    <Compile Include="Attributes\RandomAttribute.cs" />
-    <Compile Include="Attributes\RangeAttribute.cs" />
-    <Compile Include="Attributes\RepeatAttribute.cs" />
-    <Compile Include="Attributes\RequiredAddinAttribute.cs" />
-    <Compile Include="Attributes\SetCultureAttribute.cs" />
-    <Compile Include="Attributes\SetUICultureAttribute.cs" />
-    <Compile Include="Attributes\SetUpAttribute.cs" />
-    <Compile Include="Attributes\SetUpFixtureAttribute.cs" />
-    <Compile Include="Attributes\SuiteAttribute.cs" />
-    <Compile Include="Attributes\TearDownAttribute.cs" />
-    <Compile Include="Attributes\TestAttribute.cs" />
-    <Compile Include="Attributes\TestCaseAttribute.cs" />
-    <Compile Include="Attributes\TestCaseSourceAttribute.cs" />
-    <Compile Include="Attributes\TestFixtureAttribute.cs" />
-    <Compile Include="Attributes\TestFixtureSetUpAttribute.cs" />
-    <Compile Include="Attributes\TestFixtureTearDownAttribute.cs" />
-    <Compile Include="Attributes\TheoryAttribute.cs" />
-    <Compile Include="Attributes\ThreadingAttributes.cs" />
-    <Compile Include="Attributes\ValuesAttribute.cs" />
-    <Compile Include="Attributes\ValueSourceAttribute.cs" />
-    <Compile Include="CollectionAssert.cs" />
-    <Compile Include="Constraints\AttributeConstraints.cs" />
-    <Compile Include="Constraints\BasicConstraints.cs" />
-    <Compile Include="Constraints\BinaryOperations.cs" />
-    <Compile Include="Constraints\CollectionConstraints.cs" />
-    <Compile Include="Constraints\CollectionTally.cs" />
-    <Compile Include="Constraints\ComparisonAdapter.cs" />
-    <Compile Include="Constraints\ComparisonConstraints.cs" />
-    <Compile Include="Constraints\Constraint.cs" />
-    <Compile Include="Constraints\ConstraintBuilder.cs" />
-    <Compile Include="Constraints\ConstraintExpression.cs" />
-    <Compile Include="Constraints\ConstraintExpressionBase.cs" />
-    <Compile Include="Constraints\ConstraintFactory.cs" />
-    <Compile Include="Constraints\ConstraintOperators.cs" />
-    <Compile Include="Constraints\ContainsConstraint.cs" />
-    <Compile Include="Constraints\DelayedConstraint.cs" />
-    <Compile Include="Constraints\DirectoryConstraints.cs" />
-    <Compile Include="Constraints\EmptyConstraint.cs" />
-    <Compile Include="Constraints\EqualConstraint.cs" />
-    <Compile Include="Constraints\EqualityAdapter.cs" />
-    <Compile Include="Constraints\FloatingPointNumerics.cs" />
-    <Compile Include="Constraints\GreaterThanConstraint.cs" />
-    <Compile Include="Constraints\GreaterThanOrEqualConstraint.cs" />
-    <Compile Include="Constraints\IResolveConstraint.cs" />
-    <Compile Include="Constraints\LessThanConstraint.cs" />
-    <Compile Include="Constraints\LessThanOrEqualConstraint.cs" />
-    <Compile Include="Constraints\MessageWriter.cs" />
-    <Compile Include="Constraints\MsgUtils.cs" />
-    <Compile Include="Constraints\Numerics.cs" />
-    <Compile Include="Constraints\NUnitComparer.cs" />
-    <Compile Include="Constraints\NUnitEqualityComparer.cs" />
-    <Compile Include="Constraints\PathConstraints.cs" />
-    <Compile Include="Constraints\PredicateConstraint.cs" />
-    <Compile Include="Constraints\PrefixConstraints.cs" />
-    <Compile Include="Constraints\PropertyConstraint.cs" />
-    <Compile Include="Constraints\RangeConstraint.cs" />
-    <Compile Include="Constraints\ResolvableConstraintExpression.cs" />
-    <Compile Include="Constraints\ReusableConstraint.cs" />
-    <Compile Include="Constraints\SameAsConstraint.cs" />
-    <Compile Include="Constraints\SerializableConstraints.cs" />
-    <Compile Include="Constraints\StringConstraints.cs" />
-    <Compile Include="Constraints\ThrowsConstraint.cs" />
-    <Compile Include="Constraints\Tolerance.cs" />
-    <Compile Include="Constraints\TypeConstraints.cs" />
-    <Compile Include="Contains.cs" />
-    <Compile Include="DirectoryAssert.cs" />
-    <Compile Include="Exceptions\AssertionException.cs" />
-    <Compile Include="Exceptions\IgnoreException.cs" />
-    <Compile Include="Exceptions\InconclusiveException.cs" />
-    <Compile Include="Exceptions\SuccessException.cs" />
-    <Compile Include="FileAssert.cs" />
-    <Compile Include="GlobalSettings.cs" />
-    <Compile Include="Has.cs" />
-    <Compile Include="Interfaces\INUnitEqualityComparer.cs" />
-    <Compile Include="Interfaces\ITestAction.cs" />
-    <Compile Include="IExpectException.cs" />
-    <Compile Include="Is.cs" />
-    <Compile Include="Interfaces\ITestCaseAction.cs" />
-    <Compile Include="ITestCaseData.cs" />
-    <Compile Include="Interfaces\ITestSuiteAction.cs" />
-    <Compile Include="Iz.cs" />
-    <Compile Include="List.cs" />
-    <Compile Include="ListMapper.cs" />
-    <Compile Include="Randomizer.cs" />
-    <Compile Include="SpecialValue.cs" />
-    <Compile Include="StringAssert.cs" />
-    <Compile Include="TestCaseData.cs" />
-    <Compile Include="TestContext.cs" />
-    <Compile Include="TestState.cs" />
-    <Compile Include="TestStatus.cs" />
-    <Compile Include="Text.cs" />
-    <Compile Include="TextMessageWriter.cs" />
-    <Compile Include="Throws.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="nunit.framework.build" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{83DD7E12-A705-4DBA-9D71-09C8973D9382}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>nunit.framework</AssemblyName>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Library</OutputType>
+    <RootNamespace>NUnit.Framework</RootNamespace>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>2.0</OldToolsVersion>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>..\..\..\bin\Debug\framework\</OutputPath>
+    <BaseAddress>285212672</BaseAddress>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;DEBUG;CLR_2_0</DefineConstants>
+    <DocumentationFile>..\..\..\bin\Debug\framework\nunit.framework.xml</DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoWarn>1699</NoWarn>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>..\..\..\bin\Release\framework\</OutputPath>
+    <BaseAddress>285212672</BaseAddress>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE;CLR_2_0</DefineConstants>
+    <DocumentationFile>..\..\..\bin\Release\framework\nunit.framework.xml</DocumentationFile>
+    <FileAlignment>4096</FileAlignment>
+    <NoWarn>1699</NoWarn>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\CommonAssemblyInfo.cs">
+      <Link>CommonAssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="Assert.cs" />
+    <Compile Include="AssertionHelper.cs" />
+    <Compile Include="Assume.cs" />
+    <Compile Include="ActionTargets.cs" />
+    <Compile Include="Attributes\CategoryAttribute.cs" />
+    <Compile Include="Attributes\DatapointAttributes.cs" />
+    <Compile Include="Attributes\DescriptionAttribute.cs" />
+    <Compile Include="Attributes\ExpectedExceptionAttribute.cs" />
+    <Compile Include="Attributes\ExplicitAttribute.cs" />
+    <Compile Include="Attributes\IgnoreAttribute.cs" />
+    <Compile Include="Attributes\IncludeExcludeAttributes.cs" />
+    <Compile Include="Attributes\JoinTypeAttributes.cs" />
+    <Compile Include="Attributes\MaxTimeAttribute.cs" />
+    <Compile Include="Attributes\PropertyAttribute.cs" />
+    <Compile Include="Attributes\RandomAttribute.cs" />
+    <Compile Include="Attributes\RangeAttribute.cs" />
+    <Compile Include="Attributes\RepeatAttribute.cs" />
+    <Compile Include="Attributes\RequiredAddinAttribute.cs" />
+    <Compile Include="Attributes\SetCultureAttribute.cs" />
+    <Compile Include="Attributes\SetUICultureAttribute.cs" />
+    <Compile Include="Attributes\SetUpAttribute.cs" />
+    <Compile Include="Attributes\SetUpFixtureAttribute.cs" />
+    <Compile Include="Attributes\SuiteAttribute.cs" />
+    <Compile Include="Attributes\TearDownAttribute.cs" />
+    <Compile Include="Attributes\TestActionAttribute.cs" />
+    <Compile Include="Attributes\TestAttribute.cs" />
+    <Compile Include="Attributes\TestCaseAttribute.cs" />
+    <Compile Include="Attributes\TestCaseSourceAttribute.cs" />
+    <Compile Include="Attributes\TestFixtureAttribute.cs" />
+    <Compile Include="Attributes\TestFixtureSetUpAttribute.cs" />
+    <Compile Include="Attributes\TestFixtureTearDownAttribute.cs" />
+    <Compile Include="Attributes\TheoryAttribute.cs" />
+    <Compile Include="Attributes\ThreadingAttributes.cs" />
+    <Compile Include="Attributes\ValuesAttribute.cs" />
+    <Compile Include="Attributes\ValueSourceAttribute.cs" />
+    <Compile Include="CollectionAssert.cs" />
+    <Compile Include="Constraints\AttributeConstraints.cs" />
+    <Compile Include="Constraints\BasicConstraints.cs" />
+    <Compile Include="Constraints\BinaryOperations.cs" />
+    <Compile Include="Constraints\CollectionConstraints.cs" />
+    <Compile Include="Constraints\CollectionTally.cs" />
+    <Compile Include="Constraints\ComparisonAdapter.cs" />
+    <Compile Include="Constraints\ComparisonConstraints.cs" />
+    <Compile Include="Constraints\Constraint.cs" />
+    <Compile Include="Constraints\ConstraintBuilder.cs" />
+    <Compile Include="Constraints\ConstraintExpression.cs" />
+    <Compile Include="Constraints\ConstraintExpressionBase.cs" />
+    <Compile Include="Constraints\ConstraintFactory.cs" />
+    <Compile Include="Constraints\ConstraintOperators.cs" />
+    <Compile Include="Constraints\ContainsConstraint.cs" />
+    <Compile Include="Constraints\DelayedConstraint.cs" />
+    <Compile Include="Constraints\DirectoryConstraints.cs" />
+    <Compile Include="Constraints\EmptyConstraint.cs" />
+    <Compile Include="Constraints\EqualConstraint.cs" />
+    <Compile Include="Constraints\EqualityAdapter.cs" />
+    <Compile Include="Constraints\FloatingPointNumerics.cs" />
+    <Compile Include="Constraints\GreaterThanConstraint.cs" />
+    <Compile Include="Constraints\GreaterThanOrEqualConstraint.cs" />
+    <Compile Include="Constraints\IResolveConstraint.cs" />
+    <Compile Include="Constraints\LessThanConstraint.cs" />
+    <Compile Include="Constraints\LessThanOrEqualConstraint.cs" />
+    <Compile Include="Constraints\MessageWriter.cs" />
+    <Compile Include="Constraints\MsgUtils.cs" />
+    <Compile Include="Constraints\Numerics.cs" />
+    <Compile Include="Constraints\NUnitComparer.cs" />
+    <Compile Include="Constraints\NUnitEqualityComparer.cs" />
+    <Compile Include="Constraints\PathConstraints.cs" />
+    <Compile Include="Constraints\PredicateConstraint.cs" />
+    <Compile Include="Constraints\PrefixConstraints.cs" />
+    <Compile Include="Constraints\PropertyConstraint.cs" />
+    <Compile Include="Constraints\RangeConstraint.cs" />
+    <Compile Include="Constraints\ResolvableConstraintExpression.cs" />
+    <Compile Include="Constraints\ReusableConstraint.cs" />
+    <Compile Include="Constraints\SameAsConstraint.cs" />
+    <Compile Include="Constraints\SerializableConstraints.cs" />
+    <Compile Include="Constraints\StringConstraints.cs" />
+    <Compile Include="Constraints\ThrowsConstraint.cs" />
+    <Compile Include="Constraints\Tolerance.cs" />
+    <Compile Include="Constraints\TypeConstraints.cs" />
+    <Compile Include="Contains.cs" />
+    <Compile Include="DirectoryAssert.cs" />
+    <Compile Include="Exceptions\AssertionException.cs" />
+    <Compile Include="Exceptions\IgnoreException.cs" />
+    <Compile Include="Exceptions\InconclusiveException.cs" />
+    <Compile Include="Exceptions\SuccessException.cs" />
+    <Compile Include="FileAssert.cs" />
+    <Compile Include="GlobalSettings.cs" />
+    <Compile Include="Has.cs" />
+    <Compile Include="Interfaces\INUnitEqualityComparer.cs" />
+    <Compile Include="Interfaces\ITestAction.cs" />
+    <Compile Include="IExpectException.cs" />
+    <Compile Include="TestDetails.cs" />
+    <Compile Include="Is.cs" />
+    <Compile Include="ITestCaseData.cs" />
+    <Compile Include="Iz.cs" />
+    <Compile Include="List.cs" />
+    <Compile Include="ListMapper.cs" />
+    <Compile Include="Randomizer.cs" />
+    <Compile Include="SpecialValue.cs" />
+    <Compile Include="StringAssert.cs" />
+    <Compile Include="TestCaseData.cs" />
+    <Compile Include="TestContext.cs" />
+    <Compile Include="TestState.cs" />
+    <Compile Include="TestStatus.cs" />
+    <Compile Include="Text.cs" />
+    <Compile Include="TextMessageWriter.cs" />
+    <Compile Include="Throws.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="nunit.framework.build" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
 </Project>
\ No newline at end of file

=== modified file 'src/tests/test-assembly/ActionAttributeExceptionFixture.cs'
--- src/tests/test-assembly/ActionAttributeExceptionFixture.cs	2011-08-26 19:45:20 +0000
+++ src/tests/test-assembly/ActionAttributeExceptionFixture.cs	2012-01-29 01:29:26 +0000
@@ -1,8 +1,8 @@
 #if CLR_2_0 || CLR_4_0
 using System;
 using System.Reflection;
-using NUnit.Framework;
-
+using NUnit.Framework;
+
 namespace NUnit.TestData
 {
     [ExceptionThrowingAction]
@@ -29,7 +29,7 @@
         [TearDown]
         public void TearDown()
         {
-            TearDownRun = false;
+            TearDownRun = true;
         }
 
         [ExceptionThrowingAction]
@@ -41,67 +41,39 @@
     }
 
     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
-    public class ExceptionThrowingActionAttribute : Attribute, ITestSuiteAction, ITestCaseAction
+    public class ExceptionThrowingActionAttribute : TestActionAttribute
     {
-        private static bool _ThrowBeforeSuiteException;
-        private static bool _ThrowAfterSuiteException;
-        private static bool _ThrowBeforeCaseException;
-        private static bool _ThrowAfterCaseException;
+        private static bool _ThrowBeforeException;
+        private static bool _ThrowAfterException;
 
         public static void Reset()
         {
-            ThrowBeforeSuiteException = false;
-            ThrowAfterSuiteException = false;
-            ThrowBeforeCaseException = false;
-            ThrowAfterCaseException = false;
-        }
-
-        public void BeforeTestSuite(object fixture, MethodInfo method)
-        {
-            if (ThrowBeforeSuiteException)
-                throw new InvalidOperationException("Failure in BeforeTestSuite.");
-        }
-
-        public void AfterTestSuite(object fixture, MethodInfo method)
-        {
-            if (ThrowAfterSuiteException)
-                throw new InvalidOperationException("Failure in AfterTestSuite.");
-        }
-
-        public void BeforeTestCase(object fixture, MethodInfo method)
-        {
-            if (ThrowBeforeCaseException)
-                throw new InvalidOperationException("Failure in BeforeTestCase.");
-        }
-
-        public void AfterTestCase(object fixture, MethodInfo method)
-        {
-            if (ThrowAfterCaseException)
-                throw new InvalidOperationException("Failure in AfterTestCase.");
-        }
-
-        public static bool ThrowBeforeSuiteException
-        {
-            get { return _ThrowBeforeSuiteException; }
-            set { _ThrowBeforeSuiteException = value; }
-        }
-
-        public static bool ThrowAfterSuiteException
-        {
-            get { return _ThrowAfterSuiteException; }
-            set { _ThrowAfterSuiteException = value; }
-        }
-
-        public static bool ThrowBeforeCaseException
-        {
-            get { return _ThrowBeforeCaseException; }
-            set { _ThrowBeforeCaseException = value; }
-        }
-
-        public static bool ThrowAfterCaseException
-        {
-            get { return _ThrowAfterCaseException; }
-            set { _ThrowAfterCaseException = value; }
+            ThrowBeforeException = false;
+            ThrowAfterException = false;
+        }
+
+        public override void BeforeTest(TestDetails testDetails)
+        {
+            if (ThrowBeforeException)
+                throw new InvalidOperationException("Failure in BeforeTest.");
+        }
+
+        public override void AfterTest(TestDetails testDetails)
+        {
+            if (ThrowAfterException)
+                throw new InvalidOperationException("Failure in AfterTest.");
+        }
+
+        public static bool ThrowBeforeException
+        {
+            get { return _ThrowBeforeException; }
+            set { _ThrowBeforeException = value; }
+        }
+
+        public static bool ThrowAfterException
+        {
+            get { return _ThrowAfterException; }
+            set { _ThrowAfterException = value; }
         }
     }
 }

=== modified file 'src/tests/test-assembly/ActionAttributeFixture.cs'
--- src/tests/test-assembly/ActionAttributeFixture.cs	2011-08-26 23:38:44 +0000
+++ src/tests/test-assembly/ActionAttributeFixture.cs	2012-01-29 01:29:26 +0000
@@ -1,111 +1,126 @@
 #if CLR_2_0 || CLR_4_0
 using System;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 using NUnit.Framework;
 using System.Diagnostics;
-using System.Reflection;
+using System.Reflection;
 using NUnit.TestData.ActionAttributeTests;
 
-[assembly: SampleAction("Assembly")]
+[assembly: SampleAction("AssemblySuite", ActionTargets.Suite)]
+[assembly: SampleAction("AssemblyTest", ActionTargets.Test)]
+[assembly: SampleAction("AssemblySite")]
 
 namespace NUnit.TestData.ActionAttributeTests
 {
-    [SetUpFixture]
-    [SampleAction("SetUpFixture")]
+    [SetUpFixture]
+    [SampleAction("SetupFixtureSuite", ActionTargets.Suite)]
+    [SampleAction("SetupFixtureTest", ActionTargets.Test)]
+    [SampleAction("SetupFixtureSite")]
     public class SetupFixture : BaseSetupFixture
     {
-    }
-
-    [SampleAction("BaseSetUpFixture")]
+    }
+
+    [SampleAction("BaseSetupFixtureSuite", ActionTargets.Suite)]
+    [SampleAction("BaseSetupFixtureTest", ActionTargets.Test)]
+    [SampleAction("BaseSetupFixtureSite")]
     public abstract class BaseSetupFixture
     {
     }
 
-    [TestFixture]
-    [SampleAction("Fixture")]
+    [TestFixture]
+    [SampleAction("FixtureSuite", ActionTargets.Suite)]
+    [SampleAction("FixtureTest", ActionTargets.Test)]
+    [SampleAction("FixtureSite")]
     public class ActionAttributeFixture : BaseActionAttributeFixture, IWithAction
     {
-        private static StringCollection _Results = null;
-        public static StringCollection Results
+        private static List<string> _Results = null;
+        public static List<string> Results
         {
             get { return _Results; }
             set { _Results = value; }
         }
 
-        StringCollection IWithAction.Results { get { return Results; } }
+        List<string> IWithAction.Results { get { return Results; } }
 
-        [Test, TestCase("SomeTest-Case1"), TestCase("SomeTest-Case2")]
-        [SampleAction("Method")]
+        [Test, TestCase("SomeTest-Case1"), TestCase("SomeTest-Case2")]
+        [SampleAction("ParameterizedSuite", ActionTargets.Suite)]
+        [SampleAction("ParameterizedTest", ActionTargets.Test)]
+        [SampleAction("ParameterizedSite")]
         public void SomeTest(string message)
         {
             ((IWithAction)this).Results.Add(message);
         }
 
-        [Test]
-        public void SomeOtherTest()
-        {
-            ((IWithAction)this).Results.Add("SomeOtherTest");
+        [Test]
+        [SampleAction("MethodSuite", ActionTargets.Suite)] // should never get invoked
+        [SampleAction("MethodTest", ActionTargets.Test)]
+        [SampleAction("MethodSite")]
+        public void SomeTestNotParameterized()
+        {
+            ((IWithAction)this).Results.Add("SomeTestNotParameterized");
         }
-
-    }
-
-    [SampleAction("BaseFixture")]
+    }
+
+    [SampleAction("BaseFixtureSuite", ActionTargets.Suite)]
+    [SampleAction("BaseFixtureTest", ActionTargets.Test)]
+    [SampleAction("BaseFixtureSite")]
     public abstract class BaseActionAttributeFixture : IBaseWithAction
     {
-    }
-
-    [SampleAction("Interface")]
-    public interface IWithAction : IBaseWithAction
+    }
+
+    [SampleAction("InterfaceSuite", ActionTargets.Suite)]
+    [SampleAction("InterfaceTest", ActionTargets.Test)]
+    [SampleAction("InterfaceSite")]
+    public interface IWithAction
     {
-        StringCollection Results { get; }
-    }
-
-    [SampleAction("BaseInterface")]
+        List<string> Results { get; }
+    }
+
+    [SampleAction("BaseInterfaceSuite", ActionTargets.Suite)]
+    [SampleAction("BaseInterfaceTest", ActionTargets.Test)]
+    [SampleAction("BaseInterfaceSite")]
     public interface IBaseWithAction
     {
     }
 
-    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Module, AllowMultiple = true, Inherited = true)]
-    public class SampleActionAttribute : Attribute, ITestSuiteAction, ITestCaseAction
+    public class SampleActionAttribute : TestActionAttribute
     {
-        private string _Prefix = null;
+        private readonly string _Prefix = null;
+        private readonly ActionTargets _Targets = ActionTargets.Site;
 
         public SampleActionAttribute(string prefix)
         {
             _Prefix = prefix;
-        }
-
-        void ITestSuiteAction.BeforeTestSuite(object fixture, MethodInfo method)
-        {
-            AddResult(fixture, method);
-        }
-
-        void ITestSuiteAction.AfterTestSuite(object fixture, MethodInfo method)
-        {
-            AddResult(fixture, method);
-        }
-
-        void ITestCaseAction.BeforeTestCase(object fixture, MethodInfo method)
-        {
-            AddResult(fixture, method);
-        }
-
-        void ITestCaseAction.AfterTestCase(object fixture, MethodInfo method)
-        {
-            AddResult(fixture, method);
-        }
-
-        private void AddResult(object fixture, MethodInfo method)
-        {
-            StackFrame frame = new StackFrame(1);
-            MethodBase actionMethod = frame.GetMethod();
-
-            string actionMethodName = actionMethod.Name.Substring(actionMethod.Name.LastIndexOf('.') + 1);
-            string message = string.Format("{0}.{1}-{2}" + (method != null ? "-{3}" : ""),
+        }
+
+        public SampleActionAttribute(string prefix, ActionTargets targets)
+        {
+            _Prefix = prefix;
+            _Targets = targets;
+        }
+
+        public override void BeforeTest(TestDetails testDetails)
+        {
+            AddResult("Before", testDetails);
+        }
+
+        public override void AfterTest(TestDetails testDetails)
+        {
+            AddResult("After", testDetails);
+        }
+
+        public override ActionTargets Targets
+        {
+            get { return _Targets; }
+        }
+
+        private void AddResult(string phase, TestDetails testDetails)
+        {
+            string message = string.Format("{0}.{1}.{2}.{3}",
                                            _Prefix,
-                                           actionMethodName,
-                                           fixture == null ? "{no-fixture}" : fixture.GetType().Name,
-                                           method != null ? method.Name : "");
+                                           phase,
+                                           testDetails.Fixture != null ? "true" : "false",
+                                           testDetails.Method != null ? "true" : "false");
 
             if(ActionAttributeFixture.Results != null)
                 ActionAttributeFixture.Results.Add(message);


Follow ups