(command.CommandList
  children: [
    (C {<hash>} {<-r>})
    (command.ShFunction
      name: wait_for_ssh
      body: 
        (command.BraceGroup
          children: [
            (C {<local>} {<Id.Lit_VarLike 'hostname='> (DQ ($ Id.VSub_Number '$1'))})
            (C {<local>} 
              {<Id.Lit_VarLike 'min='> 
                (braced_var_sub
                  token: <Id.VSub_Number 2>
                  suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{<1>})
                )
              } 
              {<Id.Lit_VarLike 'max='> 
                (braced_var_sub
                  token: <Id.VSub_Number 3>
                  suffix_op: (suffix_op.Unary op_id:Id.VTest_ColonHyphen arg_word:{<10>})
                )
              }
            )
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ (${ Id.VSub_Name hostname))} 
                          {<Id.Lit_RBracket ']'>}
                        )
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  action: [
                    (command.Sentence
                      child: (command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<1>})
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  spids: [49 65]
                )
              ]
            )
            (command.Simple
              words: [{<exec>}]
              redirects: [(redir.Redir op:<Id.Redir_GreatAnd '3>&'> fd:3 arg_word:{<2>})]
            )
            (command.Simple
              words: [{<exec>}]
              redirects: [(redir.Redir op:<Id.Redir_Great '2>'> fd:2 arg_word:{</dev/null>})]
            )
            (command.WhileUntil
              keyword: <Id.KW_While while>
              cond: [(command.Sentence child:(C {<true>}) terminator:<Id.Op_Semi _>)]
              body: 
                (command.DoGroup
                  children: [
                    (command.If
                      arms: [
                        (if_arm
                          cond: [
                            (command.Sentence
                              child: 
                                (command.Simple
                                  words: [{<echo>}]
                                  redirects: [
                                    (redir.Redir
                                      op: <Id.Redir_Great '>'>
                                      fd: -1
                                      arg_word: {</dev/tcp/> (${ Id.VSub_Name hostname) </22>}
                                    )
                                  ]
                                )
                              terminator: <Id.Op_Semi _>
                            )
                          ]
                          action: [
                            (command.ControlFlow
                              token: <Id.ControlFlow_Return return>
                              arg_word: {<0>}
                            )
                          ]
                          spids: [97 111]
                        )
                      ]
                    )
                    (C {<sleep>} 
                      {
                        (word_part.ArithSub
                          anode: 
                            (arith_expr.Binary
                              op_id: Id.Arith_Plus
                              left: 
                                (arith_expr.Binary
                                  op_id: Id.Arith_Percent
                                  left: (arith_expr.ArithWord w:{($ Id.VSub_DollarName '$RANDOM')})
                                  right: (arith_expr.ArithWord w:{($ Id.VSub_DollarName '$max')})
                                )
                              right: (arith_expr.ArithWord w:{($ Id.VSub_DollarName '$min')})
                            )
                        )
                      }
                    )
                  ]
                )
            )
            (command.Simple
              words: [{<exec>}]
              redirects: [(redir.Redir op:<Id.Redir_GreatAnd '2>&'> fd:2 arg_word:{<3>})]
            )
            (command.Simple
              words: [{<exec>}]
              redirects: [(redir.Redir op:<Id.Redir_GreatAnd '3>&'> fd:3 arg_word:{<->})]
            )
          ]
        )
    )
    (command.ShFunction
      name: wait_for_snapshot
      body: 
        (command.BraceGroup
          children: [
            (C {<local>} {<Id.Lit_VarLike 'ip='> (DQ ($ Id.VSub_Number '$1'))})
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ (${ Id.VSub_Name ip))} 
                          {<Id.Lit_RBracket ']'>}
                        )
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  action: [(command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<1>})]
                  spids: [171 187]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {<local>} 
                  {<Id.Lit_VarLike 'vmname='> 
                    (DQ 
                      (command_sub
                        left_token: <Id.Left_DollarParen '$('>
                        command_list: 
                          (command.CommandList
                            children: [(C {<ip_to_name>} {(${ Id.VSub_Name ip)})]
                          )
                      )
                    )
                  }
                )
                (command.ControlFlow
                  token: <Id.ControlFlow_Return return>
                  arg_word: {<2>}
                )
              ]
            )
            (C {<echo>} 
              {
                (DQ <'Waiting to snapshot '> (${ Id.VSub_Name vmname) <' at '> (${ Id.VSub_Name ip) <...>)
              }
            )
            (C {<wait_for_ssh>} {(DQ (${ Id.VSub_Name ip))})
            (C {<VBoxManage>} {<snapshot>} {(DQ (${ Id.VSub_Name vmname))} {<take>} {<build_completed>} 
              {<--description>} {(DQ <'Base OS installed'>)}
            )
          ]
        )
    )
    (command.ShFunction
      name: ip_to_name
      body: 
        (command.BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (command.Sentence
                      child: 
                        (C {<Id.Lit_LBracket '['>} {<-z>} {(DQ ($ Id.VSub_Number '$1'))} 
                          {<Id.Lit_RBracket ']'>}
                        )
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  action: [
                    (command.Sentence
                      child: (command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<1>})
                      terminator: <Id.Op_Semi _>
                    )
                  ]
                  spids: [274 288]
                )
              ]
            )
            (C {<local>} 
              {<Id.Lit_VarLike 'l='> 
                (DQ 
                  (braced_var_sub
                    token: <Id.VSub_Number 1>
                    suffix_op: (suffix_op.Unary op_id:Id.VOp1_DPound arg_word:{<'*.'>})
                  )
                )
              }
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:l)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (word_part.ArithSub
                        anode: 
                          (arith_expr.Binary
                            op_id: Id.Arith_Minus
                            left: (arith_expr.VarRef token:<Id.Lit_ArithVarLike l>)
                            right: (arith_expr.ArithWord w:{<Id.Lit_Digits 10>})
                          )
                      )
                    }
                  spids: [311]
                )
              ]
            )
            (C {<echo>} {(DQ <bcpc-vm> (${ Id.VSub_Name l))})
          ]
        )
    )
    (command.ForEach
      iter_name: ip
      iter_words: [
        (word.BracedTree
          parts: [<10.0.100.> (word_part.BracedRange kind:Id.Range_Int start:11 end:13 step:1)]
        )
      ]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (command.Sentence
              child: (C {<eval>} {(DQ <'wait_for_snapshot '> (${ Id.VSub_Name ip) <' &'>)})
              terminator: <Id.Op_Semi _>
            )
          ]
        )
    )
    (C {<wait>})
  ]
)