diff --git a/diff3.cabal b/diff3.cabal
--- a/diff3.cabal
+++ b/diff3.cabal
@@ -1,5 +1,5 @@
 name:                diff3
-version:             0.2.0.3
+version:             0.3.0
 synopsis:            Perform a 3-way difference of documents
 homepage:            http://github.com/ocharles/diff3.git
 license:             BSD3
diff --git a/src/Data/Algorithm/Diff3.hs b/src/Data/Algorithm/Diff3.hs
--- a/src/Data/Algorithm/Diff3.hs
+++ b/src/Data/Algorithm/Diff3.hs
@@ -100,8 +100,8 @@
           (bs, tb) = break isBoth b
           am = sum $ map motion as
           bm = sum $ map motion bs
-          (as', ta') = incurMotion bm ta
-          (bs', tb') = incurMotion am tb
+          (as', ta') = if bm > am then incurMotion (bm-am) ta else ([], ta)
+          (bs', tb') = if am > bm then incurMotion (am-bm) tb else ([], tb)
       in if am == bm
          then ((as, bs), ta, tb)
          else ((as ++ as', bs ++ bs'), [], []) <> go ta' tb'
@@ -118,7 +118,7 @@
 incurMotion _ [] = ([], [])
 incurMotion 0 as  = ([], as)
 incurMotion n (a@(Both _ _):as) = ([a], []) <> incurMotion (pred n) as
-incurMotion n (a@(Second _):as) = ([a], []) <> incurMotion (pred n) as
+incurMotion n (a@(First _):as) = ([a], []) <> incurMotion (pred n) as
 incurMotion n (a:as) = ([a], []) <> incurMotion n as
 
 
diff --git a/test/properties.hs b/test/properties.hs
--- a/test/properties.hs
+++ b/test/properties.hs
@@ -21,6 +21,40 @@
 identityMerge :: [Int] -> Bool
 identityMerge as = merge (diff3 as as as) == Right as
 
+-- The value in `Just a` has to match the next list item
+-- `Nothing` is a wildcard that can match zero or more list items
+matching :: (Eq a) => [Maybe a] -> [a] -> Bool
+matching [] [] = True
+matching [] bs = False
+matching (Just a:as) (b:bs) = a == b && matching as bs
+matching (Just a:as) [] = False
+matching (as@(Nothing:as')) (bs@(_:bs')) = matching as' bs || matching as bs'
+matching (Nothing:as') (bs@[]) = matching as' bs
+
+matchLeft :: [Int] -> [Int] -> [Int] -> Bool
+matchLeft left original right = matching (matcher $ diff3 left original right) left
+  where matcher [] = []
+        matcher (LeftChange as:hs) = map Just as ++ matcher hs
+        matcher (RightChange as:hs) = Nothing : matcher hs
+        matcher (Unchanged as:hs) = map Just as ++ matcher hs
+        matcher (Conflict as os bs:hs) = map Just as ++ matcher hs
+
+matchRight :: [Int] -> [Int] -> [Int] -> Bool
+matchRight left original right = matching (matcher $ diff3 left original right) right
+  where matcher [] = []
+        matcher (LeftChange as:hs) = Nothing : matcher hs
+        matcher (RightChange as:hs) = map Just as ++ matcher hs
+        matcher (Unchanged as:hs) = map Just as ++ matcher hs
+        matcher (Conflict as os bs:hs) = map Just bs ++ matcher hs
+
+matchOriginal :: [Int] -> [Int] -> [Int] -> Bool
+matchOriginal left original right = matching (matcher $ diff3 left original right) original
+  where matcher [] = []
+        matcher (LeftChange as:hs) = Nothing : matcher hs
+        matcher (RightChange as:hs) = Nothing : matcher hs
+        matcher (Unchanged as:hs) = map Just as ++ matcher hs
+        matcher (Conflict as os bs:hs) = map Just os ++ matcher hs
+
 main :: IO ()
 main =
   let testOpts = mempty { topt_maximum_generated_tests = Just 1000 }
@@ -30,5 +64,8 @@
        , testProperty "Can make changes in right document" rightChanges
        , testProperty "Left/right identical changes conflict" identicalChanges
        , testProperty "The 'identity' merge always succeeds" identityMerge
+       , testProperty "Left side of diff is part of left input" matchLeft
+       , testProperty "Right side of diff is part of right input" matchRight
+       , testProperty "Original parts of diff are part of original input" matchOriginal
        ]
        runner
