anchor.diff:                          ops |> List.iter (fun o -> w.Undo.[o] <- o.Run())
                       | _ -> ()
   
  -        let rec forwardCollectOps (w : WorkingCopy) (current : History) (target : History) =
  +        let rec forwardMerge (w : WorkingCopy) (conflictTable : Dictionary<obj, Op>) (current : History) (target : History) =
               if current != target then
                   match target with
                       | Commit(b,{ ops = ops }) ->
  -                        let inner = forwardCollectOps w current b
  -                        ops |> List.iter (fun o -> w.Undo.[o] <- o.Run())
  -                        inner @ ops
  -                    | _ -> []
  +                        let res, inner = forwardMerge w conflictTable current b
  +                        let rec tryMerge (ops : list<Op>) =
  +                            match ops with
  +                                | [] -> [], []
  +                                | o::ops ->
  +                                    let working, conflicts = tryMerge ops
  +
  +                                    let op = 
  +                                        match conflictTable.TryGetValue o.Target with
  +                                            | (true, other) ->
  +                                                match o.TryMerge(other) with
  +                                                    | Some res ->
  +                                                        Left res
  +                                                    | None -> Right (o, other)
  +                                            | _ -> Left o
  +
  +                                    match op with
  +                                        | Left o ->
  +                                            o::working, conflicts
  +                                        | Right c ->
  +                                            working, c::conflicts
  +     
  +                        let working, conflicts = tryMerge ops
  +
  +                        match res with
  +                            | Success ->
  +                                if List.isEmpty conflicts then 
  +                                    working |> List.iter (fun o -> w.Undo.[o] <- o.Run())
  +                                    let result = Change.append inner (Change.ofList working)
  +
  +                                    Success, result
  +                                else
  +                                    backward w b current
  +                                    Conflicts conflicts, NoChange
  +
  +
  +                            | Conflicts inner ->
  +                                Conflicts (inner @ conflicts), NoChange
  +
  +                    | _ -> Success, NoChange
               else
  -                []
  +                Success,NoChange
  +
  +        let rec changeFromTo (current : History) (target : History) =
  +            if current != target then
  +                match target with
  +                    | Commit(b,{ ops = ops }) ->
  +                        let inner = changeFromTo current b
  +                        Change.append inner (Change.ofList ops)
  +                    | _ -> NoChange
  +            else
  +                NoChange
   
       let init (folder : string) = WorkingCopy(folder)
   
  
positive.code: 
  
  type Op =
      abstract member Run : unit -> Op
      abstract member ConflictsWith : Op -> bool
  
  
  type Change =
  
negative.code:                     | Empty ->
                          ()
          
          let private undo (w : WorkingCopy) (o : Op) =
              match w.Undo.TryRemove o with
                  | (true, u) -> u.Run() |> ignore
                  | _ ->  ()
  
          let rec forward (w : WorkingCopy) (current : History) (target : History) =
              if current != target then
                  match target with
  