anchor.diff:  let parseTokens messageTemplate = seq {
       if messageTemplate = "" then yield Token.EmptyText
       else
  -        let mutable isDone = false
  -        let mutable nextIndex = 0
  -        while not isDone do
  -            let beforeText = nextIndex
  -            let tt = parseTextToken nextIndex messageTemplate &nextIndex
  -            if nextIndex > beforeText then
  +        let isDone = ref false
  +        let nextIndex = ref 0
  +        while not !isDone do
  +            let beforeText = !nextIndex
  +            let tt = parseTextToken !nextIndex messageTemplate nextIndex
  +            if !nextIndex > beforeText then
                   yield tt
  -            if nextIndex = messageTemplate.Length then
  -                isDone <- true
  -            if not isDone then
  +            if !nextIndex = messageTemplate.Length then
  +                isDone := true
  +            if not !isDone then
                   let beforeProp = nextIndex
  -                let pt = parsePropertyToken nextIndex messageTemplate &nextIndex
  +                let pt = parsePropertyToken !nextIndex messageTemplate nextIndex
                   if beforeProp < nextIndex then
                       yield pt
  -                if nextIndex = messageTemplate.Length then
  -                    isDone <- true
  +                if !nextIndex = messageTemplate.Length then
  +                    isDone := true
   }
   
   let parse (s:string) =
  
positive.code: 
      // skip over characters until we reach a character that is *NOT* a valid part of
      // the property tag
      while thisChIdx < messageTemplate.Length && isValidCharInPropTag(peekThisCh()) do
          thisChIdx <- thisChIdx + 1
  
      // if we stopped at the end of the string or the last char wasn't a close brace
      // then we treat all the characters we found as a text token, and finish.
      if thisChIdx = messageTemplate.Length || peekThisCh() <> '}' then
          nextIndex <- thisChIdx
          Tk.text first (messageTemplate.Substring(first, thisChIdx - first))
      else
          nextIndex <- thisChIdx + 1 // tell the caller of the next char they should start parsing
          let rawText = messageTemplate.Substring(first, nextIndex - first)
          let tagContent = messageTemplate.Substring(first + 1, nextIndex - (first + 2))
          match trySplitTagContent tagContent with
  
negative.code:             if thisChar = '}' && isNextChar '}' then moveToNextChar () // treat "}}" as "}"
  
          if thisChar <> '{' then moveToNextChar()
          isDone <- isDone || !next >= template.Length
  
      callersNextIndex := !next
      if accum.IsValueCreated then Tk.text first (accum.Force().ToString())
      else Token.EmptyText
  
  type ch = System.Char
  let parsePropertyToken (startAt:int) (messageTemplate:string) (callersNextIndex: int ref) : Token =
      let first = startAt
      let mutable thisChIdx = startAt
      let peekChAt (index) = messageTemplate.[index]
      let isValidInPropName c = c = '_' || ch.IsLetterOrDigit c
      let isValidInDestrHint c = c = '@' || c = '$'
      let isValidInAlignment c = c = '-' || ch.IsDigit c
  