← Back to team overview

nunit-core team mailing list archive

[Merge] lp:~saidout/nunit-3.0/constraint-class-refactoring into lp:nunit-3.0

 

Said Outgajjouft has proposed merging lp:~saidout/nunit-3.0/constraint-class-refactoring into lp:nunit-3.0.

Requested reviews:
  NUnit Core Developers (nunit-core)

For more details, see:
https://code.launchpad.net/~saidout/nunit-3.0/constraint-class-refactoring/+merge/63480

Change signature of Matches to return IConstraintResult.

Added one class StandardConstraintResult.cs to the Constraint folder.
Note that this has only been done for the NUnitFrameworkVS2010.sln solution located in the \src\NUnitFramework folder.

-- 
The attached diff has been truncated due to its size.
https://code.launchpad.net/~saidout/nunit-3.0/constraint-class-refactoring/+merge/63480
Your team NUnit Core Developers is requested to review the proposed merge of lp:~saidout/nunit-3.0/constraint-class-refactoring into lp:nunit-3.0.
=== modified file 'src/NUnitFramework/direct-runner/FrameworkDriver.cs'
--- src/NUnitFramework/direct-runner/FrameworkDriver.cs	2011-04-04 23:55:06 +0000
+++ src/NUnitFramework/direct-runner/FrameworkDriver.cs	2011-06-04 23:12:29 +0000
@@ -1,115 +1,115 @@
-// ***********************************************************************
-// Copyright (c) 2009 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Collections;
-using System.Xml;
-
-namespace NUnit.DirectRunner
-{
-    /// <summary>
-    /// FrameworkController is used by the test-runner to load and run
-    /// tests using the NUnit framework assembly.
-    /// </summary>
-    public class FrameworkDriver
-    {
-        AppDomain testDomain;
-
-        object testController;
-
-        public FrameworkDriver(AppDomain testDomain)
-        {
-            this.testDomain = testDomain;
-            this.testController = CreateObject("NUnit.Framework.Api.TestController");
-        }
-
-        public bool Load(string assemblyFileName, IDictionary options)
-        {
-            CallbackHandler handler = new CallbackHandler();
-
-            CreateObject("NUnit.Framework.Api.TestController+LoadTestsAction",
-                testController, assemblyFileName, options, handler.Callback);
-
-            Debug.Assert(handler.Result is bool, "Returned result was not a bool");
-
-            return (bool)handler.Result;
-        }
-
-        public XmlNode ExploreTests(string assemblyFileName, IDictionary options)
-        {
-            CallbackHandler handler = new CallbackHandler();
-
-            CreateObject("NUnit.Framework.Api.TestController+ExploreTestsAction",
-                testController, assemblyFileName, options, handler.Callback);
-
- 			XmlDocument doc = new XmlDocument();
-			doc.LoadXml((string)handler.Result);
-            return doc.FirstChild;
-        }
-
-        public XmlNode GetLoadedTests()
-        {
-            CallbackHandler handler = new CallbackHandler();
-
-            CreateObject("NUnit.Framework.Api.TestController+GetLoadedTestsAction",
-                testController, handler.Callback);
-
-            Debug.Assert(handler.Result == null || handler.Result is string,
-                "Returned result was not an XmlNode");
-
-			XmlDocument doc = new XmlDocument();
-			doc.LoadXml((string)handler.Result);
-            return doc.FirstChild;
-        }
-
-        public XmlNode Run(IDictionary runOptions)
-        {
-            CallbackHandler handler = new RunTestsCallbackHandler();
-
-            CreateObject("NUnit.Framework.Api.TestController+RunTestsAction", testController, runOptions, handler.Callback);
-
-            Debug.Assert(handler.Result is string, "Returned result was not a string");
-
-			XmlDocument doc = new XmlDocument();
-			doc.LoadXml((string)handler.Result);
-            return doc.FirstChild;
-        }
-
-        #region Helper Methods
-
-        private object CreateObject(string typeName, params object[] args)
-        {
-            return this.testDomain.CreateInstanceAndUnwrap(
-                "nunit.framework", typeName, false, 0,
-#if !NET_4_0
-                null, args, null, null, null );
+// ***********************************************************************
+// Copyright (c) 2009 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Collections;
+using System.Xml;
+
+namespace NUnit.DirectRunner
+{
+    /// <summary>
+    /// FrameworkController is used by the test-runner to load and run
+    /// tests using the NUnit framework assembly.
+    /// </summary>
+    public class FrameworkDriver
+    {
+        AppDomain testDomain;
+
+        object testController;
+
+        public FrameworkDriver(AppDomain testDomain)
+        {
+            this.testDomain = testDomain;
+            this.testController = CreateObject("NUnit.Framework.Api.TestController");
+        }
+
+        public bool Load(string assemblyFileName, IDictionary options)
+        {
+            CallbackHandler handler = new CallbackHandler();
+
+            CreateObject("NUnit.Framework.Api.TestController+LoadTestsAction",
+                testController, assemblyFileName, options, handler.Callback);
+
+            Debug.Assert(handler.Result is bool, "Returned result was not a bool");
+
+            return (bool)handler.Result;
+        }
+
+        public XmlNode ExploreTests(string assemblyFileName, IDictionary options)
+        {
+            CallbackHandler handler = new CallbackHandler();
+
+            CreateObject("NUnit.Framework.Api.TestController+ExploreTestsAction",
+                testController, assemblyFileName, options, handler.Callback);
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml((string)handler.Result);
+            return doc.FirstChild;
+        }
+
+        public XmlNode GetLoadedTests()
+        {
+            CallbackHandler handler = new CallbackHandler();
+
+            CreateObject("NUnit.Framework.Api.TestController+GetLoadedTestsAction",
+                testController, handler.Callback);
+
+            Debug.Assert(handler.Result == null || handler.Result is string,
+                "Returned result was not an XmlNode");
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml((string)handler.Result);
+            return doc.FirstChild;
+        }
+
+        public XmlNode Run(IDictionary runOptions)
+        {
+            CallbackHandler handler = new RunTestsCallbackHandler();
+
+            CreateObject("NUnit.Framework.Api.TestController+RunTestsAction", testController, runOptions, handler.Callback);
+
+            Debug.Assert(handler.Result is string, "Returned result was not a string");
+
+            XmlDocument doc = new XmlDocument();
+            doc.LoadXml((string)handler.Result);
+            return doc.FirstChild;
+        }
+
+        #region Helper Methods
+
+        private object CreateObject(string typeName, params object[] args)
+        {
+            return this.testDomain.CreateInstanceAndUnwrap(
+                "nunit.framework", typeName, false, 0,
+#if !NET_4_0
+ null, args, null, null, null);
 #else
                 null, args, null, null );
-#endif
-        }
-
-        #endregion
-    }
-}
+#endif
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/direct-runner/direct-runner-vs2010.csproj'
--- src/NUnitFramework/direct-runner/direct-runner-vs2010.csproj	2011-06-03 03:06:00 +0000
+++ src/NUnitFramework/direct-runner/direct-runner-vs2010.csproj	2011-06-04 23:12:29 +0000
@@ -1,3 +1,4 @@
+<<<<<<< TREE
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
   <PropertyGroup>
@@ -67,11 +68,122 @@
     <None Include="direct-runner.build" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+=======
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{126DBBB4-1731-4E0D-8937-4F2FAADCA0EF}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>NUnit.DirectRunner</RootNamespace>
+    <AssemblyName>direct-runner</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</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>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET_3_5;CLR_2_0</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Commandlineparameters>nunit.framework.tests.dll -a</Commandlineparameters>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5;CLR_2_0</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Commandlineparameters>nunit.framework.tests.dll</Commandlineparameters>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject>NUnit.DirectRunner.Program</StartupObject>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="CallbackHandler.cs" />
+    <Compile Include="CommandLineOptions.cs" />
+    <Compile Include="ConsoleRunner.cs" />
+    <Compile Include="FrameworkDriver.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="ResultReporter.cs" />
+    <Compile Include="ResultSummary.cs" />
+    <Compile Include="RunTestsCallbackHandler.cs" />
+    <Compile Include="StackTraceFilter.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="direct-runner.build" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+>>>>>>> MERGE-SOURCE
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Assert.cs'
--- src/NUnitFramework/framework/Assert.cs	2011-06-03 00:00:26 +0000
+++ src/NUnitFramework/framework/Assert.cs	2011-06-04 23:12:29 +0000
@@ -418,7 +418,7 @@
             Constraint constraint = expr.Resolve();
 
             TestExecutionContext.CurrentContext.IncrementAssertCount();
-            if (!constraint.Matches(del))
+            if (!constraint.Matches(del).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);
@@ -484,7 +484,7 @@
             Constraint constraint = expression.Resolve();
 
             TestExecutionContext.CurrentContext.IncrementAssertCount();
-            if (!constraint.Matches(actual))
+            if (!constraint.Matches(actual).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);
@@ -528,7 +528,7 @@
             Constraint constraint = expression.Resolve();
 
             TestExecutionContext.CurrentContext.IncrementAssertCount();
-            if (!constraint.Matches(ref actual))
+            if (!constraint.Matches(ref actual).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);

=== modified file 'src/NUnitFramework/framework/Assume.cs'
--- src/NUnitFramework/framework/Assume.cs	2010-08-02 02:42:35 +0000
+++ src/NUnitFramework/framework/Assume.cs	2011-06-04 23:12:29 +0000
@@ -104,7 +104,7 @@
         {
             Constraint constraint = expression.Resolve();
 
-            if (!constraint.Matches(actual))
+            if (!constraint.Matches(actual).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);
@@ -149,7 +149,7 @@
         {
             Constraint constraint = expr.Resolve();
 
-            if (!constraint.Matches(del))
+            if (!constraint.Matches(del).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);
@@ -195,7 +195,7 @@
         {
             Constraint constraint = expression.Resolve();
 
-            if (!constraint.Matches(ref actual))
+            if (!constraint.Matches(ref actual).HasSucceeded)
             {
                 MessageWriter writer = new TextMessageWriter(message, args);
                 constraint.WriteMessageTo(writer);

=== modified file 'src/NUnitFramework/framework/Constraints/AllItemsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AllItemsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AllItemsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,75 +1,75 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// AllItemsConstraint applies another constraint to each
-	/// item in a collection, succeeding if they all succeed.
-	/// </summary>
-	public class AllItemsConstraint : PrefixConstraint
-	{
-		/// <summary>
-		/// Construct an AllItemsConstraint on top of an existing constraint
-		/// </summary>
-		/// <param name="itemConstraint"></param>
-		public AllItemsConstraint(Constraint itemConstraint)
-			: base( itemConstraint )
-        {
-            this.DisplayName = "all";
-        }
-
-		/// <summary>
-		/// Apply the item constraint to each item in the collection,
-		/// failing if any item fails.
-		/// </summary>
-		/// <param name="actual"></param>
-		/// <returns></returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			if ( !(actual is IEnumerable) )
-				throw new ArgumentException( "The actual value must be an IEnumerable", "actual" );
-
-			foreach(object item in (IEnumerable)actual)
-				if (!baseConstraint.Matches(item))
-					return false;
-
-			return true;
-		}
-
-		/// <summary>
-		/// Write a description of this constraint to a MessageWriter
-		/// </summary>
-		/// <param name="writer"></param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate("all items");
-			baseConstraint.WriteDescriptionTo(writer);
-		}
-	}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// AllItemsConstraint applies another constraint to each
+    /// item in a collection, succeeding if they all succeed.
+    /// </summary>
+    public class AllItemsConstraint : PrefixConstraint
+    {
+        /// <summary>
+        /// Construct an AllItemsConstraint on top of an existing constraint
+        /// </summary>
+        /// <param name="itemConstraint"></param>
+        public AllItemsConstraint(Constraint itemConstraint)
+            : base(itemConstraint)
+        {
+            this.DisplayName = "all";
+        }
+
+        /// <summary>
+        /// Apply the item constraint to each item in the collection,
+        /// failing if any item fails.
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            if (!(actual is IEnumerable))
+                throw new ArgumentException("The actual value must be an IEnumerable", "actual");
+
+            foreach (object item in (IEnumerable)actual)
+                if (!baseConstraint.Matches(item).HasSucceeded)
+                    return new StandardConstraintResult(false);
+
+            return new StandardConstraintResult(true);
+        }
+
+        /// <summary>
+        /// Write a description of this constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("all items");
+            baseConstraint.WriteDescriptionTo(writer);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/AndConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AndConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AndConstraint.cs	2011-06-04 23:12:29 +0000
@@ -42,25 +42,25 @@
         /// </summary>
         /// <param name="left">The first constraint</param>
         /// <param name="right">The second constraint</param>
-        public AndConstraint(Constraint left, Constraint right) : base(left, right) { }
-
-        /// <summary>
-        /// Apply both member constraints to an actual value, succeeding 
-        /// succeeding only if both of them succeed.
-        /// </summary>
-        /// <param name="actual">The actual value</param>
-        /// <returns>True if the constraints both succeeded</returns>
-        public override bool Matches(object actual)
+        public AndConstraint(Constraint left, Constraint right) : base(left, right) { }
+
+        /// <summary>
+        /// Apply both member constraints to an actual value, succeeding 
+        /// succeeding only if both of them succeed.
+        /// </summary>
+        /// <param name="actual">The actual value</param>
+        /// <returns>True if the constraints both succeeded</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
-            failurePoint = Left.Matches(actual)
-                ? Right.Matches(actual)
+            failurePoint = Left.Matches(actual).HasSucceeded
+                ? Right.Matches(actual).HasSucceeded
                     ? FailurePoint.None
                     : FailurePoint.Right
                 : FailurePoint.Left;
 
-            return failurePoint == FailurePoint.None;
+            return new StandardConstraintResult(failurePoint == FailurePoint.None);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/AssignableFromConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AssignableFromConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AssignableFromConstraint.cs	2011-06-04 23:12:29 +0000
@@ -35,17 +35,18 @@
         /// Construct an AssignableFromConstraint for the type provided
         /// </summary>
         /// <param name="type"></param>
-        public AssignableFromConstraint(Type type) : base(type) { }
-
-        /// <summary>
-        /// Test whether an object can be assigned from the specified type
-        /// </summary>
-        /// <param name="actual">The object to be tested</param>
-        /// <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
-        public override bool Matches(object actual)
+        public AssignableFromConstraint(Type type) : base(type) { }
+
+        /// <summary>
+        /// Test whether an object can be assigned from the specified type
+        /// </summary>
+        /// <param name="actual">The object to be tested</param>
+        /// <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
+        public override IConstraintResult Matches(object actual)
         {
-            this.actual = actual;
-            return actual != null && actual.GetType().IsAssignableFrom(expectedType);
+            this.actual = actual;
+            bool hasSucceeded = actual != null && actual.GetType().IsAssignableFrom(expectedType);
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>
@@ -58,4 +59,4 @@
             writer.WriteExpectedValue(expectedType);
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/AssignableToConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AssignableToConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AssignableToConstraint.cs	2011-06-04 23:12:29 +0000
@@ -35,17 +35,18 @@
         /// Construct an AssignableToConstraint for the type provided
         /// </summary>
         /// <param name="type"></param>
-        public AssignableToConstraint(Type type) : base(type) { }
-
-        /// <summary>
-        /// Test whether an object can be assigned to the specified type
-        /// </summary>
-        /// <param name="actual">The object to be tested</param>
-        /// <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
-        public override bool Matches(object actual)
+        public AssignableToConstraint(Type type) : base(type) { }
+
+        /// <summary>
+        /// Test whether an object can be assigned to the specified type
+        /// </summary>
+        /// <param name="actual">The object to be tested</param>
+        /// <returns>True if the object can be assigned a value of the expected Type, otherwise false.</returns>
+        public override IConstraintResult Matches(object actual)
         {
-            this.actual = actual;
-            return actual != null && expectedType.IsAssignableFrom(actual.GetType());
+            this.actual = actual;
+            bool hasSucceeded = actual != null && expectedType.IsAssignableFrom(actual.GetType());
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/AttributeConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AttributeConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AttributeConstraint.cs	2011-06-04 23:12:29 +0000
@@ -56,7 +56,7 @@
         /// expected attribute and if its value matches the
         /// additional constraint specified.
         /// </summary>
-        public override bool Matches(object actual)
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
             System.Reflection.ICustomAttributeProvider attrProvider =
@@ -69,7 +69,7 @@
             if (attrs.Length == 0)
                 throw new ArgumentException(string.Format("Attribute {0} was not found", expectedType), "actual");
 
-            this.attrFound = attrs[0];
+            attrFound = attrs[0];
             return baseConstraint.Matches(attrFound);
         }
 

=== modified file 'src/NUnitFramework/framework/Constraints/AttributeExistsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/AttributeExistsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/AttributeExistsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -45,23 +45,24 @@
             if (!typeof(Attribute).IsAssignableFrom(expectedType))
                 throw new ArgumentException(string.Format(
                     "Type {0} is not an attribute", expectedType), "type");
-        }
-
-        /// <summary>
-        /// Tests whether the object provides the expected attribute.
-        /// </summary>
-        /// <param name="actual">A Type, MethodInfo, or other ICustomAttributeProvider</param>
-        /// <returns>True if the expected attribute is present, otherwise false</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Tests whether the object provides the expected attribute.
+        /// </summary>
+        /// <param name="actual">A Type, MethodInfo, or other ICustomAttributeProvider</param>
+        /// <returns>True if the expected attribute is present, otherwise false</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
             System.Reflection.ICustomAttributeProvider attrProvider =
                 actual as System.Reflection.ICustomAttributeProvider;
 
             if (attrProvider == null)
-                throw new ArgumentException(string.Format("Actual value {0} does not implement ICustomAttributeProvider", actual), "actual");
-
-            return attrProvider.GetCustomAttributes(expectedType, true).Length > 0;
+                throw new ArgumentException(string.Format("Actual value {0} does not implement ICustomAttributeProvider", actual), "actual");
+
+            bool hasSucceeded = attrProvider.GetCustomAttributes(expectedType, true).Length > 0;
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/BasicConstraint.cs'
--- src/NUnitFramework/framework/Constraints/BasicConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/BasicConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,75 +1,73 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// BasicConstraint is the abstract base for constraints that
-    /// perform a simple comparison to a constant value.
-    /// </summary>
-    public abstract class BasicConstraint : Constraint
-    {
-        private readonly object expected;
-        private readonly string description;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:BasicConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected.</param>
-        /// <param name="description">The description.</param>
-        protected BasicConstraint(object expected, string description)
-        {
-            this.expected = expected;
-            this.description = description;
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            if (actual == null && expected == null)
-                return true;
-
-            if (actual == null || expected == null)
-                return false;
-
-            return expected.Equals(actual);
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.Write(description);
-        }
-    }    
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// BasicConstraint is the abstract base for constraints that
+    /// perform a simple comparison to a constant value.
+    /// </summary>
+    public abstract class BasicConstraint : Constraint
+    {
+        private readonly object expected;
+        private readonly string description;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:BasicConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected.</param>
+        /// <param name="description">The description.</param>
+        protected BasicConstraint(object expected, string description)
+        {
+            this.expected = expected;
+            this.description = description;
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            if (actual == null && expected == null)
+                return new StandardConstraintResult(true);
+
+            if (actual == null || expected == null)
+                return new StandardConstraintResult(false);
+
+            return new StandardConstraintResult(expected.Equals(actual));
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.Write(description);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/BinaryConstraint.cs'
--- src/NUnitFramework/framework/Constraints/BinaryConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/BinaryConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,52 +1,53 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// BinaryConstraint is the abstract base of all constraints
-	/// that combine two other constraints in some fashion.
-	/// </summary>
-    public abstract class BinaryConstraint : Constraint
-    {
-		/// <summary>
-		/// The first constraint being combined
-		/// </summary>
-		protected Constraint Left;
-		/// <summary>
-		/// The second constraint being combined
-		/// </summary>
-		protected Constraint Right;
-
-		/// <summary>
-		/// Construct a BinaryConstraint from two other constraints
-		/// </summary>
-		/// <param name="left">The first constraint</param>
-		/// <param name="right">The second constraint</param>
-		protected BinaryConstraint(Constraint left, Constraint right) : base(left, right)
-        {
-            this.Left = left;
-            this.Right = right;
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// BinaryConstraint is the abstract base of all constraints
+    /// that combine two other constraints in some fashion.
+    /// </summary>
+    public abstract class BinaryConstraint : Constraint
+    {
+        /// <summary>
+        /// The first constraint being combined
+        /// </summary>
+        protected Constraint Left;
+        /// <summary>
+        /// The second constraint being combined
+        /// </summary>
+        protected Constraint Right;
+
+        /// <summary>
+        /// Construct a BinaryConstraint from two other constraints
+        /// </summary>
+        /// <param name="left">The first constraint</param>
+        /// <param name="right">The second constraint</param>
+        protected BinaryConstraint(Constraint left, Constraint right)
+            : base(left, right)
+        {
+            this.Left = left;
+            this.Right = right;
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/BinarySerializableConstraint.cs'
--- src/NUnitFramework/framework/Constraints/BinarySerializableConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/BinarySerializableConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,100 +1,100 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-#if !NETCF
-using System;
-using System.IO;
-using System.Runtime.Serialization;
-using System.Runtime.Serialization.Formatters.Binary;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// BinarySerializableConstraint tests whether 
-    /// an object is serializable in binary format.
-    /// </summary>
-    public class BinarySerializableConstraint : Constraint
-    {
-        readonly BinaryFormatter serializer = new BinaryFormatter();
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            if (actual == null)
-                throw new ArgumentException();
-
-            MemoryStream stream = new MemoryStream();
-
-            try
-            {
-                serializer.Serialize(stream, actual);
-
-                stream.Seek(0, SeekOrigin.Begin);
-
-                object value = serializer.Deserialize(stream);
-
-                return value != null;
-            }
-            catch (SerializationException)
-            {
-                return false;
-            }
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.Write("binary serializable");
-        }
-
-        /// <summary>
-        /// Write the actual value for a failing constraint test to a
-        /// MessageWriter. The default implementation simply writes
-        /// the raw value of actual, leaving it to the writer to
-        /// perform any formatting.
-        /// </summary>
-        /// <param name="writer">The writer on which the actual value is displayed</param>
-        public override void WriteActualValueTo(MessageWriter writer)
-        {
-            writer.Write("<{0}>", actual.GetType().Name);
-        }
-
-        /// <summary>
-        /// Returns the string representation
-        /// </summary>
-        protected override string GetStringRepresentation()
-        {
-            return "<binaryserializable>";
-        }
-    }
-}
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+#if !NETCF
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// BinarySerializableConstraint tests whether 
+    /// an object is serializable in binary format.
+    /// </summary>
+    public class BinarySerializableConstraint : Constraint
+    {
+        readonly BinaryFormatter serializer = new BinaryFormatter();
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            if (actual == null)
+                throw new ArgumentException();
+
+            MemoryStream stream = new MemoryStream();
+
+            try
+            {
+                serializer.Serialize(stream, actual);
+
+                stream.Seek(0, SeekOrigin.Begin);
+
+                object value = serializer.Deserialize(stream);
+
+                return new StandardConstraintResult(value != null);
+            }
+            catch (SerializationException)
+            {
+                return new StandardConstraintResult(false);
+            }
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.Write("binary serializable");
+        }
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a
+        /// MessageWriter. The default implementation simply writes
+        /// the raw value of actual, leaving it to the writer to
+        /// perform any formatting.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public override void WriteActualValueTo(MessageWriter writer)
+        {
+            writer.Write("<{0}>", actual.GetType().Name);
+        }
+
+        /// <summary>
+        /// Returns the string representation
+        /// </summary>
+        protected override string GetStringRepresentation()
+        {
+            return "<binaryserializable>";
+        }
+    }
+}
 #endif
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/CollectionConstraint.cs'
--- src/NUnitFramework/framework/Constraints/CollectionConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/CollectionConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,85 +1,85 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// CollectionConstraint is the abstract base class for
-    /// constraints that operate on collections.
-    /// </summary>
-    public abstract class CollectionConstraint : Constraint
-    {
-        /// <summary>
-        /// Construct an empty CollectionConstraint
-        /// </summary>
-        protected CollectionConstraint() { }
-
-        /// <summary>
-        /// Construct a CollectionConstraint
-        /// </summary>
-        /// <param name="arg"></param>
-        protected CollectionConstraint(object arg) : base(arg) { }
-
-        /// <summary>
-        /// Determines whether the specified enumerable is empty.
-        /// </summary>
-        /// <param name="enumerable">The enumerable.</param>
-        /// <returns>
-        /// 	<c>true</c> if the specified enumerable is empty; otherwise, <c>false</c>.
-        /// </returns>
-		protected static bool IsEmpty( IEnumerable enumerable )
-		{
-			ICollection collection = enumerable as ICollection;
-			if ( collection != null )
-				return collection.Count == 0;
-			else
-				return !enumerable.GetEnumerator().MoveNext();
-		}
-
-		/// <summary>
-		/// Test whether the constraint is satisfied by a given value
-		/// </summary>
-		/// <param name="actual">The value to be tested</param>
-		/// <returns>True for success, false for failure</returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			IEnumerable enumerable = actual as IEnumerable;
-			if ( enumerable == null )
-				throw new ArgumentException( "The actual value must be an IEnumerable", "actual" );
-		
-			return doMatch( enumerable );
-		}
-
-		/// <summary>
-		/// Protected method to be implemented by derived classes
-		/// </summary>
-		/// <param name="collection"></param>
-		/// <returns></returns>
-		protected abstract bool doMatch(IEnumerable collection);
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// CollectionConstraint is the abstract base class for
+    /// constraints that operate on collections.
+    /// </summary>
+    public abstract class CollectionConstraint : Constraint
+    {
+        /// <summary>
+        /// Construct an empty CollectionConstraint
+        /// </summary>
+        protected CollectionConstraint() { }
+
+        /// <summary>
+        /// Construct a CollectionConstraint
+        /// </summary>
+        /// <param name="arg"></param>
+        protected CollectionConstraint(object arg) : base(arg) { }
+
+        /// <summary>
+        /// Determines whether the specified enumerable is empty.
+        /// </summary>
+        /// <param name="enumerable">The enumerable.</param>
+        /// <returns>
+        /// <c>true</c> if the specified enumerable is empty; otherwise, <c>false</c>.
+        /// </returns>
+        protected static bool IsEmpty(IEnumerable enumerable)
+        {
+            ICollection collection = enumerable as ICollection;
+            if (collection != null)
+                return collection.Count == 0;
+
+            return !enumerable.GetEnumerator().MoveNext();
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            IEnumerable enumerable = actual as IEnumerable;
+            if (enumerable == null)
+                throw new ArgumentException("The actual value must be an IEnumerable", "actual");
+
+            return new StandardConstraintResult(doMatch(enumerable));
+        }
+
+        /// <summary>
+        /// Protected method to be implemented by derived classes
+        /// </summary>
+        /// <param name="collection"></param>
+        /// <returns></returns>
+        protected abstract bool doMatch(IEnumerable collection);
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/CollectionEquivalentConstraint.cs'
--- src/NUnitFramework/framework/Constraints/CollectionEquivalentConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/CollectionEquivalentConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,72 +1,73 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// CollectionEquivalentCOnstraint is used to determine whether two
-    /// collections are equivalent.
-    /// </summary>
-    public class CollectionEquivalentConstraint : CollectionItemsEqualConstraint
-    {
-        private readonly IEnumerable expected;
-
-        /// <summary>
-        /// Construct a CollectionEquivalentConstraint
-        /// </summary>
-        /// <param name="expected"></param>
-        public CollectionEquivalentConstraint(IEnumerable expected) : base(expected)
-        {
-            this.expected = expected;
-            this.DisplayName = "equivalent";
-        }
-
-        /// <summary>
-        /// Test whether two collections are equivalent
-        /// </summary>
-        /// <param name="actual"></param>
-        /// <returns></returns>
-        protected override bool doMatch(IEnumerable actual)
-        {
-			// This is just an optimization
-			if( expected is ICollection && actual is ICollection )
-				if( ((ICollection)actual).Count != ((ICollection)expected).Count )
-					return false;
-
-            CollectionTally tally = Tally(expected);
-            return tally.TryRemove(actual) && tally.Count == 0;
-        }
-
-        /// <summary>
-        /// Write a description of this constraint to a MessageWriter
-        /// </summary>
-        /// <param name="writer"></param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WritePredicate("equivalent to");
-            writer.WriteExpectedValue(expected);
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// CollectionEquivalentCOnstraint is used to determine whether two
+    /// collections are equivalent.
+    /// </summary>
+    public class CollectionEquivalentConstraint : CollectionItemsEqualConstraint
+    {
+        private readonly IEnumerable expected;
+
+        /// <summary>
+        /// Construct a CollectionEquivalentConstraint
+        /// </summary>
+        /// <param name="expected"></param>
+        public CollectionEquivalentConstraint(IEnumerable expected)
+            : base(expected)
+        {
+            this.expected = expected;
+            this.DisplayName = "equivalent";
+        }
+
+        /// <summary>
+        /// Test whether two collections are equivalent
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        protected override bool doMatch(IEnumerable actual)
+        {
+            // This is just an optimization
+            if (expected is ICollection && actual is ICollection)
+                if (((ICollection)actual).Count != ((ICollection)expected).Count)
+                    return false;
+
+            CollectionTally tally = Tally(expected);
+            return tally.TryRemove(actual) && tally.Count == 0;
+        }
+
+        /// <summary>
+        /// Write a description of this constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("equivalent to");
+            writer.WriteExpectedValue(expected);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/CollectionOrderedConstraint.cs'
--- src/NUnitFramework/framework/Constraints/CollectionOrderedConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/CollectionOrderedConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,185 +1,185 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-using System.Reflection;
-using System.Text;
-#if CLR_2_0 || CLR_4_0
-using System.Collections.Generic;
-#endif
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// CollectionOrderedConstraint is used to test whether a collection is ordered.
-    /// </summary>
-    public class CollectionOrderedConstraint : CollectionConstraint
-    {
-        private ComparisonAdapter comparer = ComparisonAdapter.Default;
-        private string comparerName;
-        private string propertyName;
-        private bool descending;
-
-        /// <summary>
-        /// Construct a CollectionOrderedConstraint
-        /// </summary>
-        public CollectionOrderedConstraint() 
-        {
-            this.DisplayName = "ordered";
-        }
-
-        ///<summary>
-        /// If used performs a reverse comparison
-        ///</summary>
-        public CollectionOrderedConstraint Descending
-        {
-            get
-            {
-                descending = true;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Modifies the constraint to use an IComparer and returns self.
-        /// </summary>
-        public CollectionOrderedConstraint Using(IComparer comparer)
-        {
-            this.comparer = ComparisonAdapter.For( comparer );
-            this.comparerName = comparer.GetType().FullName;
-            return this;
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Modifies the constraint to use an IComparer&lt;T&gt; and returns self.
-        /// </summary>
-        public CollectionOrderedConstraint Using<T>(IComparer<T> comparer)
-        {
-            this.comparer = ComparisonAdapter.For(comparer);
-            this.comparerName = comparer.GetType().FullName;
-            return this;
-        }
-
-        /// <summary>
-        /// Modifies the constraint to use a Comparison&lt;T&gt; and returns self.
-        /// </summary>
-        public CollectionOrderedConstraint Using<T>(Comparison<T> comparer)
-        {
-            this.comparer = ComparisonAdapter.For(comparer);
-            this.comparerName = comparer.GetType().FullName;
-            return this;
-        }
-#endif
-
-        /// <summary>
-        /// Modifies the constraint to test ordering by the value of
-        /// a specified property and returns self.
-        /// </summary>
-        public CollectionOrderedConstraint By(string propertyName)
-		{
-			this.propertyName = propertyName;
-			return this;
-		}
-
-        /// <summary>
-        /// Test whether the collection is ordered
-        /// </summary>
-        /// <param name="actual"></param>
-        /// <returns></returns>
-        protected override bool doMatch(IEnumerable actual)
-        {
-            object previous = null;
-            int index = 0;
-            foreach(object obj in actual)
-            {
-                object objToCompare = obj;
-                if (obj == null)
-                    throw new ArgumentNullException("actual", "Null value at index " + index.ToString());
-
-                if (this.propertyName != null)
-                {
-                    PropertyInfo prop = obj.GetType().GetProperty(propertyName);
-                    objToCompare = prop.GetValue(obj, null);
-                    if (objToCompare == null)
-                        throw new ArgumentNullException("actual", "Null property value at index " + index.ToString());
-                }
-
-                if (previous != null)
-                {
-                    //int comparisonResult = comparer.Compare(al[i], al[i + 1]);
-                    int comparisonResult = comparer.Compare(previous, objToCompare);
-
-                    if (descending && comparisonResult < 0)
-                        return false;
-                    if (!descending && comparisonResult > 0)
-                        return false;
-                }
-
-                previous = objToCompare;
-                index++;
-            }
-
-            return true;
-        }
-
-        /// <summary>
-        /// Write a description of the constraint to a MessageWriter
-        /// </summary>
-        /// <param name="writer"></param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            if (propertyName == null)
-                writer.Write("collection ordered");
-            else
-            {
-                writer.WritePredicate("collection ordered by");
-                writer.WriteExpectedValue(propertyName);
-            }
-
-            if (descending)
-                writer.WriteModifier("descending");
-        }
-
-        /// <summary>
-        /// Returns the string representation of the constraint.
-        /// </summary>
-        /// <returns></returns>
-        protected override string GetStringRepresentation()
-        {
-            StringBuilder sb = new StringBuilder("<ordered");
-
-            if (propertyName != null)
-                sb.Append("by " + propertyName);
-            if (descending)
-                sb.Append(" descending");
-            if (comparerName != null)
-                sb.Append(" " + comparerName);
-
-            sb.Append(">");
-
-            return sb.ToString();
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Text;
+#if CLR_2_0 || CLR_4_0
+using System.Collections.Generic;
+#endif
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// CollectionOrderedConstraint is used to test whether a collection is ordered.
+    /// </summary>
+    public class CollectionOrderedConstraint : CollectionConstraint
+    {
+        private ComparisonAdapter comparer = ComparisonAdapter.Default;
+        private string comparerName;
+        private string propertyName;
+        private bool descending;
+
+        /// <summary>
+        /// Construct a CollectionOrderedConstraint
+        /// </summary>
+        public CollectionOrderedConstraint()
+        {
+            this.DisplayName = "ordered";
+        }
+
+        ///<summary>
+        /// If used performs a reverse comparison
+        ///</summary>
+        public CollectionOrderedConstraint Descending
+        {
+            get
+            {
+                descending = true;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Modifies the constraint to use an IComparer and returns self.
+        /// </summary>
+        public CollectionOrderedConstraint Using(IComparer comparer)
+        {
+            this.comparer = ComparisonAdapter.For(comparer);
+            this.comparerName = comparer.GetType().FullName;
+            return this;
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Modifies the constraint to use an IComparer&lt;T&gt; and returns self.
+        /// </summary>
+        public CollectionOrderedConstraint Using<T>(IComparer<T> comparer)
+        {
+            this.comparer = ComparisonAdapter.For(comparer);
+            this.comparerName = comparer.GetType().FullName;
+            return this;
+        }
+
+        /// <summary>
+        /// Modifies the constraint to use a Comparison&lt;T&gt; and returns self.
+        /// </summary>
+        public CollectionOrderedConstraint Using<T>(Comparison<T> comparer)
+        {
+            this.comparer = ComparisonAdapter.For(comparer);
+            this.comparerName = comparer.GetType().FullName;
+            return this;
+        }
+#endif
+
+        /// <summary>
+        /// Modifies the constraint to test ordering by the value of
+        /// a specified property and returns self.
+        /// </summary>
+        public CollectionOrderedConstraint By(string propertyName)
+        {
+            this.propertyName = propertyName;
+            return this;
+        }
+
+        /// <summary>
+        /// Test whether the collection is ordered
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        protected override bool doMatch(IEnumerable actual)
+        {
+            object previous = null;
+            int index = 0;
+            foreach (object obj in actual)
+            {
+                object objToCompare = obj;
+                if (obj == null)
+                    throw new ArgumentNullException("actual", "Null value at index " + index.ToString());
+
+                if (this.propertyName != null)
+                {
+                    PropertyInfo prop = obj.GetType().GetProperty(propertyName);
+                    objToCompare = prop.GetValue(obj, null);
+                    if (objToCompare == null)
+                        throw new ArgumentNullException("actual", "Null property value at index " + index.ToString());
+                }
+
+                if (previous != null)
+                {
+                    //int comparisonResult = comparer.Compare(al[i], al[i + 1]);
+                    int comparisonResult = comparer.Compare(previous, objToCompare);
+
+                    if (descending && comparisonResult < 0)
+                        return false;
+                    if (!descending && comparisonResult > 0)
+                        return false;
+                }
+
+                previous = objToCompare;
+                index++;
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Write a description of the constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            if (propertyName == null)
+                writer.Write("collection ordered");
+            else
+            {
+                writer.WritePredicate("collection ordered by");
+                writer.WriteExpectedValue(propertyName);
+            }
+
+            if (descending)
+                writer.WriteModifier("descending");
+        }
+
+        /// <summary>
+        /// Returns the string representation of the constraint.
+        /// </summary>
+        /// <returns></returns>
+        protected override string GetStringRepresentation()
+        {
+            StringBuilder sb = new StringBuilder("<ordered");
+
+            if (propertyName != null)
+                sb.Append("by " + propertyName);
+            if (descending)
+                sb.Append(" descending");
+            if (comparerName != null)
+                sb.Append(" " + comparerName);
+
+            sb.Append(">");
+
+            return sb.ToString();
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/ComparisonConstraint.cs'
--- src/NUnitFramework/framework/Constraints/ComparisonConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/ComparisonConstraint.cs	2011-06-04 23:12:29 +0000
@@ -78,14 +78,14 @@
             this.equalComparisonResult = equalComparisonResult;
             this.greaterComparisonResult = greaterComparisonResult;
             this.predicate = predicate;
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
@@ -97,7 +97,8 @@
 
             int icomp = comparer.Compare(expected, actual);
 
-            return icomp < 0 && greaterComparisonResult || icomp == 0 && equalComparisonResult || icomp > 0 && lessComparisonResult;
+            bool hasSucceeded = icomp < 0 && greaterComparisonResult || icomp == 0 && equalComparisonResult || icomp > 0 && lessComparisonResult;
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/Constraint.cs'
--- src/NUnitFramework/framework/Constraints/Constraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/Constraint.cs	2011-06-04 23:12:29 +0000
@@ -1,401 +1,401 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// Delegate used to delay evaluation of the actual value
-    /// to be used in evaluating a constraint
-    /// </summary>
-    public delegate object ActualValueDelegate();
-    
-    /// <summary>
-    /// The Constraint class is the base of all built-in constraints
-    /// within NUnit. It provides the operator overloads used to combine 
-    /// constraints.
-    /// </summary>
-    public abstract class Constraint : IResolveConstraint
-    {
-        #region UnsetObject Class
-        /// <summary>
-        /// Class used to detect any derived constraints
-        /// that fail to set the actual value in their
-        /// Matches override.
-        /// </summary>
-        private class UnsetObject
-        {
-            public override string ToString()
-            {
-                return "UNSET";
-            }
-        }
-        #endregion
-
-		#region Static and Instance Fields
-        /// <summary>
-        /// Static UnsetObject used to detect derived constraints
-        /// failing to set the actual value.
-        /// </summary>
-        protected static object UNSET = new UnsetObject();
-
-		/// <summary>
-        /// The actual value being tested against a constraint
-        /// </summary>
-        protected object actual = UNSET;
-
-        /// <summary>
-        /// The display name of this Constraint for use by ToString()
-        /// </summary>
-        private string displayName;
-
-        /// <summary>
-        /// Argument fields used by ToString();
-        /// </summary>
-        private readonly int argcnt;
-        private readonly object arg1;
-        private readonly object arg2;
-
-        /// <summary>
-        /// The builder holding this constraint
-        /// </summary>
-        private ConstraintBuilder builder;
-        #endregion
-
-        #region Constructors
-        /// <summary>
-        /// Construct a constraint with no arguments
-        /// </summary>
-        protected Constraint()
-        {
-            argcnt = 0;
-        }
-
-        /// <summary>
-        /// Construct a constraint with one argument
-        /// </summary>
-        protected Constraint(object arg)
-        {
-            argcnt = 1;
-            this.arg1 = arg;
-        }
-
-        /// <summary>
-        /// Construct a constraint with two arguments
-        /// </summary>
-        protected Constraint(object arg1, object arg2)
-        {
-            argcnt = 2;
-            this.arg1 = arg1;
-            this.arg2 = arg2;
-        }
-        #endregion
-
-        #region Set Containing ConstraintBuilder
-        /// <summary>
-        /// Sets the ConstraintBuilder holding this constraint
-        /// </summary>
-        internal void SetBuilder(ConstraintBuilder builder)
-        {
-            this.builder = builder;
-        }
-        #endregion
-
-        #region Properties
-        /// <summary>
-        /// The display name of this Constraint for use by ToString().
-        /// The default value is the name of the constraint with
-        /// trailing "Constraint" removed. Derived classes may set
-        /// this to another name in their constructors.
-        /// </summary>
-        public string DisplayName
-        {
-            get
-            {
-                if (displayName == null)
-                {
-                    displayName = this.GetType().Name.ToLower();
-                    if (displayName.EndsWith("`1") || displayName.EndsWith("`2"))
-                        displayName = displayName.Substring(0, displayName.Length - 2);
-                    if (displayName.EndsWith("constraint"))
-                        displayName = displayName.Substring(0, displayName.Length - 10);
-                }
-
-                return displayName;
-            }
-
-            set { displayName = value; }
-        }
-		#endregion
-
-		#region Abstract and Virtual Methods
-        /// <summary>
-        /// Write the failure message to the MessageWriter provided
-        /// as an argument. The default implementation simply passes
-        /// the constraint and the actual value to the writer, which
-        /// then displays the constraint description and the value.
-        /// 
-        /// Constraints that need to provide additional details,
-        /// such as where the error occured can override this.
-        /// </summary>
-        /// <param name="writer">The MessageWriter on which to display the message</param>
-        public virtual void WriteMessageTo(MessageWriter writer)
-        {
-            writer.DisplayDifferences(this);
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public abstract bool Matches(object actual);
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by an
-        /// ActualValueDelegate that returns the value to be tested.
-        /// The default implementation simply evaluates the delegate
-        /// but derived classes may override it to provide for delayed 
-        /// processing.
-        /// </summary>
-        /// <param name="del">An ActualValueDelegate</param>
-        /// <returns>True for success, false for failure</returns>
-        public virtual bool Matches(ActualValueDelegate del)
-        {
-            return Matches(del());
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given reference.
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Delegate used to delay evaluation of the actual value
+    /// to be used in evaluating a constraint
+    /// </summary>
+    public delegate object ActualValueDelegate();
+
+    /// <summary>
+    /// The Constraint class is the base of all built-in constraints
+    /// within NUnit. It provides the operator overloads used to combine 
+    /// constraints.
+    /// </summary>
+    public abstract class Constraint : IResolveConstraint
+    {
+        #region UnsetObject Class
+        /// <summary>
+        /// Class used to detect any derived constraints
+        /// that fail to set the actual value in their
+        /// Matches override.
+        /// </summary>
+        private class UnsetObject
+        {
+            public override string ToString()
+            {
+                return "UNSET";
+            }
+        }
+        #endregion
+
+        #region Static and Instance Fields
+        /// <summary>
+        /// Static UnsetObject used to detect derived constraints
+        /// failing to set the actual value.
+        /// </summary>
+        protected static object UNSET = new UnsetObject();
+
+        /// <summary>
+        /// The actual value being tested against a constraint
+        /// </summary>
+        protected object actual = UNSET;
+
+        /// <summary>
+        /// The display name of this Constraint for use by ToString()
+        /// </summary>
+        private string displayName;
+
+        /// <summary>
+        /// Argument fields used by ToString();
+        /// </summary>
+        private readonly int argcnt;
+        private readonly object arg1;
+        private readonly object arg2;
+
+        /// <summary>
+        /// The builder holding this constraint
+        /// </summary>
+        private ConstraintBuilder builder;
+        #endregion
+
+        #region Constructors
+        /// <summary>
+        /// Construct a constraint with no arguments
+        /// </summary>
+        protected Constraint()
+        {
+            argcnt = 0;
+        }
+
+        /// <summary>
+        /// Construct a constraint with one argument
+        /// </summary>
+        protected Constraint(object arg)
+        {
+            argcnt = 1;
+            this.arg1 = arg;
+        }
+
+        /// <summary>
+        /// Construct a constraint with two arguments
+        /// </summary>
+        protected Constraint(object arg1, object arg2)
+        {
+            argcnt = 2;
+            this.arg1 = arg1;
+            this.arg2 = arg2;
+        }
+        #endregion
+
+        #region Set Containing ConstraintBuilder
+        /// <summary>
+        /// Sets the ConstraintBuilder holding this constraint
+        /// </summary>
+        internal void SetBuilder(ConstraintBuilder builder)
+        {
+            this.builder = builder;
+        }
+        #endregion
+
+        #region Properties
+        /// <summary>
+        /// The display name of this Constraint for use by ToString().
+        /// The default value is the name of the constraint with
+        /// trailing "Constraint" removed. Derived classes may set
+        /// this to another name in their constructors.
+        /// </summary>
+        public string DisplayName
+        {
+            get
+            {
+                if (displayName == null)
+                {
+                    displayName = this.GetType().Name.ToLower();
+                    if (displayName.EndsWith("`1") || displayName.EndsWith("`2"))
+                        displayName = displayName.Substring(0, displayName.Length - 2);
+                    if (displayName.EndsWith("constraint"))
+                        displayName = displayName.Substring(0, displayName.Length - 10);
+                }
+
+                return displayName;
+            }
+
+            set { displayName = value; }
+        }
+        #endregion
+
+        #region Abstract and Virtual Methods
+        /// <summary>
+        /// Write the failure message to the MessageWriter provided
+        /// as an argument. The default implementation simply passes
+        /// the constraint and the actual value to the writer, which
+        /// then displays the constraint description and the value.
+        /// 
+        /// Constraints that need to provide additional details,
+        /// such as where the error occured can override this.
+        /// </summary>
+        /// <param name="writer">The MessageWriter on which to display the message</param>
+        public virtual void WriteMessageTo(MessageWriter writer)
+        {
+            writer.DisplayDifferences(this);
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public abstract IConstraintResult Matches(object actual);
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by an
+        /// ActualValueDelegate that returns the value to be tested.
+        /// The default implementation simply evaluates the delegate
+        /// but derived classes may override it to provide for delayed 
+        /// processing.
+        /// </summary>
+        /// <param name="del">An ActualValueDelegate</param>
+        /// <returns>True for success, false for failure</returns>
+        public virtual IConstraintResult Matches(ActualValueDelegate del)
+        {
+            return Matches(del());
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given reference.
+        /// The default implementation simply dereferences the value but
+        /// derived classes may override it to provide for delayed processing.
+        /// </summary>
+        /// <param name="actual">A reference to the value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public virtual IConstraintResult Matches<T>(ref T actual)
+        {
+            return Matches(actual);
+        }
+#else
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given bool reference.
         /// The default implementation simply dereferences the value but
         /// derived classes may override it to provide for delayed processing.
         /// </summary>
         /// <param name="actual">A reference to the value to be tested</param>
         /// <returns>True for success, false for failure</returns>
-        public virtual bool Matches<T>(ref T actual)
+        public virtual IConstraintResult Matches(ref bool actual)
         {
             return Matches(actual);
         }
-#else
-		/// <summary>
-		/// Test whether the constraint is satisfied by a given bool reference.
-		/// The default implementation simply dereferences the value but
-		/// derived classes may override it to provide for delayed processing.
-		/// </summary>
-		/// <param name="actual">A reference to the value to be tested</param>
-		/// <returns>True for success, false for failure</returns>
-		public virtual bool Matches(ref bool actual)
-		{
-			return Matches(actual);
-		}
-#endif
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public abstract void WriteDescriptionTo(MessageWriter writer);
-
-        /// <summary>
-		/// Write the actual value for a failing constraint test to a
-		/// MessageWriter. The default implementation simply writes
-		/// the raw value of actual, leaving it to the writer to
-		/// perform any formatting.
-		/// </summary>
-		/// <param name="writer">The writer on which the actual value is displayed</param>
-		public virtual void WriteActualValueTo(MessageWriter writer)
-		{
-			writer.WriteActualValue( actual );
-		}
-		#endregion
-
-        #region ToString Override
-        /// <summary>
-        /// Default override of ToString returns the constraint DisplayName
-        /// followed by any arguments within angle brackets.
-        /// </summary>
-        /// <returns></returns>
-        public override string ToString()
-        {
-            string rep = GetStringRepresentation();
-
-            return this.builder == null ? rep : string.Format("<unresolved {0}>", rep);
-        }
-
-        /// <summary>
-        /// Returns the string representation of this constraint
-        /// </summary>
-        /// <returns></returns>
-        protected virtual string GetStringRepresentation()
-        {
-            switch (argcnt)
-            {
-                default:
-                case 0:
-                    return string.Format("<{0}>", DisplayName);
-                case 1:
-                    return string.Format("<{0} {1}>", DisplayName, _displayable(arg1));
-                case 2:
-                    return string.Format("<{0} {1} {2}>", DisplayName, _displayable(arg1), _displayable(arg2));
-            }
-        }
-
-        private static string _displayable(object o)
-        {
-            if (o == null) return "null";
-
-            string fmt = o is string ? "\"{0}\"" : "{0}";
-            return string.Format(System.Globalization.CultureInfo.InvariantCulture, fmt, o);
-        }
-        #endregion
-
-        #region Operator Overloads
-        /// <summary>
-        /// This operator creates a constraint that is satisfied only if both 
-        /// argument constraints are satisfied.
-        /// </summary>
-        public static Constraint operator &(Constraint left, Constraint right)
-        {
-            IResolveConstraint l = (IResolveConstraint)left;
-            IResolveConstraint r = (IResolveConstraint)right;
-            return new AndConstraint(l.Resolve(), r.Resolve());
-        }
-
-        /// <summary>
-        /// This operator creates a constraint that is satisfied if either 
-        /// of the argument constraints is satisfied.
-        /// </summary>
-        public static Constraint operator |(Constraint left, Constraint right)
-        {
-            IResolveConstraint l = (IResolveConstraint)left;
-            IResolveConstraint r = (IResolveConstraint)right;
-            return new OrConstraint(l.Resolve(), r.Resolve());
-        }
-
-        /// <summary>
-        /// This operator creates a constraint that is satisfied if the 
-        /// argument constraint is not satisfied.
-        /// </summary>
-        public static Constraint operator !(Constraint constraint)
-        {
-            IResolveConstraint r = constraint as IResolveConstraint;
-            return new NotConstraint(r == null ? new NullConstraint() : r.Resolve());
-        }
-        #endregion
-
-        #region Binary Operators
-        /// <summary>
-        /// Returns a ConstraintExpression by appending And
-        /// to the current constraint.
-        /// </summary>
-        public ConstraintExpression And
-        {
-            get
-            {
-                ConstraintBuilder builder = this.builder;
-                if (builder == null)
-                {
-                    builder = new ConstraintBuilder();
-                    builder.Append(this);
-                }
-
-                builder.Append(new AndOperator());
-
-                return new ConstraintExpression(builder);
-            }
-        }
-
-        /// <summary>
-        /// Returns a ConstraintExpression by appending And
-        /// to the current constraint.
-        /// </summary>
-        public ConstraintExpression With
-        {
-            get { return this.And; }
-        }
-
-        /// <summary>
-        /// Returns a ConstraintExpression by appending Or
-        /// to the current constraint.
-        /// </summary>
-        public ConstraintExpression Or
-        {
-            get
-            {
-                ConstraintBuilder builder = this.builder;
-                if (builder == null)
-                {
-                    builder = new ConstraintBuilder();
-                    builder.Append(this);
-                }
-
-                builder.Append(new OrOperator());
-
-                return new ConstraintExpression(builder);
-            }
-        }
-        #endregion
-
-        #region After Modifier
-
-#if !NUNITLITE
-        /// <summary>
-        /// Returns a DelayedConstraint with the specified delay time.
-        /// </summary>
-        /// <param name="delayInMilliseconds">The delay in milliseconds.</param>
-        /// <returns></returns>
-        public DelayedConstraint After(int delayInMilliseconds)
-        {
-            return new DelayedConstraint(
-                builder == null ? this : builder.Resolve(),
-                delayInMilliseconds);
-        }
-
-        /// <summary>
-        /// Returns a DelayedConstraint with the specified delay time
-        /// and polling interval.
-        /// </summary>
-        /// <param name="delayInMilliseconds">The delay in milliseconds.</param>
-        /// <param name="pollingInterval">The interval at which to test the constraint.</param>
-        /// <returns></returns>
-        public DelayedConstraint After(int delayInMilliseconds, int pollingInterval)
-        {
-            return new DelayedConstraint(
-                builder == null ? this : builder.Resolve(),
-                delayInMilliseconds,
-                pollingInterval);
-        }
-
-#endif
-        #endregion
-
-        #region IResolveConstraint Members
-        Constraint IResolveConstraint.Resolve()
-        {
-            return builder == null ? this : builder.Resolve();
-        }
-        #endregion
-    }
+#endif
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public abstract void WriteDescriptionTo(MessageWriter writer);
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a
+        /// MessageWriter. The default implementation simply writes
+        /// the raw value of actual, leaving it to the writer to
+        /// perform any formatting.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public virtual void WriteActualValueTo(MessageWriter writer)
+        {
+            writer.WriteActualValue(actual);
+        }
+        #endregion
+
+        #region ToString Override
+        /// <summary>
+        /// Default override of ToString returns the constraint DisplayName
+        /// followed by any arguments within angle brackets.
+        /// </summary>
+        /// <returns></returns>
+        public override string ToString()
+        {
+            string rep = GetStringRepresentation();
+
+            return this.builder == null ? rep : string.Format("<unresolved {0}>", rep);
+        }
+
+        /// <summary>
+        /// Returns the string representation of this constraint
+        /// </summary>
+        /// <returns></returns>
+        protected virtual string GetStringRepresentation()
+        {
+            switch (argcnt)
+            {
+                default:
+                case 0:
+                    return string.Format("<{0}>", DisplayName);
+                case 1:
+                    return string.Format("<{0} {1}>", DisplayName, _displayable(arg1));
+                case 2:
+                    return string.Format("<{0} {1} {2}>", DisplayName, _displayable(arg1), _displayable(arg2));
+            }
+        }
+
+        private static string _displayable(object o)
+        {
+            if (o == null) return "null";
+
+            string fmt = o is string ? "\"{0}\"" : "{0}";
+            return string.Format(System.Globalization.CultureInfo.InvariantCulture, fmt, o);
+        }
+        #endregion
+
+        #region Operator Overloads
+        /// <summary>
+        /// This operator creates a constraint that is satisfied only if both 
+        /// argument constraints are satisfied.
+        /// </summary>
+        public static Constraint operator &(Constraint left, Constraint right)
+        {
+            IResolveConstraint l = (IResolveConstraint)left;
+            IResolveConstraint r = (IResolveConstraint)right;
+            return new AndConstraint(l.Resolve(), r.Resolve());
+        }
+
+        /// <summary>
+        /// This operator creates a constraint that is satisfied if either 
+        /// of the argument constraints is satisfied.
+        /// </summary>
+        public static Constraint operator |(Constraint left, Constraint right)
+        {
+            IResolveConstraint l = (IResolveConstraint)left;
+            IResolveConstraint r = (IResolveConstraint)right;
+            return new OrConstraint(l.Resolve(), r.Resolve());
+        }
+
+        /// <summary>
+        /// This operator creates a constraint that is satisfied if the 
+        /// argument constraint is not satisfied.
+        /// </summary>
+        public static Constraint operator !(Constraint constraint)
+        {
+            IResolveConstraint r = constraint as IResolveConstraint;
+            return new NotConstraint(r == null ? new NullConstraint() : r.Resolve());
+        }
+        #endregion
+
+        #region Binary Operators
+        /// <summary>
+        /// Returns a ConstraintExpression by appending And
+        /// to the current constraint.
+        /// </summary>
+        public ConstraintExpression And
+        {
+            get
+            {
+                ConstraintBuilder builder = this.builder;
+                if (builder == null)
+                {
+                    builder = new ConstraintBuilder();
+                    builder.Append(this);
+                }
+
+                builder.Append(new AndOperator());
+
+                return new ConstraintExpression(builder);
+            }
+        }
+
+        /// <summary>
+        /// Returns a ConstraintExpression by appending And
+        /// to the current constraint.
+        /// </summary>
+        public ConstraintExpression With
+        {
+            get { return this.And; }
+        }
+
+        /// <summary>
+        /// Returns a ConstraintExpression by appending Or
+        /// to the current constraint.
+        /// </summary>
+        public ConstraintExpression Or
+        {
+            get
+            {
+                ConstraintBuilder builder = this.builder;
+                if (builder == null)
+                {
+                    builder = new ConstraintBuilder();
+                    builder.Append(this);
+                }
+
+                builder.Append(new OrOperator());
+
+                return new ConstraintExpression(builder);
+            }
+        }
+        #endregion
+
+        #region After Modifier
+
+#if !NUNITLITE
+        /// <summary>
+        /// Returns a DelayedConstraint with the specified delay time.
+        /// </summary>
+        /// <param name="delayInMilliseconds">The delay in milliseconds.</param>
+        /// <returns></returns>
+        public DelayedConstraint After(int delayInMilliseconds)
+        {
+            return new DelayedConstraint(
+                builder == null ? this : builder.Resolve(),
+                delayInMilliseconds);
+        }
+
+        /// <summary>
+        /// Returns a DelayedConstraint with the specified delay time
+        /// and polling interval.
+        /// </summary>
+        /// <param name="delayInMilliseconds">The delay in milliseconds.</param>
+        /// <param name="pollingInterval">The interval at which to test the constraint.</param>
+        /// <returns></returns>
+        public DelayedConstraint After(int delayInMilliseconds, int pollingInterval)
+        {
+            return new DelayedConstraint(
+                builder == null ? this : builder.Resolve(),
+                delayInMilliseconds,
+                pollingInterval);
+        }
+
+#endif
+        #endregion
+
+        #region IResolveConstraint Members
+        Constraint IResolveConstraint.Resolve()
+        {
+            return builder == null ? this : builder.Resolve();
+        }
+        #endregion
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/ContainsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/ContainsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/ContainsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,104 +1,103 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-	// TODO Needs tests
-	/// <summary>
-	/// ContainsConstraint tests a whether a string contains a substring
-	/// or a collection contains an object. It postpones the decision of
-	/// which test to use until the type of the actual argument is known.
-	/// This allows testing whether a string is contained in a collection
-	/// or as a substring of another string using the same syntax.
-	/// </summary>
-	public class ContainsConstraint : Constraint
-	{
-	    readonly object expected;
-		Constraint realConstraint;
-        bool ignoreCase;
-
-		private Constraint RealConstraint
-		{
-			get 
-			{
-				if ( realConstraint == null )
-				{
-                    if (actual is string)
-                    {
-                        StringConstraint constraint = new SubstringConstraint((string)expected);
-                        if (this.ignoreCase)
-                            constraint = constraint.IgnoreCase;
-                        this.realConstraint = constraint;
-                    }
-                    else
-                        this.realConstraint = new CollectionContainsConstraint(expected);
-				}
-
-				return realConstraint;
-			}
-			set 
-			{ 
-				realConstraint = value; 
-			}
-		}
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:ContainsConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected.</param>
-		public ContainsConstraint( object expected )
-		{
-			this.expected = expected;
-		}
-
-        /// <summary>
-        /// Flag the constraint to ignore case and return self.
-        /// </summary>
-        public ContainsConstraint IgnoreCase
-        {
-            get { this.ignoreCase = true; return this; }
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-		public override bool Matches(object actual)
-		{
-            this.actual = actual;
-			return this.RealConstraint.Matches( actual );
-		}
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			this.RealConstraint.WriteDescriptionTo(writer);
-		}
-	}
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+
+namespace NUnit.Framework.Constraints
+{
+    // TODO Needs tests
+    /// <summary>
+    /// ContainsConstraint tests a whether a string contains a substring
+    /// or a collection contains an object. It postpones the decision of
+    /// which test to use until the type of the actual argument is known.
+    /// This allows testing whether a string is contained in a collection
+    /// or as a substring of another string using the same syntax.
+    /// </summary>
+    public class ContainsConstraint : Constraint
+    {
+        readonly object expected;
+        Constraint realConstraint;
+        bool ignoreCase;
+
+        private Constraint RealConstraint
+        {
+            get
+            {
+                if (realConstraint == null)
+                {
+                    if (actual is string)
+                    {
+                        StringConstraint constraint = new SubstringConstraint((string)expected);
+                        if (this.ignoreCase)
+                            constraint = constraint.IgnoreCase;
+                        this.realConstraint = constraint;
+                    }
+                    else
+                        this.realConstraint = new CollectionContainsConstraint(expected);
+                }
+
+                return realConstraint;
+            }
+            set
+            {
+                realConstraint = value;
+            }
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ContainsConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected.</param>
+        public ContainsConstraint(object expected)
+        {
+            this.expected = expected;
+        }
+
+        /// <summary>
+        /// Flag the constraint to ignore case and return self.
+        /// </summary>
+        public ContainsConstraint IgnoreCase
+        {
+            get { this.ignoreCase = true; return this; }
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+            return this.RealConstraint.Matches(actual);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            this.RealConstraint.WriteDescriptionTo(writer);
+        }
+    }
+}

=== modified file 'src/NUnitFramework/framework/Constraints/DelayedConstraint.cs'
--- src/NUnitFramework/framework/Constraints/DelayedConstraint.cs	2010-08-02 02:42:35 +0000
+++ src/NUnitFramework/framework/Constraints/DelayedConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,111 +1,139 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-#if !NUNITLITE
-using System;
-using System.Threading;
-
-namespace NUnit.Framework.Constraints
-{
-    ///<summary>
-    /// Applies a delay to the match so that a match can be evaluated in the future.
-    ///</summary>
-    public class DelayedConstraint : PrefixConstraint
-    {
-        private readonly int delayInMilliseconds;
-        private readonly int pollingInterval;
-
-        ///<summary>
-        /// Creates a new DelayedConstraint
-        ///</summary>
-        ///<param name="baseConstraint">The inner constraint two decorate</param>
-        ///<param name="delayInMilliseconds">The time interval after which the match is performed</param>
-        ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
-        public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds)
-            : this(baseConstraint, delayInMilliseconds, 0) { }
-
-        ///<summary>
-        /// Creates a new DelayedConstraint
-        ///</summary>
-        ///<param name="baseConstraint">The inner constraint two decorate</param>
-        ///<param name="delayInMilliseconds">The time interval after which the match is performed</param>
-        ///<param name="pollingInterval">The time interval used for polling</param>
-        ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
-        public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds, int pollingInterval)
-            : base(baseConstraint)
-        {
-            if (delayInMilliseconds < 0)
-                throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds");
-
-            this.delayInMilliseconds = delayInMilliseconds;
-            this.pollingInterval = pollingInterval;
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for if the base constraint fails, false if it succeeds</returns>
-        public override bool Matches(object actual)
-        {
-            Thread.Sleep(delayInMilliseconds);
-            this.actual = actual;
-            return baseConstraint.Matches(actual);
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a delegate
-        /// </summary>
-        /// <param name="del">The delegate whose value is to be tested</param>
-        /// <returns>True for if the base constraint fails, false if it succeeds</returns>
-        public override bool Matches(ActualValueDelegate del)
-        {
-			int remainingDelay = delayInMilliseconds;
-
-			while (pollingInterval > 0 && pollingInterval < remainingDelay)
-			{
-				remainingDelay -= pollingInterval;
-				Thread.Sleep(pollingInterval);
-				this.actual = del();
-				if (baseConstraint.Matches(actual))
-					return true;
-			}
-
-			if ( remainingDelay > 0 )
-				Thread.Sleep(remainingDelay);
-			this.actual = del();
-			return baseConstraint.Matches(actual);
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given reference.
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+#if !NUNITLITE
+using System;
+using System.Threading;
+
+namespace NUnit.Framework.Constraints
+{
+    ///<summary>
+    /// Applies a delay to the match so that a match can be evaluated in the future.
+    ///</summary>
+    public class DelayedConstraint : PrefixConstraint
+    {
+        private readonly int delayInMilliseconds;
+        private readonly int pollingInterval;
+
+        ///<summary>
+        /// Creates a new DelayedConstraint
+        ///</summary>
+        ///<param name="baseConstraint">The inner constraint two decorate</param>
+        ///<param name="delayInMilliseconds">The time interval after which the match is performed</param>
+        ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
+        public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds)
+            : this(baseConstraint, delayInMilliseconds, 0) { }
+
+        ///<summary>
+        /// Creates a new DelayedConstraint
+        ///</summary>
+        ///<param name="baseConstraint">The inner constraint two decorate</param>
+        ///<param name="delayInMilliseconds">The time interval after which the match is performed</param>
+        ///<param name="pollingInterval">The time interval used for polling</param>
+        ///<exception cref="InvalidOperationException">If the value of <paramref name="delayInMilliseconds"/> is less than 0</exception>
+        public DelayedConstraint(Constraint baseConstraint, int delayInMilliseconds, int pollingInterval)
+            : base(baseConstraint)
+        {
+            if (delayInMilliseconds < 0)
+                throw new ArgumentException("Cannot check a condition in the past", "delayInMilliseconds");
+
+            this.delayInMilliseconds = delayInMilliseconds;
+            this.pollingInterval = pollingInterval;
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for if the base constraint fails, false if it succeeds</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            Thread.Sleep(delayInMilliseconds);
+            this.actual = actual;
+            return baseConstraint.Matches(actual);
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a delegate
+        /// </summary>
+        /// <param name="del">The delegate whose value is to be tested</param>
+        /// <returns>True for if the base constraint fails, false if it succeeds</returns>
+        public override IConstraintResult Matches(ActualValueDelegate del)
+        {
+            int remainingDelay = delayInMilliseconds;
+
+            while (pollingInterval > 0 && pollingInterval < remainingDelay)
+            {
+                remainingDelay -= pollingInterval;
+                Thread.Sleep(pollingInterval);
+                actual = del();
+                IConstraintResult result = baseConstraint.Matches(actual);
+                if (result.HasSucceeded)
+                    return result;
+            }
+
+            if (remainingDelay > 0)
+                Thread.Sleep(remainingDelay);
+            actual = del();
+            return baseConstraint.Matches(actual);
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given reference.
+        /// Overridden to wait for the specified delay period before
+        /// calling the base constraint with the dereferenced value.
+        /// </summary>
+        /// <param name="actual">A reference to the value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches<T>(ref T actual)
+        {
+            int remainingDelay = delayInMilliseconds;
+
+            while (pollingInterval > 0 && pollingInterval < remainingDelay)
+            {
+                remainingDelay -= pollingInterval;
+                Thread.Sleep(pollingInterval);
+                this.actual = actual;
+                IConstraintResult result = baseConstraint.Matches(actual);
+                if (result.HasSucceeded)
+                    return result;
+            }
+
+            if (remainingDelay > 0)
+                Thread.Sleep(remainingDelay);
+            this.actual = actual;
+            return baseConstraint.Matches(actual);
+        }
+#else
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given boolean reference.
         /// Overridden to wait for the specified delay period before
         /// calling the base constraint with the dereferenced value.
         /// </summary>
         /// <param name="actual">A reference to the value to be tested</param>
         /// <returns>True for success, false for failure</returns>
-        public override bool Matches<T>(ref T actual)
+        public override bool Matches(ref bool actual)
         {
             int remainingDelay = delayInMilliseconds;
 
@@ -120,63 +148,38 @@
 
             if ( remainingDelay > 0 )
                 Thread.Sleep(remainingDelay);
+            
             this.actual = actual;
             return baseConstraint.Matches(actual);
         }
-#else
-		/// <summary>
-		/// Test whether the constraint is satisfied by a given boolean reference.
-		/// Overridden to wait for the specified delay period before
-		/// calling the base constraint with the dereferenced value.
-		/// </summary>
-		/// <param name="actual">A reference to the value to be tested</param>
-		/// <returns>True for success, false for failure</returns>
-		public override bool Matches(ref bool actual)
-		{
-			int remainingDelay = delayInMilliseconds;
-
-			while (pollingInterval > 0 && pollingInterval < remainingDelay)
-			{
-				remainingDelay -= pollingInterval;
-				Thread.Sleep(pollingInterval);
-				this.actual = actual;
-				if (baseConstraint.Matches(actual))
-					return true;
-			}
-
-			if ( remainingDelay > 0 )
-				Thread.Sleep(remainingDelay);
-			this.actual = actual;
-			return baseConstraint.Matches(actual);
-		}
-#endif
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            baseConstraint.WriteDescriptionTo(writer);
-            writer.Write(string.Format(" after {0} millisecond delay", delayInMilliseconds));
-        }
-
-        /// <summary>
-        /// Write the actual value for a failing constraint test to a MessageWriter.
-        /// </summary>
-        /// <param name="writer">The writer on which the actual value is displayed</param>
-        public override void WriteActualValueTo(MessageWriter writer)
-        {
-            baseConstraint.WriteActualValueTo(writer);
-        }
-
-        /// <summary>
-        /// Returns the string representation of the constraint.
-        /// </summary>
-        protected override string GetStringRepresentation()
-        {
-            return string.Format("<after {0} {1}>", delayInMilliseconds, baseConstraint);
-        }
-    }
-}
-#endif
+#endif
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            baseConstraint.WriteDescriptionTo(writer);
+            writer.Write(string.Format(" after {0} millisecond delay", delayInMilliseconds));
+        }
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a MessageWriter.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public override void WriteActualValueTo(MessageWriter writer)
+        {
+            baseConstraint.WriteActualValueTo(writer);
+        }
+
+        /// <summary>
+        /// Returns the string representation of the constraint.
+        /// </summary>
+        protected override string GetStringRepresentation()
+        {
+            return string.Format("<after {0} {1}>", delayInMilliseconds, baseConstraint);
+        }
+    }
+}
+#endif
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EmptyCollectionConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EmptyCollectionConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/EmptyCollectionConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,52 +1,52 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// EmptyCollectionConstraint tests whether a collection is empty. 
-    /// </summary>
-    public class EmptyCollectionConstraint : CollectionConstraint
-	{
-		/// <summary>
-		/// Check that the collection is empty
-		/// </summary>
-		/// <param name="collection"></param>
-		/// <returns></returns>
-		protected override bool doMatch(IEnumerable collection)
-		{
-			return IsEmpty( collection );
-		}
-	
-		/// <summary>
-		/// Write the constraint description to a MessageWriter
-		/// </summary>
-		/// <param name="writer"></param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.Write( "<empty>" );
-		}
-	}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EmptyCollectionConstraint tests whether a collection is empty. 
+    /// </summary>
+    public class EmptyCollectionConstraint : CollectionConstraint
+    {
+        /// <summary>
+        /// Check that the collection is empty
+        /// </summary>
+        /// <param name="collection"></param>
+        /// <returns></returns>
+        protected override bool doMatch(IEnumerable collection)
+        {
+            return IsEmpty(collection);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.Write("<empty>");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EmptyConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EmptyConstraint.cs	2010-07-17 13:44:46 +0000
+++ src/NUnitFramework/framework/Constraints/EmptyConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,70 +1,67 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// EmptyConstraint tests a whether a string or collection is empty,
-	/// postponing the decision about which test is applied until the
-	/// type of the actual argument is known.
-	/// </summary>
-	public class EmptyConstraint : Constraint
-	{
-		private Constraint RealConstraint
-		{
-			get 
-			{
-				if ( actual is string )
-					return new EmptyStringConstraint();
-                else if (actual is System.IO.DirectoryInfo)
-                    return new EmptyDirectoryContraint();
-                else
-					return new EmptyCollectionConstraint();
-			}
-		}
-		
-		/// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			return this.RealConstraint.Matches( actual );
-		}
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			this.RealConstraint.WriteDescriptionTo( writer );
-		}
-	}
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EmptyConstraint tests a whether a string or collection is empty,
+    /// postponing the decision about which test is applied until the
+    /// type of the actual argument is known.
+    /// </summary>
+    public class EmptyConstraint : Constraint
+    {
+        private Constraint RealConstraint
+        {
+            get
+            {
+                if (actual is string)
+                    return new EmptyStringConstraint();
+                else if (actual is System.IO.DirectoryInfo)
+                    return new EmptyDirectoryContraint();
+                else
+                    return new EmptyCollectionConstraint();
+            }
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            return RealConstraint.Matches(actual);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            RealConstraint.WriteDescriptionTo(writer);
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EmptyDirectoryConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EmptyDirectoryConstraint.cs	2010-07-17 13:44:46 +0000
+++ src/NUnitFramework/framework/Constraints/EmptyDirectoryConstraint.cs	2011-06-04 23:12:29 +0000
@@ -32,14 +32,14 @@
     public class EmptyDirectoryContraint : Constraint
     {
         private int files = 0;
-        private int subdirs = 0;
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        private int subdirs = 0;
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
@@ -48,9 +48,10 @@
                 throw new ArgumentException("The actual value must be a DirectoryInfo", "actual");
 
             files = dirInfo.GetFiles().Length;
-            subdirs = dirInfo.GetDirectories().Length;
+            subdirs = dirInfo.GetDirectories().Length;
+            bool hasSucceeded = files == 0 && subdirs == 0;
 
-            return files == 0 && subdirs == 0;
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/EmptyStringConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EmptyStringConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/EmptyStringConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,55 +1,55 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// EmptyStringConstraint tests whether a string is empty.
-    /// </summary>
-    public class EmptyStringConstraint : Constraint
-    {
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            if (!(actual is string))
-                return false;
-
-            return (string)actual == string.Empty;
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.Write("<empty>");
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EmptyStringConstraint tests whether a string is empty.
+    /// </summary>
+    public class EmptyStringConstraint : Constraint
+    {
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            string actualAsString = actual as string;
+            bool hasSucceeded = actual != null && string.IsNullOrEmpty(actualAsString);
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.Write("<empty>");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EndsWithConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EndsWithConstraint.cs	2011-04-20 16:40:19 +0000
+++ src/NUnitFramework/framework/Constraints/EndsWithConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,67 +1,67 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// EndsWithConstraint can test whether a string ends
-    /// with an expected substring.
-    /// </summary>
-    public class EndsWithConstraint : StringConstraint
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:EndsWithConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected string</param>
-        public EndsWithConstraint(string expected) : base(expected) { }
-
-        /// <summary>
-        /// Test whether the constraint is matched by the actual value.
-        /// This is a template method, which calls the IsMatch method
-        /// of the derived class.
-        /// </summary>
-        /// <param name="actual"></param>
-        /// <returns></returns>
-        protected override bool Matches(string actual)
-        {
-            //this.actual = actual;
-
-            if (this.caseInsensitive)
-                return actual.ToLower().EndsWith(expected.ToLower());
-            else
-                return actual.EndsWith(expected);
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WritePredicate("String ending with");
-            writer.WriteExpectedValue(expected);
-			if ( this.caseInsensitive )
-				writer.WriteModifier( "ignoring case" );
-		}
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EndsWithConstraint can test whether a string ends
+    /// with an expected substring.
+    /// </summary>
+    public class EndsWithConstraint : StringConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:EndsWithConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected string</param>
+        public EndsWithConstraint(string expected) : base(expected) { }
+
+        /// <summary>
+        /// Test whether the constraint is matched by the actual value.
+        /// This is a template method, which calls the IsMatch method
+        /// of the derived class.
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        protected override bool Matches(string actual)
+        {
+            //this.actual = actual;
+
+            if (this.caseInsensitive)
+                return actual.ToLower().EndsWith(expected.ToLower());
+            else
+                return actual.EndsWith(expected);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("String ending with");
+            writer.WriteExpectedValue(expected);
+            if (this.caseInsensitive)
+                writer.WriteModifier("ignoring case");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EqualConstraint.cs'
--- src/NUnitFramework/framework/Constraints/EqualConstraint.cs	2010-08-02 02:42:35 +0000
+++ src/NUnitFramework/framework/Constraints/EqualConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,515 +1,517 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.IO;
-using System.Collections;
-#if CLR_2_0 || CLR_4_0
-using System.Collections.Generic;
-#endif
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// EqualConstraint is able to compare an actual value with the
-    /// expected value provided in its constructor. Two objects are 
-    /// considered equal if both are null, or if both have the same 
-    /// value. NUnit has special semantics for some object types.
-    /// </summary>
-    public class EqualConstraint : Constraint
-    {
-        #region Static and Instance Fields
-
-        private readonly object expected;
-
-        /// <summary>
-        /// If true, strings in error messages will be clipped
-        /// </summary>
-        private bool clipStrings = true;
-
-        /// <summary>
-        /// NUnitEqualityComparer used to test equality.
-        /// </summary>
-        private NUnitEqualityComparer comparer = new NUnitEqualityComparer();
-
-        #region Message Strings
-        private static readonly string StringsDiffer_1 =
-			"String lengths are both {0}. Strings differ at index {1}.";
-		private static readonly string StringsDiffer_2 =
-			"Expected string length {0} but was {1}. Strings differ at index {2}.";
-		private static readonly string StreamsDiffer_1 =
-			"Stream lengths are both {0}. Streams differ at offset {1}.";
-		private static readonly string StreamsDiffer_2 =
-			"Expected Stream length {0} but was {1}.";// Streams differ at offset {2}.";
-		private static readonly string CollectionType_1 =
-			"Expected and actual are both {0}";
-		private static readonly string CollectionType_2 =
-			"Expected is {0}, actual is {1}";
-		private static readonly string ValuesDiffer_1 =
-			"Values differ at index {0}";
-		private static readonly string ValuesDiffer_2 =
-			"Values differ at expected index {0}, actual index {1}";
-        #endregion
-
-        #endregion
-
-        #region Constructor
-        /// <summary>
-        /// Initializes a new instance of the <see cref="EqualConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected value.</param>
-        public EqualConstraint(object expected) : base(expected)
-        {
-            this.expected = expected;
-        }
-        #endregion
-
-        #region Constraint Modifiers
-        /// <summary>
-        /// Flag the constraint to ignore case and return self.
-        /// </summary>
-        public EqualConstraint IgnoreCase
-        {
-            get
-            {
-                comparer.IgnoreCase = true;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Flag the constraint to suppress string clipping 
-        /// and return self.
-        /// </summary>
-        public EqualConstraint NoClip
-        {
-            get
-            {
-                clipStrings = false;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Flag the constraint to compare arrays as collections
-        /// and return self.
-        /// </summary>
-        public EqualConstraint AsCollection
-        {
-            get
-            {
-                comparer.CompareAsCollection = true;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Flag the constraint to use a tolerance when determining equality.
-        /// </summary>
-        /// <param name="amount">Tolerance value to be used</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Within(object amount)
-        {
-            if (!comparer.Tolerance.IsEmpty)
-                throw new InvalidOperationException("Within modifier may appear only once in a constraint expression");
-
-            comparer.Tolerance = new Tolerance(amount);
-            return this;
-        }
-
-        /// <summary>
-        /// Switches the .Within() modifier to interpret its tolerance as
-        /// a distance in representable values (see remarks).
-        /// </summary>
-        /// <returns>Self.</returns>
-        /// <remarks>
-        /// Ulp stands for "unit in the last place" and describes the minimum
-        /// amount a given value can change. For any integers, an ulp is 1 whole
-        /// digit. For floating point values, the accuracy of which is better
-        /// for smaller numbers and worse for larger numbers, an ulp depends
-        /// on the size of the number. Using ulps for comparison of floating
-        /// point results instead of fixed tolerances is safer because it will
-        /// automatically compensate for the added inaccuracy of larger numbers.
-        /// </remarks>
-        public EqualConstraint Ulps
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Ulps;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Switches the .Within() modifier to interpret its tolerance as
-        /// a percentage that the actual values is allowed to deviate from
-        /// the expected value.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Percent
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Percent;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in days.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Days
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Days;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in hours.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Hours
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Hours;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in minutes.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Minutes
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Minutes;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in seconds.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Seconds
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Seconds;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in milliseconds.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Milliseconds
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Milliseconds;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Causes the tolerance to be interpreted as a TimeSpan in clock ticks.
-        /// </summary>
-        /// <returns>Self</returns>
-        public EqualConstraint Ticks
-        {
-            get
-            {
-                comparer.Tolerance = comparer.Tolerance.Ticks;
-                return this;
-            }
-        }
-
-        /// <summary>
-        /// Flag the constraint to use the supplied IComparer object.
-        /// </summary>
-        /// <param name="comparer">The IComparer object to use.</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Using(IComparer comparer)
-        {
-            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
-            return this;
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Flag the constraint to use the supplied IComparer object.
-        /// </summary>
-        /// <param name="comparer">The IComparer object to use.</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Using<T>(IComparer<T> comparer)
-        {
-            this.comparer.ExternalComparer = EqualityAdapter.For( comparer );
-            return this;
-        }
-
-                /// <summary>
-        /// Flag the constraint to use the supplied Comparison object.
-        /// </summary>
-        /// <param name="comparer">The IComparer object to use.</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Using<T>(Comparison<T> comparer)
-        {
-            this.comparer.ExternalComparer = EqualityAdapter.For( comparer );
-            return this;
-        }
-
-        /// <summary>
-        /// Flag the constraint to use the supplied IEqualityComparer object.
-        /// </summary>
-        /// <param name="comparer">The IComparer object to use.</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Using(IEqualityComparer comparer)
-        {
-            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
-            return this;
-        }
-
-        /// <summary>
-        /// Flag the constraint to use the supplied IEqualityComparer object.
-        /// </summary>
-        /// <param name="comparer">The IComparer object to use.</param>
-        /// <returns>Self.</returns>
-        public EqualConstraint Using<T>(IEqualityComparer<T> comparer)
-        {
-            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
-            return this;
-        }
-#endif
-        #endregion
-
-        #region Public Methods
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            return comparer.ObjectsEqual(expected, actual);
-        }
-
-        /// <summary>
-        /// Write a failure message. Overridden to provide custom 
-        /// failure messages for EqualConstraint.
-        /// </summary>
-        /// <param name="writer">The MessageWriter to write to</param>
-        public override void WriteMessageTo(MessageWriter writer)
-        {
-            DisplayDifferences(writer, expected, actual, 0);
-        }
-
-
-        /// <summary>
-        /// Write description of this constraint
-        /// </summary>
-        /// <param name="writer">The MessageWriter to write to</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-			writer.WriteExpectedValue( expected );
-
-            if (comparer.Tolerance != null && !comparer.Tolerance.IsEmpty)
-			{
-				writer.WriteConnector("+/-");
-                writer.WriteExpectedValue(comparer.Tolerance.Value);
-			}
-
-			if ( comparer.IgnoreCase )
-				writer.WriteModifier("ignoring case");
-        }
-
-        private void DisplayDifferences(MessageWriter writer, object expected, object actual, int depth)
-        {
-            if (expected is string && actual is string)
-                DisplayStringDifferences(writer, (string)expected, (string)actual);
-            else if (expected is ICollection && actual is ICollection)
-                DisplayCollectionDifferences(writer, (ICollection)expected, (ICollection)actual, depth);
-            else if (expected is Stream && actual is Stream)
-                DisplayStreamDifferences(writer, (Stream)expected, (Stream)actual, depth);
-            else if (comparer.Tolerance != null)
-                writer.DisplayDifferences(expected, actual, comparer.Tolerance);
-            else
-                writer.DisplayDifferences(expected, actual);
-        }
-        #endregion
-
-        #region DisplayStringDifferences
-        private void DisplayStringDifferences(MessageWriter writer, string expected, string actual)
-        {
-            int mismatch = MsgUtils.FindMismatchPosition(expected, actual, 0, comparer.IgnoreCase);
-
-            if (expected.Length == actual.Length)
-				writer.WriteMessageLine(StringsDiffer_1, expected.Length, mismatch);
-			else
-				writer.WriteMessageLine(StringsDiffer_2, expected.Length, actual.Length, mismatch);
-
-            writer.DisplayStringDifferences(expected, actual, mismatch, comparer.IgnoreCase, clipStrings);
-        }
-        #endregion
-
-		#region DisplayStreamDifferences
-		private void DisplayStreamDifferences(MessageWriter writer, Stream expected, Stream actual, int depth)
-		{
-            if (expected.Length == actual.Length)
-			{
-                long offset = (long)comparer.FailurePoints[depth];
-                writer.WriteMessageLine(StreamsDiffer_1, expected.Length, offset);
-			}
-			else
-				writer.WriteMessageLine(StreamsDiffer_2, expected.Length, actual.Length);
-		}
-		#endregion
-
-        #region DisplayCollectionDifferences
-        /// <summary>
-        /// Display the failure information for two collections that did not match.
-        /// </summary>
-		/// <param name="writer">The MessageWriter on which to display</param>
-		/// <param name="expected">The expected collection.</param>
-        /// <param name="actual">The actual collection</param>
-        /// <param name="depth">The depth of this failure in a set of nested collections</param>
-        private void DisplayCollectionDifferences(MessageWriter writer, ICollection expected, ICollection actual, int depth)
-        {
-            int failurePoint = comparer.FailurePoints.Count > depth ? (int)comparer.FailurePoints[depth] : -1;
-
-            DisplayCollectionTypesAndSizes(writer, expected, actual, depth);
-
-            if (failurePoint >= 0)
-            {
-                DisplayFailurePoint(writer, expected, actual, failurePoint, depth);
-				if (failurePoint < expected.Count && failurePoint < actual.Count)
-					DisplayDifferences(
-						writer,
-						GetValueFromCollection(expected, (int)failurePoint),
-						GetValueFromCollection(actual, (int)failurePoint),
-						++depth);
-				else if (expected.Count < actual.Count)
-				{
-					writer.Write( "  Extra:    " );
-					writer.WriteCollectionElements( actual, (int)failurePoint, 3 );
-				}
-				else
-				{
-					writer.Write( "  Missing:  " );
-					writer.WriteCollectionElements( expected, (int)failurePoint, 3 );
-				}
-            }
-        }
-
-        /// <summary>
-        /// Displays a single line showing the types and sizes of the expected
-        /// and actual collections or arrays. If both are identical, the value is 
-        /// only shown once.
-        /// </summary>
-		/// <param name="writer">The MessageWriter on which to display</param>
-		/// <param name="expected">The expected collection or array</param>
-        /// <param name="actual">The actual collection or array</param>
-		/// <param name="indent">The indentation level for the message line</param>
-		private void DisplayCollectionTypesAndSizes(MessageWriter writer, ICollection expected, ICollection actual, int indent)
-        {
-            string sExpected = MsgUtils.GetTypeRepresentation(expected);
-            if (!(expected is Array))
-                sExpected += string.Format(" with {0} elements", expected.Count);
-
-            string sActual = MsgUtils.GetTypeRepresentation(actual);
-            if (!(actual is Array))
-                sActual += string.Format(" with {0} elements", actual.Count);
-
-            if (sExpected == sActual)
-                writer.WriteMessageLine(indent, CollectionType_1, sExpected);
-            else
-                writer.WriteMessageLine(indent, CollectionType_2, sExpected, sActual);
-        }
-
-        /// <summary>
-        /// Displays a single line showing the point in the expected and actual
-        /// arrays at which the comparison failed. If the arrays have different
-        /// structures or dimensions, both values are shown.
-        /// </summary>
-		/// <param name="writer">The MessageWriter on which to display</param>
-		/// <param name="expected">The expected array</param>
-        /// <param name="actual">The actual array</param>
-        /// <param name="failurePoint">Index of the failure point in the underlying collections</param>
-		/// <param name="indent">The indentation level for the message line</param>
-		private void DisplayFailurePoint(MessageWriter writer, ICollection expected, ICollection actual, long failurePoint, int indent)
-        {
-            Array expectedArray = expected as Array;
-            Array actualArray = actual as Array;
-
-            int expectedRank = expectedArray != null ? expectedArray.Rank : 1;
-            int actualRank = actualArray != null ? actualArray.Rank : 1;
-
-            bool useOneIndex = expectedRank == actualRank;
-
-            if (expectedArray != null && actualArray != null)
-                for (int r = 1; r < expectedRank && useOneIndex; r++)
-                    if (expectedArray.GetLength(r) != actualArray.GetLength(r))
-                        useOneIndex = false;
-
-            int[] expectedIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(expected, (int)failurePoint);
-            if (useOneIndex)
-            {
-                writer.WriteMessageLine(indent, ValuesDiffer_1, MsgUtils.GetArrayIndicesAsString(expectedIndices));
-            }
-            else
-            {
-                int[] actualIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(actual, (int)failurePoint);
-                writer.WriteMessageLine(indent, ValuesDiffer_2,
-                    MsgUtils.GetArrayIndicesAsString(expectedIndices), MsgUtils.GetArrayIndicesAsString(actualIndices));
-            }
-        }
-
-        private static object GetValueFromCollection(ICollection collection, int index)
-        {
-            Array array = collection as Array;
-
-            if (array != null && array.Rank > 1)
-                return array.GetValue(MsgUtils.GetArrayIndicesFromCollectionIndex(array, index));
-
-            if (collection is IList)
-                return ((IList)collection)[index];
-
-            foreach (object obj in collection)
-                if (--index < 0)
-                    return obj;
-
-            return null;
-        }
-        #endregion
-    }
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.IO;
+using System.Collections;
+#if CLR_2_0 || CLR_4_0
+using System.Collections.Generic;
+#endif
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EqualConstraint is able to compare an actual value with the
+    /// expected value provided in its constructor. Two objects are 
+    /// considered equal if both are null, or if both have the same 
+    /// value. NUnit has special semantics for some object types.
+    /// </summary>
+    public class EqualConstraint : Constraint
+    {
+        #region Static and Instance Fields
+
+        private readonly object expected;
+
+        /// <summary>
+        /// If true, strings in error messages will be clipped
+        /// </summary>
+        private bool clipStrings = true;
+
+        /// <summary>
+        /// NUnitEqualityComparer used to test equality.
+        /// </summary>
+        private NUnitEqualityComparer comparer = new NUnitEqualityComparer();
+
+        #region Message Strings
+        private static readonly string StringsDiffer_1 =
+            "String lengths are both {0}. Strings differ at index {1}.";
+        private static readonly string StringsDiffer_2 =
+            "Expected string length {0} but was {1}. Strings differ at index {2}.";
+        private static readonly string StreamsDiffer_1 =
+            "Stream lengths are both {0}. Streams differ at offset {1}.";
+        private static readonly string StreamsDiffer_2 =
+            "Expected Stream length {0} but was {1}.";// Streams differ at offset {2}.";
+        private static readonly string CollectionType_1 =
+            "Expected and actual are both {0}";
+        private static readonly string CollectionType_2 =
+            "Expected is {0}, actual is {1}";
+        private static readonly string ValuesDiffer_1 =
+            "Values differ at index {0}";
+        private static readonly string ValuesDiffer_2 =
+            "Values differ at expected index {0}, actual index {1}";
+        #endregion
+
+        #endregion
+
+        #region Constructor
+        /// <summary>
+        /// Initializes a new instance of the <see cref="EqualConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected value.</param>
+        public EqualConstraint(object expected)
+            : base(expected)
+        {
+            this.expected = expected;
+        }
+        #endregion
+
+        #region Constraint Modifiers
+        /// <summary>
+        /// Flag the constraint to ignore case and return self.
+        /// </summary>
+        public EqualConstraint IgnoreCase
+        {
+            get
+            {
+                comparer.IgnoreCase = true;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Flag the constraint to suppress string clipping 
+        /// and return self.
+        /// </summary>
+        public EqualConstraint NoClip
+        {
+            get
+            {
+                clipStrings = false;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Flag the constraint to compare arrays as collections
+        /// and return self.
+        /// </summary>
+        public EqualConstraint AsCollection
+        {
+            get
+            {
+                comparer.CompareAsCollection = true;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Flag the constraint to use a tolerance when determining equality.
+        /// </summary>
+        /// <param name="amount">Tolerance value to be used</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Within(object amount)
+        {
+            if (!comparer.Tolerance.IsEmpty)
+                throw new InvalidOperationException("Within modifier may appear only once in a constraint expression");
+
+            comparer.Tolerance = new Tolerance(amount);
+            return this;
+        }
+
+        /// <summary>
+        /// Switches the .Within() modifier to interpret its tolerance as
+        /// a distance in representable values (see remarks).
+        /// </summary>
+        /// <returns>Self.</returns>
+        /// <remarks>
+        /// Ulp stands for "unit in the last place" and describes the minimum
+        /// amount a given value can change. For any integers, an ulp is 1 whole
+        /// digit. For floating point values, the accuracy of which is better
+        /// for smaller numbers and worse for larger numbers, an ulp depends
+        /// on the size of the number. Using ulps for comparison of floating
+        /// point results instead of fixed tolerances is safer because it will
+        /// automatically compensate for the added inaccuracy of larger numbers.
+        /// </remarks>
+        public EqualConstraint Ulps
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Ulps;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Switches the .Within() modifier to interpret its tolerance as
+        /// a percentage that the actual values is allowed to deviate from
+        /// the expected value.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Percent
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Percent;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in days.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Days
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Days;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in hours.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Hours
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Hours;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in minutes.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Minutes
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Minutes;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in seconds.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Seconds
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Seconds;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in milliseconds.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Milliseconds
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Milliseconds;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Causes the tolerance to be interpreted as a TimeSpan in clock ticks.
+        /// </summary>
+        /// <returns>Self</returns>
+        public EqualConstraint Ticks
+        {
+            get
+            {
+                comparer.Tolerance = comparer.Tolerance.Ticks;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Flag the constraint to use the supplied IComparer object.
+        /// </summary>
+        /// <param name="comparer">The IComparer object to use.</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Using(IComparer comparer)
+        {
+            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
+            return this;
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Flag the constraint to use the supplied IComparer object.
+        /// </summary>
+        /// <param name="comparer">The IComparer object to use.</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Using<T>(IComparer<T> comparer)
+        {
+            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
+            return this;
+        }
+
+        /// <summary>
+        /// Flag the constraint to use the supplied Comparison object.
+        /// </summary>
+        /// <param name="comparer">The IComparer object to use.</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Using<T>(Comparison<T> comparer)
+        {
+            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
+            return this;
+        }
+
+        /// <summary>
+        /// Flag the constraint to use the supplied IEqualityComparer object.
+        /// </summary>
+        /// <param name="comparer">The IComparer object to use.</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Using(IEqualityComparer comparer)
+        {
+            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
+            return this;
+        }
+
+        /// <summary>
+        /// Flag the constraint to use the supplied IEqualityComparer object.
+        /// </summary>
+        /// <param name="comparer">The IComparer object to use.</param>
+        /// <returns>Self.</returns>
+        public EqualConstraint Using<T>(IEqualityComparer<T> comparer)
+        {
+            this.comparer.ExternalComparer = EqualityAdapter.For(comparer);
+            return this;
+        }
+#endif
+        #endregion
+
+        #region Public Methods
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            return new StandardConstraintResult(comparer.ObjectsEqual(expected, actual));
+        }
+
+        /// <summary>
+        /// Write a failure message. Overridden to provide custom 
+        /// failure messages for EqualConstraint.
+        /// </summary>
+        /// <param name="writer">The MessageWriter to write to</param>
+        public override void WriteMessageTo(MessageWriter writer)
+        {
+            DisplayDifferences(writer, expected, actual, 0);
+        }
+
+
+        /// <summary>
+        /// Write description of this constraint
+        /// </summary>
+        /// <param name="writer">The MessageWriter to write to</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WriteExpectedValue(expected);
+
+            if (comparer.Tolerance != null && !comparer.Tolerance.IsEmpty)
+            {
+                writer.WriteConnector("+/-");
+                writer.WriteExpectedValue(comparer.Tolerance.Value);
+            }
+
+            if (comparer.IgnoreCase)
+                writer.WriteModifier("ignoring case");
+        }
+
+        private void DisplayDifferences(MessageWriter writer, object expected, object actual, int depth)
+        {
+            if (expected is string && actual is string)
+                DisplayStringDifferences(writer, (string)expected, (string)actual);
+            else if (expected is ICollection && actual is ICollection)
+                DisplayCollectionDifferences(writer, (ICollection)expected, (ICollection)actual, depth);
+            else if (expected is Stream && actual is Stream)
+                DisplayStreamDifferences(writer, (Stream)expected, (Stream)actual, depth);
+            else if (comparer.Tolerance != null)
+                writer.DisplayDifferences(expected, actual, comparer.Tolerance);
+            else
+                writer.DisplayDifferences(expected, actual);
+        }
+        #endregion
+
+        #region DisplayStringDifferences
+        private void DisplayStringDifferences(MessageWriter writer, string expected, string actual)
+        {
+            int mismatch = MsgUtils.FindMismatchPosition(expected, actual, 0, comparer.IgnoreCase);
+
+            if (expected.Length == actual.Length)
+                writer.WriteMessageLine(StringsDiffer_1, expected.Length, mismatch);
+            else
+                writer.WriteMessageLine(StringsDiffer_2, expected.Length, actual.Length, mismatch);
+
+            writer.DisplayStringDifferences(expected, actual, mismatch, comparer.IgnoreCase, clipStrings);
+        }
+        #endregion
+
+        #region DisplayStreamDifferences
+        private void DisplayStreamDifferences(MessageWriter writer, Stream expected, Stream actual, int depth)
+        {
+            if (expected.Length == actual.Length)
+            {
+                long offset = (long)comparer.FailurePoints[depth];
+                writer.WriteMessageLine(StreamsDiffer_1, expected.Length, offset);
+            }
+            else
+                writer.WriteMessageLine(StreamsDiffer_2, expected.Length, actual.Length);
+        }
+        #endregion
+
+        #region DisplayCollectionDifferences
+        /// <summary>
+        /// Display the failure information for two collections that did not match.
+        /// </summary>
+        /// <param name="writer">The MessageWriter on which to display</param>
+        /// <param name="expected">The expected collection.</param>
+        /// <param name="actual">The actual collection</param>
+        /// <param name="depth">The depth of this failure in a set of nested collections</param>
+        private void DisplayCollectionDifferences(MessageWriter writer, ICollection expected, ICollection actual, int depth)
+        {
+            int failurePoint = comparer.FailurePoints.Count > depth ? (int)comparer.FailurePoints[depth] : -1;
+
+            DisplayCollectionTypesAndSizes(writer, expected, actual, depth);
+
+            if (failurePoint >= 0)
+            {
+                DisplayFailurePoint(writer, expected, actual, failurePoint, depth);
+                if (failurePoint < expected.Count && failurePoint < actual.Count)
+                    DisplayDifferences(
+                        writer,
+                        GetValueFromCollection(expected, (int)failurePoint),
+                        GetValueFromCollection(actual, (int)failurePoint),
+                        ++depth);
+                else if (expected.Count < actual.Count)
+                {
+                    writer.Write("  Extra:    ");
+                    writer.WriteCollectionElements(actual, (int)failurePoint, 3);
+                }
+                else
+                {
+                    writer.Write("  Missing:  ");
+                    writer.WriteCollectionElements(expected, (int)failurePoint, 3);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Displays a single line showing the types and sizes of the expected
+        /// and actual collections or arrays. If both are identical, the value is 
+        /// only shown once.
+        /// </summary>
+        /// <param name="writer">The MessageWriter on which to display</param>
+        /// <param name="expected">The expected collection or array</param>
+        /// <param name="actual">The actual collection or array</param>
+        /// <param name="indent">The indentation level for the message line</param>
+        private void DisplayCollectionTypesAndSizes(MessageWriter writer, ICollection expected, ICollection actual, int indent)
+        {
+            string sExpected = MsgUtils.GetTypeRepresentation(expected);
+            if (!(expected is Array))
+                sExpected += string.Format(" with {0} elements", expected.Count);
+
+            string sActual = MsgUtils.GetTypeRepresentation(actual);
+            if (!(actual is Array))
+                sActual += string.Format(" with {0} elements", actual.Count);
+
+            if (sExpected == sActual)
+                writer.WriteMessageLine(indent, CollectionType_1, sExpected);
+            else
+                writer.WriteMessageLine(indent, CollectionType_2, sExpected, sActual);
+        }
+
+        /// <summary>
+        /// Displays a single line showing the point in the expected and actual
+        /// arrays at which the comparison failed. If the arrays have different
+        /// structures or dimensions, both values are shown.
+        /// </summary>
+        /// <param name="writer">The MessageWriter on which to display</param>
+        /// <param name="expected">The expected array</param>
+        /// <param name="actual">The actual array</param>
+        /// <param name="failurePoint">Index of the failure point in the underlying collections</param>
+        /// <param name="indent">The indentation level for the message line</param>
+        private void DisplayFailurePoint(MessageWriter writer, ICollection expected, ICollection actual, long failurePoint, int indent)
+        {
+            Array expectedArray = expected as Array;
+            Array actualArray = actual as Array;
+
+            int expectedRank = expectedArray != null ? expectedArray.Rank : 1;
+            int actualRank = actualArray != null ? actualArray.Rank : 1;
+
+            bool useOneIndex = expectedRank == actualRank;
+
+            if (expectedArray != null && actualArray != null)
+                for (int r = 1; r < expectedRank && useOneIndex; r++)
+                    if (expectedArray.GetLength(r) != actualArray.GetLength(r))
+                        useOneIndex = false;
+
+            int[] expectedIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(expected, (int)failurePoint);
+            if (useOneIndex)
+            {
+                writer.WriteMessageLine(indent, ValuesDiffer_1, MsgUtils.GetArrayIndicesAsString(expectedIndices));
+            }
+            else
+            {
+                int[] actualIndices = MsgUtils.GetArrayIndicesFromCollectionIndex(actual, (int)failurePoint);
+                writer.WriteMessageLine(indent, ValuesDiffer_2,
+                    MsgUtils.GetArrayIndicesAsString(expectedIndices), MsgUtils.GetArrayIndicesAsString(actualIndices));
+            }
+        }
+
+        private static object GetValueFromCollection(ICollection collection, int index)
+        {
+            Array array = collection as Array;
+
+            if (array != null && array.Rank > 1)
+                return array.GetValue(MsgUtils.GetArrayIndicesFromCollectionIndex(array, index));
+
+            if (collection is IList)
+                return ((IList)collection)[index];
+
+            foreach (object obj in collection)
+                if (--index < 0)
+                    return obj;
+
+            return null;
+        }
+        #endregion
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/EqualityAdapter.cs'
--- src/NUnitFramework/framework/Constraints/EqualityAdapter.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/EqualityAdapter.cs	2011-06-04 23:12:29 +0000
@@ -1,137 +1,137 @@
-// ***********************************************************************
-// Copyright (c) 2009 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-#if CLR_2_0 || CLR_4_0
-using System.Collections.Generic;
-#endif
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// EqualityAdapter class handles all equality comparisons
-    /// that use an IEqualityComparer, IEqualityComparer&lt;T&gt;
-    /// or a ComparisonAdapter.
-    /// </summary>
-    public abstract class EqualityAdapter
-    {
-        /// <summary>
-        /// Compares two objects, returning true if they are equal
-        /// </summary>
-        public abstract bool ObjectsEqual(object x, object y);
-
-        /// <summary>
-        /// Returns an EqualityAdapter that wraps an IComparer.
-        /// </summary>
-        public static EqualityAdapter For(IComparer comparer)
-        {
-            return new ComparisonAdapterAdapter(ComparisonAdapter.For(comparer));
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Returns an EqualityAdapter that wraps an IEqualityComparer.
-        /// </summary>
-        public static EqualityAdapter For(IEqualityComparer comparer)
-        {
-            return new EqualityComparerAdapter(comparer);
-        }
-
-        /// <summary>
-        /// Returns an EqualityAdapter that wraps an IEqualityComparer&lt;T&gt;.
-        /// </summary>
-        public static EqualityAdapter For<T>(IEqualityComparer<T> comparer)
-        {
-            return new EqualityComparerAdapter<T>(comparer);
-        }
-
-        /// <summary>
-        /// Returns an EqualityAdapter that wraps an IComparer&lt;T&gt;.
-        /// </summary>
-        public static EqualityAdapter For<T>(IComparer<T> comparer)
-        {
-            return new ComparisonAdapterAdapter( ComparisonAdapter.For(comparer) );
-        }
-
-        /// <summary>
-        /// Returns an EqualityAdapter that wraps a Comparison&lt;T&gt;.
-        /// </summary>
-        public static EqualityAdapter For<T>(Comparison<T> comparer)
-        {
-            return new ComparisonAdapterAdapter( ComparisonAdapter.For(comparer) );
-        }
-
-        class EqualityComparerAdapter : EqualityAdapter
-        {
-            private readonly IEqualityComparer comparer;
-
-            public EqualityComparerAdapter(IEqualityComparer comparer)
-            {
-                this.comparer = comparer;
-            }
-
-            public override bool ObjectsEqual(object x, object y)
-            {
-                return comparer.Equals(x, y);
-            }
-        }
-
-        class EqualityComparerAdapter<T> : EqualityAdapter
-        {
-            private readonly IEqualityComparer<T> comparer;
-
-            public EqualityComparerAdapter(IEqualityComparer<T> comparer)
-            {
-                this.comparer = comparer;
-            }
-
-            public override bool ObjectsEqual(object x, object y)
-            {
-                if (!typeof(T).IsAssignableFrom(x.GetType()))
-                    throw new ArgumentException("Cannot compare " + x.ToString());
-
-                if (!typeof(T).IsAssignableFrom(y.GetType()))
-                    throw new ArgumentException("Cannot compare to " + y.ToString());
-
-                return comparer.Equals((T)x, (T)y);
-            }
-        }
-#endif
-
-        class ComparisonAdapterAdapter : EqualityAdapter
-        {
-            private readonly ComparisonAdapter comparer;
-
-            public ComparisonAdapterAdapter(ComparisonAdapter comparer)
-            {
-                this.comparer = comparer;
-            }
-
-            public override bool ObjectsEqual(object x, object y)
-            {
-                return comparer.Compare(x, y) == 0;
-            }
-        }
-    }
-}
+// ***********************************************************************
+// Copyright (c) 2009 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+#if CLR_2_0 || CLR_4_0
+using System.Collections.Generic;
+#endif
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// EqualityAdapter class handles all equality comparisons
+    /// that use an IEqualityComparer, IEqualityComparer&lt;T&gt;
+    /// or a ComparisonAdapter.
+    /// </summary>
+    public abstract class EqualityAdapter
+    {
+        /// <summary>
+        /// Compares two objects, returning true if they are equal
+        /// </summary>
+        public abstract bool ObjectsEqual(object x, object y);
+
+        /// <summary>
+        /// Returns an EqualityAdapter that wraps an IComparer.
+        /// </summary>
+        public static EqualityAdapter For(IComparer comparer)
+        {
+            return new ComparisonAdapterAdapter(ComparisonAdapter.For(comparer));
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Returns an EqualityAdapter that wraps an IEqualityComparer.
+        /// </summary>
+        public static EqualityAdapter For(IEqualityComparer comparer)
+        {
+            return new EqualityComparerAdapter(comparer);
+        }
+
+        /// <summary>
+        /// Returns an EqualityAdapter that wraps an IEqualityComparer&lt;T&gt;.
+        /// </summary>
+        public static EqualityAdapter For<T>(IEqualityComparer<T> comparer)
+        {
+            return new EqualityComparerAdapter<T>(comparer);
+        }
+
+        /// <summary>
+        /// Returns an EqualityAdapter that wraps an IComparer&lt;T&gt;.
+        /// </summary>
+        public static EqualityAdapter For<T>(IComparer<T> comparer)
+        {
+            return new ComparisonAdapterAdapter(ComparisonAdapter.For(comparer));
+        }
+
+        /// <summary>
+        /// Returns an EqualityAdapter that wraps a Comparison&lt;T&gt;.
+        /// </summary>
+        public static EqualityAdapter For<T>(Comparison<T> comparer)
+        {
+            return new ComparisonAdapterAdapter(ComparisonAdapter.For(comparer));
+        }
+
+        class EqualityComparerAdapter : EqualityAdapter
+        {
+            private readonly IEqualityComparer comparer;
+
+            public EqualityComparerAdapter(IEqualityComparer comparer)
+            {
+                this.comparer = comparer;
+            }
+
+            public override bool ObjectsEqual(object x, object y)
+            {
+                return comparer.Equals(x, y);
+            }
+        }
+
+        class EqualityComparerAdapter<T> : EqualityAdapter
+        {
+            private readonly IEqualityComparer<T> comparer;
+
+            public EqualityComparerAdapter(IEqualityComparer<T> comparer)
+            {
+                this.comparer = comparer;
+            }
+
+            public override bool ObjectsEqual(object x, object y)
+            {
+                if (!typeof(T).IsAssignableFrom(x.GetType()))
+                    throw new ArgumentException("Cannot compare " + x.ToString());
+
+                if (!typeof(T).IsAssignableFrom(y.GetType()))
+                    throw new ArgumentException("Cannot compare to " + y.ToString());
+
+                return comparer.Equals((T)x, (T)y);
+            }
+        }
+#endif
+
+        class ComparisonAdapterAdapter : EqualityAdapter
+        {
+            private readonly ComparisonAdapter comparer;
+
+            public ComparisonAdapterAdapter(ComparisonAdapter comparer)
+            {
+                this.comparer = comparer;
+            }
+
+            public override bool ObjectsEqual(object x, object y)
+            {
+                return comparer.Compare(x, y) == 0;
+            }
+        }
+    }
+}

=== modified file 'src/NUnitFramework/framework/Constraints/ExactTypeConstraint.cs'
--- src/NUnitFramework/framework/Constraints/ExactTypeConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/ExactTypeConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,64 +1,66 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// ExactTypeConstraint is used to test that an object
-    /// is of the exact type provided in the constructor
-    /// </summary>
-    public class ExactTypeConstraint : TypeConstraint
-    {
-        /// <summary>
-        /// Construct an ExactTypeConstraint for a given Type
-        /// </summary>
-        /// <param name="type">The expected Type.</param>
-        public ExactTypeConstraint(Type type)
-            : base(type)
-        {
-            this.DisplayName = "typeof";
-        }
-
-        /// <summary>
-        /// Test that an object is of the exact type specified
-        /// </summary>
-        /// <param name="actual">The actual value.</param>
-        /// <returns>True if the tested object is of the exact type provided, otherwise false.</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-            return actual != null && actual.GetType() == this.expectedType;
-        }
-
-        /// <summary>
-        /// Write the description of this constraint to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The MessageWriter to use</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WriteExpectedValue(expectedType);
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// ExactTypeConstraint is used to test that an object
+    /// is of the exact type provided in the constructor
+    /// </summary>
+    public class ExactTypeConstraint : TypeConstraint
+    {
+        /// <summary>
+        /// Construct an ExactTypeConstraint for a given Type
+        /// </summary>
+        /// <param name="type">The expected Type.</param>
+        public ExactTypeConstraint(Type type)
+            : base(type)
+        {
+            this.DisplayName = "typeof";
+        }
+
+        /// <summary>
+        /// Test that an object is of the exact type specified
+        /// </summary>
+        /// <param name="actual">The actual value.</param>
+        /// <returns>True if the tested object is of the exact type provided, otherwise false.</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+            bool hasSucceeded = actual != null && actual.GetType() == expectedType;
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the description of this constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The MessageWriter to use</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WriteExpectedValue(expectedType);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/FloatingPointNumerics.cs'
--- src/NUnitFramework/framework/Constraints/FloatingPointNumerics.cs	2009-10-28 22:51:26 +0000
+++ src/NUnitFramework/framework/Constraints/FloatingPointNumerics.cs	2011-06-04 23:12:29 +0000
@@ -1,255 +1,255 @@
-// ***********************************************************************
-// Copyright (c) 2009 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-#if !NETCF_1_0
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace NUnit.Framework.Constraints
-{
-
-    /// <summary>Helper routines for working with floating point numbers</summary>
-    /// <remarks>
-    ///   <para>
-    ///     The floating point comparison code is based on this excellent article:
-    ///     http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
-    ///   </para>
-    ///   <para>
-    ///     "ULP" means Unit in the Last Place and in the context of this library refers to
-    ///     the distance between two adjacent floating point numbers. IEEE floating point
-    ///     numbers can only represent a finite subset of natural numbers, with greater
-    ///     accuracy for smaller numbers and lower accuracy for very large numbers.
-    ///   </para>
-    ///   <para>
-    ///     If a comparison is allowed "2 ulps" of deviation, that means the values are
-    ///     allowed to deviate by up to 2 adjacent floating point values, which might be
-    ///     as low as 0.0000001 for small numbers or as high as 10.0 for large numbers.
-    ///   </para>
-    /// </remarks>
-    public class FloatingPointNumerics
-    {
-
-        #region struct FloatIntUnion
-
-        /// <summary>Union of a floating point variable and an integer</summary>
-        [StructLayout(LayoutKind.Explicit)]
-        private struct FloatIntUnion
-        {
-            /// <summary>The union's value as a floating point variable</summary>
-            [FieldOffset(0)]
-            public float Float;
-
-            /// <summary>The union's value as an integer</summary>
-            [FieldOffset(0)]
-            public int Int;
-
-            /// <summary>The union's value as an unsigned integer</summary>
-            [FieldOffset(0)]
-            public uint UInt;
-        }
-
-        #endregion // struct FloatIntUnion
-
-        #region struct DoubleLongUnion
-
-        /// <summary>Union of a double precision floating point variable and a long</summary>
-        [StructLayout(LayoutKind.Explicit)]
-        private struct DoubleLongUnion
-        {
-            /// <summary>The union's value as a double precision floating point variable</summary>
-            [FieldOffset(0)]
-            public double Double;
-
-            /// <summary>The union's value as a long</summary>
-            [FieldOffset(0)]
-            public long Long;
-
-            /// <summary>The union's value as an unsigned long</summary>
-            [FieldOffset(0)]
-            public ulong ULong;
-        }
-
-        #endregion // struct DoubleLongUnion
-
-        /// <summary>Compares two floating point values for equality</summary>
-        /// <param name="left">First floating point value to be compared</param>
-        /// <param name="right">Second floating point value t be compared</param>
-        /// <param name="maxUlps">
-        ///   Maximum number of representable floating point values that are allowed to
-        ///   be between the left and the right floating point values
-        /// </param>
-        /// <returns>True if both numbers are equal or close to being equal</returns>
-        /// <remarks>
-        ///   <para>
-        ///     Floating point values can only represent a finite subset of natural numbers.
-        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
-        ///     but nothing inbetween them.
-        ///   </para>
-        ///   <para>
-        ///     This comparison will count how many possible floating point values are between
-        ///     the left and the right number. If the number of possible values between both
-        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
-        ///     being equal.
-        ///   </para>
-        ///   <para>
-        ///     Implementation partially follows the code outlined here:
-        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
-        ///   </para>
-        /// </remarks>
-        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
-        {
-            FloatIntUnion leftUnion = new FloatIntUnion();
-            FloatIntUnion rightUnion = new FloatIntUnion();
-
-            leftUnion.Float = left;
-            rightUnion.Float = right;
-
-            uint leftSignMask = (leftUnion.UInt >> 31);
-            uint rightSignMask = (rightUnion.UInt >> 31);
-
-            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);
-            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);
-
-            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);
-            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);
-
-            return (Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
-        }
-
-        /// <summary>Compares two double precision floating point values for equality</summary>
-        /// <param name="left">First double precision floating point value to be compared</param>
-        /// <param name="right">Second double precision floating point value t be compared</param>
-        /// <param name="maxUlps">
-        ///   Maximum number of representable double precision floating point values that are
-        ///   allowed to be between the left and the right double precision floating point values
-        /// </param>
-        /// <returns>True if both numbers are equal or close to being equal</returns>
-        /// <remarks>
-        ///   <para>
-        ///     Double precision floating point values can only represent a limited series of
-        ///     natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004
-        ///     can be stored in a double, but nothing inbetween them.
-        ///   </para>
-        ///   <para>
-        ///     This comparison will count how many possible double precision floating point
-        ///     values are between the left and the right number. If the number of possible
-        ///     values between both numbers is less than or equal to maxUlps, then the numbers
-        ///     are considered as being equal.
-        ///   </para>
-        ///   <para>
-        ///     Implementation partially follows the code outlined here:
-        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
-        ///   </para>
-        /// </remarks>
-        public static bool AreAlmostEqualUlps(double left, double right, long maxUlps)
-        {
-            DoubleLongUnion leftUnion = new DoubleLongUnion();
-            DoubleLongUnion rightUnion = new DoubleLongUnion();
-
-            leftUnion.Double = left;
-            rightUnion.Double = right;
-
-            ulong leftSignMask = (leftUnion.ULong >> 63);
-            ulong rightSignMask = (rightUnion.ULong >> 63);
-
-            ulong leftTemp = ((0x8000000000000000 - leftUnion.ULong) & leftSignMask);
-            leftUnion.ULong = leftTemp | (leftUnion.ULong & ~leftSignMask);
-
-            ulong rightTemp = ((0x8000000000000000 - rightUnion.ULong) & rightSignMask);
-            rightUnion.ULong = rightTemp | (rightUnion.ULong & ~rightSignMask);
-
-            return (Math.Abs(leftUnion.Long - rightUnion.Long) <= maxUlps);
-        }
-
-        /// <summary>
-        ///   Reinterprets the memory contents of a floating point value as an integer value
-        /// </summary>
-        /// <param name="value">
-        ///   Floating point value whose memory contents to reinterpret
-        /// </param>
-        /// <returns>
-        ///   The memory contents of the floating point value interpreted as an integer
-        /// </returns>
-        public static int ReinterpretAsInt(float value)
-        {
-            FloatIntUnion union = new FloatIntUnion();
-            union.Float = value;
-            return union.Int;
-        }
-
-        /// <summary>
-        ///   Reinterprets the memory contents of a double precision floating point
-        ///   value as an integer value
-        /// </summary>
-        /// <param name="value">
-        ///   Double precision floating point value whose memory contents to reinterpret
-        /// </param>
-        /// <returns>
-        ///   The memory contents of the double precision floating point value
-        ///   interpreted as an integer
-        /// </returns>
-        public static long ReinterpretAsLong(double value)
-        {
-            DoubleLongUnion union = new DoubleLongUnion();
-            union.Double = value;
-            return union.Long;
-        }
-
-        /// <summary>
-        ///   Reinterprets the memory contents of an integer as a floating point value
-        /// </summary>
-        /// <param name="value">Integer value whose memory contents to reinterpret</param>
-        /// <returns>
-        ///   The memory contents of the integer value interpreted as a floating point value
-        /// </returns>
-        public static float ReinterpretAsFloat(int value)
-        {
-            FloatIntUnion union = new FloatIntUnion();
-            union.Int = value;
-            return union.Float;
-        }
-
-        /// <summary>
-        ///   Reinterprets the memory contents of an integer value as a double precision
-        ///   floating point value
-        /// </summary>
-        /// <param name="value">Integer whose memory contents to reinterpret</param>
-        /// <returns>
-        ///   The memory contents of the integer interpreted as a double precision
-        ///   floating point value
-        /// </returns>
-        public static double ReinterpretAsDouble(long value)
-        {
-            DoubleLongUnion union = new DoubleLongUnion();
-            union.Long = value;
-            return union.Double;
-        }
-
-		private FloatingPointNumerics()
-		{
-		}
-    }
-}
-
-#endif
+// ***********************************************************************
+// Copyright (c) 2009 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+#if !NETCF_1_0
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace NUnit.Framework.Constraints
+{
+
+    /// <summary>Helper routines for working with floating point numbers</summary>
+    /// <remarks>
+    ///   <para>
+    ///     The floating point comparison code is based on this excellent article:
+    ///     http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
+    ///   </para>
+    ///   <para>
+    ///     "ULP" means Unit in the Last Place and in the context of this library refers to
+    ///     the distance between two adjacent floating point numbers. IEEE floating point
+    ///     numbers can only represent a finite subset of natural numbers, with greater
+    ///     accuracy for smaller numbers and lower accuracy for very large numbers.
+    ///   </para>
+    ///   <para>
+    ///     If a comparison is allowed "2 ulps" of deviation, that means the values are
+    ///     allowed to deviate by up to 2 adjacent floating point values, which might be
+    ///     as low as 0.0000001 for small numbers or as high as 10.0 for large numbers.
+    ///   </para>
+    /// </remarks>
+    public class FloatingPointNumerics
+    {
+
+        #region struct FloatIntUnion
+
+        /// <summary>Union of a floating point variable and an integer</summary>
+        [StructLayout(LayoutKind.Explicit)]
+        private struct FloatIntUnion
+        {
+            /// <summary>The union's value as a floating point variable</summary>
+            [FieldOffset(0)]
+            public float Float;
+
+            /// <summary>The union's value as an integer</summary>
+            [FieldOffset(0)]
+            public int Int;
+
+            /// <summary>The union's value as an unsigned integer</summary>
+            [FieldOffset(0)]
+            public uint UInt;
+        }
+
+        #endregion // struct FloatIntUnion
+
+        #region struct DoubleLongUnion
+
+        /// <summary>Union of a double precision floating point variable and a long</summary>
+        [StructLayout(LayoutKind.Explicit)]
+        private struct DoubleLongUnion
+        {
+            /// <summary>The union's value as a double precision floating point variable</summary>
+            [FieldOffset(0)]
+            public double Double;
+
+            /// <summary>The union's value as a long</summary>
+            [FieldOffset(0)]
+            public long Long;
+
+            /// <summary>The union's value as an unsigned long</summary>
+            [FieldOffset(0)]
+            public ulong ULong;
+        }
+
+        #endregion // struct DoubleLongUnion
+
+        /// <summary>Compares two floating point values for equality</summary>
+        /// <param name="left">First floating point value to be compared</param>
+        /// <param name="right">Second floating point value t be compared</param>
+        /// <param name="maxUlps">
+        ///   Maximum number of representable floating point values that are allowed to
+        ///   be between the left and the right floating point values
+        /// </param>
+        /// <returns>True if both numbers are equal or close to being equal</returns>
+        /// <remarks>
+        ///   <para>
+        ///     Floating point values can only represent a finite subset of natural numbers.
+        ///     For example, the values 2.00000000 and 2.00000024 can be stored in a float,
+        ///     but nothing inbetween them.
+        ///   </para>
+        ///   <para>
+        ///     This comparison will count how many possible floating point values are between
+        ///     the left and the right number. If the number of possible values between both
+        ///     numbers is less than or equal to maxUlps, then the numbers are considered as
+        ///     being equal.
+        ///   </para>
+        ///   <para>
+        ///     Implementation partially follows the code outlined here:
+        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
+        ///   </para>
+        /// </remarks>
+        public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
+        {
+            FloatIntUnion leftUnion = new FloatIntUnion();
+            FloatIntUnion rightUnion = new FloatIntUnion();
+
+            leftUnion.Float = left;
+            rightUnion.Float = right;
+
+            uint leftSignMask = (leftUnion.UInt >> 31);
+            uint rightSignMask = (rightUnion.UInt >> 31);
+
+            uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);
+            leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);
+
+            uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);
+            rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);
+
+            return (Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps);
+        }
+
+        /// <summary>Compares two double precision floating point values for equality</summary>
+        /// <param name="left">First double precision floating point value to be compared</param>
+        /// <param name="right">Second double precision floating point value t be compared</param>
+        /// <param name="maxUlps">
+        ///   Maximum number of representable double precision floating point values that are
+        ///   allowed to be between the left and the right double precision floating point values
+        /// </param>
+        /// <returns>True if both numbers are equal or close to being equal</returns>
+        /// <remarks>
+        ///   <para>
+        ///     Double precision floating point values can only represent a limited series of
+        ///     natural numbers. For example, the values 2.0000000000000000 and 2.0000000000000004
+        ///     can be stored in a double, but nothing inbetween them.
+        ///   </para>
+        ///   <para>
+        ///     This comparison will count how many possible double precision floating point
+        ///     values are between the left and the right number. If the number of possible
+        ///     values between both numbers is less than or equal to maxUlps, then the numbers
+        ///     are considered as being equal.
+        ///   </para>
+        ///   <para>
+        ///     Implementation partially follows the code outlined here:
+        ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
+        ///   </para>
+        /// </remarks>
+        public static bool AreAlmostEqualUlps(double left, double right, long maxUlps)
+        {
+            DoubleLongUnion leftUnion = new DoubleLongUnion();
+            DoubleLongUnion rightUnion = new DoubleLongUnion();
+
+            leftUnion.Double = left;
+            rightUnion.Double = right;
+
+            ulong leftSignMask = (leftUnion.ULong >> 63);
+            ulong rightSignMask = (rightUnion.ULong >> 63);
+
+            ulong leftTemp = ((0x8000000000000000 - leftUnion.ULong) & leftSignMask);
+            leftUnion.ULong = leftTemp | (leftUnion.ULong & ~leftSignMask);
+
+            ulong rightTemp = ((0x8000000000000000 - rightUnion.ULong) & rightSignMask);
+            rightUnion.ULong = rightTemp | (rightUnion.ULong & ~rightSignMask);
+
+            return (Math.Abs(leftUnion.Long - rightUnion.Long) <= maxUlps);
+        }
+
+        /// <summary>
+        ///   Reinterprets the memory contents of a floating point value as an integer value
+        /// </summary>
+        /// <param name="value">
+        ///   Floating point value whose memory contents to reinterpret
+        /// </param>
+        /// <returns>
+        ///   The memory contents of the floating point value interpreted as an integer
+        /// </returns>
+        public static int ReinterpretAsInt(float value)
+        {
+            FloatIntUnion union = new FloatIntUnion();
+            union.Float = value;
+            return union.Int;
+        }
+
+        /// <summary>
+        ///   Reinterprets the memory contents of a double precision floating point
+        ///   value as an integer value
+        /// </summary>
+        /// <param name="value">
+        ///   Double precision floating point value whose memory contents to reinterpret
+        /// </param>
+        /// <returns>
+        ///   The memory contents of the double precision floating point value
+        ///   interpreted as an integer
+        /// </returns>
+        public static long ReinterpretAsLong(double value)
+        {
+            DoubleLongUnion union = new DoubleLongUnion();
+            union.Double = value;
+            return union.Long;
+        }
+
+        /// <summary>
+        ///   Reinterprets the memory contents of an integer as a floating point value
+        /// </summary>
+        /// <param name="value">Integer value whose memory contents to reinterpret</param>
+        /// <returns>
+        ///   The memory contents of the integer value interpreted as a floating point value
+        /// </returns>
+        public static float ReinterpretAsFloat(int value)
+        {
+            FloatIntUnion union = new FloatIntUnion();
+            union.Int = value;
+            return union.Float;
+        }
+
+        /// <summary>
+        ///   Reinterprets the memory contents of an integer value as a double precision
+        ///   floating point value
+        /// </summary>
+        /// <param name="value">Integer whose memory contents to reinterpret</param>
+        /// <returns>
+        ///   The memory contents of the integer interpreted as a double precision
+        ///   floating point value
+        /// </returns>
+        public static double ReinterpretAsDouble(long value)
+        {
+            DoubleLongUnion union = new DoubleLongUnion();
+            union.Long = value;
+            return union.Double;
+        }
+
+        private FloatingPointNumerics()
+        {
+        }
+    }
+}
+
+#endif
\ No newline at end of file

=== added file 'src/NUnitFramework/framework/Constraints/IConstraintResult.cs'
--- src/NUnitFramework/framework/Constraints/IConstraintResult.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Constraints/IConstraintResult.cs	2011-06-04 23:12:29 +0000
@@ -0,0 +1,105 @@
+// ***********************************************************************
+// Copyright (c) 2011 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+
+    /// <summary>
+    /// Contain the result of <see cref="Constraint.Matches(object)"/> executed against an actual value.
+    /// </summary>
+    public interface IConstraintResult
+    {
+        /// <summary>
+        /// True if actual value meets the Constraint criteria otherwise false.
+        /// </summary>
+        bool HasSucceeded { get; }
+
+        /// <summary>
+        /// The actual value that were passed to the <see cref="Constraint.Matches(object)"/> method.
+        /// </summary>
+        object Actual { get; }
+
+        /// <summary>
+        /// The expected criteria the Constraint matches the actual value against.
+        /// </summary>
+        object Expected { get; }
+
+        #region Constraint Information
+
+        /// <summary>
+        /// Display friendly name of the constraint.
+        /// </summary>
+        string Name { get; }
+
+        /// <summary>
+        /// Description of the constraint may be affected by the state the constraint hade 
+        /// when <see cref="Constraint.Matches(object)"/> was performed against the actual value.
+        /// </summary>
+        string Description { get; }
+
+        /// <summary>
+        /// Predicate that were used when <see cref="Constraint.Matches(object)"/> was performed, 
+        /// set to empty string if no predicate were used.
+        /// </summary>
+        string Predicate { get; }
+
+        /// <summary>
+        /// Modifier that were used when <see cref="Constraint.Matches(object)"/> was performed, 
+        /// set to empty string if no modifier were used.
+        /// </summary>
+        string Modifier { get; }
+
+        #endregion
+
+        #region Write Methods
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        void WriteDescriptionTo(MessageWriter writer);
+
+        /// <summary>
+        /// Write the failure message to the MessageWriter provided
+        /// as an argument. The default implementation simply passes
+        /// the constraint and the actual value to the writer, which
+        /// then displays the constraint description and the value.
+        /// 
+        /// Constraints that need to provide additional details,
+        /// such as where the error occured can override this.
+        /// </summary>
+        /// <param name="writer">The MessageWriter on which to display the message</param>
+        void WriteMessageTo(MessageWriter writer);
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a
+        /// MessageWriter. The default implementation simply writes
+        /// the raw value of actual, leaving it to the writer to
+        /// perform any formatting.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        void WriteActualValueTo(MessageWriter writer);
+
+        #endregion
+    }
+}

=== modified file 'src/NUnitFramework/framework/Constraints/InstanceOfTypeConstraint.cs'
--- src/NUnitFramework/framework/Constraints/InstanceOfTypeConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/InstanceOfTypeConstraint.cs	2011-06-04 23:12:29 +0000
@@ -39,17 +39,19 @@
             : base(type)
         {
             this.DisplayName = "instanceof";
-        }
-
-        /// <summary>
-        /// Test whether an object is of the specified type or a derived type
-        /// </summary>
-        /// <param name="actual">The object to be tested</param>
-        /// <returns>True if the object is of the provided type or derives from it, otherwise false.</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Test whether an object is of the specified type or a derived type
+        /// </summary>
+        /// <param name="actual">The object to be tested</param>
+        /// <returns>True if the object is of the provided type or derives from it, otherwise false.</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
-            return actual != null && expectedType.IsInstanceOfType(actual);
+            bool hasSucceeded = actual != null && expectedType.IsInstanceOfType(actual);
+
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/MessageWriter.cs'
--- src/NUnitFramework/framework/Constraints/MessageWriter.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/MessageWriter.cs	2011-06-04 23:12:29 +0000
@@ -1,154 +1,154 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System.IO;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// MessageWriter is the abstract base for classes that write
-	/// constraint descriptions and messages in some form. The
-	/// class has separate methods for writing various components
-	/// of a message, allowing implementations to tailor the
-	/// presentation as needed.
-	/// </summary>
-    public abstract class MessageWriter : StringWriter
-    {
-
-		/// <summary>
-		/// Construct a MessageWriter given a culture
-		/// </summary>
-		protected MessageWriter() : base( System.Globalization.CultureInfo.InvariantCulture ) { }
-
-        /// <summary>
-        /// Abstract method to get the max line length
-        /// </summary>
-        public abstract int MaxLineLength { get; set; }
-
-		/// <summary>
-		/// Method to write single line  message with optional args, usually
-		/// written to precede the general failure message.
-		/// </summary>
-		/// <param name="message">The message to be written</param>
-		/// <param name="args">Any arguments used in formatting the message</param>
-		public void WriteMessageLine(string message, params object[] args)
-        {
-            WriteMessageLine(0, message, args);
-        }
-
-        /// <summary>
-        /// Method to write single line  message with optional args, usually
-        /// written to precede the general failure message, at a givel 
-        /// indentation level.
-        /// </summary>
-        /// <param name="level">The indentation level of the message</param>
-        /// <param name="message">The message to be written</param>
-        /// <param name="args">Any arguments used in formatting the message</param>
-        public abstract void WriteMessageLine(int level, string message, params object[] args);
-
-        /// <summary>
-        /// Display Expected and Actual lines for a constraint. This
-        /// is called by MessageWriter's default implementation of 
-        /// WriteMessageTo and provides the generic two-line display. 
-        /// </summary>
-        /// <param name="constraint">The constraint that failed</param>
-        public abstract void DisplayDifferences(Constraint constraint);
-
-		/// <summary>
-		/// Display Expected and Actual lines for given values. This
-		/// method may be called by constraints that need more control over
-		/// the display of actual and expected values than is provided
-		/// by the default implementation.
-		/// </summary>
-		/// <param name="expected">The expected value</param>
-		/// <param name="actual">The actual value causing the failure</param>
-		public abstract void DisplayDifferences(object expected, object actual);
-
-		/// <summary>
-		/// Display Expected and Actual lines for given values, including
-		/// a tolerance value on the Expected line.
-		/// </summary>
-		/// <param name="expected">The expected value</param>
-		/// <param name="actual">The actual value causing the failure</param>
-		/// <param name="tolerance">The tolerance within which the test was made</param>
-		public abstract void DisplayDifferences(object expected, object actual, Tolerance tolerance);
-
-		/// <summary>
-        /// Display the expected and actual string values on separate lines.
-        /// If the mismatch parameter is >=0, an additional line is displayed
-        /// line containing a caret that points to the mismatch point.
-        /// </summary>
-        /// <param name="expected">The expected string value</param>
-        /// <param name="actual">The actual string value</param>
-        /// <param name="mismatch">The point at which the strings don't match or -1</param>
-        /// <param name="ignoreCase">If true, case is ignored in locating the point where the strings differ</param>
-        /// <param name="clipping">If true, the strings should be clipped to fit the line</param>
-        public abstract void DisplayStringDifferences(string expected, string actual, int mismatch, bool ignoreCase, bool clipping);
-
-        /// <summary>
-        /// Writes the text for a connector.
-        /// </summary>
-        /// <param name="connector">The connector.</param>
-        public abstract void WriteConnector(string connector);
-
-        /// <summary>
-        /// Writes the text for a predicate.
-        /// </summary>
-        /// <param name="predicate">The predicate.</param>
-        public abstract void WritePredicate(string predicate);
-
-		/// <summary>
-		/// Writes the text for an expected value.
-		/// </summary>
-		/// <param name="expected">The expected value.</param>
-		public abstract void WriteExpectedValue(object expected);
-
-		/// <summary>
-		/// Writes the text for a modifier
-		/// </summary>
-		/// <param name="modifier">The modifier.</param>
-		public abstract void WriteModifier(string modifier);
-
-		/// <summary>
-		/// Writes the text for an actual value.
-		/// </summary>
-		/// <param name="actual">The actual value.</param>
-		public abstract void WriteActualValue(object actual);
-
-		/// <summary>
-		/// Writes the text for a generalized value.
-		/// </summary>
-		/// <param name="val">The value.</param>
-		public abstract void WriteValue(object val);
-    
-		/// <summary>
-		/// Writes the text for a collection value,
-		/// starting at a particular point, to a max length
-		/// </summary>
-		/// <param name="collection">The collection containing elements to write.</param>
-        /// <param name="start">The starting point of the elements to write</param>
-        /// <param name="max">The maximum number of elements to write</param>
-		public abstract void WriteCollectionElements(ICollection collection, int start, int max);
-	}
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System.IO;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// MessageWriter is the abstract base for classes that write
+    /// constraint descriptions and messages in some form. The
+    /// class has separate methods for writing various components
+    /// of a message, allowing implementations to tailor the
+    /// presentation as needed.
+    /// </summary>
+    public abstract class MessageWriter : StringWriter
+    {
+
+        /// <summary>
+        /// Construct a MessageWriter given a culture
+        /// </summary>
+        protected MessageWriter() : base(System.Globalization.CultureInfo.InvariantCulture) { }
+
+        /// <summary>
+        /// Abstract method to get the max line length
+        /// </summary>
+        public abstract int MaxLineLength { get; set; }
+
+        /// <summary>
+        /// Method to write single line  message with optional args, usually
+        /// written to precede the general failure message.
+        /// </summary>
+        /// <param name="message">The message to be written</param>
+        /// <param name="args">Any arguments used in formatting the message</param>
+        public void WriteMessageLine(string message, params object[] args)
+        {
+            WriteMessageLine(0, message, args);
+        }
+
+        /// <summary>
+        /// Method to write single line  message with optional args, usually
+        /// written to precede the general failure message, at a givel 
+        /// indentation level.
+        /// </summary>
+        /// <param name="level">The indentation level of the message</param>
+        /// <param name="message">The message to be written</param>
+        /// <param name="args">Any arguments used in formatting the message</param>
+        public abstract void WriteMessageLine(int level, string message, params object[] args);
+
+        /// <summary>
+        /// Display Expected and Actual lines for a constraint. This
+        /// is called by MessageWriter's default implementation of 
+        /// WriteMessageTo and provides the generic two-line display. 
+        /// </summary>
+        /// <param name="constraint">The constraint that failed</param>
+        public abstract void DisplayDifferences(Constraint constraint);
+
+        /// <summary>
+        /// Display Expected and Actual lines for given values. This
+        /// method may be called by constraints that need more control over
+        /// the display of actual and expected values than is provided
+        /// by the default implementation.
+        /// </summary>
+        /// <param name="expected">The expected value</param>
+        /// <param name="actual">The actual value causing the failure</param>
+        public abstract void DisplayDifferences(object expected, object actual);
+
+        /// <summary>
+        /// Display Expected and Actual lines for given values, including
+        /// a tolerance value on the Expected line.
+        /// </summary>
+        /// <param name="expected">The expected value</param>
+        /// <param name="actual">The actual value causing the failure</param>
+        /// <param name="tolerance">The tolerance within which the test was made</param>
+        public abstract void DisplayDifferences(object expected, object actual, Tolerance tolerance);
+
+        /// <summary>
+        /// Display the expected and actual string values on separate lines.
+        /// If the mismatch parameter is >=0, an additional line is displayed
+        /// line containing a caret that points to the mismatch point.
+        /// </summary>
+        /// <param name="expected">The expected string value</param>
+        /// <param name="actual">The actual string value</param>
+        /// <param name="mismatch">The point at which the strings don't match or -1</param>
+        /// <param name="ignoreCase">If true, case is ignored in locating the point where the strings differ</param>
+        /// <param name="clipping">If true, the strings should be clipped to fit the line</param>
+        public abstract void DisplayStringDifferences(string expected, string actual, int mismatch, bool ignoreCase, bool clipping);
+
+        /// <summary>
+        /// Writes the text for a connector.
+        /// </summary>
+        /// <param name="connector">The connector.</param>
+        public abstract void WriteConnector(string connector);
+
+        /// <summary>
+        /// Writes the text for a predicate.
+        /// </summary>
+        /// <param name="predicate">The predicate.</param>
+        public abstract void WritePredicate(string predicate);
+
+        /// <summary>
+        /// Writes the text for an expected value.
+        /// </summary>
+        /// <param name="expected">The expected value.</param>
+        public abstract void WriteExpectedValue(object expected);
+
+        /// <summary>
+        /// Writes the text for a modifier
+        /// </summary>
+        /// <param name="modifier">The modifier.</param>
+        public abstract void WriteModifier(string modifier);
+
+        /// <summary>
+        /// Writes the text for an actual value.
+        /// </summary>
+        /// <param name="actual">The actual value.</param>
+        public abstract void WriteActualValue(object actual);
+
+        /// <summary>
+        /// Writes the text for a generalized value.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        public abstract void WriteValue(object val);
+
+        /// <summary>
+        /// Writes the text for a collection value,
+        /// starting at a particular point, to a max length
+        /// </summary>
+        /// <param name="collection">The collection containing elements to write.</param>
+        /// <param name="start">The starting point of the elements to write</param>
+        /// <param name="max">The maximum number of elements to write</param>
+        public abstract void WriteCollectionElements(ICollection collection, int start, int max);
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/MsgUtils.cs'
--- src/NUnitFramework/framework/Constraints/MsgUtils.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/MsgUtils.cs	2011-06-04 23:12:29 +0000
@@ -1,281 +1,281 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Text;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// Static methods used in creating messages
-    /// </summary>
-    public class MsgUtils
-    {
-        /// <summary>
-        /// Static string used when strings are clipped
-        /// </summary>
-        private const string ELLIPSIS = "...";
-
-        /// <summary>
-        /// Returns the representation of a type as used in NUnitLite.
-        /// This is the same as Type.ToString() except for arrays,
-        /// which are displayed with their declared sizes.
-        /// </summary>
-        /// <param name="obj"></param>
-        /// <returns></returns>
-        public static string GetTypeRepresentation(object obj)
-        {
-            Array array = obj as Array;
-            if ( array == null )
-                return string.Format( "<{0}>", obj.GetType() );
-
-            StringBuilder sb = new StringBuilder();
-            Type elementType = array.GetType();
-            int nest = 0;
-            while (elementType.IsArray)
-            {
-                elementType = elementType.GetElementType();
-                ++nest;
-            }
-            sb.Append(elementType.ToString());
-            sb.Append('[');
-            for (int r = 0; r < array.Rank; r++)
-            {
-                if (r > 0) sb.Append(',');
-                sb.Append(array.GetLength(r));
-            }
-            sb.Append(']');
-
-            while (--nest > 0)
-                sb.Append("[]");
-
-            return string.Format( "<{0}>", sb.ToString() );
-        }
-        /// <summary>
-        /// Converts any control characters in a string 
-        /// to their escaped representation.
-        /// </summary>
-        /// <param name="s">The string to be converted</param>
-        /// <returns>The converted string</returns>
-        public static string EscapeControlChars(string s)
-        {
-            if (s != null)
-            {
-                StringBuilder sb = new StringBuilder();
-
-                foreach (char c in s)
-                {
-                    switch (c)
-                    {
-                            //case '\'':
-                            //    sb.Append("\\\'");
-                            //    break;
-                            //case '\"':
-                            //    sb.Append("\\\"");
-                            //    break;
-                        case '\\':
-                            sb.Append("\\\\");
-                            break;
-                        case '\0':
-                            sb.Append("\\0");
-                            break;
-                        case '\a':
-                            sb.Append("\\a");
-                            break;
-                        case '\b':
-                            sb.Append("\\b");
-                            break;
-                        case '\f':
-                            sb.Append("\\f");
-                            break;
-                        case '\n':
-                            sb.Append("\\n");
-                            break;
-                        case '\r':
-                            sb.Append("\\r");
-                            break;
-                        case '\t':
-                            sb.Append("\\t");
-                            break;
-                        case '\v':
-                            sb.Append("\\v");
-                            break;
-
-                        case '\x0085':
-                        case '\x2028':
-                        case '\x2029':
-                            sb.Append(string.Format("\\x{0:X4}", (int)c));
-                            break;
-
-                        default:
-                            sb.Append(c);
-                            break;
-                    }
-                }
-
-                s = sb.ToString();
-            }
-
-			return s;
-        }
-
-        /// <summary>
-        /// Return the a string representation for a set of indices into an array
-        /// </summary>
-        /// <param name="indices">Array of indices for which a string is needed</param>
-        public static string GetArrayIndicesAsString(int[] indices)
-        {
-            StringBuilder sb = new StringBuilder();
-            sb.Append('[');
-            for (int r = 0; r < indices.Length; r++)
-            {
-                if (r > 0) sb.Append(',');
-                sb.Append(indices[r].ToString());
-            }
-            sb.Append(']');
-            return sb.ToString();
-        }
-
-        /// <summary>
-        /// Get an array of indices representing the point in a collection or
-        /// array corresponding to a single int index into the collection.
-        /// </summary>
-        /// <param name="collection">The collection to which the indices apply</param>
-        /// <param name="index">Index in the collection</param>
-        /// <returns>Array of indices</returns>
-        public static int[] GetArrayIndicesFromCollectionIndex(ICollection collection, int index)
-        {
-            Array array = collection as Array;
-
-            int rank = array == null ? 1 : array.Rank;
-            int[] result = new int[rank];
-
-            for (int r = rank; --r > 0; )
-            {
-                int l = array.GetLength(r);
-                result[r] = index % l;
-                index /= l;
-            }
-
-            result[0] = index;
-            return result;
-        }
-
-        /// <summary>
-        /// Clip a string to a given length, starting at a particular offset, returning the clipped
-        /// string with ellipses representing the removed parts
-        /// </summary>
-        /// <param name="s">The string to be clipped</param>
-        /// <param name="maxStringLength">The maximum permitted length of the result string</param>
-        /// <param name="clipStart">The point at which to start clipping</param>
-        /// <returns>The clipped string</returns>
-        public static string ClipString(string s, int maxStringLength, int clipStart)
-        {
-            int clipLength = maxStringLength;
-            StringBuilder sb = new StringBuilder();
-
-            if (clipStart > 0)
-            {
-                clipLength -= ELLIPSIS.Length;
-                sb.Append( ELLIPSIS );
-            }
-
-            if (s.Length - clipStart > clipLength)
-            {
-                clipLength -= ELLIPSIS.Length;
-                sb.Append( s.Substring( clipStart, clipLength ));
-                sb.Append(ELLIPSIS);
-            }
-            else if (clipStart > 0)
-                sb.Append( s.Substring(clipStart));
-            else
-                sb.Append( s );
- 
-            return sb.ToString();
-        }
-
-        /// <summary>
-        /// Clip the expected and actual strings in a coordinated fashion, 
-        /// so that they may be displayed together.
-        /// </summary>
-        /// <param name="expected"></param>
-        /// <param name="actual"></param>
-        /// <param name="maxDisplayLength"></param>
-        /// <param name="mismatch"></param>
-        public static void ClipExpectedAndActual(ref string expected, ref string actual, int maxDisplayLength, int mismatch)
-        {
-            // Case 1: Both strings fit on line
-            int maxStringLength = Math.Max(expected.Length, actual.Length);
-            if (maxStringLength <= maxDisplayLength)
-                return;
-
-            // Case 2: Assume that the tail of each string fits on line
-            int clipLength = maxDisplayLength - ELLIPSIS.Length;
-            int clipStart = maxStringLength - clipLength;
-
-            // Case 3: If it doesn't, center the mismatch position
-            if ( clipStart > mismatch )
-                clipStart = Math.Max( 0, mismatch - clipLength / 2 );
-
-            expected = ClipString(expected, maxDisplayLength, clipStart);
-            actual = ClipString(actual, maxDisplayLength, clipStart);
-        }
-
-        /// <summary>
-        /// Shows the position two strings start to differ.  Comparison 
-        /// starts at the start index.
-        /// </summary>
-        /// <param name="expected">The expected string</param>
-        /// <param name="actual">The actual string</param>
-        /// <param name="istart">The index in the strings at which comparison should start</param>
-        /// <param name="ignoreCase">Boolean indicating whether case should be ignored</param>
-        /// <returns>-1 if no mismatch found, or the index where mismatch found</returns>
-        static public int FindMismatchPosition(string expected, string actual, int istart, bool ignoreCase)
-        {
-            int length = Math.Min(expected.Length, actual.Length);
-
-            string s1 = ignoreCase ? expected.ToLower() : expected;
-            string s2 = ignoreCase ? actual.ToLower() : actual;
-
-            for (int i = istart; i < length; i++)
-            {
-                if (s1[i] != s2[i])
-                    return i;
-            }
-
-            //
-            // Strings have same content up to the length of the shorter string.
-            // Mismatch occurs because string lengths are different, so show
-            // that they start differing where the shortest string ends
-            //
-            if (expected.Length != actual.Length)
-                return length;
-
-            //
-            // Same strings : We shouldn't get here
-            //
-            return -1;
-        }
-    }
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Text;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Static methods used in creating messages
+    /// </summary>
+    public class MsgUtils
+    {
+        /// <summary>
+        /// Static string used when strings are clipped
+        /// </summary>
+        private const string ELLIPSIS = "...";
+
+        /// <summary>
+        /// Returns the representation of a type as used in NUnitLite.
+        /// This is the same as Type.ToString() except for arrays,
+        /// which are displayed with their declared sizes.
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public static string GetTypeRepresentation(object obj)
+        {
+            Array array = obj as Array;
+            if (array == null)
+                return string.Format("<{0}>", obj.GetType());
+
+            StringBuilder sb = new StringBuilder();
+            Type elementType = array.GetType();
+            int nest = 0;
+            while (elementType.IsArray)
+            {
+                elementType = elementType.GetElementType();
+                ++nest;
+            }
+            sb.Append(elementType.ToString());
+            sb.Append('[');
+            for (int r = 0; r < array.Rank; r++)
+            {
+                if (r > 0) sb.Append(',');
+                sb.Append(array.GetLength(r));
+            }
+            sb.Append(']');
+
+            while (--nest > 0)
+                sb.Append("[]");
+
+            return string.Format("<{0}>", sb.ToString());
+        }
+        /// <summary>
+        /// Converts any control characters in a string 
+        /// to their escaped representation.
+        /// </summary>
+        /// <param name="s">The string to be converted</param>
+        /// <returns>The converted string</returns>
+        public static string EscapeControlChars(string s)
+        {
+            if (s != null)
+            {
+                StringBuilder sb = new StringBuilder();
+
+                foreach (char c in s)
+                {
+                    switch (c)
+                    {
+                        //case '\'':
+                        //    sb.Append("\\\'");
+                        //    break;
+                        //case '\"':
+                        //    sb.Append("\\\"");
+                        //    break;
+                        case '\\':
+                            sb.Append("\\\\");
+                            break;
+                        case '\0':
+                            sb.Append("\\0");
+                            break;
+                        case '\a':
+                            sb.Append("\\a");
+                            break;
+                        case '\b':
+                            sb.Append("\\b");
+                            break;
+                        case '\f':
+                            sb.Append("\\f");
+                            break;
+                        case '\n':
+                            sb.Append("\\n");
+                            break;
+                        case '\r':
+                            sb.Append("\\r");
+                            break;
+                        case '\t':
+                            sb.Append("\\t");
+                            break;
+                        case '\v':
+                            sb.Append("\\v");
+                            break;
+
+                        case '\x0085':
+                        case '\x2028':
+                        case '\x2029':
+                            sb.Append(string.Format("\\x{0:X4}", (int)c));
+                            break;
+
+                        default:
+                            sb.Append(c);
+                            break;
+                    }
+                }
+
+                s = sb.ToString();
+            }
+
+            return s;
+        }
+
+        /// <summary>
+        /// Return the a string representation for a set of indices into an array
+        /// </summary>
+        /// <param name="indices">Array of indices for which a string is needed</param>
+        public static string GetArrayIndicesAsString(int[] indices)
+        {
+            StringBuilder sb = new StringBuilder();
+            sb.Append('[');
+            for (int r = 0; r < indices.Length; r++)
+            {
+                if (r > 0) sb.Append(',');
+                sb.Append(indices[r].ToString());
+            }
+            sb.Append(']');
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Get an array of indices representing the point in a collection or
+        /// array corresponding to a single int index into the collection.
+        /// </summary>
+        /// <param name="collection">The collection to which the indices apply</param>
+        /// <param name="index">Index in the collection</param>
+        /// <returns>Array of indices</returns>
+        public static int[] GetArrayIndicesFromCollectionIndex(ICollection collection, int index)
+        {
+            Array array = collection as Array;
+
+            int rank = array == null ? 1 : array.Rank;
+            int[] result = new int[rank];
+
+            for (int r = rank; --r > 0; )
+            {
+                int l = array.GetLength(r);
+                result[r] = index % l;
+                index /= l;
+            }
+
+            result[0] = index;
+            return result;
+        }
+
+        /// <summary>
+        /// Clip a string to a given length, starting at a particular offset, returning the clipped
+        /// string with ellipses representing the removed parts
+        /// </summary>
+        /// <param name="s">The string to be clipped</param>
+        /// <param name="maxStringLength">The maximum permitted length of the result string</param>
+        /// <param name="clipStart">The point at which to start clipping</param>
+        /// <returns>The clipped string</returns>
+        public static string ClipString(string s, int maxStringLength, int clipStart)
+        {
+            int clipLength = maxStringLength;
+            StringBuilder sb = new StringBuilder();
+
+            if (clipStart > 0)
+            {
+                clipLength -= ELLIPSIS.Length;
+                sb.Append(ELLIPSIS);
+            }
+
+            if (s.Length - clipStart > clipLength)
+            {
+                clipLength -= ELLIPSIS.Length;
+                sb.Append(s.Substring(clipStart, clipLength));
+                sb.Append(ELLIPSIS);
+            }
+            else if (clipStart > 0)
+                sb.Append(s.Substring(clipStart));
+            else
+                sb.Append(s);
+
+            return sb.ToString();
+        }
+
+        /// <summary>
+        /// Clip the expected and actual strings in a coordinated fashion, 
+        /// so that they may be displayed together.
+        /// </summary>
+        /// <param name="expected"></param>
+        /// <param name="actual"></param>
+        /// <param name="maxDisplayLength"></param>
+        /// <param name="mismatch"></param>
+        public static void ClipExpectedAndActual(ref string expected, ref string actual, int maxDisplayLength, int mismatch)
+        {
+            // Case 1: Both strings fit on line
+            int maxStringLength = Math.Max(expected.Length, actual.Length);
+            if (maxStringLength <= maxDisplayLength)
+                return;
+
+            // Case 2: Assume that the tail of each string fits on line
+            int clipLength = maxDisplayLength - ELLIPSIS.Length;
+            int clipStart = maxStringLength - clipLength;
+
+            // Case 3: If it doesn't, center the mismatch position
+            if (clipStart > mismatch)
+                clipStart = Math.Max(0, mismatch - clipLength / 2);
+
+            expected = ClipString(expected, maxDisplayLength, clipStart);
+            actual = ClipString(actual, maxDisplayLength, clipStart);
+        }
+
+        /// <summary>
+        /// Shows the position two strings start to differ.  Comparison 
+        /// starts at the start index.
+        /// </summary>
+        /// <param name="expected">The expected string</param>
+        /// <param name="actual">The actual string</param>
+        /// <param name="istart">The index in the strings at which comparison should start</param>
+        /// <param name="ignoreCase">Boolean indicating whether case should be ignored</param>
+        /// <returns>-1 if no mismatch found, or the index where mismatch found</returns>
+        static public int FindMismatchPosition(string expected, string actual, int istart, bool ignoreCase)
+        {
+            int length = Math.Min(expected.Length, actual.Length);
+
+            string s1 = ignoreCase ? expected.ToLower() : expected;
+            string s2 = ignoreCase ? actual.ToLower() : actual;
+
+            for (int i = istart; i < length; i++)
+            {
+                if (s1[i] != s2[i])
+                    return i;
+            }
+
+            //
+            // Strings have same content up to the length of the shorter string.
+            // Mismatch occurs because string lengths are different, so show
+            // that they start differing where the shortest string ends
+            //
+            if (expected.Length != actual.Length)
+                return length;
+
+            //
+            // Same strings : We shouldn't get here
+            //
+            return -1;
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/NUnitComparer.cs'
--- src/NUnitFramework/framework/Constraints/NUnitComparer.cs	2010-01-14 19:39:31 +0000
+++ src/NUnitFramework/framework/Constraints/NUnitComparer.cs	2011-06-04 23:12:29 +0000
@@ -19,12 +19,11 @@
 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.IO;
+// ***********************************************************************
+
+using System;
+using System.Collections;
 using System.Reflection;
-using System.Collections;
 
 namespace NUnit.Framework.Constraints
 {
@@ -78,4 +77,4 @@
             throw new ArgumentException("Neither value implements IComparable or IComparable<T>");
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/NUnitEqualityComparer.cs'
--- src/NUnitFramework/framework/Constraints/NUnitEqualityComparer.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/NUnitEqualityComparer.cs	2011-06-04 23:12:29 +0000
@@ -342,4 +342,4 @@
         #endregion
 
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/NaNConstraint.cs'
--- src/NUnitFramework/framework/Constraints/NaNConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/NaNConstraint.cs	2011-06-04 23:12:29 +0000
@@ -27,18 +27,19 @@
     /// NaNConstraint tests that the actual value is a double or float NaN
     /// </summary>
     public class NaNConstraint : Constraint
-    {
-        /// <summary>
-        /// Test that the actual value is an NaN
-        /// </summary>
-        /// <param name="actual"></param>
-        /// <returns></returns>
-        public override bool Matches(object actual)
+    {
+        /// <summary>
+        /// Test that the actual value is an NaN
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
-
-            return actual is double && double.IsNaN((double)actual)
-                || actual is float && float.IsNaN((float)actual);
+            bool hasSucceeded = actual is double && double.IsNaN((double)actual)
+                || actual is float && float.IsNaN((float)actual);
+
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/NoItemConstraint.cs'
--- src/NUnitFramework/framework/Constraints/NoItemConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/NoItemConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,75 +1,75 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// NoItemConstraint applies another constraint to each
-    /// item in a collection, failing if any of them succeeds.
-    /// </summary>
-    public class NoItemConstraint : PrefixConstraint
-	{
-		/// <summary>
-		/// Construct a SomeItemsConstraint on top of an existing constraint
-		/// </summary>
-		/// <param name="itemConstraint"></param>
-		public NoItemConstraint(Constraint itemConstraint)
-			: base( itemConstraint ) 
-        {
-            this.DisplayName = "none";
-        }
-
-		/// <summary>
-		/// Apply the item constraint to each item in the collection,
-		/// failing if any item fails.
-		/// </summary>
-		/// <param name="actual"></param>
-		/// <returns></returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			if ( !(actual is IEnumerable) )
-				throw new ArgumentException( "The actual value must be an IEnumerable", "actual" );
-
-			foreach(object item in (IEnumerable)actual)
-				if (baseConstraint.Matches(item))
-					return false;
-
-			return true;
-		}
-
-		/// <summary>
-		/// Write a description of this constraint to a MessageWriter
-		/// </summary>
-		/// <param name="writer"></param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate("no item");
-			baseConstraint.WriteDescriptionTo(writer);
-		}
-	}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// NoItemConstraint applies another constraint to each
+    /// item in a collection, failing if any of them succeeds.
+    /// </summary>
+    public class NoItemConstraint : PrefixConstraint
+    {
+        /// <summary>
+        /// Construct a SomeItemsConstraint on top of an existing constraint
+        /// </summary>
+        /// <param name="itemConstraint"></param>
+        public NoItemConstraint(Constraint itemConstraint)
+            : base(itemConstraint)
+        {
+            this.DisplayName = "none";
+        }
+
+        /// <summary>
+        /// Apply the item constraint to each item in the collection,
+        /// failing if any item fails.
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            if (!(actual is IEnumerable))
+                throw new ArgumentException("The actual value must be an IEnumerable", "actual");
+
+            foreach (object item in (IEnumerable)actual)
+                if (baseConstraint.Matches(item).HasSucceeded)
+                    return new StandardConstraintResult(false);
+
+            return new StandardConstraintResult(true);
+        }
+
+        /// <summary>
+        /// Write a description of this constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("no item");
+            baseConstraint.WriteDescriptionTo(writer);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/NotConstraint.cs'
--- src/NUnitFramework/framework/Constraints/NotConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/NotConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,68 +1,68 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-	/// NotConstraint negates the effect of some other constraint
-	/// </summary>
-	public class NotConstraint : PrefixConstraint
-	{
-		/// <summary>
-		/// Initializes a new instance of the <see cref="T:NotConstraint"/> class.
-		/// </summary>
-		/// <param name="baseConstraint">The base constraint to be negated.</param>
-		public NotConstraint(Constraint baseConstraint)
-			: base( baseConstraint ) { }
-
-		/// <summary>
-		/// Test whether the constraint is satisfied by a given value
-		/// </summary>
-		/// <param name="actual">The value to be tested</param>
-		/// <returns>True for if the base constraint fails, false if it succeeds</returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-			return !baseConstraint.Matches(actual);
-		}
-
-		/// <summary>
-		/// Write the constraint description to a MessageWriter
-		/// </summary>
-		/// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo( MessageWriter writer )
-		{
-			writer.WritePredicate( "not" );
-			baseConstraint.WriteDescriptionTo( writer );
-		}
-
-		/// <summary>
-		/// Write the actual value for a failing constraint test to a MessageWriter.
-		/// </summary>
-		/// <param name="writer">The writer on which the actual value is displayed</param>
-		public override void WriteActualValueTo(MessageWriter writer)
-		{
-			baseConstraint.WriteActualValueTo (writer);
-		}
-	}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// NotConstraint negates the effect of some other constraint
+    /// </summary>
+    public class NotConstraint : PrefixConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="NotConstraint"/> class.
+        /// </summary>
+        /// <param name="baseConstraint">The base constraint to be negated.</param>
+        public NotConstraint(Constraint baseConstraint)
+            : base(baseConstraint) { }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for if the base constraint fails, false if it succeeds</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+            return new StandardConstraintResult(!baseConstraint.Matches(actual).HasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("not");
+            baseConstraint.WriteDescriptionTo(writer);
+        }
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a MessageWriter.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public override void WriteActualValueTo(MessageWriter writer)
+        {
+            baseConstraint.WriteActualValueTo(writer);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/NullOrEmptyStringConstraint.cs'
--- src/NUnitFramework/framework/Constraints/NullOrEmptyStringConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/NullOrEmptyStringConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,68 +1,67 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// NullEmptyStringConstraint tests whether a string is either null or empty.
-    /// </summary>
-    public class NullOrEmptyStringConstraint : Constraint
-    {
-        /// <summary>
-        /// Constructs a new NullOrEmptyStringConstraint
-        /// </summary>
-        public NullOrEmptyStringConstraint()
-        {
-            this.DisplayName = "nullorempty";
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            if (actual == null)
-                return true;
-
-            if (!(actual is string))
-                throw new ArgumentException("Actual value must be a string", "actual");
-
-            return (string)actual == string.Empty;
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.Write("null or empty string");
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// NullEmptyStringConstraint tests whether a string is either null or empty.
+    /// </summary>
+    public class NullOrEmptyStringConstraint : Constraint
+    {
+        /// <summary>
+        /// Constructs a new NullOrEmptyStringConstraint
+        /// </summary>
+        public NullOrEmptyStringConstraint()
+        {
+            this.DisplayName = "nullorempty";
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            string actualAsString = actual as string;
+            if (actual != null && actualAsString == null)
+                throw new ArgumentException("Actual value must be a string", "actual");
+
+            bool hasSucceeded = string.IsNullOrEmpty(actualAsString);
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.Write("null or empty string");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Numerics.cs'
--- src/NUnitFramework/framework/Constraints/Numerics.cs	2009-10-28 22:51:26 +0000
+++ src/NUnitFramework/framework/Constraints/Numerics.cs	2011-06-04 23:12:29 +0000
@@ -1,380 +1,380 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// The Numerics class contains common operations on numeric values.
-	/// </summary>
-	public class Numerics
-	{
-		#region Numeric Type Recognition
-		/// <summary>
-		/// Checks the type of the object, returning true if
-		/// the object is a numeric type.
-		/// </summary>
-		/// <param name="obj">The object to check</param>
-		/// <returns>true if the object is a numeric type</returns>
-		public static bool IsNumericType(Object obj)
-		{
-			return IsFloatingPointNumeric( obj ) || IsFixedPointNumeric( obj );
-		}
-
-		/// <summary>
-		/// Checks the type of the object, returning true if
-		/// the object is a floating point numeric type.
-		/// </summary>
-		/// <param name="obj">The object to check</param>
-		/// <returns>true if the object is a floating point numeric type</returns>
-		public static bool IsFloatingPointNumeric(Object obj)
-		{
-			if (null != obj)
-			{
-				if (obj is System.Double) return true;
-				if (obj is System.Single) return true;
-			}
-			return false;
-		}
-		/// <summary>
-		/// Checks the type of the object, returning true if
-		/// the object is a fixed point numeric type.
-		/// </summary>
-		/// <param name="obj">The object to check</param>
-		/// <returns>true if the object is a fixed point numeric type</returns>
-		public static bool IsFixedPointNumeric(Object obj)
-		{
-			if (null != obj)
-			{
-				if (obj is System.Byte) return true;
-				if (obj is System.SByte) return true;
-				if (obj is System.Decimal) return true;
-				if (obj is System.Int32) return true;
-				if (obj is System.UInt32) return true;
-				if (obj is System.Int64) return true;
-				if (obj is System.UInt64) return true;
-				if (obj is System.Int16) return true;
-				if (obj is System.UInt16) return true;
-			}
-			return false;
-		}
-		#endregion
-
-		#region Numeric Equality
-        /// <summary>
-        /// Test two numeric values for equality, performing the usual numeric 
-        /// conversions and using a provided or default tolerance. If the tolerance 
-        /// provided is Empty, this method may set it to a default tolerance.
-        /// </summary>
-        /// <param name="expected">The expected value</param>
-        /// <param name="actual">The actual value</param>
-        /// <param name="tolerance">A reference to the tolerance in effect</param>
-        /// <returns>True if the values are equal</returns>
-		public static bool AreEqual( object expected, object actual, ref Tolerance tolerance )
-		{
-            if ( expected is double || actual is double )
-                return AreEqual( Convert.ToDouble(expected), Convert.ToDouble(actual), ref tolerance );
-
-            if ( expected is float || actual is float )
-                return AreEqual( Convert.ToSingle(expected), Convert.ToSingle(actual), ref tolerance );
-
-            if (tolerance.Mode == ToleranceMode.Ulps)
-                throw new InvalidOperationException("Ulps may only be specified for floating point arguments");
-
-			if ( expected is decimal || actual is decimal )
-				return AreEqual( Convert.ToDecimal(expected), Convert.ToDecimal(actual), tolerance );
-
-            if (expected is ulong || actual is ulong)
-                return AreEqual(Convert.ToUInt64(expected), Convert.ToUInt64(actual), tolerance );
-		
-			if ( expected is long || actual is long )
-				return AreEqual( Convert.ToInt64(expected), Convert.ToInt64(actual), tolerance );
-			
-			if ( expected is uint || actual is uint )
-				return AreEqual( Convert.ToUInt32(expected), Convert.ToUInt32(actual), tolerance );
-
-			return AreEqual( Convert.ToInt32(expected), Convert.ToInt32(actual), tolerance );
-		}
-
-        private static bool AreEqual( double expected, double actual, ref Tolerance tolerance )
-		{
-            if (double.IsNaN(expected) && double.IsNaN(actual))
-                return true;
-
-            // Handle infinity specially since subtracting two infinite values gives 
-            // NaN and the following test fails. mono also needs NaN to be handled
-            // specially although ms.net could use either method. Also, handle
-            // situation where no tolerance is used.
-            if (double.IsInfinity(expected) || double.IsNaN(expected) || double.IsNaN(actual))
-            {
-                return expected.Equals(actual);
-            }
-
-            if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
-                tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
-
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
-
-                case ToleranceMode.Percent:
-                    if (expected == 0.0)
-                        return expected.Equals(actual);
-                    
-                    double relativeError = Math.Abs((expected - actual) / expected);
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-#if !NETCF_1_0
-                case ToleranceMode.Ulps:
-                    return FloatingPointNumerics.AreAlmostEqualUlps(
-                        expected, actual, Convert.ToInt64(tolerance.Value));
-#endif
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-        }
-
-        private static bool AreEqual( float expected, float actual, ref Tolerance tolerance )
-		{
-            if ( float.IsNaN(expected) && float.IsNaN(actual) )
-                return true;
-
-            // handle infinity specially since subtracting two infinite values gives 
-            // NaN and the following test fails. mono also needs NaN to be handled
-            // specially although ms.net could use either method.
-            if (float.IsInfinity(expected) || float.IsNaN(expected) || float.IsNaN(actual))
-            {
-                return expected.Equals(actual);
-            }
-
-            if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
-                tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
-
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
-
-                case ToleranceMode.Percent:
-                    if (expected == 0.0f)
-                        return expected.Equals(actual);
-                    float relativeError = Math.Abs((expected - actual) / expected);
-                    return (relativeError <= Convert.ToSingle(tolerance.Value) / 100.0f);
-#if !NETCF_1_0
-                case ToleranceMode.Ulps:
-                    return FloatingPointNumerics.AreAlmostEqualUlps(
-                        expected, actual, Convert.ToInt32(tolerance.Value));
-#endif
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-		}
-
-
-        private static bool AreEqual( decimal expected, decimal actual, Tolerance tolerance )
-        {
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    decimal decimalTolerance = Convert.ToDecimal(tolerance.Value);
-                    if(decimalTolerance > 0m)
-                      return Math.Abs(expected - actual) <= decimalTolerance;
-				
-			        return expected.Equals( actual );
-
-                case ToleranceMode.Percent:
-                    if(expected == 0m)
-                        return expected.Equals(actual);
-
-                    double relativeError = Math.Abs(
-                        (double)(expected - actual) / (double)expected);
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-        }
-
-		private static bool AreEqual( ulong expected, ulong actual, Tolerance tolerance )
-		{
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    ulong ulongTolerance = Convert.ToUInt64(tolerance.Value);
-                    if(ulongTolerance > 0ul)
-			        {
-				        ulong diff = expected >= actual ? expected - actual : actual - expected;
-                        return diff <= ulongTolerance;
-			        }
-
-			        return expected.Equals( actual );
-
-                case ToleranceMode.Percent:
-                    if (expected == 0ul)
-                        return expected.Equals(actual);
-
-                    // Can't do a simple Math.Abs() here since it's unsigned
-                    ulong difference = Math.Max(expected, actual) - Math.Min(expected, actual);
-                    double relativeError = Math.Abs( (double)difference / (double)expected );
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-		}
-
-		private static bool AreEqual( long expected, long actual, Tolerance tolerance )
-		{
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    long longTolerance = Convert.ToInt64(tolerance.Value);
-                    if(longTolerance > 0L)
-				        return Math.Abs(expected - actual) <= longTolerance;
-
-			        return expected.Equals( actual );
-
-                case ToleranceMode.Percent:
-                    if(expected == 0L)
-                        return expected.Equals(actual);
-
-                    double relativeError = Math.Abs(
-                        (double)(expected - actual) / (double)expected);
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-		}
-
-		private static bool AreEqual( uint expected, uint actual, Tolerance tolerance )
-		{
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    uint uintTolerance = Convert.ToUInt32(tolerance.Value);
-                    if(uintTolerance > 0)
-			        {
-				        uint diff = expected >= actual ? expected - actual : actual - expected;
-                        return diff <= uintTolerance;
-			        }
-				
-			        return expected.Equals( actual );
-
-                case ToleranceMode.Percent:
-                    if(expected == 0u)
-                        return expected.Equals(actual);
-
-                    // Can't do a simple Math.Abs() here since it's unsigned
-                    uint difference = Math.Max(expected, actual) - Math.Min(expected, actual);
-                    double relativeError = Math.Abs((double)difference / (double)expected );
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-		}
-
-		private static bool AreEqual( int expected, int actual, Tolerance tolerance )
-		{
-            switch (tolerance.Mode)
-            {
-                case ToleranceMode.None:
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Linear:
-                    int intTolerance = Convert.ToInt32(tolerance.Value);
-                    if (intTolerance > 0)
-                        return Math.Abs(expected - actual) <= intTolerance;
-
-                    return expected.Equals(actual);
-
-                case ToleranceMode.Percent:
-                    if (expected == 0)
-                        return expected.Equals(actual);
-
-                    double relativeError = Math.Abs(
-                        (double)(expected - actual) / (double)expected);
-                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
-
-                default:
-                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
-            }
-		}
-		#endregion
-
-		#region Numeric Comparisons 
-        /// <summary>
-        /// Compare two numeric values, performing the usual numeric conversions.
-        /// </summary>
-        /// <param name="expected">The expected value</param>
-        /// <param name="actual">The actual value</param>
-        /// <returns>The relationship of the values to each other</returns>
-		public static int Compare( object expected, object actual )
-		{
-			if( !IsNumericType( expected ) || !IsNumericType( actual ) )
-				throw new ArgumentException( "Both arguments must be numeric");
-
-			if ( IsFloatingPointNumeric(expected) || IsFloatingPointNumeric(actual) )
-				return Convert.ToDouble(expected).CompareTo(Convert.ToDouble(actual));
-
-			if ( expected is decimal || actual is decimal )
-				return Convert.ToDecimal(expected).CompareTo(Convert.ToDecimal(actual));
-		
-			if ( expected is ulong || actual is ulong )
-				return Convert.ToUInt64(expected).CompareTo(Convert.ToUInt64(actual));
-	
-			if ( expected is long || actual is long )
-				return Convert.ToInt64(expected).CompareTo(Convert.ToInt64(actual));
-		
-			if ( expected is uint || actual is uint )
-				return Convert.ToUInt32(expected).CompareTo(Convert.ToUInt32(actual));
-
-			return Convert.ToInt32(expected).CompareTo(Convert.ToInt32(actual));
-        }
-		#endregion
-
-		private Numerics()
-		{
-		}
-	}
-}
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// The Numerics class contains common operations on numeric values.
+    /// </summary>
+    public class Numerics
+    {
+        #region Numeric Type Recognition
+        /// <summary>
+        /// Checks the type of the object, returning true if
+        /// the object is a numeric type.
+        /// </summary>
+        /// <param name="obj">The object to check</param>
+        /// <returns>true if the object is a numeric type</returns>
+        public static bool IsNumericType(Object obj)
+        {
+            return IsFloatingPointNumeric(obj) || IsFixedPointNumeric(obj);
+        }
+
+        /// <summary>
+        /// Checks the type of the object, returning true if
+        /// the object is a floating point numeric type.
+        /// </summary>
+        /// <param name="obj">The object to check</param>
+        /// <returns>true if the object is a floating point numeric type</returns>
+        public static bool IsFloatingPointNumeric(Object obj)
+        {
+            if (null != obj)
+            {
+                if (obj is System.Double) return true;
+                if (obj is System.Single) return true;
+            }
+            return false;
+        }
+        /// <summary>
+        /// Checks the type of the object, returning true if
+        /// the object is a fixed point numeric type.
+        /// </summary>
+        /// <param name="obj">The object to check</param>
+        /// <returns>true if the object is a fixed point numeric type</returns>
+        public static bool IsFixedPointNumeric(Object obj)
+        {
+            if (null != obj)
+            {
+                if (obj is System.Byte) return true;
+                if (obj is System.SByte) return true;
+                if (obj is System.Decimal) return true;
+                if (obj is System.Int32) return true;
+                if (obj is System.UInt32) return true;
+                if (obj is System.Int64) return true;
+                if (obj is System.UInt64) return true;
+                if (obj is System.Int16) return true;
+                if (obj is System.UInt16) return true;
+            }
+            return false;
+        }
+        #endregion
+
+        #region Numeric Equality
+        /// <summary>
+        /// Test two numeric values for equality, performing the usual numeric 
+        /// conversions and using a provided or default tolerance. If the tolerance 
+        /// provided is Empty, this method may set it to a default tolerance.
+        /// </summary>
+        /// <param name="expected">The expected value</param>
+        /// <param name="actual">The actual value</param>
+        /// <param name="tolerance">A reference to the tolerance in effect</param>
+        /// <returns>True if the values are equal</returns>
+        public static bool AreEqual(object expected, object actual, ref Tolerance tolerance)
+        {
+            if (expected is double || actual is double)
+                return AreEqual(Convert.ToDouble(expected), Convert.ToDouble(actual), ref tolerance);
+
+            if (expected is float || actual is float)
+                return AreEqual(Convert.ToSingle(expected), Convert.ToSingle(actual), ref tolerance);
+
+            if (tolerance.Mode == ToleranceMode.Ulps)
+                throw new InvalidOperationException("Ulps may only be specified for floating point arguments");
+
+            if (expected is decimal || actual is decimal)
+                return AreEqual(Convert.ToDecimal(expected), Convert.ToDecimal(actual), tolerance);
+
+            if (expected is ulong || actual is ulong)
+                return AreEqual(Convert.ToUInt64(expected), Convert.ToUInt64(actual), tolerance);
+
+            if (expected is long || actual is long)
+                return AreEqual(Convert.ToInt64(expected), Convert.ToInt64(actual), tolerance);
+
+            if (expected is uint || actual is uint)
+                return AreEqual(Convert.ToUInt32(expected), Convert.ToUInt32(actual), tolerance);
+
+            return AreEqual(Convert.ToInt32(expected), Convert.ToInt32(actual), tolerance);
+        }
+
+        private static bool AreEqual(double expected, double actual, ref Tolerance tolerance)
+        {
+            if (double.IsNaN(expected) && double.IsNaN(actual))
+                return true;
+
+            // Handle infinity specially since subtracting two infinite values gives 
+            // NaN and the following test fails. mono also needs NaN to be handled
+            // specially although ms.net could use either method. Also, handle
+            // situation where no tolerance is used.
+            if (double.IsInfinity(expected) || double.IsNaN(expected) || double.IsNaN(actual))
+            {
+                return expected.Equals(actual);
+            }
+
+            if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
+                tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
+
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0.0)
+                        return expected.Equals(actual);
+
+                    double relativeError = Math.Abs((expected - actual) / expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+#if !NETCF_1_0
+                case ToleranceMode.Ulps:
+                    return FloatingPointNumerics.AreAlmostEqualUlps(
+                        expected, actual, Convert.ToInt64(tolerance.Value));
+#endif
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+        private static bool AreEqual(float expected, float actual, ref Tolerance tolerance)
+        {
+            if (float.IsNaN(expected) && float.IsNaN(actual))
+                return true;
+
+            // handle infinity specially since subtracting two infinite values gives 
+            // NaN and the following test fails. mono also needs NaN to be handled
+            // specially although ms.net could use either method.
+            if (float.IsInfinity(expected) || float.IsNaN(expected) || float.IsNaN(actual))
+            {
+                return expected.Equals(actual);
+            }
+
+            if (tolerance.IsEmpty && GlobalSettings.DefaultFloatingPointTolerance > 0.0d)
+                tolerance = new Tolerance(GlobalSettings.DefaultFloatingPointTolerance);
+
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    return Math.Abs(expected - actual) <= Convert.ToDouble(tolerance.Value);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0.0f)
+                        return expected.Equals(actual);
+                    float relativeError = Math.Abs((expected - actual) / expected);
+                    return (relativeError <= Convert.ToSingle(tolerance.Value) / 100.0f);
+#if !NETCF_1_0
+                case ToleranceMode.Ulps:
+                    return FloatingPointNumerics.AreAlmostEqualUlps(
+                        expected, actual, Convert.ToInt32(tolerance.Value));
+#endif
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+
+        private static bool AreEqual(decimal expected, decimal actual, Tolerance tolerance)
+        {
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    decimal decimalTolerance = Convert.ToDecimal(tolerance.Value);
+                    if (decimalTolerance > 0m)
+                        return Math.Abs(expected - actual) <= decimalTolerance;
+
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0m)
+                        return expected.Equals(actual);
+
+                    double relativeError = Math.Abs(
+                        (double)(expected - actual) / (double)expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+        private static bool AreEqual(ulong expected, ulong actual, Tolerance tolerance)
+        {
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    ulong ulongTolerance = Convert.ToUInt64(tolerance.Value);
+                    if (ulongTolerance > 0ul)
+                    {
+                        ulong diff = expected >= actual ? expected - actual : actual - expected;
+                        return diff <= ulongTolerance;
+                    }
+
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0ul)
+                        return expected.Equals(actual);
+
+                    // Can't do a simple Math.Abs() here since it's unsigned
+                    ulong difference = Math.Max(expected, actual) - Math.Min(expected, actual);
+                    double relativeError = Math.Abs((double)difference / (double)expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+        private static bool AreEqual(long expected, long actual, Tolerance tolerance)
+        {
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    long longTolerance = Convert.ToInt64(tolerance.Value);
+                    if (longTolerance > 0L)
+                        return Math.Abs(expected - actual) <= longTolerance;
+
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0L)
+                        return expected.Equals(actual);
+
+                    double relativeError = Math.Abs(
+                        (double)(expected - actual) / (double)expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+        private static bool AreEqual(uint expected, uint actual, Tolerance tolerance)
+        {
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    uint uintTolerance = Convert.ToUInt32(tolerance.Value);
+                    if (uintTolerance > 0)
+                    {
+                        uint diff = expected >= actual ? expected - actual : actual - expected;
+                        return diff <= uintTolerance;
+                    }
+
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0u)
+                        return expected.Equals(actual);
+
+                    // Can't do a simple Math.Abs() here since it's unsigned
+                    uint difference = Math.Max(expected, actual) - Math.Min(expected, actual);
+                    double relativeError = Math.Abs((double)difference / (double)expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+
+        private static bool AreEqual(int expected, int actual, Tolerance tolerance)
+        {
+            switch (tolerance.Mode)
+            {
+                case ToleranceMode.None:
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Linear:
+                    int intTolerance = Convert.ToInt32(tolerance.Value);
+                    if (intTolerance > 0)
+                        return Math.Abs(expected - actual) <= intTolerance;
+
+                    return expected.Equals(actual);
+
+                case ToleranceMode.Percent:
+                    if (expected == 0)
+                        return expected.Equals(actual);
+
+                    double relativeError = Math.Abs(
+                        (double)(expected - actual) / (double)expected);
+                    return (relativeError <= Convert.ToDouble(tolerance.Value) / 100.0);
+
+                default:
+                    throw new ArgumentException("Unknown tolerance mode specified", "mode");
+            }
+        }
+        #endregion
+
+        #region Numeric Comparisons
+        /// <summary>
+        /// Compare two numeric values, performing the usual numeric conversions.
+        /// </summary>
+        /// <param name="expected">The expected value</param>
+        /// <param name="actual">The actual value</param>
+        /// <returns>The relationship of the values to each other</returns>
+        public static int Compare(object expected, object actual)
+        {
+            if (!IsNumericType(expected) || !IsNumericType(actual))
+                throw new ArgumentException("Both arguments must be numeric");
+
+            if (IsFloatingPointNumeric(expected) || IsFloatingPointNumeric(actual))
+                return Convert.ToDouble(expected).CompareTo(Convert.ToDouble(actual));
+
+            if (expected is decimal || actual is decimal)
+                return Convert.ToDecimal(expected).CompareTo(Convert.ToDecimal(actual));
+
+            if (expected is ulong || actual is ulong)
+                return Convert.ToUInt64(expected).CompareTo(Convert.ToUInt64(actual));
+
+            if (expected is long || actual is long)
+                return Convert.ToInt64(expected).CompareTo(Convert.ToInt64(actual));
+
+            if (expected is uint || actual is uint)
+                return Convert.ToUInt32(expected).CompareTo(Convert.ToUInt32(actual));
+
+            return Convert.ToInt32(expected).CompareTo(Convert.ToInt32(actual));
+        }
+        #endregion
+
+        private Numerics()
+        {
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Operators/ConstraintOperator.cs'
--- src/NUnitFramework/framework/Constraints/Operators/ConstraintOperator.cs	2011-04-29 22:50:53 +0000
+++ src/NUnitFramework/framework/Constraints/Operators/ConstraintOperator.cs	2011-06-04 23:12:29 +0000
@@ -1,96 +1,96 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// The ConstraintOperator class is used internally by a
-    /// ConstraintBuilder to represent an operator that 
-    /// modifies or combines constraints. 
-    /// 
-    /// Constraint operators use left and right precedence
-    /// values to determine whether the top operator on the
-    /// stack should be reduced before pushing a new operator.
-    /// </summary>
-    public abstract class ConstraintOperator
-    {
-        private object leftContext;
-        private object rightContext;
-
-		/// <summary>
-		/// The precedence value used when the operator
-		/// is about to be pushed to the stack.
-		/// </summary>
-		protected int left_precedence;
-        
-		/// <summary>
-		/// The precedence value used when the operator
-		/// is on the top of the stack.
-		/// </summary>
-		protected int right_precedence;
-
-		/// <summary>
-		/// The syntax element preceding this operator
-		/// </summary>
-        public object LeftContext
-        {
-            get { return leftContext; }
-            set { leftContext = value; }
-        }
-
-		/// <summary>
-		/// The syntax element folowing this operator
-		/// </summary>
-        public object RightContext
-        {
-            get { return rightContext; }
-            set { rightContext = value; }
-        }
-
-		/// <summary>
-		/// The precedence value used when the operator
-		/// is about to be pushed to the stack.
-		/// </summary>
-		public virtual int LeftPrecedence
-        {
-            get { return left_precedence; }
-        }
-
-		/// <summary>
-		/// The precedence value used when the operator
-		/// is on the top of the stack.
-		/// </summary>
-		public virtual int RightPrecedence
-        {
-            get { return right_precedence; }
-        }
-
-		/// <summary>
-		/// Reduce produces a constraint from the operator and 
-		/// any arguments. It takes the arguments from the constraint 
-		/// stack and pushes the resulting constraint on it.
-		/// </summary>
-		/// <param name="stack"></param>
-		public abstract void Reduce(ConstraintBuilder.ConstraintStack stack);
-    }
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// The ConstraintOperator class is used internally by a
+    /// ConstraintBuilder to represent an operator that 
+    /// modifies or combines constraints. 
+    /// 
+    /// Constraint operators use left and right precedence
+    /// values to determine whether the top operator on the
+    /// stack should be reduced before pushing a new operator.
+    /// </summary>
+    public abstract class ConstraintOperator
+    {
+        private object leftContext;
+        private object rightContext;
+
+        /// <summary>
+        /// The precedence value used when the operator
+        /// is about to be pushed to the stack.
+        /// </summary>
+        protected int left_precedence;
+
+        /// <summary>
+        /// The precedence value used when the operator
+        /// is on the top of the stack.
+        /// </summary>
+        protected int right_precedence;
+
+        /// <summary>
+        /// The syntax element preceding this operator
+        /// </summary>
+        public object LeftContext
+        {
+            get { return leftContext; }
+            set { leftContext = value; }
+        }
+
+        /// <summary>
+        /// The syntax element folowing this operator
+        /// </summary>
+        public object RightContext
+        {
+            get { return rightContext; }
+            set { rightContext = value; }
+        }
+
+        /// <summary>
+        /// The precedence value used when the operator
+        /// is about to be pushed to the stack.
+        /// </summary>
+        public virtual int LeftPrecedence
+        {
+            get { return left_precedence; }
+        }
+
+        /// <summary>
+        /// The precedence value used when the operator
+        /// is on the top of the stack.
+        /// </summary>
+        public virtual int RightPrecedence
+        {
+            get { return right_precedence; }
+        }
+
+        /// <summary>
+        /// Reduce produces a constraint from the operator and 
+        /// any arguments. It takes the arguments from the constraint 
+        /// stack and pushes the resulting constraint on it.
+        /// </summary>
+        /// <param name="stack"></param>
+        public abstract void Reduce(ConstraintBuilder.ConstraintStack stack);
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Operators/PrefixOperator.cs'
--- src/NUnitFramework/framework/Constraints/Operators/PrefixOperator.cs	2011-04-29 22:50:53 +0000
+++ src/NUnitFramework/framework/Constraints/Operators/PrefixOperator.cs	2011-06-04 23:12:29 +0000
@@ -1,51 +1,51 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-	/// PrefixOperator takes a single constraint and modifies
-	/// it's action in some way.
-	/// </summary>
-    public abstract class PrefixOperator : ConstraintOperator
-    {
-		/// <summary>
-		/// Reduce produces a constraint from the operator and 
-		/// any arguments. It takes the arguments from the constraint 
-		/// stack and pushes the resulting constraint on it.
-		/// </summary>
-		/// <param name="stack"></param>
-		public override void Reduce(ConstraintBuilder.ConstraintStack stack)
-        {
-            stack.Push(ApplyPrefix(stack.Pop()));
-        }
-
-        /// <summary>
-        /// Returns the constraint created by applying this
-        /// prefix to another constraint.
-        /// </summary>
-        /// <param name="constraint"></param>
-        /// <returns></returns>
-        public abstract Constraint ApplyPrefix(Constraint constraint);
-    }
- }
\ No newline at end of file
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// PrefixOperator takes a single constraint and modifies
+    /// it's action in some way.
+    /// </summary>
+    public abstract class PrefixOperator : ConstraintOperator
+    {
+        /// <summary>
+        /// Reduce produces a constraint from the operator and 
+        /// any arguments. It takes the arguments from the constraint 
+        /// stack and pushes the resulting constraint on it.
+        /// </summary>
+        /// <param name="stack"></param>
+        public override void Reduce(ConstraintBuilder.ConstraintStack stack)
+        {
+            stack.Push(ApplyPrefix(stack.Pop()));
+        }
+
+        /// <summary>
+        /// Returns the constraint created by applying this
+        /// prefix to another constraint.
+        /// </summary>
+        /// <param name="constraint"></param>
+        /// <returns></returns>
+        public abstract Constraint ApplyPrefix(Constraint constraint);
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Operators/PropOperator.cs'
--- src/NUnitFramework/framework/Constraints/Operators/PropOperator.cs	2011-04-29 22:50:53 +0000
+++ src/NUnitFramework/framework/Constraints/Operators/PropOperator.cs	2011-06-04 23:12:29 +0000
@@ -1,69 +1,69 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// Operator used to test for the presence of a named Property
-    /// on an object and optionally apply further tests to the
-    /// value of that property.
-    /// </summary>
-    public class PropOperator : SelfResolvingOperator
-    {
-        private readonly string name;
-
-        /// <summary>
-        /// Gets the name of the property to which the operator applies
-        /// </summary>
-        public string Name
-        {
-            get { return name; }
-        }
-
-        /// <summary>
-        /// Constructs a PropOperator for a particular named property
-        /// </summary>
-        public PropOperator(string name)
-        {
-            this.name = name;
-
-            // Prop stacks on anything and allows only 
-            // prefix operators to stack on it.
-            this.left_precedence = this.right_precedence = 1;
-        }
-
-        /// <summary>
-        /// Reduce produces a constraint from the operator and 
-        /// any arguments. It takes the arguments from the constraint 
-        /// stack and pushes the resulting constraint on it.
-        /// </summary>
-        /// <param name="stack"></param>
-        public override void Reduce(ConstraintBuilder.ConstraintStack stack)
-        {
-            if (RightContext == null || RightContext is BinaryOperator)
-                stack.Push(new PropertyExistsConstraint(name));
-            else
-                stack.Push(new PropertyConstraint(name, stack.Pop()));
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Operator used to test for the presence of a named Property
+    /// on an object and optionally apply further tests to the
+    /// value of that property.
+    /// </summary>
+    public class PropOperator : SelfResolvingOperator
+    {
+        private readonly string name;
+
+        /// <summary>
+        /// Gets the name of the property to which the operator applies
+        /// </summary>
+        public string Name
+        {
+            get { return name; }
+        }
+
+        /// <summary>
+        /// Constructs a PropOperator for a particular named property
+        /// </summary>
+        public PropOperator(string name)
+        {
+            this.name = name;
+
+            // Prop stacks on anything and allows only 
+            // prefix operators to stack on it.
+            this.left_precedence = this.right_precedence = 1;
+        }
+
+        /// <summary>
+        /// Reduce produces a constraint from the operator and 
+        /// any arguments. It takes the arguments from the constraint 
+        /// stack and pushes the resulting constraint on it.
+        /// </summary>
+        /// <param name="stack"></param>
+        public override void Reduce(ConstraintBuilder.ConstraintStack stack)
+        {
+            if (RightContext == null || RightContext is BinaryOperator)
+                stack.Push(new PropertyExistsConstraint(name));
+            else
+                stack.Push(new PropertyConstraint(name, stack.Pop()));
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Operators/ThrowsOperator.cs'
--- src/NUnitFramework/framework/Constraints/Operators/ThrowsOperator.cs	2011-04-29 22:50:53 +0000
+++ src/NUnitFramework/framework/Constraints/Operators/ThrowsOperator.cs	2011-06-04 23:12:29 +0000
@@ -1,57 +1,57 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// Operator that tests that an exception is thrown and
-    /// optionally applies further tests to the exception.
-    /// </summary>
-    public class ThrowsOperator : SelfResolvingOperator
-    {
-        /// <summary>
-        /// Construct a ThrowsOperator
-        /// </summary>
-        public ThrowsOperator()
-        {
-            // ThrowsOperator stacks on everything but
-            // it's always the first item on the stack
-            // anyway. It is evaluated last of all ops.
-            this.left_precedence = 1;
-            this.right_precedence = 100;
-        }
-
-        /// <summary>
-        /// Reduce produces a constraint from the operator and 
-        /// any arguments. It takes the arguments from the constraint 
-        /// stack and pushes the resulting constraint on it.
-        /// </summary>
-        public override void Reduce(ConstraintBuilder.ConstraintStack stack)
-        {
-            if (RightContext == null || RightContext is BinaryOperator)
-                stack.Push(new ThrowsConstraint(null));
-            else
-                stack.Push(new ThrowsConstraint(stack.Pop()));
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Operator that tests that an exception is thrown and
+    /// optionally applies further tests to the exception.
+    /// </summary>
+    public class ThrowsOperator : SelfResolvingOperator
+    {
+        /// <summary>
+        /// Construct a ThrowsOperator
+        /// </summary>
+        public ThrowsOperator()
+        {
+            // ThrowsOperator stacks on everything but
+            // it's always the first item on the stack
+            // anyway. It is evaluated last of all ops.
+            this.left_precedence = 1;
+            this.right_precedence = 100;
+        }
+
+        /// <summary>
+        /// Reduce produces a constraint from the operator and 
+        /// any arguments. It takes the arguments from the constraint 
+        /// stack and pushes the resulting constraint on it.
+        /// </summary>
+        public override void Reduce(ConstraintBuilder.ConstraintStack stack)
+        {
+            if (RightContext == null || RightContext is BinaryOperator)
+                stack.Push(new ThrowsConstraint(null));
+            else
+                stack.Push(new ThrowsConstraint(stack.Pop()));
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Operators/WithOperator.cs'
--- src/NUnitFramework/framework/Constraints/Operators/WithOperator.cs	2011-04-29 22:50:53 +0000
+++ src/NUnitFramework/framework/Constraints/Operators/WithOperator.cs	2011-06-04 23:12:29 +0000
@@ -1,51 +1,51 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{    
-    /// <summary>
-    /// Represents a constraint that simply wraps the
-    /// constraint provided as an argument, without any
-    /// further functionality, but which modifes the
-    /// order of evaluation because of its precedence.
-    /// </summary>
-    public class WithOperator : PrefixOperator
-    {
-        /// <summary>
-        /// Constructor for the WithOperator
-        /// </summary>
-        public WithOperator()
-        {
-            this.left_precedence = 1;
-            this.right_precedence = 4;
-        }
-
-        /// <summary>
-        /// Returns a constraint that wraps its argument
-        /// </summary>
-        public override Constraint ApplyPrefix(Constraint constraint)
-        {
-            return constraint;
-        }
-    } 
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Represents a constraint that simply wraps the
+    /// constraint provided as an argument, without any
+    /// further functionality, but which modifes the
+    /// order of evaluation because of its precedence.
+    /// </summary>
+    public class WithOperator : PrefixOperator
+    {
+        /// <summary>
+        /// Constructor for the WithOperator
+        /// </summary>
+        public WithOperator()
+        {
+            this.left_precedence = 1;
+            this.right_precedence = 4;
+        }
+
+        /// <summary>
+        /// Returns a constraint that wraps its argument
+        /// </summary>
+        public override Constraint ApplyPrefix(Constraint constraint)
+        {
+            return constraint;
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/OrConstraint.cs'
--- src/NUnitFramework/framework/Constraints/OrConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/OrConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,60 +1,62 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// OrConstraint succeeds if either member succeeds
-	/// </summary>
-    public class OrConstraint : BinaryConstraint
-    {
-		/// <summary>
-		/// Create an OrConstraint from two other constraints
-		/// </summary>
-		/// <param name="left">The first constraint</param>
-		/// <param name="right">The second constraint</param>
-		public OrConstraint(Constraint left, Constraint right) : base(left, right) { }
-
-		/// <summary>
-		/// Apply the member constraints to an actual value, succeeding 
-		/// succeeding as soon as one of them succeeds.
-		/// </summary>
-		/// <param name="actual">The actual value</param>
-		/// <returns>True if either constraint succeeded</returns>
-		public override bool Matches(object actual)
-        {
-            this.actual = actual;
-            return Left.Matches(actual) || Right.Matches(actual);
-        }
-
-		/// <summary>
-		/// Write a description for this contraint to a MessageWriter
-		/// </summary>
-		/// <param name="writer">The MessageWriter to receive the description</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            Left.WriteDescriptionTo(writer);
-            writer.WriteConnector("or");
-            Right.WriteDescriptionTo(writer);
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// OrConstraint succeeds if either member succeeds
+    /// </summary>
+    public class OrConstraint : BinaryConstraint
+    {
+        /// <summary>
+        /// Create an OrConstraint from two other constraints
+        /// </summary>
+        /// <param name="left">The first constraint</param>
+        /// <param name="right">The second constraint</param>
+        public OrConstraint(Constraint left, Constraint right) : base(left, right) { }
+
+        /// <summary>
+        /// Apply the member constraints to an actual value, succeeding 
+        /// succeeding as soon as one of them succeeds.
+        /// </summary>
+        /// <param name="actual">The actual value</param>
+        /// <returns>True if either constraint succeeded</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            bool hasSucceeded = Left.Matches(actual).HasSucceeded || Right.Matches(actual).HasSucceeded;
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write a description for this contraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The MessageWriter to receive the description</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            Left.WriteDescriptionTo(writer);
+            writer.WriteConnector("or");
+            Right.WriteDescriptionTo(writer);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/PathConstraint.cs'
--- src/NUnitFramework/framework/Constraints/PathConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/PathConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,163 +1,164 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.IO;
-
-namespace NUnit.Framework.Constraints
-{
-    #region PathConstraint
-    /// <summary>
-	/// PathConstraint serves as the abstract base of constraints
-	/// that operate on paths and provides several helper methods.
-	/// </summary>
-	public abstract class PathConstraint : Constraint
-	{
-        private static readonly char[] DirectorySeparatorChars = new char[] { '\\', '/' };
-
-		/// <summary>
-		/// The expected path used in the constraint
-		/// </summary>
-		protected string expected;
-
-        /// <summary>
-        /// Flag indicating whether a caseInsensitive comparison should be made
-        /// </summary>
-        protected bool caseInsensitive = Path.DirectorySeparatorChar == '\\';
-
-        /// <summary>
-		/// Construct a PathConstraint for a give expected path
-		/// </summary>
-		/// <param name="expected">The expected path</param>
-		protected PathConstraint( string expected ) : base(expected)
-		{
-			this.expected = expected;
-        }
-
-        /// <summary>
-        /// Modifies the current instance to be case-insensitve
-        /// and returns it.
-        /// </summary>
-        public PathConstraint IgnoreCase
-        {
-            get { caseInsensitive = true; return this; }
-        }
-
-        /// <summary>
-        /// Modifies the current instance to be case-sensitve
-        /// and returns it.
-        /// </summary>
-        public PathConstraint RespectCase
-        {
-            get { caseInsensitive = false; return this; }
-        }
-
-        /// <summary>
-        /// Returns the string representation of this constraint
-        /// </summary>
-        protected override string GetStringRepresentation()
-        {
-            return string.Format( "<{0} \"{1}\" {2}>", DisplayName, expected, caseInsensitive ? "ignorecase" : "respectcase" );
-        }
-
-        #region Helper Methods
-        /// <summary>
-		/// Canonicalize the provided path
-		/// </summary>
-		/// <param name="path"></param>
-		/// <returns>The path in standardized form</returns>
-		protected string Canonicalize( string path )
-		{
-			string[] parts = path.Split( DirectorySeparatorChars );
-
-            int count = 0;
-            bool shifting = false;
-			foreach( string part in parts )
-			{
-				switch( part )
-				{
-					case ".":
-                        shifting = true;
-						break;
-				
-					case "..":
-                        shifting = true;
-						if ( count > 0 )
-                            --count;
-						break;
-					default:
-                        if (shifting)
-                            parts[count] = part;
-                        ++count;
-						break;
-				}
-			}
-	
-			return String.Join( Path.DirectorySeparatorChar.ToString(), parts, 0, count );
-		}
-
-		/// <summary>
-		/// Test whether two paths are the same
-		/// </summary>
-		/// <param name="path1">The first path</param>
-		/// <param name="path2">The second path</param>
-		/// <returns></returns>
-		protected bool IsSamePath( string path1, string path2 )
-		{
-			return string.Compare( Canonicalize( expected ), Canonicalize( (string)actual ), caseInsensitive ) == 0;
-		}
-
-		/// <summary>
-		/// Test whether one path is the same as or under another path
-		/// </summary>
-		/// <param name="path1">The first path - supposed to be the parent path</param>
-		/// <param name="path2">The second path - supposed to be the child path</param>
-		/// <returns></returns>
-		protected bool IsSamePathOrUnder( string path1, string path2 )
-		{
-			path1 = Canonicalize( path1 );
-			path2 = Canonicalize( path2 );
-
-			int length1 = path1.Length;
-			int length2 = path2.Length;
-
-			// if path1 is longer, then path2 can't be under it
-			if ( length1 > length2 )
-				return false;
-
-			// if lengths are the same, check for equality
-			if ( length1 == length2 )
-				return string.Compare( path1, path2, caseInsensitive ) == 0;
-
-			// path 2 is longer than path 1: see if initial parts match
-			if ( string.Compare( path1, path2.Substring( 0, length1 ), caseInsensitive ) != 0 )
-				return false;
-			
-			// must match through or up to a directory separator boundary
-			return	path2[length1-1] == Path.DirectorySeparatorChar ||
-				path2[length1] == Path.DirectorySeparatorChar;
-        }
-        #endregion
-    }
-    #endregion
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.IO;
+
+namespace NUnit.Framework.Constraints
+{
+    #region PathConstraint
+    /// <summary>
+    /// PathConstraint serves as the abstract base of constraints
+    /// that operate on paths and provides several helper methods.
+    /// </summary>
+    public abstract class PathConstraint : Constraint
+    {
+        private static readonly char[] DirectorySeparatorChars = new char[] { '\\', '/' };
+
+        /// <summary>
+        /// The expected path used in the constraint
+        /// </summary>
+        protected string expected;
+
+        /// <summary>
+        /// Flag indicating whether a caseInsensitive comparison should be made
+        /// </summary>
+        protected bool caseInsensitive = Path.DirectorySeparatorChar == '\\';
+
+        /// <summary>
+        /// Construct a PathConstraint for a give expected path
+        /// </summary>
+        /// <param name="expected">The expected path</param>
+        protected PathConstraint(string expected)
+            : base(expected)
+        {
+            this.expected = expected;
+        }
+
+        /// <summary>
+        /// Modifies the current instance to be case-insensitve
+        /// and returns it.
+        /// </summary>
+        public PathConstraint IgnoreCase
+        {
+            get { caseInsensitive = true; return this; }
+        }
+
+        /// <summary>
+        /// Modifies the current instance to be case-sensitve
+        /// and returns it.
+        /// </summary>
+        public PathConstraint RespectCase
+        {
+            get { caseInsensitive = false; return this; }
+        }
+
+        /// <summary>
+        /// Returns the string representation of this constraint
+        /// </summary>
+        protected override string GetStringRepresentation()
+        {
+            return string.Format("<{0} \"{1}\" {2}>", DisplayName, expected, caseInsensitive ? "ignorecase" : "respectcase");
+        }
+
+        #region Helper Methods
+        /// <summary>
+        /// Canonicalize the provided path
+        /// </summary>
+        /// <param name="path"></param>
+        /// <returns>The path in standardized form</returns>
+        protected string Canonicalize(string path)
+        {
+            string[] parts = path.Split(DirectorySeparatorChars);
+
+            int count = 0;
+            bool shifting = false;
+            foreach (string part in parts)
+            {
+                switch (part)
+                {
+                    case ".":
+                        shifting = true;
+                        break;
+
+                    case "..":
+                        shifting = true;
+                        if (count > 0)
+                            --count;
+                        break;
+                    default:
+                        if (shifting)
+                            parts[count] = part;
+                        ++count;
+                        break;
+                }
+            }
+
+            return String.Join(Path.DirectorySeparatorChar.ToString(), parts, 0, count);
+        }
+
+        /// <summary>
+        /// Test whether two paths are the same
+        /// </summary>
+        /// <param name="path1">The first path</param>
+        /// <param name="path2">The second path</param>
+        /// <returns></returns>
+        protected bool IsSamePath(string path1, string path2)
+        {
+            return string.Compare(Canonicalize(expected), Canonicalize((string)actual), caseInsensitive) == 0;
+        }
+
+        /// <summary>
+        /// Test whether one path is the same as or under another path
+        /// </summary>
+        /// <param name="path1">The first path - supposed to be the parent path</param>
+        /// <param name="path2">The second path - supposed to be the child path</param>
+        /// <returns></returns>
+        protected bool IsSamePathOrUnder(string path1, string path2)
+        {
+            path1 = Canonicalize(path1);
+            path2 = Canonicalize(path2);
+
+            int length1 = path1.Length;
+            int length2 = path2.Length;
+
+            // if path1 is longer, then path2 can't be under it
+            if (length1 > length2)
+                return false;
+
+            // if lengths are the same, check for equality
+            if (length1 == length2)
+                return string.Compare(path1, path2, caseInsensitive) == 0;
+
+            // path 2 is longer than path 1: see if initial parts match
+            if (string.Compare(path1, path2.Substring(0, length1), caseInsensitive) != 0)
+                return false;
+
+            // must match through or up to a directory separator boundary
+            return path2[length1 - 1] == Path.DirectorySeparatorChar ||
+                path2[length1] == Path.DirectorySeparatorChar;
+        }
+        #endregion
+    }
+    #endregion
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/PredicateConstraint.cs'
--- src/NUnitFramework/framework/Constraints/PredicateConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/PredicateConstraint.cs	2011-06-04 23:12:29 +0000
@@ -47,14 +47,14 @@
         /// Determines whether the predicate succeeds when applied
         /// to the actual value.
         /// </summary>
-        public override bool Matches(object actual)
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
             if (!(actual is T))
                 throw new ArgumentException("The actual value is not of type " + typeof(T).Name, "actual");
 
-            return predicate((T)actual);
+            return new StandardConstraintResult(predicate((T)actual));
         }
 
         /// <summary>
@@ -69,4 +69,4 @@
         }
     }
 }
-#endif
+#endif
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/PrefixConstraint.cs'
--- src/NUnitFramework/framework/Constraints/PrefixConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/PrefixConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,46 +1,47 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// Abstract base class used for prefixes
-	/// </summary>
-    public abstract class PrefixConstraint : Constraint
-    {
-        /// <summary>
-        /// The base constraint
-        /// </summary>
-        protected Constraint baseConstraint;
-
-        /// <summary>
-        /// Construct given a base constraint
-        /// </summary>
-        /// <param name="resolvable"></param>
-        protected PrefixConstraint(IResolveConstraint resolvable) : base(resolvable)
-        {
-            if ( resolvable != null )
-                this.baseConstraint = resolvable.Resolve();
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Abstract base class used for prefixes
+    /// </summary>
+    public abstract class PrefixConstraint : Constraint
+    {
+        /// <summary>
+        /// The base constraint
+        /// </summary>
+        protected Constraint baseConstraint;
+
+        /// <summary>
+        /// Construct given a base constraint
+        /// </summary>
+        /// <param name="resolvable"></param>
+        protected PrefixConstraint(IResolveConstraint resolvable)
+            : base(resolvable)
+        {
+            if (resolvable != null)
+                this.baseConstraint = resolvable.Resolve();
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/PropertyConstraint.cs'
--- src/NUnitFramework/framework/Constraints/PropertyConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/PropertyConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,111 +1,110 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-using System.Reflection;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// PropertyConstraint extracts a named property and uses
-    /// its value as the actual value for a chained constraint.
-	/// </summary>
-	public class PropertyConstraint : PrefixConstraint
-	{
-		private readonly string name;
-		private object propValue;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:PropertyConstraint"/> class.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="baseConstraint">The constraint to apply to the property.</param>
-        public PropertyConstraint(string name, Constraint baseConstraint)
-			: base( baseConstraint ) 
-		{ 
-			this.name = name;
-		}
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-		{
-            this.actual = actual;
-            if (actual == null) 
-                throw new ArgumentNullException("actual");
-
-            Type actualType = actual as Type;
-            if ( actualType == null )
-                actualType = actual.GetType();
-
-            PropertyInfo property = actualType.GetProperty(name,
-                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
-
-            if (property == null)
-                throw new ArgumentException(string.Format("Property {0} was not found",name), "name");
-
-			propValue = property.GetValue( actual, null );
-			return baseConstraint.Matches( propValue );
-		}
-
-		/// <summary>
-		/// Write the constraint description to a MessageWriter
-		/// </summary>
-		/// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate( "property " + name );
-            if (baseConstraint != null)
-            {
-                if (baseConstraint is EqualConstraint)
-                    writer.WritePredicate("equal to");
-                baseConstraint.WriteDescriptionTo(writer);
-            }
-        }
-
-		/// <summary>
-		/// Write the actual value for a failing constraint test to a
-		/// MessageWriter. The default implementation simply writes
-		/// the raw value of actual, leaving it to the writer to
-		/// perform any formatting.
-		/// </summary>
-		/// <param name="writer">The writer on which the actual value is displayed</param>
-		public override void WriteActualValueTo(MessageWriter writer)
-		{
-            writer.WriteActualValue(propValue);
-		}
-
-        /// <summary>
-        /// Returns the string representation of the constraint.
-        /// </summary>
-        /// <returns></returns>
-        protected override string GetStringRepresentation()
-        {
-            return string.Format("<property {0} {1}>", name, baseConstraint);
-        }
-	}
-}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Reflection;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// PropertyConstraint extracts a named property and uses
+    /// its value as the actual value for a chained constraint.
+    /// </summary>
+    public class PropertyConstraint : PrefixConstraint
+    {
+        private readonly string name;
+        private object propValue;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:PropertyConstraint"/> class.
+        /// </summary>
+        /// <param name="name">The name.</param>
+        /// <param name="baseConstraint">The constraint to apply to the property.</param>
+        public PropertyConstraint(string name, Constraint baseConstraint)
+            : base(baseConstraint)
+        {
+            this.name = name;
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+            if (actual == null)
+                throw new ArgumentNullException("actual");
+
+            Type actualType = actual as Type;
+            if (actualType == null)
+                actualType = actual.GetType();
+
+            PropertyInfo property = actualType.GetProperty(name,
+                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
+
+            if (property == null)
+                throw new ArgumentException(string.Format("Property {0} was not found", name), "name");
+
+            propValue = property.GetValue(actual, null);
+            return baseConstraint.Matches(propValue);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("property " + name);
+            if (baseConstraint != null)
+            {
+                if (baseConstraint is EqualConstraint)
+                    writer.WritePredicate("equal to");
+                baseConstraint.WriteDescriptionTo(writer);
+            }
+        }
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a
+        /// MessageWriter. The default implementation simply writes
+        /// the raw value of actual, leaving it to the writer to
+        /// perform any formatting.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public override void WriteActualValueTo(MessageWriter writer)
+        {
+            writer.WriteActualValue(propValue);
+        }
+
+        /// <summary>
+        /// Returns the string representation of the constraint.
+        /// </summary>
+        /// <returns></returns>
+        protected override string GetStringRepresentation()
+        {
+            return string.Format("<property {0} {1}>", name, baseConstraint);
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/PropertyExistsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/PropertyExistsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/PropertyExistsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -48,28 +48,28 @@
             : base(name)
         {
             this.name = name;
-        }
-
-        /// <summary>
-        /// Test whether the property exists for a given object
-        /// </summary>
-        /// <param name="actual">The object to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Test whether the property exists for a given object
+        /// </summary>
+        /// <param name="actual">The object to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
             if (actual == null)
                 throw new ArgumentNullException("actual");
 
-            this.actualType = actual as Type;
+            actualType = actual as Type;
             if (actualType == null)
                 actualType = actual.GetType();
 
             PropertyInfo property = actualType.GetProperty(name,
                 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty);
 
-            return property != null;
+            return new StandardConstraintResult(property != null);
         }
 
         /// <summary>

=== modified file 'src/NUnitFramework/framework/Constraints/RangeConstraint.cs'
--- src/NUnitFramework/framework/Constraints/RangeConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/RangeConstraint.cs	2011-06-04 23:12:29 +0000
@@ -49,22 +49,22 @@
         {
             this.from = from;
             this.to = to;
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
             if ( from == null || to == null || actual == null)
-                throw new ArgumentException( "Cannot compare using a null reference", "expected" );
+                throw new ArgumentException( "Cannot compare using a null reference", "actual" );
 
-            return comparer.Compare(from, actual) <= 0 &&
-                   comparer.Compare(to, actual) >= 0;
+            bool isInsideRange = comparer.Compare(from, actual) <= 0 && comparer.Compare(to, actual) >= 0;
+            return new StandardConstraintResult(isInsideRange);
         }
 
         /// <summary>
@@ -106,4 +106,4 @@
         }
 #endif
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/RegexConstraint.cs'
--- src/NUnitFramework/framework/Constraints/RegexConstraint.cs	2011-04-20 16:40:19 +0000
+++ src/NUnitFramework/framework/Constraints/RegexConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,71 +1,71 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-#if !NETCF
-using System.Text.RegularExpressions;
-#endif
-
-namespace NUnit.Framework.Constraints
-{
-#if !NETCF
-    /// <summary>
-    /// RegexConstraint can test whether a string matches
-    /// the pattern provided.
-    /// </summary>
-    public class RegexConstraint : StringConstraint
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:RegexConstraint"/> class.
-        /// </summary>
-        /// <param name="pattern">The pattern.</param>
-        public RegexConstraint(string pattern) : base(pattern) { }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        protected override bool Matches(string actual)
-        {
-            //this.actual = actual;
-
-            return Regex.IsMatch(
-                    actual,
-                    this.expected,
-                    this.caseInsensitive ? RegexOptions.IgnoreCase : RegexOptions.None);
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WritePredicate("String matching");
-            writer.WriteExpectedValue(this.expected);
-			if ( this.caseInsensitive )
-				writer.WriteModifier( "ignoring case" );
-		}
-    }
-#endif
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+#if !NETCF
+using System.Text.RegularExpressions;
+#endif
+
+namespace NUnit.Framework.Constraints
+{
+#if !NETCF
+    /// <summary>
+    /// RegexConstraint can test whether a string matches
+    /// the pattern provided.
+    /// </summary>
+    public class RegexConstraint : StringConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:RegexConstraint"/> class.
+        /// </summary>
+        /// <param name="pattern">The pattern.</param>
+        public RegexConstraint(string pattern) : base(pattern) { }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        protected override bool Matches(string actual)
+        {
+            //this.actual = actual;
+
+            return Regex.IsMatch(
+                    actual,
+                    this.expected,
+                    this.caseInsensitive ? RegexOptions.IgnoreCase : RegexOptions.None);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("String matching");
+            writer.WriteExpectedValue(this.expected);
+            if (this.caseInsensitive)
+                writer.WriteModifier("ignoring case");
+        }
+    }
+#endif
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/SameAsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/SameAsConstraint.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/SameAsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -18,11 +18,9 @@
 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
 namespace NUnit.Framework.Constraints
 {
     /// <summary>
@@ -40,23 +38,25 @@
         public SameAsConstraint(object expected) : base(expected)
         {
             this.expected = expected;
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
 #if NETCF_1_0
             // TODO: THis makes it compile, now make it work.
-            return expected.Equals(actual);
+            bool hasSucceeded = expected.Equals(actual);
 #else
-            return Object.ReferenceEquals(expected, actual);
-#endif
+            bool hasSucceeded = ReferenceEquals(expected, actual);
+#endif
+
+            return new StandardConstraintResult(hasSucceeded);
         }
 
         /// <summary>
@@ -69,4 +69,4 @@
             writer.WriteExpectedValue(expected);
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/SamePathConstraint.cs'
--- src/NUnitFramework/framework/Constraints/SamePathConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/SamePathConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,62 +1,62 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-	/// Summary description for SamePathConstraint.
-	/// </summary>
-	public class SamePathConstraint : PathConstraint
-	{
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:SamePathConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected path</param>
-		public SamePathConstraint( string expected ) : base( expected ) { }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			if ( !(actual is string) )
-				return false;
-
-			return IsSamePath( expected, (string)actual );
-		}
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate( "Path matching" );
-			writer.WriteExpectedValue( expected );
-		}
-    }
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// Summary description for SamePathConstraint.
+    /// </summary>
+    public class SamePathConstraint : PathConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:SamePathConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected path</param>
+        public SamePathConstraint(string expected) : base(expected) { }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            string actualAsString = actual as string;
+            bool hasSucceeded = actualAsString != null && IsSamePath(expected, actualAsString);
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("Path matching");
+            writer.WriteExpectedValue(expected);
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/SamePathOrUnderConstraint.cs'
--- src/NUnitFramework/framework/Constraints/SamePathOrUnderConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/SamePathOrUnderConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,62 +1,62 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// SamePathOrUnderConstraint tests that one path is under another
-    /// </summary>
-	public class SamePathOrUnderConstraint : PathConstraint
-	{
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:SamePathOrUnderConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected path</param>
-		public SamePathOrUnderConstraint( string expected ) : base( expected ) { }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			if ( !(actual is string) )
-				return false;
-
-			return IsSamePathOrUnder( expected, (string) actual );
-		}
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate( "Path under or matching" );
-			writer.WriteExpectedValue( expected );
-		}
-    }
-}
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// SamePathOrUnderConstraint tests that one path is under another
+    /// </summary>
+    public class SamePathOrUnderConstraint : PathConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:SamePathOrUnderConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected path</param>
+        public SamePathOrUnderConstraint(string expected) : base(expected) { }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            string actualAsString = actual as string;
+            bool hasSucceeded = actualAsString != null && IsSamePathOrUnder(expected, actualAsString);
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("Path under or matching");
+            writer.WriteExpectedValue(expected);
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/SomeItemsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/SomeItemsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/SomeItemsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,75 +1,75 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Collections;
-
-namespace NUnit.Framework.Constraints
-{
-	/// <summary>
-	/// SomeItemsConstraint applies another constraint to each
-	/// item in a collection, succeeding if any of them succeeds.
-	/// </summary>
-	public class SomeItemsConstraint : PrefixConstraint
-	{
-		/// <summary>
-		/// Construct a SomeItemsConstraint on top of an existing constraint
-		/// </summary>
-		/// <param name="itemConstraint"></param>
-		public SomeItemsConstraint(Constraint itemConstraint)
-			: base( itemConstraint ) 
-        {
-            this.DisplayName = "some";
-        }
-
-		/// <summary>
-		/// Apply the item constraint to each item in the collection,
-		/// succeeding if any item succeeds.
-		/// </summary>
-		/// <param name="actual"></param>
-		/// <returns></returns>
-		public override bool Matches(object actual)
-		{
-			this.actual = actual;
-
-			if ( !(actual is IEnumerable) )
-				throw new ArgumentException( "The actual value must be an IEnumerable", "actual" );
-
-			foreach(object item in (IEnumerable)actual)
-				if (baseConstraint.Matches(item))
-					return true;
-
-			return false;
-		}
-
-		/// <summary>
-		/// Write a description of this constraint to a MessageWriter
-		/// </summary>
-		/// <param name="writer"></param>
-		public override void WriteDescriptionTo(MessageWriter writer)
-		{
-			writer.WritePredicate("some item");
-			baseConstraint.WriteDescriptionTo(writer);
-		}
-	}
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// SomeItemsConstraint applies another constraint to each
+    /// item in a collection, succeeding if any of them succeeds.
+    /// </summary>
+    public class SomeItemsConstraint : PrefixConstraint
+    {
+        /// <summary>
+        /// Construct a SomeItemsConstraint on top of an existing constraint
+        /// </summary>
+        /// <param name="itemConstraint"></param>
+        public SomeItemsConstraint(Constraint itemConstraint)
+            : base(itemConstraint)
+        {
+            this.DisplayName = "some";
+        }
+
+        /// <summary>
+        /// Apply the item constraint to each item in the collection,
+        /// succeeding if any item succeeds.
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            if (!(actual is IEnumerable))
+                throw new ArgumentException("The actual value must be an IEnumerable", "actual");
+
+            foreach (object item in (IEnumerable)actual)
+                if (baseConstraint.Matches(item).HasSucceeded)
+                    return new StandardConstraintResult(true);
+
+            return new StandardConstraintResult(false);
+        }
+
+        /// <summary>
+        /// Write a description of this constraint to a MessageWriter
+        /// </summary>
+        /// <param name="writer"></param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("some item");
+            baseConstraint.WriteDescriptionTo(writer);
+        }
+    }
 }
\ No newline at end of file

=== added file 'src/NUnitFramework/framework/Constraints/StandardConstraintResult.cs'
--- src/NUnitFramework/framework/Constraints/StandardConstraintResult.cs	1970-01-01 00:00:00 +0000
+++ src/NUnitFramework/framework/Constraints/StandardConstraintResult.cs	2011-06-04 23:12:29 +0000
@@ -0,0 +1,83 @@
+// ***********************************************************************
+// Copyright (c) 2011 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+
+    internal class StandardConstraintResult : IConstraintResult
+    {
+        private readonly bool hasSucceeded;
+
+        public StandardConstraintResult(bool hasSucceeded)
+        {
+            this.hasSucceeded = hasSucceeded;
+        }
+
+        public bool HasSucceeded
+        {
+            get { return hasSucceeded; }
+        }
+
+        public object Actual
+        {
+            get { return null; }
+        }
+
+        public object Expected
+        {
+            get { return null; }
+        }
+
+        public string Name
+        {
+            get { return string.Empty; }
+        }
+
+        public string Description
+        {
+            get { return string.Empty; }
+        }
+
+        public string Predicate
+        {
+            get { return string.Empty; }
+        }
+
+        public string Modifier
+        {
+            get { return string.Empty; }
+        }
+
+        public void WriteDescriptionTo(MessageWriter writer)
+        {
+        }
+
+        public void WriteMessageTo(MessageWriter writer)
+        {
+        }
+
+        public void WriteActualValueTo(MessageWriter writer)
+        {
+        }
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/StartsWithConstraint.cs'
--- src/NUnitFramework/framework/Constraints/StartsWithConstraint.cs	2011-04-20 16:40:19 +0000
+++ src/NUnitFramework/framework/Constraints/StartsWithConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,67 +1,67 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-	/// StartsWithConstraint can test whether a string starts
-	/// with an expected substring.
-	/// </summary>
-    public class StartsWithConstraint : StringConstraint
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:StartsWithConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected string</param>
-        public StartsWithConstraint(string expected) : base(expected) { }
-
-        /// <summary>
-        /// Test whether the constraint is matched by the actual value.
-        /// This is a template method, which calls the IsMatch method
-        /// of the derived class.
-        /// </summary>
-        /// <param name="actual"></param>
-        /// <returns></returns>
-        protected override bool Matches(string actual)
-        {
-            //this.actual = actual;
-
-            if (this.caseInsensitive)
-                return actual.ToLower().StartsWith(expected.ToLower());
-            else
-                return actual.StartsWith(expected);
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WritePredicate("String starting with");
-            writer.WriteExpectedValue( MsgUtils.ClipString(expected, writer.MaxLineLength - 40, 0) );
-			if ( this.caseInsensitive )
-				writer.WriteModifier( "ignoring case" );
-		}
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// StartsWithConstraint can test whether a string starts
+    /// with an expected substring.
+    /// </summary>
+    public class StartsWithConstraint : StringConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:StartsWithConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected string</param>
+        public StartsWithConstraint(string expected) : base(expected) { }
+
+        /// <summary>
+        /// Test whether the constraint is matched by the actual value.
+        /// This is a template method, which calls the IsMatch method
+        /// of the derived class.
+        /// </summary>
+        /// <param name="actual"></param>
+        /// <returns></returns>
+        protected override bool Matches(string actual)
+        {
+            //this.actual = actual;
+
+            if (this.caseInsensitive)
+                return actual.ToLower().StartsWith(expected.ToLower());
+            else
+                return actual.StartsWith(expected);
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("String starting with");
+            writer.WriteExpectedValue(MsgUtils.ClipString(expected, writer.MaxLineLength - 40, 0));
+            if (this.caseInsensitive)
+                writer.WriteModifier("ignoring case");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/StringConstraint.cs'
--- src/NUnitFramework/framework/Constraints/StringConstraint.cs	2011-05-24 05:49:11 +0000
+++ src/NUnitFramework/framework/Constraints/StringConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,83 +1,83 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// StringConstraint is the abstract base for constraints
-    /// that operate on strings. It supports the IgnoreCase
-    /// modifier for string operations.
-    /// </summary>
-    public abstract class StringConstraint : Constraint
-    {
-        /// <summary>
-        /// The expected value
-        /// </summary>
-        protected string expected;
-
-        /// <summary>
-        /// Indicates whether tests should be case-insensitive
-        /// </summary>
-        protected bool caseInsensitive;
-
-        /// <summary>
-        /// Constructs a StringConstraint given an expected value
-        /// </summary>
-        /// <param name="expected">The expected value</param>
-        protected StringConstraint(string expected)
-            : base(expected)
-        {
-            this.expected = expected;
-        }
-
-        /// <summary>
-        /// Modify the constraint to ignore case in matching.
-        /// </summary>
-        public StringConstraint IgnoreCase
-        {
-            get { caseInsensitive = true; return this; }
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
-        {
-            this.actual = actual;
-
-            if (!(actual is string))
-                return false;
-
-            return Matches((string)actual);
-        }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given string
-        /// </summary>
-        /// <param name="actual">The string to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        protected abstract bool Matches(string actual);
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// StringConstraint is the abstract base for constraints
+    /// that operate on strings. It supports the IgnoreCase
+    /// modifier for string operations.
+    /// </summary>
+    public abstract class StringConstraint : Constraint
+    {
+        /// <summary>
+        /// The expected value
+        /// </summary>
+        protected string expected;
+
+        /// <summary>
+        /// Indicates whether tests should be case-insensitive
+        /// </summary>
+        protected bool caseInsensitive;
+
+        /// <summary>
+        /// Constructs a StringConstraint given an expected value
+        /// </summary>
+        /// <param name="expected">The expected value</param>
+        protected StringConstraint(string expected)
+            : base(expected)
+        {
+            this.expected = expected;
+        }
+
+        /// <summary>
+        /// Modify the constraint to ignore case in matching.
+        /// </summary>
+        public StringConstraint IgnoreCase
+        {
+            get { caseInsensitive = true; return this; }
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            this.actual = actual;
+
+            string actualAsString = actual as string;
+            bool hasSucceeded = actualAsString != null && Matches(actualAsString);
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given string
+        /// </summary>
+        /// <param name="actual">The string to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        protected abstract bool Matches(string actual);
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/SubstringConstraint.cs'
--- src/NUnitFramework/framework/Constraints/SubstringConstraint.cs	2011-04-20 16:40:19 +0000
+++ src/NUnitFramework/framework/Constraints/SubstringConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,65 +1,65 @@
-// ***********************************************************************
-// Copyright (c) 2007 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-	/// SubstringConstraint can test whether a string contains
-	/// the expected substring.
-	/// </summary>
-    public class SubstringConstraint : StringConstraint
-    {
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:SubstringConstraint"/> class.
-        /// </summary>
-        /// <param name="expected">The expected.</param>
-        public SubstringConstraint(string expected) : base(expected) { }
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        protected override bool Matches(string actual)
-        {
-            //this.actual = actual;
-
-            if (this.caseInsensitive)
-                return actual.ToLower().IndexOf(expected.ToLower()) >= 0;
-            else
-                return actual.IndexOf(expected) >= 0;
-        }
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            writer.WritePredicate("String containing");
-            writer.WriteExpectedValue(expected);
-			if ( this.caseInsensitive )
-				writer.WriteModifier( "ignoring case" );
-		}
-    } 
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// SubstringConstraint can test whether a string contains
+    /// the expected substring.
+    /// </summary>
+    public class SubstringConstraint : StringConstraint
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:SubstringConstraint"/> class.
+        /// </summary>
+        /// <param name="expected">The expected.</param>
+        public SubstringConstraint(string expected) : base(expected) { }
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        protected override bool Matches(string actual)
+        {
+            //this.actual = actual;
+
+            if (this.caseInsensitive)
+                return actual.ToLower().IndexOf(expected.ToLower()) >= 0;
+            else
+                return actual.IndexOf(expected) >= 0;
+        }
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            writer.WritePredicate("String containing");
+            writer.WriteExpectedValue(expected);
+            if (this.caseInsensitive)
+                writer.WriteModifier("ignoring case");
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/ThrowsConstraint.cs'
--- src/NUnitFramework/framework/Constraints/ThrowsConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/ThrowsConstraint.cs	2011-06-04 23:12:29 +0000
@@ -1,139 +1,140 @@
-// ***********************************************************************
-// Copyright (c) 2008 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-
-namespace NUnit.Framework.Constraints
-{
-    /// <summary>
-    /// ThrowsConstraint is used to test the exception thrown by 
-    /// a delegate by applying a constraint to it.
-    /// </summary>
-    public class ThrowsConstraint : PrefixConstraint
-    {
-        private Exception caughtException;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="T:ThrowsConstraint"/> class,
-        /// using a constraint to be applied to the exception.
-        /// </summary>
-        /// <param name="baseConstraint">A constraint to apply to the caught exception.</param>
-        public ThrowsConstraint(Constraint baseConstraint)
-            : base(baseConstraint) { }
-
-        /// <summary>
-        /// Get the actual exception thrown - used by Assert.Throws.
-        /// </summary>
-        public Exception ActualException
-        {
-            get { return caughtException; }
-        }
-
-        #region Constraint Overrides
-        /// <summary>
-        /// Executes the code of the delegate and captures any exception.
-        /// If a non-null base constraint was provided, it applies that
-        /// constraint to the exception.
-        /// </summary>
-        /// <param name="actual">A delegate representing the code to be tested</param>
-        /// <returns>True if an exception is thrown and the constraint succeeds, otherwise false</returns>
-        public override bool Matches(object actual)
-        {
-            TestDelegate code = actual as TestDelegate;
-            if (code == null)
-                throw new ArgumentException(
-                    string.Format("The actual value must be a TestDelegate but was {0}", actual.GetType().Name), "actual");
-
-            this.caughtException = null;
-
-            try
-            {
-                code();
-            }
-            catch (Exception ex)
-            {
-                this.caughtException = ex;
-            }
-
-            if (this.caughtException == null)
-                return false;
-
-            return baseConstraint == null || baseConstraint.Matches(caughtException);
-        }
-
-#if CLR_2_0 || CLR_4_0
-        /// <summary>
-        /// Converts an ActualValueDelegate to a TestDelegate
-        /// before calling the primary overload.
-        /// </summary>
-        /// <param name="del"></param>
-        /// <returns></returns>
-        public override bool Matches(ActualValueDelegate del)
-        {
-            TestDelegate testDelegate = new TestDelegate(delegate { del(); });
-            return Matches((object)testDelegate);
-        }
-#endif
-
-        /// <summary>
-        /// Write the constraint description to a MessageWriter
-        /// </summary>
-        /// <param name="writer">The writer on which the description is displayed</param>
-        public override void WriteDescriptionTo(MessageWriter writer)
-        {
-            if (baseConstraint == null)
-                writer.WritePredicate("an exception");
-            else
-                baseConstraint.WriteDescriptionTo(writer);
-        }
-
-        /// <summary>
-        /// Write the actual value for a failing constraint test to a
-        /// MessageWriter. The default implementation simply writes
-        /// the raw value of actual, leaving it to the writer to
-        /// perform any formatting.
-        /// </summary>
-        /// <param name="writer">The writer on which the actual value is displayed</param>
-        public override void WriteActualValueTo(MessageWriter writer)
-        {
-            if (caughtException == null)
-                writer.Write("no exception thrown");
-            else if (baseConstraint != null)
-                baseConstraint.WriteActualValueTo(writer);
-            else
-                writer.WriteActualValue(caughtException);
-        }
-        #endregion
-
-        /// <summary>
-        /// Returns the string representation of this constraint
-        /// </summary>
-        protected override string GetStringRepresentation()
-        {
-            if (baseConstraint == null)
-                return "<throws>";
-
-            return base.GetStringRepresentation();
-        }
-    }
+// ***********************************************************************
+// Copyright (c) 2008 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+
+namespace NUnit.Framework.Constraints
+{
+    /// <summary>
+    /// ThrowsConstraint is used to test the exception thrown by 
+    /// a delegate by applying a constraint to it.
+    /// </summary>
+    public class ThrowsConstraint : PrefixConstraint
+    {
+        private Exception caughtException;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="T:ThrowsConstraint"/> class,
+        /// using a constraint to be applied to the exception.
+        /// </summary>
+        /// <param name="baseConstraint">A constraint to apply to the caught exception.</param>
+        public ThrowsConstraint(Constraint baseConstraint)
+            : base(baseConstraint) { }
+
+        /// <summary>
+        /// Get the actual exception thrown - used by Assert.Throws.
+        /// </summary>
+        public Exception ActualException
+        {
+            get { return caughtException; }
+        }
+
+        #region Constraint Overrides
+
+        /// <summary>
+        /// Executes the code of the delegate and captures any exception.
+        /// If a non-null base constraint was provided, it applies that
+        /// constraint to the exception.
+        /// </summary>
+        /// <param name="actual">A delegate representing the code to be tested</param>
+        /// <returns>True if an exception is thrown and the constraint succeeds, otherwise false</returns>
+        public override IConstraintResult Matches(object actual)
+        {
+            TestDelegate code = actual as TestDelegate;
+            if (code == null)
+                throw new ArgumentException(
+                    string.Format("The actual value must be a TestDelegate but was {0}", actual.GetType().Name), "actual");
+
+            caughtException = null;
+
+            try
+            {
+                code();
+            }
+            catch (Exception ex)
+            {
+                caughtException = ex;
+            }
+
+            bool hasSucceeded = caughtException != null &&
+                (baseConstraint == null || baseConstraint.Matches(caughtException).HasSucceeded);
+
+            return new StandardConstraintResult(hasSucceeded);
+        }
+
+#if CLR_2_0 || CLR_4_0
+        /// <summary>
+        /// Converts an ActualValueDelegate to a TestDelegate
+        /// before calling the primary overload.
+        /// </summary>
+        /// <param name="del"></param>
+        /// <returns></returns>
+        public override IConstraintResult Matches(ActualValueDelegate del)
+        {
+            TestDelegate testDelegate = new TestDelegate(delegate { del(); });
+            return Matches((object)testDelegate);
+        }
+#endif
+
+        /// <summary>
+        /// Write the constraint description to a MessageWriter
+        /// </summary>
+        /// <param name="writer">The writer on which the description is displayed</param>
+        public override void WriteDescriptionTo(MessageWriter writer)
+        {
+            if (baseConstraint == null)
+                writer.WritePredicate("an exception");
+            else
+                baseConstraint.WriteDescriptionTo(writer);
+        }
+
+        /// <summary>
+        /// Write the actual value for a failing constraint test to a
+        /// MessageWriter. The default implementation simply writes
+        /// the raw value of actual, leaving it to the writer to
+        /// perform any formatting.
+        /// </summary>
+        /// <param name="writer">The writer on which the actual value is displayed</param>
+        public override void WriteActualValueTo(MessageWriter writer)
+        {
+            if (caughtException == null)
+                writer.Write("no exception thrown");
+            else if (baseConstraint != null)
+                baseConstraint.WriteActualValueTo(writer);
+            else
+                writer.WriteActualValue(caughtException);
+        }
+        #endregion
+
+        /// <summary>
+        /// Returns the string representation of this constraint
+        /// </summary>
+        protected override string GetStringRepresentation()
+        {
+            if (baseConstraint == null)
+                return "<throws>";
+
+            return base.GetStringRepresentation();
+        }
+    }
 }
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/ThrowsNothingConstraint.cs'
--- src/NUnitFramework/framework/Constraints/ThrowsNothingConstraint.cs	2011-03-31 17:46:09 +0000
+++ src/NUnitFramework/framework/Constraints/ThrowsNothingConstraint.cs	2011-06-04 23:12:29 +0000
@@ -31,20 +31,20 @@
     /// </summary>
     public class ThrowsNothingConstraint : Constraint
     {
-        private Exception caughtException;
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True if no exception is thrown, otherwise false</returns>
-        public override bool Matches(object actual)
+        private Exception caughtException;
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True if no exception is thrown, otherwise false</returns>
+        public override IConstraintResult Matches(object actual)
         {
             TestDelegate code = actual as TestDelegate;
             if (code == null)
                 throw new ArgumentException("The actual value must be a TestDelegate", "actual");
 
-            this.caughtException = null;
+            caughtException = null;
 
             try
             {
@@ -52,10 +52,10 @@
             }
             catch (Exception ex)
             {
-                this.caughtException = ex;
+                caughtException = ex;
             }
 
-            return this.caughtException == null;
+            return new StandardConstraintResult(caughtException == null);
         }
 
         /// <summary>
@@ -76,7 +76,7 @@
         /// <param name="writer">The writer on which the actual value is displayed</param>
         public override void WriteActualValueTo(MessageWriter writer)
         {
-            writer.WriteActualValue(this.caughtException.GetType());
+            writer.WriteActualValue(caughtException.GetType());
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/Tolerance.cs'
--- src/NUnitFramework/framework/Constraints/Tolerance.cs	2010-09-19 16:45:44 +0000
+++ src/NUnitFramework/framework/Constraints/Tolerance.cs	2011-06-04 23:12:29 +0000
@@ -206,4 +206,4 @@
             get { return mode == ToleranceMode.None; }
         }
     }
-}
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/Constraints/XmlSerializableConstraint.cs'
--- src/NUnitFramework/framework/Constraints/XmlSerializableConstraint.cs	2010-07-26 18:53:17 +0000
+++ src/NUnitFramework/framework/Constraints/XmlSerializableConstraint.cs	2011-06-04 23:12:29 +0000
@@ -37,14 +37,14 @@
     /// </summary>
     public class XmlSerializableConstraint : Constraint
     {
-        private XmlSerializer serializer;
-
-        /// <summary>
-        /// Test whether the constraint is satisfied by a given value
-        /// </summary>
-        /// <param name="actual">The value to be tested</param>
-        /// <returns>True for success, false for failure</returns>
-        public override bool Matches(object actual)
+        private XmlSerializer serializer;
+
+        /// <summary>
+        /// Test whether the constraint is satisfied by a given value
+        /// </summary>
+        /// <param name="actual">The value to be tested</param>
+        /// <returns>True for success, false for failure</returns>
+        public override IConstraintResult Matches(object actual)
         {
             this.actual = actual;
 
@@ -63,15 +63,15 @@
 
                 object value = serializer.Deserialize(stream);
 
-                return value != null;
+                return new StandardConstraintResult(value != null);
             }
             catch (NotSupportedException)
             {
-                return false;
+                return new StandardConstraintResult(false);
             }
             catch (InvalidOperationException)
             {
-                return false;
+                return new StandardConstraintResult(false);
             }
         }
 

=== modified file 'src/NUnitFramework/framework/nunit.framework-vs2010.csproj'
--- src/NUnitFramework/framework/nunit.framework-vs2010.csproj	2011-06-04 16:54:09 +0000
+++ src/NUnitFramework/framework/nunit.framework-vs2010.csproj	2011-06-04 23:12:29 +0000
@@ -1,3 +1,4 @@
+<<<<<<< TREE
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
   <PropertyGroup>
@@ -40,12 +41,58 @@
     <DocumentationFile>..\..\..\bin\Release\nunit.framework.xml</DocumentationFile>
   </PropertyGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+=======
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{12B66B03-90F1-4992-BD33-BDF3C69AE49E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>NUnit.Framework</RootNamespace>
+    <AssemblyName>nunit.framework</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>nunit.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET_3_5;CLR_2_0</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>..\..\..\bin\Debug\nunit.framework.xml</DocumentationFile>
+    <NoWarn>1699</NoWarn>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5;CLR_2_0</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>..\..\..\bin\Release\nunit.framework.xml</DocumentationFile>
+  </PropertyGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+>>>>>>> MERGE-SOURCE
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
+<<<<<<< TREE
   -->
   <ItemGroup>
     <None Include="nunit.snk" />
@@ -344,4 +391,309 @@
     <Reference Include="System.Configuration" />
     <Reference Include="System.Xml" />
   </ItemGroup>
+=======
+  -->
+  <ItemGroup>
+    <None Include="nunit.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\CommonAssemblyInfo.cs">
+      <Link>CommonAssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="Api\IApplyToTest.cs" />
+    <Compile Include="Api\IParameterDataSource.cs" />
+    <Compile Include="Api\IPropertyBag.cs" />
+    <Compile Include="Api\IPropertySet.cs" />
+    <Compile Include="Api\ITest.cs" />
+    <Compile Include="Api\ITestAssemblyBuilder.cs" />
+    <Compile Include="Api\ITestAssemblyRunner.cs" />
+    <Compile Include="Api\ITestCaseData.cs" />
+    <Compile Include="Api\ITestCaseSource.cs" />
+    <Compile Include="Api\ITestCaseSourceProvider.cs" />
+    <Compile Include="Api\ITestFilter.cs" />
+    <Compile Include="Api\ITestListener.cs" />
+    <Compile Include="Api\ITestResult.cs" />
+    <Compile Include="Api\IXmlNodeBuilder.cs" />
+    <Compile Include="Api\PropertyEntry.cs" />
+    <Compile Include="Api\PropertyNames.cs" />
+    <Compile Include="Api\ResultState.cs" />
+    <Compile Include="Api\RunState.cs" />
+    <Compile Include="Api\TestController.cs" />
+    <Compile Include="Api\TestOutput.cs" />
+    <Compile Include="Api\TestStatus.cs" />
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="Assert.cs" />
+    <Compile Include="AssertionHelper.cs" />
+    <Compile Include="Assume.cs" />
+    <Compile Include="Attributes\CategoryAttribute.cs" />
+    <Compile Include="Attributes\CombinatorialAttribute.cs" />
+    <Compile Include="Attributes\CultureAttribute.cs" />
+    <Compile Include="Attributes\DataAttribute.cs" />
+    <Compile Include="Attributes\DatapointAttribute.cs" />
+    <Compile Include="Attributes\DatapointsAttribute.cs" />
+    <Compile Include="Attributes\DatapointSourceAttribute.cs" />
+    <Compile Include="Attributes\DescriptionAttribute.cs" />
+    <Compile Include="Attributes\ExpectedExceptionAttribute.cs" />
+    <Compile Include="Attributes\ExplicitAttribute.cs" />
+    <Compile Include="Attributes\IgnoreAttribute.cs" />
+    <Compile Include="Attributes\IncludeExcludeAttribute.cs" />
+    <Compile Include="Attributes\MaxTimeAttribute.cs" />
+    <Compile Include="Attributes\NUnitAttribute.cs" />
+    <Compile Include="Attributes\PairwiseAttribute.cs" />
+    <Compile Include="Attributes\PlatformAttribute.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\RequiresMTAAtribute.cs" />
+    <Compile Include="Attributes\RequiresSTAAttribute.cs" />
+    <Compile Include="Attributes\RequiresThreadAttribute.cs" />
+    <Compile Include="Attributes\SequentialAttribute.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\TestModificationAttribute.cs" />
+    <Compile Include="Attributes\TheoryAttribute.cs" />
+    <Compile Include="Attributes\TimeoutAttribute.cs" />
+    <Compile Include="Attributes\ValuesAttribute.cs" />
+    <Compile Include="Attributes\ValueSourceAttribute.cs" />
+    <Compile Include="CollectionAssert.cs" />
+    <Compile Include="Constraints\AllItemsConstraint.cs" />
+    <Compile Include="Constraints\AndConstraint.cs" />
+    <Compile Include="Constraints\AssignableFromConstraint.cs" />
+    <Compile Include="Constraints\AssignableToConstraint.cs" />
+    <Compile Include="Constraints\AttributeConstraint.cs" />
+    <Compile Include="Constraints\AttributeExistsConstraint.cs" />
+    <Compile Include="Constraints\BasicConstraint.cs" />
+    <Compile Include="Constraints\StandardConstraintResult.cs" />
+    <Compile Include="Constraints\BinaryConstraint.cs" />
+    <Compile Include="Constraints\BinarySerializableConstraint.cs" />
+    <Compile Include="Constraints\CollectionConstraint.cs" />
+    <Compile Include="Constraints\CollectionContainsConstraint.cs" />
+    <Compile Include="Constraints\CollectionEquivalentConstraint.cs" />
+    <Compile Include="Constraints\CollectionItemsEqualConstraint.cs" />
+    <Compile Include="Constraints\CollectionOrderedConstraint.cs" />
+    <Compile Include="Constraints\CollectionSubsetConstraint.cs" />
+    <Compile Include="Constraints\CollectionTally.cs" />
+    <Compile Include="Constraints\ComparisonAdapter.cs" />
+    <Compile Include="Constraints\ComparisonConstraint.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\IConstraintResult.cs" />
+    <Compile Include="Constraints\ContainsConstraint.cs" />
+    <Compile Include="Constraints\DelayedConstraint.cs" />
+    <Compile Include="Constraints\EmptyCollectionConstraint.cs" />
+    <Compile Include="Constraints\EmptyConstraint.cs" />
+    <Compile Include="Constraints\EmptyDirectoryConstraint.cs" />
+    <Compile Include="Constraints\EmptyStringConstraint.cs" />
+    <Compile Include="Constraints\EndsWithConstraint.cs" />
+    <Compile Include="Constraints\EqualConstraint.cs" />
+    <Compile Include="Constraints\EqualityAdapter.cs" />
+    <Compile Include="Constraints\ExactTypeConstraint.cs" />
+    <Compile Include="Constraints\FalseConstraint.cs" />
+    <Compile Include="Constraints\FloatingPointNumerics.cs" />
+    <Compile Include="Constraints\GreaterThanConstraint.cs" />
+    <Compile Include="Constraints\GreaterThanOrEqualConstraint.cs" />
+    <Compile Include="Constraints\InstanceOfTypeConstraint.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\NaNConstraint.cs" />
+    <Compile Include="Constraints\NoItemConstraint.cs" />
+    <Compile Include="Constraints\NotConstraint.cs" />
+    <Compile Include="Constraints\NullConstraint.cs" />
+    <Compile Include="Constraints\NullOrEmptyStringConstraint.cs" />
+    <Compile Include="Constraints\Numerics.cs" />
+    <Compile Include="Constraints\NUnitComparer.cs" />
+    <Compile Include="Constraints\NUnitEqualityComparer.cs" />
+    <Compile Include="Constraints\Operators\AndOperator.cs" />
+    <Compile Include="Constraints\Operators\AttributeOperator.cs" />
+    <Compile Include="Constraints\Operators\BinaryOperator.cs" />
+    <Compile Include="Constraints\Operators\CollectionOperator.cs" />
+    <Compile Include="Constraints\Operators\ConstraintOperator.cs" />
+    <Compile Include="Constraints\Operators\NotOperator.cs" />
+    <Compile Include="Constraints\Operators\OrOperator.cs" />
+    <Compile Include="Constraints\Operators\PrefixOperator.cs" />
+    <Compile Include="Constraints\Operators\PropOperator.cs" />
+    <Compile Include="Constraints\Operators\SelfResolvingOperator.cs" />
+    <Compile Include="Constraints\Operators\ThrowsOperator.cs" />
+    <Compile Include="Constraints\Operators\WithOperator.cs" />
+    <Compile Include="Constraints\OrConstraint.cs" />
+    <Compile Include="Constraints\PathConstraint.cs" />
+    <Compile Include="Constraints\PredicateConstraint.cs" />
+    <Compile Include="Constraints\PrefixConstraint.cs" />
+    <Compile Include="Constraints\PropertyConstraint.cs" />
+    <Compile Include="Constraints\PropertyExistsConstraint.cs" />
+    <Compile Include="Constraints\RangeConstraint.cs" />
+    <Compile Include="Constraints\RegexConstraint.cs" />
+    <Compile Include="Constraints\ResolvableConstraintExpression.cs" />
+    <Compile Include="Constraints\ReusableConstraint.cs" />
+    <Compile Include="Constraints\SameAsConstraint.cs" />
+    <Compile Include="Constraints\SamePathConstraint.cs" />
+    <Compile Include="Constraints\SamePathOrUnderConstraint.cs" />
+    <Compile Include="Constraints\SomeItemsConstraint.cs" />
+    <Compile Include="Constraints\StartsWithConstraint.cs" />
+    <Compile Include="Constraints\StringConstraint.cs" />
+    <Compile Include="Constraints\SubstringConstraint.cs" />
+    <Compile Include="Constraints\ThrowsConstraint.cs" />
+    <Compile Include="Constraints\ThrowsNothingConstraint.cs" />
+    <Compile Include="Constraints\Tolerance.cs" />
+    <Compile Include="Constraints\ToleranceMode.cs" />
+    <Compile Include="Constraints\TrueConstraint.cs" />
+    <Compile Include="Constraints\TypeConstraint.cs" />
+    <Compile Include="Constraints\UniqueItemsConstraint.cs" />
+    <Compile Include="Constraints\XmlSerializableConstraint.cs" />
+    <Compile Include="Contains.cs" />
+    <Compile Include="Env.cs" />
+    <Compile Include="Exceptions\AssertionException.cs" />
+    <Compile Include="Exceptions\IgnoreException.cs" />
+    <Compile Include="Exceptions\InconclusiveException.cs" />
+    <Compile Include="Exceptions\SuccessException.cs" />
+    <Compile Include="Extensibility\Addin.cs" />
+    <Compile Include="Extensibility\AddinStatus.cs" />
+    <Compile Include="Extensibility\ExtensionType.cs" />
+    <Compile Include="Extensibility\IAddin.cs" />
+    <Compile Include="Extensibility\IAddinRegistry.cs" />
+    <Compile Include="Extensibility\IExtensionHost.cs" />
+    <Compile Include="Extensibility\IExtensionPoint.cs" />
+    <Compile Include="Extensibility\IParameterDataProvider.cs" />
+    <Compile Include="Extensibility\ISuiteBuilder.cs" />
+    <Compile Include="Extensibility\ITestCaseBuilder.cs" />
+    <Compile Include="Extensibility\ITestCaseProvider.cs" />
+    <Compile Include="Extensibility\ITestDecorator.cs" />
+    <Compile Include="Extensibility\NUnitAddinAttribute.cs" />
+    <Compile Include="Extensibility\TestFramework.cs" />
+    <Compile Include="FileAssert.cs" />
+    <Compile Include="GlobalSettings.cs" />
+    <Compile Include="Has.cs" />
+    <Compile Include="IExpectException.cs" />
+    <Compile Include="Internal\AssemblyHelper.cs" />
+    <Compile Include="Internal\AssemblyReader.cs" />
+    <Compile Include="Internal\AsyncResult.cs" />
+    <Compile Include="Internal\Builders\CombinatorialStrategy.cs" />
+    <Compile Include="Internal\Builders\CombinatorialTestCaseProvider.cs" />
+    <Compile Include="Internal\Builders\CombiningStrategy.cs" />
+    <Compile Include="Internal\Builders\DataAttributeTestCaseProvider.cs" />
+    <Compile Include="Internal\Builders\DatapointProvider.cs" />
+    <Compile Include="Internal\Builders\LegacySuiteBuilder.cs" />
+    <Compile Include="Internal\Builders\NUnitTestCaseBuilder.cs" />
+    <Compile Include="Internal\Builders\NUnitTestFixtureBuilder.cs" />
+    <Compile Include="Internal\Builders\PairwiseStrategy.cs" />
+    <Compile Include="Internal\Builders\ParameterDataProvider.cs" />
+    <Compile Include="Internal\Builders\ProviderCache.cs" />
+    <Compile Include="Internal\Builders\SequentialStrategy.cs" />
+    <Compile Include="Internal\Builders\SetUpFixtureBuilder.cs" />
+    <Compile Include="Internal\Commands\CommandBuilder.cs" />
+    <Compile Include="Internal\Commands\DelegatingTestCommand.cs" />
+    <Compile Include="Internal\Commands\ExpectedExceptionCommand.cs" />
+    <Compile Include="Internal\Commands\ITestCommand.cs" />
+    <Compile Include="Internal\Commands\MaxTimeCommand.cs" />
+    <Compile Include="Internal\Commands\RepeatedTestCommand.cs" />
+    <Compile Include="Internal\Commands\SetUpTearDownCommand.cs" />
+    <Compile Include="Internal\Commands\SkipCommand.cs" />
+    <Compile Include="Internal\Commands\TestCaseCommand.cs" />
+    <Compile Include="Internal\Commands\TestCommand.cs" />
+    <Compile Include="Internal\Commands\TestExecutionContextCommand.cs" />
+    <Compile Include="Internal\Commands\TestMethodCommand.cs" />
+    <Compile Include="Internal\Commands\TestSuiteCommand.cs" />
+    <Compile Include="Internal\Commands\ThreadedTestCommand.cs" />
+    <Compile Include="Internal\CoreExtensions.cs" />
+    <Compile Include="Internal\CultureDetector.cs" />
+    <Compile Include="Internal\DefaultTestAssemblyBuilder.cs" />
+    <Compile Include="Internal\DefaultTestAssemblyRunner.cs" />
+    <Compile Include="Internal\DirectorySwapper.cs" />
+    <Compile Include="Internal\EventListenerTextWriter.cs" />
+    <Compile Include="Internal\EventPump.cs" />
+    <Compile Include="Internal\EventQueue.cs" />
+    <Compile Include="Internal\ExceptionHelper.cs" />
+    <Compile Include="Internal\ExpectedExceptionProcessor.cs" />
+    <Compile Include="Internal\Extensibility\EventListenerCollection.cs" />
+    <Compile Include="Internal\Extensibility\ExtensionHost.cs" />
+    <Compile Include="Internal\Extensibility\ExtensionPoint.cs" />
+    <Compile Include="Internal\Extensibility\ExtensionsCollection.cs" />
+    <Compile Include="Internal\Extensibility\ParameterDataProviders.cs" />
+    <Compile Include="Internal\Extensibility\SuiteBuilderCollection.cs" />
+    <Compile Include="Internal\Extensibility\TestCaseBuilderCollection.cs" />
+    <Compile Include="Internal\Extensibility\TestCaseProviders.cs" />
+    <Compile Include="Internal\Extensibility\TestDecoratorCollection.cs" />
+    <Compile Include="Internal\Filters\SimpleNameFilter.cs" />
+    <Compile Include="Internal\InternalTrace.cs" />
+    <Compile Include="Internal\InvalidTestFixtureException.cs" />
+    <Compile Include="Internal\Log4NetCapture.cs" />
+    <Compile Include="Internal\LogCapture.cs" />
+    <Compile Include="Internal\MethodHelper.cs" />
+    <Compile Include="Internal\NamespaceTreeBuilder.cs" />
+    <Compile Include="Internal\NUnitException.cs" />
+    <Compile Include="Internal\OSPlatform.cs" />
+    <Compile Include="Internal\ParameterSet.cs" />
+    <Compile Include="Internal\PlatformHelper.cs" />
+    <Compile Include="Internal\PropertyBag.cs" />
+    <Compile Include="Internal\PropertySet.cs" />
+    <Compile Include="Internal\QueuingEventListener.cs" />
+    <Compile Include="Internal\Randomizer.cs" />
+    <Compile Include="Internal\Reflect.cs" />
+    <Compile Include="Internal\Results\TestResult.cs" />
+    <Compile Include="Internal\RuntimeFramework.cs" />
+    <Compile Include="Internal\TestExecutionContext.cs" />
+    <Compile Include="Internal\TestFilter.cs" />
+    <Compile Include="Internal\TestFixtureBuilder.cs" />
+    <Compile Include="Internal\TestListener.cs" />
+    <Compile Include="Internal\TestProgressReporter.cs" />
+    <Compile Include="Internal\Tests\LegacySuite.cs" />
+    <Compile Include="Internal\Tests\ParameterizedFixtureSuite.cs" />
+    <Compile Include="Internal\Tests\ParameterizedMethodSuite.cs" />
+    <Compile Include="Internal\Tests\SetUpFixture.cs" />
+    <Compile Include="Internal\Tests\Test.cs" />
+    <Compile Include="Internal\Tests\TestAssembly.cs" />
+    <Compile Include="Internal\Tests\TestFixture.cs" />
+    <Compile Include="Internal\Tests\TestMethod.cs" />
+    <Compile Include="Internal\Tests\TestSuite.cs" />
+    <Compile Include="Internal\TextCapture.cs" />
+    <Compile Include="Internal\TextMessageWriter.cs" />
+    <Compile Include="Internal\TypeHelper.cs" />
+    <Compile Include="Internal\XmlHelper.cs" />
+    <Compile Include="Is.cs" />
+    <Compile Include="Iz.cs" />
+    <Compile Include="List.cs" />
+    <Compile Include="ListMapper.cs" />
+    <Compile Include="MessageMatch.cs" />
+    <Compile Include="ObjectList.cs" />
+    <Compile Include="SpecialValue.cs" />
+    <Compile Include="StringAssert.cs" />
+    <Compile Include="TestCaseData.cs" />
+    <Compile Include="TestContext.cs" />
+    <Compile Include="Throws.cs" />
+    <Compile Include="Internal\Results\TestCaseResult.cs" />
+    <Compile Include="Internal\Results\TestSuiteResult.cs" />
+    <None Include="nunit.framework.build" />
+    <None Include="nunitlite.build" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="SyntaxElements.txt" />
+  </ItemGroup>
+>>>>>>> MERGE-SOURCE
 </Project>
\ No newline at end of file

=== modified file 'src/NUnitFramework/framework/nunitlite-vs2010.csproj'
--- src/NUnitFramework/framework/nunitlite-vs2010.csproj	2011-06-04 16:54:09 +0000
+++ src/NUnitFramework/framework/nunitlite-vs2010.csproj	2011-06-04 23:12:29 +0000
@@ -1,3 +1,4 @@
+<<<<<<< TREE
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
   <PropertyGroup>
@@ -247,11 +248,256 @@
     <Folder Include="Properties\" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+=======
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{0BFA7F0A-BC15-40A5-863A-FA9B55AE2FD3}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>NUnit</RootNamespace>
+    <AssemblyName>nunitlite</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\bin\Debug\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;NET_3_5;CLR_2_0;NUNITLITE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>..\..\..\bin\Debug\nunitlite.xml</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\bin\Release\</OutputPath>
+    <DefineConstants>TRACE;NET_3_5;CLR_2_0;NUNITLITE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>..\bin\Release\nunitlite.XML</DocumentationFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\CommonAssemblyInfo.cs">
+      <Link>CommonAssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="Api\IApplyToTest.cs" />
+    <Compile Include="Api\IPropertyBag.cs" />
+    <Compile Include="Api\ITest.cs" />
+    <Compile Include="Api\ITestCaseData.cs" />
+    <Compile Include="Api\ITestCaseSource.cs" />
+    <Compile Include="Api\ITestListener.cs" />
+    <Compile Include="Api\ITestResult.cs" />
+    <Compile Include="Api\IXmlNodeBuilder.cs" />
+    <Compile Include="Api\PropertyEntry.cs" />
+    <Compile Include="Api\PropertyNames.cs" />
+    <Compile Include="Api\ResultState.cs" />
+    <Compile Include="Api\RunState.cs" />
+    <Compile Include="Api\TestOutput.cs" />
+    <Compile Include="Api\TestStatus.cs" />
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="Assert.cs" />
+    <Compile Include="AssertionHelper.cs" />
+    <Compile Include="Attributes\CategoryAttribute.cs" />
+    <Compile Include="Attributes\DataAttribute.cs" />
+    <Compile Include="Attributes\DescriptionAttribute.cs" />
+    <Compile Include="Attributes\ExpectedExceptionAttribute.cs" />
+    <Compile Include="Attributes\IgnoreAttribute.cs" />
+    <Compile Include="Attributes\NUnitAttribute.cs" />
+    <Compile Include="Attributes\PropertyAttribute.cs" />
+    <Compile Include="Attributes\SetUpAttribute.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\TestModificationAttribute.cs" />
+    <Compile Include="Constraints\AllItemsConstraint.cs" />
+    <Compile Include="Constraints\AndConstraint.cs" />
+    <Compile Include="Constraints\AssignableFromConstraint.cs" />
+    <Compile Include="Constraints\AssignableToConstraint.cs" />
+    <Compile Include="Constraints\AttributeConstraint.cs" />
+    <Compile Include="Constraints\AttributeExistsConstraint.cs" />
+    <Compile Include="Constraints\BasicConstraint.cs" />
+    <Compile Include="Constraints\BinaryConstraint.cs" />
+    <Compile Include="Constraints\BinarySerializableConstraint.cs" />
+    <Compile Include="Constraints\CollectionConstraint.cs" />
+    <Compile Include="Constraints\CollectionContainsConstraint.cs" />
+    <Compile Include="Constraints\CollectionEquivalentConstraint.cs" />
+    <Compile Include="Constraints\CollectionItemsEqualConstraint.cs" />
+    <Compile Include="Constraints\CollectionOrderedConstraint.cs" />
+    <Compile Include="Constraints\CollectionSubsetConstraint.cs" />
+    <Compile Include="Constraints\CollectionTally.cs" />
+    <Compile Include="Constraints\ComparisonAdapter.cs" />
+    <Compile Include="Constraints\ComparisonConstraint.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\ContainsConstraint.cs" />
+    <Compile Include="Constraints\EmptyCollectionConstraint.cs" />
+    <Compile Include="Constraints\EmptyConstraint.cs" />
+    <Compile Include="Constraints\EmptyDirectoryConstraint.cs" />
+    <Compile Include="Constraints\EmptyStringConstraint.cs" />
+    <Compile Include="Constraints\EndsWithConstraint.cs" />
+    <Compile Include="Constraints\EqualConstraint.cs" />
+    <Compile Include="Constraints\EqualityAdapter.cs" />
+    <Compile Include="Constraints\ExactTypeConstraint.cs" />
+    <Compile Include="Constraints\FalseConstraint.cs" />
+    <Compile Include="Constraints\FloatingPointNumerics.cs" />
+    <Compile Include="Constraints\GreaterThanConstraint.cs" />
+    <Compile Include="Constraints\GreaterThanOrEqualConstraint.cs" />
+    <Compile Include="Constraints\IConstraintResult.cs" />
+    <Compile Include="Constraints\InstanceOfTypeConstraint.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\NaNConstraint.cs" />
+    <Compile Include="Constraints\NoItemConstraint.cs" />
+    <Compile Include="Constraints\NotConstraint.cs" />
+    <Compile Include="Constraints\NullConstraint.cs" />
+    <Compile Include="Constraints\NullOrEmptyStringConstraint.cs" />
+    <Compile Include="Constraints\Numerics.cs" />
+    <Compile Include="Constraints\NUnitComparer.cs" />
+    <Compile Include="Constraints\NUnitEqualityComparer.cs" />
+    <Compile Include="Constraints\Operators\AndOperator.cs" />
+    <Compile Include="Constraints\Operators\AttributeOperator.cs" />
+    <Compile Include="Constraints\Operators\BinaryOperator.cs" />
+    <Compile Include="Constraints\Operators\CollectionOperator.cs" />
+    <Compile Include="Constraints\Operators\ConstraintOperator.cs" />
+    <Compile Include="Constraints\Operators\NotOperator.cs" />
+    <Compile Include="Constraints\Operators\OrOperator.cs" />
+    <Compile Include="Constraints\Operators\PrefixOperator.cs" />
+    <Compile Include="Constraints\Operators\PropOperator.cs" />
+    <Compile Include="Constraints\Operators\SelfResolvingOperator.cs" />
+    <Compile Include="Constraints\Operators\ThrowsOperator.cs" />
+    <Compile Include="Constraints\Operators\WithOperator.cs" />
+    <Compile Include="Constraints\OrConstraint.cs" />
+    <Compile Include="Constraints\PathConstraint.cs" />
+    <Compile Include="Constraints\PrefixConstraint.cs" />
+    <Compile Include="Constraints\PropertyConstraint.cs" />
+    <Compile Include="Constraints\PropertyExistsConstraint.cs" />
+    <Compile Include="Constraints\RangeConstraint.cs" />
+    <Compile Include="Constraints\RegexConstraint.cs" />
+    <Compile Include="Constraints\ResolvableConstraintExpression.cs" />
+    <Compile Include="Constraints\SameAsConstraint.cs" />
+    <Compile Include="Constraints\SamePathConstraint.cs" />
+    <Compile Include="Constraints\SamePathOrUnderConstraint.cs" />
+    <Compile Include="Constraints\SomeItemsConstraint.cs" />
+    <Compile Include="Constraints\StandardConstraintResult.cs" />
+    <Compile Include="Constraints\StartsWithConstraint.cs" />
+    <Compile Include="Constraints\StringConstraint.cs" />
+    <Compile Include="Constraints\SubstringConstraint.cs" />
+    <Compile Include="Constraints\ThrowsConstraint.cs" />
+    <Compile Include="Constraints\ThrowsNothingConstraint.cs" />
+    <Compile Include="Constraints\Tolerance.cs" />
+    <Compile Include="Constraints\ToleranceMode.cs" />
+    <Compile Include="Constraints\TrueConstraint.cs" />
+    <Compile Include="Constraints\TypeConstraint.cs" />
+    <Compile Include="Constraints\UniqueItemsConstraint.cs" />
+    <Compile Include="Constraints\XmlSerializableConstraint.cs" />
+    <Compile Include="Contains.cs" />
+    <Compile Include="Env.cs" />
+    <Compile Include="Exceptions\AssertionException.cs" />
+    <Compile Include="Exceptions\IgnoreException.cs" />
+    <Compile Include="Exceptions\InconclusiveException.cs" />
+    <Compile Include="Exceptions\SuccessException.cs" />
+    <Compile Include="GlobalSettings.cs" />
+    <Compile Include="Has.cs" />
+    <Compile Include="IExpectException.cs" />
+    <Compile Include="Internal\Builders\NUnitLiteTestCaseBuilder.cs" />
+    <Compile Include="Internal\Builders\NUnitLiteTestFixtureBuilder.cs" />
+    <Compile Include="Internal\Commands\CommandBuilder.cs" />
+    <Compile Include="Internal\Commands\CommandRunner.cs" />
+    <Compile Include="Internal\Commands\DelegatingTestCommand.cs" />
+    <Compile Include="Internal\Commands\ExpectedExceptionCommand.cs" />
+    <Compile Include="Internal\Commands\ITestCommand.cs" />
+    <Compile Include="Internal\Commands\MaxTimeCommand.cs" />
+    <Compile Include="Internal\Commands\RepeatedTestCommand.cs" />
+    <Compile Include="Internal\Commands\SetUpTearDownCommand.cs" />
+    <Compile Include="Internal\Commands\SkipCommand.cs" />
+    <Compile Include="Internal\Commands\TestCaseCommand.cs" />
+    <Compile Include="Internal\Commands\TestCommand.cs" />
+    <Compile Include="Internal\Commands\TestExecutionContextCommand.cs" />
+    <Compile Include="Internal\Commands\TestGroupCommand.cs" />
+    <Compile Include="Internal\Commands\TestMethodCommand.cs" />
+    <Compile Include="Internal\Commands\TestSuiteCommand.cs" />
+    <Compile Include="Internal\ExceptionHelper.cs" />
+    <Compile Include="Internal\ExpectedExceptionProcessor.cs" />
+    <Compile Include="Internal\InvalidTestFixtureException.cs" />
+    <Compile Include="Internal\Log4NetCapture.cs" />
+    <Compile Include="Internal\LogCapture.cs" />
+    <Compile Include="Internal\MethodHelper.cs" />
+    <Compile Include="Internal\NUnitException.cs" />
+    <Compile Include="Internal\ParameterSet.cs" />
+    <Compile Include="Internal\PropertyBag.cs" />
+    <Compile Include="Internal\Reflect.cs" />
+    <Compile Include="Internal\Results\TestCaseResult.cs" />
+    <Compile Include="Internal\Results\TestResult.cs" />
+    <Compile Include="Internal\Results\TestSuiteResult.cs" />
+    <Compile Include="Internal\TestExecutionContext.cs" />
+    <Compile Include="Internal\TestListener.cs" />
+    <Compile Include="Internal\Tests\ParameterizedMethodSuite.cs" />
+    <Compile Include="Internal\Tests\Test.cs" />
+    <Compile Include="Internal\Tests\TestAssembly.cs" />
+    <Compile Include="Internal\Tests\TestFixture.cs" />
+    <Compile Include="Internal\Tests\TestMethod.cs" />
+    <Compile Include="Internal\Tests\TestSuite.cs" />
+    <Compile Include="Internal\TextCapture.cs" />
+    <Compile Include="Internal\TextMessageWriter.cs" />
+    <Compile Include="Internal\TypeHelper.cs" />
+    <Compile Include="Internal\XmlHelper.cs" />
+    <Compile Include="Is.cs" />
+    <Compile Include="ListMapper.cs" />
+    <Compile Include="MessageMatch.cs" />
+    <Compile Include="ObjectList.cs" />
+    <Compile Include="Runner\CommandLineOptions.cs" />
+    <Compile Include="Runner\ConsoleWriter.cs" />
+    <Compile Include="Runner\DebugWriter.cs" />
+    <Compile Include="Runner\ResultSummary.cs" />
+    <Compile Include="Runner\TcpWriter.cs" />
+    <Compile Include="Runner\TestLoader.cs" />
+    <Compile Include="Runner\TestRunner.cs" />
+    <Compile Include="Runner\TextUI.cs" />
+    <Compile Include="SpecialValue.cs" />
+    <Compile Include="TestCaseData.cs" />
+    <Compile Include="Throws.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="nunitlite.build" />
+    <None Include="nunit.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="SyntaxElements.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+>>>>>>> MERGE-SOURCE
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file

=== modified file 'src/NUnitFramework/tests/Constraints/AfterConstraintTests.cs'
--- src/NUnitFramework/tests/Constraints/AfterConstraintTests.cs	2009-12-27 21:21:21 +0000
+++ src/NUnitFramework/tests/Constraints/AfterConstraintTests.cs	2011-06-04 23:12:29 +0000
@@ -1,123 +1,123 @@
-// ***********************************************************************
-// Copyright (c) 2009 Charlie Poole
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-// 
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-// ***********************************************************************
-
-using System;
-using System.Threading;
-
-namespace NUnit.Framework.Constraints.Tests
-{
-    [TestFixture]
-	public class AfterConstraintTest : ConstraintTestBase
-	{
-		private static bool value;
-
-		[SetUp]
-		public void SetUp()
-		{
-			theConstraint = new DelayedConstraint(new EqualConstraint(true), 500);
-			expectedDescription = "True after 500 millisecond delay";
-			stringRepresentation = "<after 500 <equal True>>";
-
-            value = false;
-            //SetValueTrueAfterDelay(300);
-		}
-
-        object[] SuccessData = new object[] { true };
+// ***********************************************************************
+// Copyright (c) 2009 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Threading;
+
+namespace NUnit.Framework.Constraints.Tests
+{
+    [TestFixture]
+    public class AfterConstraintTest : ConstraintTestBase
+    {
+        private static bool value;
+
+        [SetUp]
+        public void SetUp()
+        {
+            theConstraint = new DelayedConstraint(new EqualConstraint(true), 500);
+            expectedDescription = "True after 500 millisecond delay";
+            stringRepresentation = "<after 500 <equal True>>";
+
+            value = false;
+            //SetValueTrueAfterDelay(300);
+        }
+
+        object[] SuccessData = new object[] { true };
         object[] FailureData = new object[] { 
             new TestCaseData( false, "False" ),
             new TestCaseData( 0, "0" ),
-            new TestCaseData( null, "null" ) };
-
-		object[] InvalidData = new object[] { InvalidDelegate };
-
-        ActualValueDelegate[] SuccessDelegates = new ActualValueDelegate[] { DelegateReturningValue };
-        ActualValueDelegate[] FailureDelegates = new ActualValueDelegate[] { DelegateReturningFalse, DelegateReturningZero };
-
-        [Test, TestCaseSource("SuccessDelegates")]
-        public void SucceedsWithGoodDelegates(ActualValueDelegate del)
-        {
-            SetValueTrueAfterDelay(300);
-            Assert.That(theConstraint.Matches(del));
-        }
-
-        [Test,TestCaseSource("FailureDelegates")]
-        public void FailsWithBadDelegates(ActualValueDelegate del)
-        {
-            Assert.IsFalse(theConstraint.Matches(del));
-        }
-
-        [Test]
-        public void SimpleTest()
-        {
-            SetValueTrueAfterDelay(500);
-            Assert.That(DelegateReturningValue, new DelayedConstraint(new EqualConstraint(true), 5000, 200));
-        }
-
-        [Test]
-        public void SimpleTestUsingReference()
-        {
-            SetValueTrueAfterDelay(500);
-            Assert.That(ref value, new DelayedConstraint(new EqualConstraint(true), 5000, 200));
-        }
-
-        [Test]
-        public void ThatOverload_ZeroDelayIsAllowed()
-        {
-            Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), 0));
-        }
-
-        [Test, ExpectedException(typeof(ArgumentException))]
-        public void ThatOverload_DoesNotAcceptNegativeDelayValues()
-        {
-            Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), -1));
-        }
-
-        private static int setValueTrueDelay;
-
-		private void SetValueTrueAfterDelay(int delay)
-		{
-            setValueTrueDelay = delay;
-            Thread thread = new Thread( SetValueTrueDelegate );
-            thread.Start();
-		}
-
-		private static void MethodReturningVoid() { }
-		private static TestDelegate InvalidDelegate = new TestDelegate(MethodReturningVoid);
-
-		private static object MethodReturningValue() { return value; }
-		private static ActualValueDelegate DelegateReturningValue = new ActualValueDelegate(MethodReturningValue);
-
-		private static object MethodReturningFalse() { return false; }
-		private static ActualValueDelegate DelegateReturningFalse = new ActualValueDelegate(MethodReturningFalse);
-
-		private static object MethodReturningZero() { return 0; }
-		private static ActualValueDelegate DelegateReturningZero = new ActualValueDelegate(MethodReturningZero);
-
-        private static void MethodSetsValueTrue()
-        {
-            Thread.Sleep(setValueTrueDelay);
-            value = true;
-        }
-		private ThreadStart SetValueTrueDelegate = new ThreadStart(MethodSetsValueTrue);
-	}
-}
+            new TestCaseData( null, "null" ) };
+
+        object[] InvalidData = new object[] { InvalidDelegate };
+
+        ActualValueDelegate[] SuccessDelegates = new ActualValueDelegate[] { DelegateReturningValue };
+        ActualValueDelegate[] FailureDelegates = new ActualValueDelegate[] { DelegateReturningFalse, DelegateReturningZero };
+
+        [Test, TestCaseSource("SuccessDelegates")]
+        public void SucceedsWithGoodDelegates(ActualValueDelegate del)
+        {
+            SetValueTrueAfterDelay(300);
+            Assert.That(theConstraint.Matches(del).HasSucceeded);
+        }
+
+        [Test, TestCaseSource("FailureDelegates")]
+        public void FailsWithBadDelegates(ActualValueDelegate del)
+        {
+            Assert.IsFalse(theConstraint.Matches(del).HasSucceeded);
+        }
+
+        [Test]
+        public void SimpleTest()
+        {
+            SetValueTrueAfterDelay(500);
+            Assert.That(DelegateReturningValue, new DelayedConstraint(new EqualConstraint(true), 5000, 200));
+        }
+
+        [Test]
+        public void SimpleTestUsingReference()
+        {
+            SetValueTrueAfterDelay(500);
+            Assert.That(ref value, new DelayedConstraint(new EqualConstraint(true), 5000, 200));
+        }
+
+        [Test]
+        public void ThatOverload_ZeroDelayIsAllowed()
+        {
+            Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), 0));
+        }
+
+        [Test, ExpectedException(typeof(ArgumentException))]
+        public void ThatOverload_DoesNotAcceptNegativeDelayValues()
+        {
+            Assert.That(DelegateReturningZero, new DelayedConstraint(new EqualConstraint(0), -1));
+        }
+
+        private static int setValueTrueDelay;
+
+        private void SetValueTrueAfterDelay(int delay)
+        {
+            setValueTrueDelay = delay;
+            Thread thread = new Thread(SetValueTrueDelegate);
+            thread.Start();
+        }
+
+        private static void MethodReturningVoid() { }
+        private static TestDelegate InvalidDelegate = new TestDelegate(MethodReturningVoid);
+
+        private static object MethodReturningValue() { return value; }
+        private static ActualValueDelegate DelegateReturningValue = new ActualValueDelegate(MethodReturningValue);
+
+        private static object MethodReturningFalse() { return false; }
+        private static ActualValueDelegate DelegateReturningFalse = new ActualValueDelegate(MethodReturningFalse);
+
+        private static object MethodReturningZero() { return 0; }
+        private static ActualValueDelegate DelegateReturningZero = new ActualValueDelegate(MethodReturningZero);
+
+        private static void MethodSetsValueTrue()
+        {
+            Thread.Sleep(setValueTrueDelay);
+            value = true;
+        }
+        private ThreadStart SetValueTrueDelegate = new ThreadStart(MethodSetsValueTrue);
+    }
+}
\ No newline at end of file

=== modified file 'src/NUnitFramework/tests/Constraints/CollectionConstraintTests.cs'
--- src/NUnitFramework/tests/Constraints/CollectionConstraintTests.cs	2011-05-31 17:48:23 +0000
+++ src/NUnitFramework/tests/Constraints/CollectionConstraintTests.cs	2011-06-04 23:12:29 +0000
@@ -1,3 +1,4 @@
+<<<<<<< TREE
 // ***********************************************************************
 // Copyright (c) 2007 Charlie Poole
 //
@@ -516,3 +517,521 @@
 
     #endregion
 }
+=======
+// ***********************************************************************
+// Copyright (c) 2007 Charlie Poole
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+// ***********************************************************************
+
+using System;
+using System.Collections;
+#if CLR_2_0 || CLR_4_0
+using System.Collections.Generic;
+#endif
+using NUnit.Framework.Internal;
+
+namespace NUnit.Framework.Constraints.Tests
+{
+    #region AllItems
+    [TestFixture]
+    public class AllItemsTests : NUnit.Framework.Assertions.MessageChecker
+    {
+        [Test]
+        public void AllItemsAreNotNull()
+        {
+            object[] c = new object[] { 1, "hello", 3, Environment.OSVersion };
+            Assert.That(c, new AllItemsConstraint(Is.Not.Null));
+        }
+
+        [Test, ExpectedException(typeof(AssertionException))]
+        public void AllItemsAreNotNullFails()
+        {
+            object[] c = new object[] { 1, "hello", null, 3 };
+            expectedMessage =
+                TextMessageWriter.Pfx_Expected + "all items not null" + NL +
+                TextMessageWriter.Pfx_Actual + "< 1, \"hello\", null, 3 >" + NL;
+            Assert.That(c, new AllItemsConstraint(new NotConstraint(new EqualConstraint(null))));
+        }
+
+        [Test]
+        public void AllItemsAreInRange()
+        {
+            int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 };
+            Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100)));
+        }
+
+        [Test]
+        public void AllItemsAreInRange_UsingIComparer()
+        {
+            int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 };
+            Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default)));
+        }
+
+#if CLR_2_0 || CLR_4_0
+        [Test]
+        public void AllItemsAreInRange_UsingIComparerOfT()
+        {
+            int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 };
+            Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default)));
+        }
+
+        [Test]
+        public void AllItemsAreInRange_UsingComparisonOfT()
+        {
+            int[] c = new int[] { 12, 27, 19, 32, 45, 99, 26 };
+            Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100).Using(Comparer.Default)));
+        }
+#endif
+
+        [Test, ExpectedException(typeof(AssertionException))]
+        public void AllItemsAreInRangeFailureMessage()
+        {
+            int[] c = new int[] { 12, 27, 19, 32, 107, 99, 26 };
+            expectedMessage =
+                TextMessageWriter.Pfx_Expected + "all items in range (10,100)" + NL +
+                TextMessageWriter.Pfx_Actual + "< 12, 27, 19, 32, 107, 99, 26 >" + NL;
+            Assert.That(c, new AllItemsConstraint(new RangeConstraint(10, 100)));
+        }
+
+        [Test]
+        public void AllItemsAreInstancesOfType()
+        {
+            object[] c = new object[] { 'a', 'b', 'c' };
+            Assert.That(c, new AllItemsConstraint(new InstanceOfTypeConstraint(typeof(char))));
+        }
+
+        [Test, ExpectedException(typeof(AssertionException))]
+        public void AllItemsAreInstancesOfTypeFailureMessage()
+        {
+            object[] c = new object[] { 'a', "b", 'c' };
+            expectedMessage =
+                TextMessageWriter.Pfx_Expected + "all items instance of <System.Char>" + NL +
+                TextMessageWriter.Pfx_Actual + "< 'a', \"b\", 'c' >" + NL;
+            Assert.That(c, new AllItemsConstraint(new InstanceOfTypeConstraint(typeof(char))));
+        }
+    }
+    #endregion
+
+    #region CollectionContains
+    [TestFixture]
+    public class CollectionContainsTests
+    {
+        [Test]
+        public void CanTestContentsOfArray()
+        {
+            object item = "xyz";
+            object[] c = new object[] { 123, item, "abc" };
+            Assert.That(c, new CollectionContainsConstraint(item));
+        }
+
+        [Test]
+        public void CanTestContentsOfArrayList()
+        {
+            object item = "xyz";
+            ArrayList list = new ArrayList(new object[] { 123, item, "abc" });
+            Assert.That(list, new CollectionContainsConstraint(item));
+        }
+
+#if !NETCF_1_0
+        [Test]
+        public void CanTestContentsOfSortedList()
+        {
+            object item = "xyz";
+            SortedList list = new SortedList();
+            list.Add("a", 123);
+            list.Add("b", item);
+            list.Add("c", "abc");
+            Assert.That(list.Values, new CollectionContainsConstraint(item));
+            Assert.That(list.Keys, new CollectionContainsConstraint("b"));
+        }
+#endif
+
+        [Test]
+        public void CanTestContentsOfCollectionNotImplementingIList()
+        {
+            ICollectionAdapter ints = new ICollectionAdapter(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+            Assert.That(ints, new CollectionContainsConstraint(9));
+        }
+
+        [Test]
+        public void IgnoreCaseIsHonored()
+        {
+            Assert.That(new string[] { "Hello", "World" },
+                new CollectionContainsConstraint("WORLD").IgnoreCase);
+        }
+
+#if CS_3_0 || CS_4_0
+        [Test]
+        public void UsingIsHonored()
+        {
+            Assert.That(new string[] { "Hello", "World" },
+                new CollectionContainsConstraint("WORLD").Using<string>((x, y) => String.Compare(x, y, true)));
+        }
+#endif
+    }
+    #endregion
+
+    #region CollectionEquivalent
+    public class CollectionEquivalentTests
+    {
+        [Test]
+        public void EqualCollectionsAreEquivalent()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "z");
+            ICollection set2 = new ICollectionAdapter("x", "y", "z");
+
+            Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void WorksWithCollectionsOfArrays()
+        {
+            byte[] array1 = new byte[] { 0x20, 0x44, 0x56, 0x76, 0x1e, 0xff };
+            byte[] array2 = new byte[] { 0x42, 0x52, 0x72, 0xef };
+            byte[] array3 = new byte[] { 0x20, 0x44, 0x56, 0x76, 0x1e, 0xff };
+            byte[] array4 = new byte[] { 0x42, 0x52, 0x72, 0xef };
+
+            ICollection set1 = new ICollectionAdapter(array1, array2);
+            ICollection set2 = new ICollectionAdapter(array3, array4);
+
+            Constraint constraint = new CollectionEquivalentConstraint(set1);
+            Assert.That(constraint.Matches(set2).HasSucceeded);
+
+            set2 = new ICollectionAdapter(array4, array3);
+            Assert.That(constraint.Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void EquivalentIgnoresOrder()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "z");
+            ICollection set2 = new ICollectionAdapter("z", "y", "x");
+
+            Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void EquivalentFailsWithDuplicateElementInActual()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "z");
+            ICollection set2 = new ICollectionAdapter("x", "y", "x");
+
+            Assert.False(new CollectionEquivalentConstraint(set1).Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void EquivalentFailsWithDuplicateElementInExpected()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "x");
+            ICollection set2 = new ICollectionAdapter("x", "y", "z");
+
+            Assert.False(new CollectionEquivalentConstraint(set1).Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void EquivalentHandlesNull()
+        {
+            ICollection set1 = new ICollectionAdapter(null, "x", null, "z");
+            ICollection set2 = new ICollectionAdapter("z", null, "x", null);
+
+            Assert.That(new CollectionEquivalentConstraint(set1).Matches(set2).HasSucceeded);
+        }
+
+        [Test]
+        public void EquivalentHonorsIgnoreCase()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "z");
+            ICollection set2 = new ICollectionAdapter("z", "Y", "X");
+
+            Assert.That(new CollectionEquivalentConstraint(set1).IgnoreCase.Matches(set2).HasSucceeded);
+        }
+
+#if CS_3_0 || CS_4_0
+        [Test]
+        public void EquivalentHonorsUsing()
+        {
+            ICollection set1 = new ICollectionAdapter("x", "y", "z");
+            ICollection set2 = new ICollectionAdapter("z", "Y", "X");
+
+            Assert.That(new CollectionEquivalentConstraint(set1)
+                .Using<string>((x, y) => String.Compare(x, y, true))
+                .Matches(set2).HasSucceeded);
+        }
+#endif
+    }
+    #endregion
+
+    #region CollectionOrdered
+
+    [TestFixture]
+    public class CollectionOrderedTests : NUnit.Framework.Assertions.MessageChecker
+    {
+        [Test]
+        public void IsOrdered()
+        {
+            ArrayList al = new ArrayList();
+            al.Add("x");
+            al.Add("y");
+            al.Add("z");
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test]
+        public void IsOrdered_2()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(1);
+            al.Add(2);
+            al.Add(3);
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test]
+        public void IsOrderedDescending()
+        {
+            ArrayList al = new ArrayList();
+            al.Add("z");
+            al.Add("y");
+            al.Add("x");
+
+            Assert.That(al, Is.Ordered.Descending);
+        }
+
+        [Test]
+        public void IsOrderedDescending_2()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(3);
+            al.Add(2);
+            al.Add(1);
+
+            Assert.That(al, Is.Ordered.Descending);
+        }
+
+        [Test, ExpectedException(typeof(AssertionException))]
+        public void IsOrdered_Fails()
+        {
+            ArrayList al = new ArrayList();
+            al.Add("x");
+            al.Add("z");
+            al.Add("y");
+
+            expectedMessage =
+                "  Expected: collection ordered" + NL +
+                "  But was:  < \"x\", \"z\", \"y\" >" + NL;
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test]
+        public void IsOrdered_Allows_adjacent_equal_values()
+        {
+            ArrayList al = new ArrayList();
+            al.Add("x");
+            al.Add("x");
+            al.Add("z");
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test, ExpectedException(typeof(ArgumentNullException),
+            ExpectedMessage = "index 1", MatchType = MessageMatch.Contains)]
+        public void IsOrdered_Handles_null()
+        {
+            ArrayList al = new ArrayList();
+            al.Add("x");
+            al.Add(null);
+            al.Add("z");
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test, ExpectedException(typeof(ArgumentException))]
+        public void IsOrdered_TypesMustBeComparable()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(1);
+            al.Add("x");
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test, ExpectedException(typeof(ArgumentException))]
+        public void IsOrdered_AtLeastOneArgMustImplementIComparable()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(new object());
+            al.Add(new object());
+
+            Assert.That(al, Is.Ordered);
+        }
+
+        [Test]
+        public void IsOrdered_Handles_custom_comparison()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(new object());
+            al.Add(new object());
+
+            AlwaysEqualComparer comparer = new AlwaysEqualComparer();
+            Assert.That(al, Is.Ordered.Using(comparer));
+            Assert.That(comparer.Called, "TestComparer was not called");
+        }
+
+        [Test]
+        public void IsOrdered_Handles_custom_comparison2()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(2);
+            al.Add(1);
+
+            TestComparer comparer = new TestComparer();
+            Assert.That(al, Is.Ordered.Using(comparer));
+            Assert.That(comparer.Called, "TestComparer was not called");
+        }
+
+#if CLR_2_0 || CLR_4_0
+        [Test]
+        public void UsesProvidedComparerOfT()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(1);
+            al.Add(2);
+
+            MyComparer<int> comparer = new MyComparer<int>();
+            Assert.That(al, Is.Ordered.Using(comparer));
+            Assert.That(comparer.Called, "Comparer was not called");
+        }
+
+        class MyComparer<T> : IComparer<T>
+        {
+            public bool Called;
+
+            public int Compare(T x, T y)
+            {
+                Called = true;
+                return Comparer<T>.Default.Compare(x, y);
+            }
+        }
+
+        [Test]
+        public void UsesProvidedComparisonOfT()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(1);
+            al.Add(2);
+
+            MyComparison<int> comparer = new MyComparison<int>();
+            Assert.That(al, Is.Ordered.Using(new Comparison<int>(comparer.Compare)));
+            Assert.That(comparer.Called, "Comparer was not called");
+        }
+
+        class MyComparison<T>
+        {
+            public bool Called;
+
+            public int Compare(T x, T y)
+            {
+                Called = true;
+                return Comparer<T>.Default.Compare(x, y);
+            }
+        }
+
+#if CS_3_0 || CS_4_0
+        [Test]
+        public void UsesProvidedLambda()
+        {
+            ArrayList al = new ArrayList();
+            al.Add(1);
+            al.Add(2);
+
+            Comparison<int> comparer = (x, y) => x.CompareTo(y);
+            Assert.That(al, Is.Ordered.Using(comparer));
+        }
+#endif
+#endif
+
+        [Test]
+        public void IsOrderedBy()
+        {
+            ArrayL