anchor.diff:          /// Default implementation lets everything through
           default this.preCheck path ur = true,ur 
   
  +        /// Result of preCheck failure
  +        abstract preCheckFailed : UR->Response
  +        default this.preCheckFailed ur =
  +            if ur.isPost then
  +                // take out the post content to avoid problems with follow on
  +                ur.ReadPostAsBytes() |> ignore
  +            let r = Response(401,"text/plain")   
  +            r.Text <- "Authentication required."
  +            r
  +
           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)) 
  +                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
  
positive.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)
  
negative.code:         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
                  this.preCheckFailed ur
              else
                  //printf "Testing path='%s'\n urls=%A" path (urls |> List.map (fst))
                  match List.tryFind (urlMatch ur.path) urls with
                      | None ->
                          this.Log 1 (sprintf "Unmatched url...")
                          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 ur.path url |> this.Log 3
                          try
                              let g (x:int) = m.Groups.[x].Value
                              match m.Groups.Count-1,fn with
  