anchor.diff:      let downs = Array.ofList downs
       let n = downs.Length
       for i=0 to n-1 do
  -      if 0 <= i-1 then downs.[i].L <- downs.[i-1]
  -      if i+1 < n then downs.[i].R <- downs.[i+1]
  -    let downFirst = downs.[0]
  -    let downLast = downs.[n-1]
  +      if 0 <= i-1 then downs.[i].PrevAny <- downs.[i-1]
  +      if i+1 < n  then downs.[i].NextAny <- downs.[i+1]
  +    let mutable downLastThe = null
  +    for i=0 to n-1 do
  +      downs.[i].PrevThe <- downLastThe
  +      match downs.[i] with
  +       | :? ProductDownTo<'w, 'w, 'c, 'p, 't> as the -> downLastThe <- the
  +       | _ -> ()
  +    let downLastThe = downLastThe
  +    let mutable downHeadThe = null
  +    for i=n-1 downto 0 do
  +      downs.[i].NextThe <- downHeadThe
  +      match downs.[i] with
  +       | :? ProductDownTo<'w, 'w, 'c, 'p, 't> as the -> downHeadThe <- the
  +       | _ -> ()
  +    let downHeadThe = downHeadThe
  +    let downHeadAny = downs.[0]
  +    let downLastAny = downs.[n-1]
  +    let inline downAny (way: ProductDownBase<_, _, _, _>) up t =
  +      match way with
  +       | null -> None
  +       | way ->
  +         let mutable p = m.ToProduct t
  +         way.Down (up, m, &p) |> Some
  +    let inline downThe (way: ProductDownTo<_, _, _, _, _>) up t =
  +      match way with
  +       | null -> None
  +       | way ->
  +         let mutable p = m.ToProduct t
  +         match way.Down (up, m, &p) with
  +          | :? Zipper<'w, 'w> as z -> Some z
  +          | _ -> failwith "Bug"
       {new Down<'w, 't> () with
  -      member d.DownFirst (up, t) =
  -        let mutable p = m.ToProduct t
  -        downFirst.Down (up, m, &p) |> Some
  -      member d.DownLast (up, t) =
  -        let mutable p = m.ToProduct t
  -        downLast.Down (up, m, &p) |> Some}
  +      member d.DownHeadAny (up, t) = downAny downHeadAny up t
  +      member d.DownHeadThe (up, t) = downThe downHeadThe up t
  +      member d.DownLastAny (up, t) = downAny downLastAny up t
  +      member d.DownLastThe (up, t) = downThe downLastThe up t}
   
     member z.Case (_: Case<Empty, 'cs, 'u>) : UnionDown<'w, Empty, 'cs, 'u> =
       U [{new Down<'w, 'u> () with
  -         member d.DownFirst (_, _) = None
  -         member d.DownLast (_, _) = None}]
  +         member d.DownHeadAny (_, _) = None
  +         member d.DownHeadThe (_, _) = None
  +         member d.DownLastAny (_, _) = None
  +         member d.DownLastThe (_, _) = None}]
   
     member z.Case (m: Case<'ls, 'cs, 'u>,
                    downs: ProductDown<'w, 'ls, 'ls, 'cs, 'ls, 'u>)
  
positive.code: let test () =
    do let x = 1
       printfn "%A" x
       let z = toZipper x
       printfn "%d" (get z |> Option.get)
    do let x = (1, 2.0)
       printfn "%A" x
       let z = toZipper x
       let z = z |> downFirst |> Option.get
       printfn "%d" (get z |> Option.get)
       let z = z |> right |> Option.get
       printfn "%f" (get z |> Option.get)
    do let x = (1, 2.0, "3")
       printfn "%A" x
       let z = toZipper x
       let z = z |> downLast |> Option.get
       printfn "%s" (get z |> Option.get)
       let z = z |> left |> Option.get
       printfn "%f" (get z |> Option.get)
       let z = set 2.5 z |> Option.get
       printfn "%f" (get z |> Option.get)
       let z = z |> left |> Option.get
       printfn "%d" (get z |> Option.get)
       printfn "%A" (fromZipper z)
    do let x = App (Lambda ("x", If (Var "x", Var "a", Var "a")), Var "true")
       printfn "%A" x
       //let n = Engine.numAttempts ()
       let z = toZipper x
       //printfn "Attempts: %d" (Engine.numAttempts () - n)
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> downFirst |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> downFirst |> Option.get
       printfn "%A" (get z |> Option.get : string)
       let z = z |> right |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> downFirst |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> right |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> right |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       let z = z |> set (Var "b") |> Option.get
       printfn "%A" (get z |> Option.get : Term)
       printfn "%A" (fromZipper z)
  
negative.code:                   U u: UnionDown<'w, 'c, 'c, 'u>) : Down<'w, 'u> =
      let cs = Array.ofList u
      {new Down<'w, 'u> () with
        override d.DownHeadAny (up, u) = cs.[m.Tag u].DownHeadAny (up, u)
        override d.DownHeadThe (up, u) = cs.[m.Tag u].DownHeadThe (up, u)
        override d.DownLastAny (up, u) = cs.[m.Tag u].DownLastAny (up, u)
        override d.DownLastThe (up, u) = cs.[m.Tag u].DownLastThe (up, u)}
  
    member r.Nest (r0: Rotate<'l, 'h, 'r, 'sp, 'p>) =
      {new Rotate<And<'l0, 'l>, 'h, 'r, 'sp, And<'l0, 'p>> () with
  