anchor.diff:  ///  - `server` - Ftp Server name (ex: "ftp://10.100.200.300:21/")
   ///  - `user` - Ftp Server login name (ex: "joebloggs")
   ///  - `pwd` - Ftp Server login password (ex: "J0Eblogg5")
  -let rec uploadAFolder server user pwd (srcPath:string) (rootDir:string) = 
  +let rec uploadAFolder server user pwd (srcPath : string) (rootDir : string) = 
       logfn "folder to upload=%s" srcPath
       let dirInfo = new DirectoryInfo(srcPath)
  -    if dirInfo.Exists && dirNameIsValid rootDir
  -    then dirInfo.GetFileSystemInfos () |> Seq.iter (fun fsi -> upload server user pwd fsi rootDir)
  +    if dirInfo.Exists && dirNameIsValid rootDir then 
  +        dirInfo.GetFileSystemInfos() |> Seq.iter (fun fsi -> upload server user pwd fsi rootDir)
   
  -and private upload server user pwd (fsi:FileSystemInfo) (rootDir:string) =
  +and private upload server user pwd (fsi : FileSystemInfo) (rootDir : string) = 
       match fsi.GetType().ToString() with
  -        | "System.IO.DirectoryInfo" -> createAFolder server user pwd rootDir 
  -                                       createAFolder server user pwd (sprintf "%s\\%s" rootDir fsi.Name) 
  -                                       uploadAFolder server user pwd fsi.FullName (sprintf "%s\\%s" rootDir fsi.Name)
  -        | "System.IO.FileInfo" -> uploadAFile server user pwd (sprintf "%s\\%s" rootDir fsi.Name) fsi.FullName
  -        | _ -> logfn "unknown object found at %A" fsi
  -
  +    | "System.IO.DirectoryInfo" -> 
  +        createAFolder server user pwd rootDir
  +        createAFolder server user pwd (sprintf "%s\\%s" rootDir fsi.Name)
  +        uploadAFolder server user pwd fsi.FullName (sprintf "%s\\%s" rootDir fsi.Name)
  +    | "System.IO.FileInfo" -> uploadAFile server user pwd (sprintf "%s\\%s" rootDir fsi.Name) fsi.FullName
  +    | _ -> logfn "unknown object found at %A" fsi
  
positive.code: ///  - `server` - Ftp Server name (ex: "ftp://10.100.200.300:21/")
  ///  - `user` - Ftp Server login name (ex: "joebloggs")
  ///  - `pwd` - Ftp Server login password (ex: "J0Eblogg5")
  let uploadAFile (server:string) (user:string) (pwd:string) (destPath:string) (srcPath:string) = 
      logfn "upload %s from to %s" srcPath destPath
      let fl = new FileInfo(srcPath)
      if (fl.Length <> 0L) then 
          destPath
              |> fun d -> getServerInfo (sprintf "%s/%s" server d) user pwd WebRequestMethods.Ftp.UploadFile
              |> fun si ->
                  use fs = new FileStream(srcPath, FileMode.Open, FileAccess.Read)
                  use br = new BinaryReader(fs, new System.Text.UTF8Encoding())
                  use reqStrm = si.Request.GetRequestStream()
                  writeChunkToReqStream (br.ReadBytes 1024) reqStrm br
  
  /// Given a folder name, will check if that folder is present at a given root directory of a ftp server
  /// ## Parameters
  ///  - `server` - Ftp Server name (ex: "ftp://10.100.200.300:21/")
  ///  - `user` - Ftp Server login name (ex: "joebloggs")
  ///  - `pwd` - Ftp Server login password (ex: "J0Eblogg5")
  let private checkInExistingDirList server user pwd destPath fname =
      destPath |> lastSlashPos |> getSubstring 0 destPath |> getFtpDirContents server user pwd |> regexCheck fname
  
  /// Given a folder path, will check if that folder is present at a given root directory of a ftp server
  /// ## Parameters
  
negative.code: open System.Net
  open System.Text.RegularExpressions
  
  type FtpServerInfo = 
      { Server : string
        Request : FtpWebRequest }
  
  /// Gets a connection to the Ftp server
  let private getServerInfo (serverNameIp : string) (user : string) (pwd : string) ftpMethod = 
      let ftpRequest = (WebRequest.Create serverNameIp) :?> FtpWebRequest
      ftpRequest.Credentials <- new NetworkCredential(user, pwd)
      ftpRequest.Method <- ftpMethod
      { Server = serverNameIp
        Request = ftpRequest }
  
  /// Writes given byte array into the given stream
  let rec private writeChunkToReqStream (chunk : byte []) (reqStrm : Stream) (br : BinaryReader) = 
      if chunk.Length <> 0 then 
          reqStrm.Write(chunk, 0, chunk.Length)
          writeChunkToReqStream (br.ReadBytes 1024) reqStrm |> ignore
  
  let inline private getSubstring (fromPos : int) (str : string) (toPos : int) = str.Substring(fromPos, toPos)
  let inline private lastSlashPos (str : string) = str.LastIndexOf(@"\") + 1
  
  ///Partial validation for folder name, based on http://msdn.microsoft.com/en-us/library/aa365247.aspx
  let inline private dirNameIsValid (dirName : string) = 
      let invalidChars = [ "<"; ">"; ":"; "\""; "/"; "\\"; "|"; "?"; "*" ]
      let invalidNames = 
          [ "CON"; "PRN"; "AUX"; "NUL"; "COM1"; "COM2"; "COM3"; "COM4"; "COM5"; "COM6"; "COM7"; "COM8"; "COM9"; "LPT1"; 
            "LPT2"; "LPT3"; "LPT4"; "LPT5"; "LPT6"; "LPT7"; "LPT8"; "LPT9" ]
      let invalid1 = List.exists (fun s -> s = dirName.ToUpper()) invalidNames
      let invalid2 = List.exists (fun s -> dirName.ToUpper().StartsWith(sprintf "%s." s)) invalidNames
      let invalid3 = dirName.EndsWith(" ")
      let invalid4 = dirName.EndsWith(".")
  