make Or() support MatchMayChangeInTheFuture()
- simplify tests by using empty And() or Or() instead of Receive() with a closed channel
diff --git a/matchers.go b/matchers.go
index 4bdc588..b6110c4 100644
--- a/matchers.go
+++ b/matchers.go
@@ -354,7 +354,7 @@
 }
 
 //SatisfyAll is an alias for And().
-//  Ω(foo).Should(SatisfyAll(ContainElement("bar"), HaveLen(3)))
+//  Ω("hi").Should(SatisfyAll(HaveLen(2), Equal("hi")))
 func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher {
 	return And(matchers...)
 }
@@ -369,7 +369,7 @@
 }
 
 //SatisfyAny is an alias for Or().
-//  Expect(foo).To(SatisfyAny(ContainElement("bar"), HaveLen(3)))
+//  Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2))
 func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher {
 	return Or(matchers...)
 }
diff --git a/matchers/and.go b/matchers/and.go
index 9acf470..5257b76 100644
--- a/matchers/and.go
+++ b/matchers/and.go
@@ -45,7 +45,7 @@
 
 		Match eval: T, T, T  => T
 		So match is currently T, what should MatchMayChangeInTheFuture() return?
-		Answer: Seems to depend on ANY of them being able to change to F.
+		Seems to depend on ANY of them being able to change to F.
 	*/
 
 	if m.firstFailedMatcher == nil {
diff --git a/matchers/and_test.go b/matchers/and_test.go
index 5e281ca..acf778c 100644
--- a/matchers/and_test.go
+++ b/matchers/and_test.go
@@ -64,23 +64,19 @@
 	})
 
 	Context("MatchMayChangeInTheFuture", func() {
-		// setup a closed channel
-		closedChannel := make(chan int)
-		close(closedChannel)
-		var i int
 		Context("Match returned false", func() {
 			Context("returns value of the failed matcher", func() {
 				It("false if failed matcher not going to change", func() {
 					// 3 matchers: 1st returns true, 2nd returns false and is not going to change, 3rd is never called
-					m := And(Not(BeNil()), Receive(&i), Equal(1))
-					Expect(m.Match(closedChannel)).To(BeFalse())
-					Expect(m.(*AndMatcher).MatchMayChangeInTheFuture(closedChannel)).To(BeFalse()) // closed channel, so not going to change
+					m := And(Not(BeNil()), Or(), Equal(1))
+					Expect(m.Match("hi")).To(BeFalse())
+					Expect(m.(*AndMatcher).MatchMayChangeInTheFuture("hi")).To(BeFalse()) // empty Or() indicates not going to change
 				})
 				It("true if failed matcher indicates it might change", func() {
 					// 3 matchers: 1st returns true, 2nd returns false and "might" change, 3rd is never called
 					m := And(Not(BeNil()), Equal(5), Equal(1))
-					Expect(m.Match(closedChannel)).To(BeFalse())
-					Expect(m.(*AndMatcher).MatchMayChangeInTheFuture(closedChannel)).To(BeTrue()) // Equal(5) indicates it might change
+					Expect(m.Match("hi")).To(BeFalse())
+					Expect(m.(*AndMatcher).MatchMayChangeInTheFuture("hi")).To(BeTrue()) // Equal(5) indicates it might change
 				})
 			})
 		})
diff --git a/matchers/not.go b/matchers/not.go
index 0cacc94..6aed858 100644
--- a/matchers/not.go
+++ b/matchers/not.go
@@ -1,8 +1,8 @@
 package matchers
 
 import (
-	"github.com/onsi/gomega/types"
 	"github.com/onsi/gomega/internal/asyncassertion"
+	"github.com/onsi/gomega/types"
 )
 
 type NotMatcher struct {
diff --git a/matchers/not_test.go b/matchers/not_test.go
index e745651..b3c1fdb 100644
--- a/matchers/not_test.go
+++ b/matchers/not_test.go
@@ -43,14 +43,10 @@
 	})
 
 	Context("MatchMayChangeInTheFuture()", func() {
-		It("Propogates value from wrapped matcher", func() {
-			// wrap a Receive matcher, which does implement this method
-			channel := make(chan int)
-			close(channel)
-			var i int
-			m := Not(Receive(&i))
-			Expect(m.Match(channel)).To(BeTrue())
-			Expect(m.(*NotMatcher).MatchMayChangeInTheFuture(channel)).To(BeFalse())
+		It("Propagates value from wrapped matcher", func() {
+			m := Not(Or()) // an empty Or() always returns false, and indicates it cannot change
+			Expect(m.Match("anything")).To(BeTrue())
+			Expect(m.(*NotMatcher).MatchMayChangeInTheFuture("anything")).To(BeFalse())
 		})
 		It("Defaults to true", func() {
 			m := Not(Equal(1)) // Equal does not have this method
diff --git a/matchers/or.go b/matchers/or.go
index 228fce6..29ad5c6 100644
--- a/matchers/or.go
+++ b/matchers/or.go
@@ -3,6 +3,7 @@
 import (
 	"fmt"
 	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/internal/asyncassertion"
 	"github.com/onsi/gomega/types"
 )
 
@@ -10,17 +11,18 @@
 	Matchers []types.GomegaMatcher
 
 	// state
-	successfulMatcher types.GomegaMatcher
+	firstSuccessfulMatcher types.GomegaMatcher
 }
 
 func (m *OrMatcher) Match(actual interface{}) (success bool, err error) {
+	m.firstSuccessfulMatcher = nil
 	for _, matcher := range m.Matchers {
 		success, err := matcher.Match(actual)
 		if err != nil {
 			return false, err
 		}
 		if success {
-			m.successfulMatcher = matcher
+			m.firstSuccessfulMatcher = matcher
 			return true, nil
 		}
 	}
@@ -33,5 +35,32 @@
 }
 
 func (m *OrMatcher) NegatedFailureMessage(actual interface{}) (message string) {
-	return m.successfulMatcher.NegatedFailureMessage(actual)
+	return m.firstSuccessfulMatcher.NegatedFailureMessage(actual)
+}
+
+func (m *OrMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	/*
+		Example with 3 matchers: A, B, C
+
+		Match evaluates them: F, T, <?>  => T
+		So match is currently T, what should MatchMayChangeInTheFuture() return?
+		Seems like it only depends on B, since currently B MUST change to allow the result to become F
+
+		Match eval: F, F, F  => F
+		So match is currently F, what should MatchMayChangeInTheFuture() return?
+		Seems to depend on ANY of them being able to change to T.
+	*/
+
+	if m.firstSuccessfulMatcher != nil {
+		// one of the matchers succeeded.. it must be able to change in order to affect the result
+		return asyncassertion.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
+	} else {
+		// so all matchers failed.. Any one of them changing would change the result.
+		for _, matcher := range m.Matchers {
+			if asyncassertion.MatchMayChangeInTheFuture(matcher, actual) {
+				return true
+			}
+		}
+		return false // none of were going to change
+	}
 }
diff --git a/matchers/or_test.go b/matchers/or_test.go
index d9c7b82..9589a17 100644
--- a/matchers/or_test.go
+++ b/matchers/or_test.go
@@ -3,6 +3,7 @@
 import (
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+	. "github.com/onsi/gomega/matchers"
 )
 
 var _ = Describe("OrMatcher", func() {
@@ -43,4 +44,42 @@
 			})
 		})
 	})
+
+	Context("MatchMayChangeInTheFuture", func() {
+		Context("Match returned false", func() {
+			It("returns true if any of the matchers could change", func() {
+				// 3 matchers, all return false, and all could change
+				m := Or(BeNil(), Equal("hip"), HaveLen(1))
+				Expect(m.Match("hi")).To(BeFalse())
+				Expect(m.(*OrMatcher).MatchMayChangeInTheFuture("hi")).To(BeTrue()) // all 3 of these matchers default to 'true'
+			})
+			It("returns false if none of the matchers could change", func() {
+				// empty Or() has the property of never matching, and never can change since there are no sub-matchers that could change
+				m := Or()
+				Expect(m.Match("anything")).To(BeFalse())
+				Expect(m.(*OrMatcher).MatchMayChangeInTheFuture("anything")).To(BeFalse())
+
+				// Or() with 3 sub-matchers that return false, and can't change
+				m = Or(Or(), Or(), Or())
+				Expect(m.Match("hi")).To(BeFalse())
+				Expect(m.(*OrMatcher).MatchMayChangeInTheFuture("hi")).To(BeFalse()) // the 3 empty Or()'s won't change
+			})
+		})
+		Context("Match returned true", func() {
+			Context("returns value of the successful matcher", func() {
+				It("false if successful matcher not going to change", func() {
+					// 3 matchers: 1st returns false, 2nd returns true and is not going to change, 3rd is never called
+					m := Or(BeNil(), And(), Equal(1))
+					Expect(m.Match("hi")).To(BeTrue())
+					Expect(m.(*OrMatcher).MatchMayChangeInTheFuture("hi")).To(BeFalse())
+				})
+				It("true if successful matcher indicates it might change", func() {
+					// 3 matchers: 1st returns false, 2nd returns true and "might" change, 3rd is never called
+					m := Or(Not(BeNil()), Equal("hi"), Equal(1))
+					Expect(m.Match("hi")).To(BeTrue())
+					Expect(m.(*OrMatcher).MatchMayChangeInTheFuture("hi")).To(BeTrue()) // Equal("hi") indicates it might change
+				})
+			})
+		})
+	})
 })
diff --git a/matchers/with_transform_test.go b/matchers/with_transform_test.go
index 7ac6f1c..2824df9 100644
--- a/matchers/with_transform_test.go
+++ b/matchers/with_transform_test.go
@@ -87,17 +87,10 @@
 	})
 
 	Context("MatchMayChangeInTheFuture()", func() {
-		It("Propogates value from wrapped matcher on the transformed value", func() {
-			// dummy struct that holds a channel
-			type S struct{ C chan int }
-			getC := func(s S) chan int { return s.C } // extracts channel from struct
-			// wrap a Receive matcher, which does implement this method
-			var i int
-			m := WithTransform(getC, Receive(&i))
-			s := S{make(chan int)}
-			close(s.C)
-			Expect(m.Match(s)).To(BeFalse())
-			Expect(m.(*WithTransformMatcher).MatchMayChangeInTheFuture(s)).To(BeFalse()) // channel closed so Receive return false
+		It("Propagates value from wrapped matcher on the transformed value", func() {
+			m := WithTransform(plus1, Or()) // empty Or() always returns false, and indicates it cannot change
+			Expect(m.Match(1)).To(BeFalse())
+			Expect(m.(*WithTransformMatcher).MatchMayChangeInTheFuture(1)).To(BeFalse()) // empty Or() indicates cannot change
 		})
 		It("Defaults to true", func() {
 			m := WithTransform(plus1, Equal(2)) // Equal does not have this method