Index: Rhino.Mocks.Tests/BeforeExtensionMethodTest.cs
===================================================================
--- Rhino.Mocks.Tests/BeforeExtensionMethodTest.cs	(revision 0)
+++ Rhino.Mocks.Tests/BeforeExtensionMethodTest.cs	(revision 0)
@@ -0,0 +1,47 @@
+﻿#if DOTNET35
+using MbUnit.Framework;
+using Rhino.Mocks.Exceptions;
+
+namespace Rhino.Mocks.Tests
+{
+    [TestFixture] public class BeforeExtensionMethodTest
+    {
+        public interface IBefore
+        {
+            void MethodBefore();
+        }
+
+        public interface IAfter
+        {
+            void MethodAfter();
+        }
+
+        [Test] public void Before_succeeds_if_beforeCalls_occured_before_afterCalls()
+        {
+            var mockBefore = MockRepository.GenerateStub<IBefore>();
+            var mockAfter = MockRepository.GenerateStub<IAfter>();
+            mockBefore.MethodBefore();
+            mockBefore.MethodBefore();
+            mockAfter.MethodAfter();
+            mockAfter.MethodAfter();
+            mockAfter.MethodAfter();
+            mockBefore.AssertWasCalled(b => b.MethodBefore())
+                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
+        }
+
+        [ExpectedException(typeof(ExpectationViolationException))]
+        [Test] public void Before_chokes_if_one_of_beforeCalls_occured_after_any_of_afterCalls()
+        {
+            var mockBefore = MockRepository.GenerateStub<IBefore>();
+            var mockAfter = MockRepository.GenerateStub<IAfter>();
+            mockBefore.MethodBefore();
+            mockAfter.MethodAfter();
+            mockBefore.MethodBefore();
+            mockAfter.MethodAfter();
+            mockAfter.MethodAfter();
+            mockBefore.AssertWasCalled(b => b.MethodBefore())
+                .Before(mockAfter.AssertWasCalled(a => a.MethodAfter()));
+        }
+    }
+}
+#endif
Index: Rhino.Mocks.Tests/Rhino.Mocks.Tests 3.5.csproj
===================================================================
--- Rhino.Mocks.Tests/Rhino.Mocks.Tests 3.5.csproj	(revision 2212)
+++ Rhino.Mocks.Tests/Rhino.Mocks.Tests 3.5.csproj	(working copy)
@@ -117,6 +117,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="BackToRecord.cs" />
+    <Compile Include="BeforeExtensionMethodTest.cs" />
     <Compile Include="Callbacks\CallbackTests.cs">
       <SubType>Code</SubType>
     </Compile>
Index: Rhino.Mocks/CallRecord.cs
===================================================================
--- Rhino.Mocks/CallRecord.cs	(revision 0)
+++ Rhino.Mocks/CallRecord.cs	(revision 0)
@@ -0,0 +1,23 @@
+using System.Reflection;
+using System.Threading;
+using Rhino.Mocks.Interfaces;
+
+namespace Rhino.Mocks
+{
+    /// <summary>
+    /// Record about information of a specific method invokation
+    /// </summary>
+    public class CallRecord
+    {
+        private static long sequencer = long.MinValue;
+
+        internal CallRecord()
+        {
+            Sequence = Interlocked.Increment(ref sequencer);
+        }
+        internal object[] Arguments { get; set; }
+        internal long Sequence { get; private set; }
+        internal MethodInfo Method { get; set; }
+        internal IMockedObject MockObject { get; set; }
+    }
+}
\ No newline at end of file
Index: Rhino.Mocks/ExpectationVerificationInformation.cs
===================================================================
--- Rhino.Mocks/ExpectationVerificationInformation.cs	(revision 2212)
+++ Rhino.Mocks/ExpectationVerificationInformation.cs	(working copy)
@@ -10,6 +10,23 @@
 		private IList<object[]> argumentsForAllCalls;
 		
 		public IExpectation Expected { get { return expected; } set { expected = value; } }
-		public IList<object[]> ArgumentsForAllCalls { get { return argumentsForAllCalls; } set { argumentsForAllCalls = value; }  }
+        public ICollection<CallRecord> AllCallRecords { get; set; }
+        public IList<object[]> ArgumentsForAllCalls
+	    {
+	        get
+	        {
+                if (argumentsForAllCalls==null)
+                {
+                    var allCalls = AllCallRecords;
+                    var a = new List<object[]>(allCalls.Count);
+                    foreach (var call in allCalls)
+                    {
+                        a.Add(call.Arguments);
+                    }
+                    argumentsForAllCalls = a;
+                }
+	            return argumentsForAllCalls;
+	        }
+	    }
 	}
 }
Index: Rhino.Mocks/Impl/ProxyInstance.cs
===================================================================
--- Rhino.Mocks/Impl/ProxyInstance.cs	(revision 2212)
+++ Rhino.Mocks/Impl/ProxyInstance.cs	(working copy)
@@ -51,7 +51,7 @@
 		private IDictionary eventsSubscribers;
 		private readonly Type[] implemented;
 
-	    private readonly IDictionary<MethodInfo, ICollection<object[]>> methodToActualCalls = new Dictionary<MethodInfo, ICollection<object[]>>();
+	    private readonly IDictionary<MethodInfo, ICollection<CallRecord>> methodToActualCalls = new Dictionary<MethodInfo, ICollection<CallRecord>>();
 	    private object[] constructorArguments = new object[0];
 	    private IList<IMockedObject> dependentMocks = new List<IMockedObject>();
 
@@ -284,10 +284,10 @@
 		/// <remarks>
 		/// Only method calls in replay mode are counted
 		/// </remarks>
-	    public ICollection<object[]> GetCallArgumentsFor(MethodInfo method)
+	    public ICollection<CallRecord> GetCallArgumentsFor(MethodInfo method)
 	    {
             if (methodToActualCalls.ContainsKey(method) == false)
-                return new List<object[]>();
+                return new List<CallRecord>();
 	        return methodToActualCalls[method];
 	    }
 
@@ -302,8 +302,12 @@
 	        if(repository.IsInReplayMode(this)==false)
 	            return;
             if (methodToActualCalls.ContainsKey(method) == false)
-                methodToActualCalls[method] = new List<object[]>();
-	        methodToActualCalls[method].Add(args);
+                methodToActualCalls[method] = new List<CallRecord>();
+	        methodToActualCalls[method].Add(new CallRecord{
+                Arguments = args,
+                Method = method,
+                MockObject = this,
+            });
         }
 
 	    /// <summary>
Index: Rhino.Mocks/Interfaces/IMockedObject.cs
===================================================================
--- Rhino.Mocks/Interfaces/IMockedObject.cs	(revision 2212)
+++ Rhino.Mocks/Interfaces/IMockedObject.cs	(working copy)
@@ -128,7 +128,7 @@
         /// <remarks>
         /// Only method calls in replay mode are counted
         /// </remarks>
-	    ICollection<object[]> GetCallArgumentsFor(MethodInfo method);
+        ICollection<CallRecord> GetCallArgumentsFor(MethodInfo method);
 
         /// <summary>
         /// Records the method call
Index: Rhino.Mocks/Rhino.Mocks 3.5.csproj
===================================================================
--- Rhino.Mocks/Rhino.Mocks 3.5.csproj	(revision 2212)
+++ Rhino.Mocks/Rhino.Mocks 3.5.csproj	(working copy)
@@ -52,7 +52,7 @@
     <Optimize>true</Optimize>
     <RegisterForComInterop>false</RegisterForComInterop>
     <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <WarningLevel>4</WarningLevel>
     <DebugType>pdbonly</DebugType>
     <DocumentationFile>Rhino.Mocks.XML</DocumentationFile>
@@ -77,6 +77,7 @@
     <Compile Include="Arg.cs" />
     <Compile Include="ArgManager.cs" />
     <Compile Include="BackToRecordOptions.cs" />
+    <Compile Include="CallRecord.cs" />
     <Compile Include="Constraints\AbstractConstraint.cs">
       <SubType>Code</SubType>
     </Compile>
Index: Rhino.Mocks/RhinoMocksExtensions.cs
===================================================================
--- Rhino.Mocks/RhinoMocksExtensions.cs	(revision 2212)
+++ Rhino.Mocks/RhinoMocksExtensions.cs	(working copy)
@@ -213,9 +213,9 @@
 		/// <typeparam name="T"></typeparam>
 		/// <param name="mock">The mock.</param>
 		/// <param name="action">The action.</param>
-		public static void AssertWasCalled<T>(this T mock, Action<T> action)
+        public static IList<CallRecord> AssertWasCalled<T>(this T mock, Action<T> action)
 		{
-			AssertWasCalled(mock, action, DefaultConstraintSetup);
+			return AssertWasCalled(mock, action, DefaultConstraintSetup);
 		}
 
 		private static void DefaultConstraintSetup(IMethodOptions<object> options)
@@ -230,19 +230,20 @@
 		/// <param name="mock">The mock.</param>
 		/// <param name="action">The action.</param>
 		/// <param name="setupConstraints">The setup constraints.</param>
-		public static void AssertWasCalled<T>(this T mock, Action<T> action, Action<IMethodOptions<object>> setupConstraints)
+        public static IList<CallRecord> AssertWasCalled<T>(this T mock, Action<T> action, Action<IMethodOptions<object>> setupConstraints)
 		{
 			ExpectationVerificationInformation verificationInformation = GetExpectationsToVerify(mock, action, setupConstraints);
-
-			foreach (var args in verificationInformation.ArgumentsForAllCalls)
+            List<CallRecord> records = new List<CallRecord>();
+			foreach (var record in verificationInformation.AllCallRecords)
 			{
-				if (verificationInformation.Expected.IsExpected(args))
+				if (verificationInformation.Expected.IsExpected(record.Arguments))
 				{
 					verificationInformation.Expected.AddActualCall();
+                    records.Add(record);
 				}
 			}
 			if (verificationInformation.Expected.ExpectationSatisfied)
-				return;
+				return records;
 			throw new ExpectationViolationException(verificationInformation.Expected.BuildVerificationFailureMessage());
         }
 
@@ -253,10 +254,10 @@
         /// <typeparam name="T"></typeparam>
         /// <param name="mock">The mock.</param>
         /// <param name="action">The action.</param>
-        public static void AssertWasCalled<T>(this T mock, Func<T, object> action)
+        public static IList<CallRecord> AssertWasCalled<T>(this T mock, Func<T, object> action)
         {
             var newAction = new Action<T>(t => action(t));
-            AssertWasCalled(mock, newAction, DefaultConstraintSetup);
+            return AssertWasCalled(mock, newAction, DefaultConstraintSetup);
         }
 
         /// <summary>
@@ -267,10 +268,10 @@
         /// <param name="mock">The mock.</param>
         /// <param name="action">The action.</param>
         /// <param name="setupConstraints">The setup constraints.</param>
-        public static void AssertWasCalled<T>(this T mock, Func<T, object> action, Action<IMethodOptions<object>> setupConstraints)
+        public static IList<CallRecord> AssertWasCalled<T>(this T mock, Func<T, object> action, Action<IMethodOptions<object>> setupConstraints)
         {
             var newAction = new Action<T>(t => action(t));
-            AssertWasCalled(mock, newAction, setupConstraints);
+            return AssertWasCalled(mock, newAction, setupConstraints);
         }
 
 
@@ -361,10 +362,10 @@
 				throw new InvalidOperationException(
 					"The expectation was removed from the waiting expectations list, did you call Repeat.Any() ? This is not supported in AssertWasCalled()");
 			IExpectation expected = expectationsToVerify[0];
-			ICollection<object[]> argumentsForAllCalls = mockedObject.GetCallArgumentsFor(expected.Method);
+			ICollection<CallRecord> argumentsForAllCalls = mockedObject.GetCallArgumentsFor(expected.Method);
 			return new ExpectationVerificationInformation
 					{
-						ArgumentsForAllCalls = new List<object[]>(argumentsForAllCalls),
+						AllCallRecords = new List<CallRecord>(argumentsForAllCalls),
 						Expected = expected
 					};
         }
@@ -449,6 +450,51 @@
 			eventRaiser.Raise(args);
 		}
 
+        /// <summary>
+        /// Assert that all calls specified by <paramref name="beforeCalls"/> 
+        /// happened before all calls specified by <paramref name="afterCalls"/>
+        /// </summary>
+        /// <param name="beforeCalls">
+        /// Calls that happens before <paramref name="afterCalls"/>
+        /// </param>
+        /// <param name="afterCalls">
+        /// Calls that happens after <paramref name="beforeCalls"/>
+        /// </param>
+        public static void Before(this IList<CallRecord> beforeCalls, IList<CallRecord> afterCalls)
+        {
+            long maxBefore = long.MinValue;
+            CallRecord latestBeforeCall = null;
+            foreach (var call in beforeCalls)
+            {
+                var sequence = call.Sequence;
+                if (sequence > maxBefore)
+                {
+                    maxBefore = sequence;
+                    latestBeforeCall = call;
+                }
+            }
+
+            long minAfter = long.MaxValue;
+            CallRecord earliestAfterCall = null;
+            foreach (var call in afterCalls)
+            {
+                var sequence = call.Sequence;
+                if (sequence < minAfter)
+                {
+                    minAfter = sequence;
+                    earliestAfterCall = call;
+                }
+            }
+            if (maxBefore>minAfter)
+            {
+                throw new ExpectationViolationException(
+                    "Expected that calls to " + latestBeforeCall.Method + 
+                    " occurs before " + earliestAfterCall.Method + 
+                    ", but the expectation is not satisfied.");
+
+            }
+        }
+
 		private static void AssertExactlySingleExpectaton<T>(MockRepository mocks, T mockToRecordExpectation)
 		{
 			if (mocks.Replayer.GetAllExpectationsForProxy(mockToRecordExpectation).Count == 0)
