anchor.diff:          let urlMatch path (url,_) = Regex.Match(path,url).Success
           let mutable urls = urlsInit
   
  +        // question: since path is in urInit, why have a separate path var at all?
           let dispatch urInit path =
               let ok,ur = this.preCheck path urInit
               if not ok then
  -                if ur.isPost then
  -                    ur.ReadPostAsBytes() |> ignore // take out the post content to avoid problems with follow on
  -                let r = Response(401,"text/plain")
  -                r.Text <- "Authentication required"
  -                r
  +                this.preCheckFailed ur
               else
                   //printf "Testing path='%s'\n urls=%A" path (urls |> List.map (fst))
  -                match List.tryFind (urlMatch path) urls with
  +                match List.tryFind (urlMatch ur.path) urls with
                       | None ->
                           this.Log 1 (sprintf "Unmatched url...")
  -                        Http404(sprintf "<HTML>Unmatched URL; '%s'\n</HTML>" path) :> Response
  +                        Http404(sprintf "<HTML>Unmatched URL; '%s'\n</HTML>" ur.path) :> Response
                       | Some(url,fn) ->
                           let m = Regex.Match(path,url)
                           let x = m.Groups
  -                        sprintf "fss%d UD: matching %s -> %s\n" ur.handleId path url |> this.Log 3
  +                        sprintf "fss%d UD: matching %s -> %s\n" ur.handleId ur.path url |> this.Log 3
                           try
                               let g (x:int) = m.Groups.[x].Value
                               match m.Groups.Count-1,fn with
  
positive.code:         /// Default implementation lets everything through
          default this.preCheck path ur = true,ur 
  
          member this.Start() = start()
          member this.Stop() = stop()
          override this.doGet (handleId:int) (sw : StreamWriter) (path:string) headers =
              let parseQueryArgs(s:string) =
                  s.Split([| '&' |]) |> Array.map (fun s -> match s.Split([|'='|]) with 
                                                                  | [| k ; v |] ->(k,Uri.UnescapeDataString(v)) 
                                                                  | _ -> failwithf "Invalid form args: %s" s) |> Map.ofSeq
  
              let path',args = match path.IndexOf('?') with
  
negative.code:                                     if remaining = 0 then ()
                                      else
                                          let n = s.Read(buffer,offset,remaining)
                                          if n = remaining then ()
                                          else if n = 0 then failwithf "ERROR: end of stream reading %d of %d byes in ReadBytesAsPost" (buffer.Length-remaining) buffer.Length
                                          else
                                              readWhile (offset+n) (remaining-n)
  