(command.CommandList
  children: [
    (C {(Id.KW_Set set)} {(-euo)} {(pipefail)})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:XVFB_PID)
          op: assign_op.Equal
          rhs: {(DQ )}
          spids: [59]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:RUN_SELENIUM)
          op: assign_op.Equal
          rhs: 
            {
              (DQ 
                (braced_var_sub
                  token: (Token id:Id.VSub_Name val:RUN_SELENIUM span_id:66)
                  suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{(true)})
                )
              )
            }
          spids: [63]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:BUNDLE_PATH)
          op: assign_op.Equal
          rhs: {(DQ )}
          spids: [72]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:THIS_DIR)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:77)
                command_list: 
                  (command.CommandList
                    children: [
                      (C {(dirname)} 
                        {
                          (DQ 
                            (command_sub
                              left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:81)
                              command_list: 
                                (command.CommandList
                                  children: [
                                    (C {(readlink)} {(-f)} 
                                      {
                                        (DQ 
                                          (braced_var_sub
                                            token: (Token id:Id.VSub_Name val:BASH_SOURCE span_id:88)
                                            bracket_op: 
                                              (bracket_op.ArrayIndex
                                                expr: (arith_expr.ArithWord w:{(Id.Lit_Digits 0)})
                                              )
                                          )
                                        )
                                      }
                                    )
                                  ]
                                )
                            )
                          )
                        }
                      )
                    ]
                  )
              )
            }
          spids: [76]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:METEOR_DEV_BUNDLE)
          op: assign_op.Equal
          rhs: 
            {
              (command_sub
                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:99)
                command_list: 
                  (command.CommandList
                    children: [
                      (C {(DQ ($ Id.VSub_DollarName '$THIS_DIR') (/../find-meteor-dev-bundle.sh))})
                    ]
                  )
              )
            }
          spids: [98]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:NODEJS)
          op: assign_op.Equal
          rhs: {(DQ ($ Id.VSub_DollarName '$METEOR_DEV_BUNDLE') (/bin/node))}
          spids: [106]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:NPM)
          op: assign_op.Equal
          rhs: {(DQ ($ Id.VSub_DollarName '$METEOR_DEV_BUNDLE') (/bin/npm))}
          spids: [112]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:SELENIUM_JAR)
          op: assign_op.Equal
          rhs: {(DQ (selenium-server-standalone-2.53.0.jar))}
          spids: [118]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:SELENIUM_JAR_SHA256)
          op: assign_op.Equal
          rhs: {(DQ (67b88cbfd3b130de6ff3770948f56cc485fd1abb5b7a769397d9050a59b1e036))}
          spids: [123]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:SELENIUM_DOWNLOAD_URL)
          op: assign_op.Equal
          rhs: 
            {
              (DQ ('https://selenium-release.storage.googleapis.com/2.53/') 
                ($ Id.VSub_DollarName '$SELENIUM_JAR')
              )
            }
          spids: [128]
        )
      ]
    )
    (command.ShFunction
      name: cleanExit
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:rc)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [143]
                )
              ]
            )
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {(Id.Lit_LBracket '[')} {($ Id.VSub_DollarName '$rc')} {(-ne)} {(0)} 
                          {(Id.Lit_RBracket ']')}
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:159)
                    )
                  ]
                  action: [
                    (C {(echo)} {(DQ ('Log output: '))})
                    (C {(cat)} {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR') (/var/log/sandstorm.log))})
                  ]
                  spids: [148 161]
                )
              ]
            )
            (C {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR') (/sandstorm))} {(stop)})
            (C {(sleep)} {(1)})
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {(Id.Lit_LBracket '[')} {($ Id.VSub_DollarName '$rc')} {(-eq)} {(0)} 
                          {(Id.Lit_RBracket ']')}
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:208)
                    )
                  ]
                  action: [(C {(rm)} {(-rf)} {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR'))})]
                  spids: [197 210]
                )
              ]
            )
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {(Id.Lit_LBracket '[')} {(-n)} {(DQ ($ Id.VSub_DollarName '$XVFB_PID'))} 
                          {(Id.Lit_RBracket ']')}
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:250)
                    )
                  ]
                  action: [
                    (C {(kill)} 
                      {
                        (command_sub
                          left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:269)
                          command_list: 
                            (command.CommandList
                              children: [
                                (C {(pgrep)} {(--parent)} {($ Id.VSub_DollarName '$XVFB_PID')} {(java)})
                              ]
                            )
                        )
                      }
                    )
                    (C {(wait)} {($ Id.VSub_DollarName '$XVFB_PID')})
                  ]
                  spids: [238 252]
                )
              ]
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Exit val:exit span_id:288)
              arg_word: {($ Id.VSub_DollarName '$rc')}
            )
          ]
        )
    )
    (command.ShFunction
      name: cacheSeleniumJar
      body: 
        (command.BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (command.DBracket
                          expr: 
                            (bool_expr.LogicalNot
                              child: 
                                (bool_expr.Unary
                                  op_id: Id.BoolUnary_e
                                  child: {(./) ($ Id.VSub_DollarName '$SELENIUM_JAR')}
                                )
                            )
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:315)
                    )
                  ]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DOWNLOAD)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:321)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(mktemp)} {(selenium-download.XXXXXX)})]
                                  )
                              )
                            }
                          spids: [320]
                        )
                      ]
                    )
                    (C {(curl)} {(-o)} {($ Id.VSub_DollarName '$DOWNLOAD')} 
                      {($ Id.VSub_DollarName '$SELENIUM_DOWNLOAD_URL')}
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:DOWNLOAD_SHASUM)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:338)
                                command_list: 
                                  (command.CommandList
                                    children: [
                                      (command.Pipeline
                                        children: [
                                          (C {(sha256sum)} {($ Id.VSub_DollarName '$DOWNLOAD')})
                                          (C {(cut)} {(-f)} {(1)} {(-d)} 
                                            {(SQ (Token id:Id.Lit_Chars val:' ' span_id:354))}
                                          )
                                        ]
                                        negated: F
                                      )
                                    ]
                                  )
                              )
                            }
                          spids: [337]
                        )
                      ]
                    )
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.DBracket
                                  expr: 
                                    (bool_expr.Binary
                                      op_id: Id.BoolBinary_GlobEqual
                                      left: {(DQ ($ Id.VSub_DollarName '$DOWNLOAD_SHASUM'))}
                                      right: {(DQ ($ Id.VSub_DollarName '$SELENIUM_JAR_SHA256'))}
                                    )
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:375)
                            )
                          ]
                          action: [
                            (C {(mv)} {($ Id.VSub_DollarName '$DOWNLOAD')} 
                              {(./) ($ Id.VSub_DollarName '$SELENIUM_JAR')}
                            )
                          ]
                          spids: [359 377]
                        )
                      ]
                      else_action: [
                        (C {(echo)} 
                          {
                            (DQ 
                              ("Selenium jar download didn't match expected checksum.  Discarding.")
                            )
                          }
                        )
                        (command.ControlFlow
                          token: (Token id:Id.ControlFlow_Exit val:exit span_id:398)
                          arg_word: {(1)}
                        )
                      ]
                    )
                  ]
                  spids: [302 317]
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: checkInstalled
      body: 
        (command.BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (command.Pipeline
                          children: [
                            (C 
                              {
                                (command_sub
                                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:422)
                                  command_list: 
                                    (command.CommandList
                                      children: [
                                        (command.Simple
                                          words: [{(which)} {($ Id.VSub_Number '$1')}]
                                          redirects: [
                                            (redir.Redir
                                              op: (Token id:Id.Redir_Great val:'>' span_id:427)
                                              fd: -1
                                              arg_word: {(/dev/null)}
                                            )
                                            (redir.Redir
                                              op: (Token id:Id.Redir_Great val:'2>' span_id:430)
                                              fd: 2
                                              arg_word: {(/dev/null)}
                                            )
                                          ]
                                        )
                                      ]
                                    )
                                )
                              }
                            )
                          ]
                          negated: T
                        )
                      terminator: (Token id:Id.Op_Semi val:';' span_id:434)
                    )
                  ]
                  action: [
                    (C {(echo)} 
                      {
                        (DQ ("Couldn't find executable '") ($ Id.VSub_Number '$1') 
                          ("' - try installing the ") ($ Id.VSub_Number '$2') (' package?')
                        )
                      }
                    )
                    (command.ControlFlow
                      token: (Token id:Id.ControlFlow_Exit val:exit span_id:450)
                      arg_word: {(1)}
                    )
                  ]
                  spids: [418 436]
                )
              ]
            )
          ]
        )
    )
    (command.WhileUntil
      keyword: (Token id:Id.KW_While val:while span_id:463)
      cond: [
        (command.Sentence
          child: 
            (C {(Id.Lit_LBracket '[')} {($ Id.VSub_Pound '$#')} {(-gt)} {(0)} {(Id.Lit_RBracket ']')})
          terminator: (Token id:Id.Op_Semi val:';' span_id:475)
        )
      ]
      body: 
        (command.DoGroup
          children: [
            (command.Case
              to_match: {($ Id.VSub_Number '$1')}
              arms: [
                (case_arm
                  pat_list: [{(--no-selenium)}]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:RUN_SELENIUM)
                          op: assign_op.Equal
                          rhs: {(DQ (false))}
                          spids: [491]
                        )
                      ]
                    )
                  ]
                  spids: [487 488 497 -1]
                )
                (case_arm
                  pat_list: [{(Id.Lit_Star '*')}]
                  action: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (C {(Id.Lit_LBracket '[')} {(-n)} 
                                  {(DQ ($ Id.VSub_DollarName '$BUNDLE_PATH'))} {(Id.Lit_RBracket ']')}
                                )
                              terminator: (Token id:Id.Op_Semi val:';' span_id:515)
                            )
                          ]
                          action: [
                            (C {(echo)} 
                              {(DQ ('Multiple bundle paths specified, please name only one.'))}
                            )
                            (command.ControlFlow
                              token: (Token id:Id.ControlFlow_Exit val:exit span_id:527)
                              arg_word: {(1)}
                            )
                          ]
                          spids: [504 517]
                        )
                      ]
                    )
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name name:BUNDLE_PATH)
                          op: assign_op.Equal
                          rhs: 
                            {
                              (command_sub
                                left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:536)
                                command_list: 
                                  (command.CommandList
                                    children: [(C {(readlink)} {(-f)} {(DQ ($ Id.VSub_Number '$1'))})]
                                  )
                              )
                            }
                          spids: [535]
                        )
                      ]
                    )
                  ]
                  spids: [500 501 547 -1]
                )
              ]
            )
            (C {(shift)})
          ]
        )
    )
    (command.If
      arms: [
        (if_arm
          cond: [
            (command.Sentence
              child: 
                (C {(Id.Lit_LBracket '[')} {(-z)} {(DQ ($ Id.VSub_DollarName '$BUNDLE_PATH'))} 
                  {(Id.Lit_RBracket ']')}
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:570)
            )
          ]
          action: [
            (C {(echo)} 
              {
                (DQ ("No bundle path specified; perhaps you meant to write '") ($ Id.VSub_Number '$0') 
                  (" sandstorm-0-fast.tar.xz'?")
                )
              }
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Exit val:exit span_id:584)
              arg_word: {(1)}
            )
          ]
          spids: [558 572]
        )
      ]
    )
    (C {(cd)} {(DQ ($ Id.VSub_DollarName '$THIS_DIR'))})
    (C {(checkInstalled)} {(firefox)} {(firefox)})
    (C {(DQ ($ Id.VSub_DollarName '$NPM'))} {(install)})
    (command.If
      arms: [
        (if_arm
          cond: [
            (command.Sentence
              child: 
                (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$RUN_SELENIUM'))} 
                  {(Id.KW_Bang '!') (Id.Lit_Equals '=')} {(DQ (false))} {(Id.Lit_RBracket ']')}
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:629)
            )
          ]
          action: [
            (C {(checkInstalled)} {(java)} {(default-jre-headless)})
            (C {(checkInstalled)} {(xvfb-run)} {(Xvfb)})
            (C {(checkInstalled)} {(pgrep)} {(procps)})
            (C {(cacheSeleniumJar)})
            (command.Sentence
              child: 
                (C {(xvfb-run)} {(--server-args) (Id.Lit_Equals '=') (DQ ('-screen 0, 1280x1024x24'))} 
                  {(java)} {(-jar)} {(./) ($ Id.VSub_DollarName '$SELENIUM_JAR')}
                )
              terminator: (Token id:Id.Op_Amp val:'&' span_id:673)
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:XVFB_PID)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Bang '$!')}
                  spids: [676]
                )
              ]
            )
          ]
          spids: [612 631]
        )
      ]
    )
    (C {(export)} 
      {(Id.Lit_VarLike 'SANDSTORM_DIR=') ($ Id.VSub_DollarName '$THIS_DIR') (/tmp-sandstorm)}
    )
    (C {(export)} 
      {(Id.Lit_VarLike 'OVERRIDE_SANDSTORM_DEFAULT_DIR=') ($ Id.VSub_DollarName '$SANDSTORM_DIR')}
    )
    (C {(export)} {(Id.Lit_VarLike 'PORT=') (9000)})
    (C {(export)} {(Id.Lit_VarLike 'MONGO_PORT=') (9001)})
    (C {(export)} {(Id.Lit_VarLike 'SMTP_LISTEN_PORT=') (9002)})
    (C {(export)} {(Id.Lit_VarLike 'SMTP_OUTGOING_PORT=') (9003)})
    (C {(export)} {(Id.Lit_VarLike 'IP_INTERFACE_TEST_PORT=') (9004)})
    (C {(export)} 
      {(Id.Lit_VarLike 'LAUNCH_URL=') 
        (DQ ('http://local.sandstorm.io:') ($ Id.VSub_DollarName '$PORT'))
      }
    )
    (C {(rm)} {(-rf)} {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR'))})
    (C {(../install.sh)} {(-d)} {(-u)} {(DQ ($ Id.VSub_DollarName '$BUNDLE_PATH'))})
    (command.Simple
      words: [
        {(echo)}
        {
          (DQ ('IS_TESTING=true\n') ('ALLOW_DEMO_ACCOUNTS=true\n') 
            ('BASE_URL=http://local.sandstorm.io:') ($ Id.VSub_DollarName '$PORT') ('\n') ('WILDCARD_HOST=*.local.sandstorm.io:') 
            ($ Id.VSub_DollarName '$PORT') ('\n') ('PORT=') ($ Id.VSub_DollarName '$PORT') ('\n') ('MONGO_PORT=') 
            ($ Id.VSub_DollarName '$MONGO_PORT') ('\n') ('SMTP_LISTEN_PORT=') (${ Id.VSub_Name SMTP_LISTEN_PORT) ('\n') ('MAIL_URL=smtp://127.0.0.1:') 
            (${ Id.VSub_Name SMTP_OUTGOING_PORT) ('\n') ('UPDATE_CHANNEL=none\n')
          )
        }
      ]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_DGreat val:'>>' span_id:782)
          fd: -1
          arg_word: {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR') (/sandstorm.conf))}
        )
      ]
    )
    (C {(DQ ($ Id.VSub_DollarName '$SANDSTORM_DIR') (/sandstorm))} {(start)})
    (C {(echo)} {(-n)} {(DQ ('Waiting for sandstorm to start.'))})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:COUNT)
          op: assign_op.Equal
          rhs: {(0)}
          spids: [805]
        )
      ]
    )
    (command.Sentence
      child: 
        (command.WhileUntil
          keyword: (Token id:Id.KW_While val:while span_id:808)
          cond: [
            (command.Sentence
              child: 
                (command.Pipeline
                  children: [
                    (command.Simple
                      words: [
                        {(curl)}
                        {(-s)}
                        {(localhost) (Id.Lit_Other ':') ($ Id.VSub_DollarName '$PORT')}
                      ]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:820)
                          fd: -1
                          arg_word: {(/dev/null)}
                        )
                      ]
                    )
                  ]
                  negated: T
                )
              terminator: (Token id:Id.Op_Semi val:';' span_id:823)
            )
          ]
          body: 
            (command.DoGroup
              children: [
                (command.If
                  arms: [
                    (if_arm
                      cond: [
                        (command.Sentence
                          child: 
                            (C {(Id.Lit_LBracket '[')} {(DQ ($ Id.VSub_DollarName '$COUNT'))} {(-gt)} 
                              {(600)} {(Id.Lit_RBracket ']')}
                            )
                          terminator: (Token id:Id.Op_Semi val:';' span_id:841)
                        )
                      ]
                      action: [(C {(echo)} {(DQ ('Sandstorm failed to start'))}) (C {(cleanExit)} {(1)})]
                      spids: [828 843]
                    )
                  ]
                )
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:COUNT)
                      op: assign_op.Equal
                      rhs: 
                        {
                          (word_part.ArithSub
                            anode: 
                              (arith_expr.Binary
                                op_id: Id.Arith_Plus
                                left: (arith_expr.ArithWord w:{($ Id.VSub_DollarName '$COUNT')})
                                right: (arith_expr.ArithWord w:{(Id.Lit_Digits 1)})
                              )
                          )
                        }
                      spids: [864]
                    )
                  ]
                )
                (C {(echo)} {(-n)} {(.)})
                (C {(sleep)} {(.1)})
              ]
            )
        )
      terminator: (Token id:Id.Op_Semi val:';' span_id:885)
    )
    (C {(echo)})
    (C {(Id.KW_Set set)} {(Id.Lit_Other '+') (e)})
    (C {(export)} {(Id.Lit_VarLike 'DISABLE_DEMO=') (true)})
    (C {(DQ ($ Id.VSub_DollarName '$NPM'))} {(test)})
    (C {(cleanExit)} {($ Id.VSub_QMark '$?')})
  ]
)