anchor.diff:  
     setupWhen main.Activated |>> fun () ->
   
  -      let itemsVar = Stream.Var.create []
  +      let modelVar = Stream.Var.create Map.empty
   
  -      let changedCompleted =
  -        Stream.Var.tap itemsVar
  -        |> Stream.switchMap (fun items ->
  -           Stream.ofSeq items
  -           |> Stream.mergeMap (fun item -> Stream.Var.tap item.IsCompleted)
  -           |> Stream.mapConst items)
  -        |> Stream.merge (Stream.Var.tap itemsVar)
  +      let updateItem id f model =
  +        match Map.tryFind id model with
  +         | None -> model
  +         | Some item -> Map.add id (f item) model
   
  -      let itemsAndCtrls =
  -        Stream.Var.tap itemsVar
  -        |> Stream.scanFromJob [] (fun oldItemsAndCtrls newItems -> onMain {
  -           let newCtrl item =
  -             let ctrl = ToDo.UI.ItemControl ()
  -
  -             ctrl.Header.Text <- Stream.Var.get item.Header
  -             Stream.ofObservableOnMain ctrl.Header.MouseDoubleClick
  -             |> Stream.subscribeJob (fun _ -> onMain {
  -                ctrl.Header.Focusable <- true
  -                if ctrl.Header.Focus () then
  -                  ctrl.Header.SelectAll () })
  -             Stream.ofObservableOnMain ctrl.Header.KeyUp
  -             |> Stream.filterFun (fun evt -> evt.Key = Key.Enter)
  -             |> Stream.mapIgnore
  -             |> Stream.merge (Stream.ofObservableOnMain ctrl.LostFocus
  -                              |> Stream.mapIgnore)
  -             |> Stream.subscribeJob (fun () -> onMain {
  -                Keyboard.ClearFocus ()
  -                ctrl.Header.Focusable <- false
  -                match ctrl.Header.Text.Trim () with
  -                 | "" ->
  -                   ctrl.Header.Text <- Stream.Var.get item.Header
  -                 | text ->
  -                   ctrl.Header.Text <- text
  -                   return! Stream.Var.set item.Header text })
  -
  -             Stream.ofObservableOnMain ctrl.IsCompleted.Click
  -             |> Stream.subscribeJob (fun _ -> onMain {
  -                let isChecked = ctrl.IsCompleted.IsChecked.Value
  -                if isChecked <> Stream.Var.get item.IsCompleted then
  -                  Stream.Var.set item.IsCompleted isChecked |> start })
  -             Stream.Var.tap item.IsCompleted
  -             |> Stream.subscribeJob (fun _ -> onMain {
  -                let isCompleted = Stream.Var.get item.IsCompleted
  -                if ctrl.IsCompleted.IsChecked.Value <> isCompleted then
  -                  ctrl.IsCompleted.IsChecked <- Nullable<bool> isCompleted })
  -
  -             Stream.Var.tap item.IsCompleted
  -             |> Stream.subscribeJob (fun isCompleted -> onMain {
  -                ctrl.Header.FontStyle <-
  -                  if isCompleted then FontStyles.Italic else FontStyles.Normal })
  -
  -             Stream.merge
  -              (Stream.ofObservableOnMain ctrl.MouseEnter |> Stream.mapConst +1)
  -              (Stream.ofObservableOnMain ctrl.MouseLeave |> Stream.mapConst -1)
  -             |> Stream.scanFromFun 0 (+)
  -             |> Stream.subscribeJob (fun n -> onMain {
  -                ctrl.Remove.Visibility <-
  -                  if 0 < n then Visibility.Visible else Visibility.Hidden })
  -
  -             Stream.ofObservableOnMain ctrl.Remove.Click
  -             |> Stream.subscribeJob (fun _ ->
  -                Stream.Var.get itemsVar
  -                |> List.filter ((<>) item)
  -                |> Stream.Var.set itemsVar)
  -
  -             ctrl
  -
  -           let itemToCtrl = Dictionary.create oldItemsAndCtrls
  -
  -           return newItems
  -                  |> List.map (fun item ->
  -                     (item,
  -                      match itemToCtrl.TryGet item with
  -                       | None -> newCtrl item
  -                       | Some ctrl -> ctrl)) })
  +      Stream.ofObservableOnMain main.EnterHeader.KeyUp
  +      |> Stream.filterFun (fun evt -> evt.Key = Key.Enter)
  +      |> Stream.chooseJob (fun _ -> onMain {
  +         return match main.EnterHeader.Text.Trim () with
  +                 | "" -> None
  +                 | header ->
  +                   main.EnterHeader.Text <- ""
  +                   Some header })
  +      |> Stream.subscribeJob (fun header ->
  +         Stream.Var.updateFun modelVar
  +          <| Map.add (Id.next ()) {IsCompleted = false; Header = header})
   
         let isAny _ = true
  -      let isCompleted item = Stream.Var.get item.IsCompleted
  -      let isActive item = isCompleted item |> not
  +      let isCompleted item = item.IsCompleted
  +      let isActive item = item.IsCompleted |> not
   
         let filter =
           let filterOn (button: Button) pred =
  
positive.code: 
  [<AutoOpen>]
  module internal Util =
    type IDictionary<'k, 'v> with
      member this.TryGet k =
        match this.TryGetValue k with
         | (false, _) -> None
         | (_, v) -> Some v
      member this.Add (kvs: seq<'k * 'v>) =
        kvs |> Seq.iter this.Add
    module Dictionary =
      let create kvs =
        let d = Dictionary<_, _>()
        d.Add kvs
        d
  
    let setupWhen (onEvent: IEvent<_, _>) =
      let mainCtx = ivar ()
      let handler =
  
negative.code:         |> Stream.mapJob (fun (bn, pred) -> onMain {
             [main.FilterAll; main.FilterActive; main.FilterCompleted]
             |> Seq.iter (fun bn' -> bn'.IsEnabled <- bn <> bn')
             return pred })      
  
        let newControl id item =
          let control = ToDo.UI.ItemControl ()
  
          control.IsCompleted.IsChecked <- Nullable<bool> item.IsCompleted
          control.Header.Text <- item.Header
          control.Header.FontStyle <-
            if item.IsCompleted then FontStyles.Italic else FontStyles.Normal
  
          Stream.ofObservableOnMain control.IsCompleted.Click
          |> Stream.subscribeJob (fun _ -> onMain {
            let isCompleted = control.IsCompleted.IsChecked.Value
            return! Stream.Var.updateFun modelVar
                      << updateItem id <| fun item ->
                          {item with IsCompleted = isCompleted} })
  
          Stream.ofObservableOnMain control.Header.MouseDoubleClick
          |> Stream.subscribeJob (fun _ -> onMain {
            control.Header.Focusable <- true
            if control.Header.Focus () then
              control.Header.SelectAll () })
          Stream.ofObservableOnMain control.Header.KeyUp
          |> Stream.filterFun (fun evt -> evt.Key = Key.Enter)
          |> Stream.mapIgnore
          |> Stream.merge (Stream.ofObservableOnMain control.Header.LostFocus
                          |> Stream.mapIgnore)
          |> Stream.subscribeJob (fun () -> onMain {
            Keyboard.ClearFocus ()
            control.Header.Focusable <- false
            match control.Header.Text.Trim () with
              | "" -> control.Header.Text <- item.Header
              | header ->
                return! Stream.Var.updateFun modelVar << updateItem id <| fun item ->
                        {item with Header = header} })
  
          Stream.merge
            (Stream.ofObservableOnMain control.MouseEnter |> Stream.mapConst +1)
            (Stream.ofObservableOnMain control.MouseLeave |> Stream.mapConst -1)
          |> Stream.scanFromFun 0 (+)
          |> Stream.subscribeJob (fun n -> onMain {
            control.Remove.Visibility <-
              if 0 < n then Visibility.Visible else Visibility.Hidden })
  
          Stream.ofObservableOnMain control.Remove.Click
          |> Stream.subscribeJob (fun _ ->
            Stream.Var.updateFun modelVar <| Map.remove id)
  
          control
  
        Stream.Var.tap modelVar
        |> Stream.combineLatest filter
        |> Stream.subscribeJob (fun (filter, model) -> onMain {
           main.Items.Children.Clear ()
           model
           |> Map.iter (fun id item ->
              if filter item then
                newControl id item
                |> main.Items.Children.Add
                |> ignore) })
  
        Stream.Var.tap modelVar
        |> Stream.subscribeJob (fun model -> onMain {
           let n = Map.toSeq model |> Seq.filter (snd >> isActive) |> Seq.length
           main.NumberOfItems.Text <- sprintf "%d items left" n })
  
        Stream.Var.tap modelVar
        |> Stream.subscribeJob (fun model -> onMain {
           let n = Map.toSeq model |> Seq.filter (snd >> isCompleted) |> Seq.length
           main.ClearCompleted.Visibility <-
             if n=0 then Visibility.Hidden else Visibility.Visible
           main.ClearCompleted.Content <- sprintf "Clear completed %d" n })
  
        Stream.ofObservableOnMain main.ClearCompleted.Click
        |> Stream.subscribeJob (fun _ ->
           Stream.Var.updateFun modelVar << Map.filter <| fun _ -> isActive)
  
        Stream.Var.tap modelVar
        |> Stream.mapFun (fun model ->
           not (Map.isEmpty model) && Map.forall (fun _ -> isCompleted) model)
        |> Stream.subscribeJob (fun allCompleted -> onMain {
           main.CompleteAll.IsChecked <- Nullable<bool> allCompleted })
  
        Stream.ofObservableOnMain main.CompleteAll.Click
        |> Stream.subscribeJob (fun _ ->
           onMain { return main.CompleteAll.IsChecked.Value } >>= fun isCompleted ->
           Stream.Var.updateFun modelVar << Map.map <| fun _ item ->
           {item with IsCompleted = isCompleted})
  
    |> queue
  
  