anchor.diff:  type ProcessOptions(?envVars, ?redirectOutput) =
       member val EnvVars = defaultArg envVars Map.empty<string,string>
       member val RedirectOuput = defaultArg redirectOutput false
  +
  +type Arguments =
  +    { timeout: int; port: int; commandArgs: string option }
   
   let startProcess workingDir fileName args (opts: ProcessOptions) =
       let fileName, args =
  
positive.code: let main argv =
      match Array.tryHead argv with
      | Some ("--help"|"-h") ->
          printfn """Available options:
    -h|--help           Show help
    --version           Print version
    add                 Add one or several Fable npm packages
    start               Start Fable server
    --port              Port number (default 61225) or "free" to choose a free port.
    --timeout           Stop the server if timeout (ms) is reached
    npm-run             Start a server, run an npm script and shut it down
      <script>            Name of the npm script, e.g.: `dotnet fable npm-run start`
      --port              Port number (default 61225) or "free" to choose a free port.
      --args              Args for the npm script, e.g.: `dotnet fable npm-run build --args "-p --output-filename bundle.js"`
    webpack             Start a server and invoke webpack (must be installed in current or a parent dir)
      --port              Port number (default 61225) or "free" to choose a free port.
      --args              Args for Webpack, e.g.: `dotnet fable webpack --args -p`
    shell-run           Start a server, run an abritrary command and shut it down
      <cmd>            Name of the command to run, e.g.: `dotnet fable shell-run make`
      --port              Port number (default 61225) or "free" to choose a free port.
      --args              Args for the command, e.g.: `dotnet fable shell-run make --args "build"`
    webpack-dev-server  Same as `webpack` command but invokes webpack-dev-server
  """
      | Some "--version" -> printfn "%s" Constants.VERSION
      | Some "start" ->
          let port, timeout = argv.[1..] |> argsToMap |> getPortAndTimeout
          let agent = startAgent()
          startServer port timeout agent.Post Async.RunSynchronously
      | Some "npm-run" ->
          let argsMap = argv.[2..] |> argsToMap
          let port, _ = argsMap |> getPortAndTimeout
          let execArgs =
              match Map.tryFind "args" argsMap with
              | Some npmArgs -> "run " + argv.[1] + " -- " + npmArgs
              | None -> "run " + argv.[1]
          startServerWithProcess port "npm" execArgs
      | Some ("webpack" | "webpack-dev-server" as webpack) ->
          let argsMap = argv.[1..] |> argsToMap
          let port, _ = argsMap |> getPortAndTimeout
          let workingDir = Directory.GetCurrentDirectory()
          let webpackScript =
              let webpackScript = 
                  Path.Combine(findPackageJsonDir workingDir, "node_modules", webpack, "bin", webpack + ".js")
                  |> sprintf "\"%s\""
              match Map.tryFind "args" argsMap with
              | Some args -> webpackScript + " " + args
              | None -> webpackScript
          startServerWithProcess port "node" webpackScript
      | Some "shell-run" ->
          let cmd = argv.[1]
          let argsMap = argv.[2..] |> argsToMap
          let port, _ = argsMap |> getPortAndTimeout
          let execArgs =
              match Map.tryFind "args" argsMap with
              | Some args -> args
              | None -> ""
          startServerWithProcess port cmd execArgs
      | Some "add" ->
          let workingDir = Directory.GetCurrentDirectory()
          let packages = argv.[1..]
          let packages =
              match packages with
              | [||] -> failwith "Missing packages to install"
              | [|package|] ->
                  let peers =
                      sprintf "show %s peerDependencies" package
                      |> runProcessAndReadOutput workingDir "npm"
                  if String.IsNullOrWhiteSpace(peers)
                  then [|package|]
                  else
                      JsonConvert.DeserializeObject<Map<string,string>>(peers)
                      |> Seq.map (fun kv -> kv.Key + "@" + kv.Value)
                      |> Seq.append [|package|]
                      |> Seq.toArray
              | packages -> packages
          runProcess workingDir "npm" ("install --save-dev " + (String.concat " " packages))
          let nodeModulesDir = Path.Combine(findPackageJsonDir workingDir, "node_modules")
          for pkg in packages do
              let pkg =
                  match pkg.IndexOf("@") with
                  | -1 -> pkg
                  | i -> pkg.Substring(0,i)
              let pkgDir = Path.Combine(nodeModulesDir, pkg)
              Directory.GetFiles(pkgDir, "*.fsproj") |> Array.tryHead |> function
              | Some projRef ->
                  runProcess workingDir "dotnet" ("add reference \"" + projRef + "\"")
              | None ->
                  printfn "Cannot find .fsproj in %s" pkgDir
          runProcess workingDir "dotnet" "restore"
      | Some "debug" ->
          debug argv.[1] argv.[2..]
      | Some cmd -> printfn "Unrecognized command: %s. Use `dotnet fable --help` to see available options" cmd
      | None -> printfn "Command missing. Use `dotnet fable --help` to see available options"
      0
  
negative.code:     l.Stop()
      port
  
  let parseArguments args =
      let tryFindArgValue key (args: string[]) =
          match args |> Array.tryFindIndex ((=) key) with
          | Some i -> Some args.[i]
          | None -> None
      let port =
          match tryFindArgValue "--port" args with
          | Some "free" -> getFreePort()
          | Some port -> int port
          | None -> Constants.DEFAULT_PORT
      let timeout =
          match tryFindArgValue "--timeout" args with
          | Some timeout -> int timeout
          | None -> -1
      let commandArgs =
          // Check first --args for compatibility with the old way
          match tryFindArgValue "--args" args with
          | Some commandArgs -> Some commandArgs
          | None ->
              match args |> Array.tryFindIndex ((=) "--") with
              | Some i -> args.[(i+1)..] |> String.concat " " |> Some
              | None -> None
      { port = port; timeout = timeout; commandArgs = commandArgs}
  
  let debug (projFile: string) (define: string[]) =
      let com = Compiler()
  