docs: def create_machine(self, name, key, image_id, location_id, size_id,
                         image_extra="", disk="", script="", monitoring=False,
                         ips=[], networks=[], location_name="", async=False,
                         docker_command="", quantity=1, persist=False, fire_and_forget=True,
                         timeout=6000, script_id="", script_params="", verbose=False,
                         associate_floating_ip=False, provider="", tags=None,
                         cloud_init='', env_vars=''):
          """
          Create a new machine on the given cloud
  
          :param name: Name of the machine
          :param key: Key Object to associate with the machine
          :param image_id: Id of image to be used with the creation
          :param location_id: Id of the cloud's location to create the machine
          :param size_id: If of the size of the machine
          :param image_extra: Needed only by Linode cloud
          :param disk: Needed only by Linode cloud
          :returns: An update list of added machines
          """
          if isinstance(key, basestring):
              key_id = key
          else:
              key_id = key.id
  
          payload = {
              'name': name,
              'provider': provider,
              'key': key_id,
              'image': image_id,
              'location': location_id,
              'size': size_id,
              'image_extra': image_extra,
              'disk': disk,
              'script': script,
              'monitoring': monitoring,
              'ips': ips,
              'networks': networks,
              'location_name': location_name,
              'docker_command': docker_command,
              'async': async,
              'quantity': quantity,
              'persist': persist,
              'associate_floating_ip': associate_floating_ip,
              'tags': tags,
              'cloud_init': cloud_init,
              'env_vars':  env_vars
          }
          # add as params only if they are provided
          if script_id:
              payload['script_id'] = script_id
          if script_params:
              payload['script_params'] = script_params
          data = json.dumps(payload)
          req = self.request(self.mist_client.uri+'/clouds/'+self.id+'/machines', data=data)
          result = req.post()
          self.update_machines()
  
          if not async or fire_and_forget:
              return result.json()
          else:
              job_id = result.json()['job_id']
  
              started_at = time()
              while True:
                  job = self.mist_client.get_job(job_id)
  
                  if verbose:
                      summary = job.get('summary', {})
  
                      probes = summary.get('probe', {})
                      creates = summary.get('create', {})
                      scripts = summary.get('script', {})
                      monitoring = summary.get('monitoring', {})
  
                      states = [
                          'success',
                          'error',
                          'skipped',
                          'pending'
                      ]
  
                      x = PrettyTable(['', 'SUCCESS', 'ERROR', 'SKIPPED', 'PENDING'])
  
                      if creates:
                          machines_created = {}
                          for state in states:
                              machines_created[state] = '%s/%s' % (creates.get(state, 'Undefined'), quantity)
                          x.add_row(["Create:", machines_created['success'], machines_created['error'],
                                     machines_created['skipped'], machines_created['pending']])
  
                      if probes:
                          probed_machines = {}
                          for state in states:
                              probed_machines[state] = '%s/%s' % (probes.get(state, 'Undefined'), quantity)
                          x.add_row(["Probe:", probed_machines['success'], probed_machines['error'],
                                     probed_machines['skipped'], probed_machines['pending']])
  
                      if scripts:
                          scripted_machines = {}
                          for state in states:
                              scripted_machines[state] = '%s/%s' % (scripts.get(state, 'Undefined'), quantity)
                          x.add_row(["Script:", scripted_machines['success'], scripted_machines['error'],
                                     scripted_machines['skipped'], scripted_machines['pending']])
  
                      if monitoring:
                          monitored_machines = {}
                          for state in states:
                              monitored_machines[state] = '%s/%s' % (monitoring.get(state, 'Undefined'), quantity)
                          x.add_row(["Monitoring:", monitored_machines['success'], monitored_machines['error'],
                                     monitored_machines['skipped'], monitored_machines['pending']])
  
                      print x
                      print
  
                  if job.get('finished_at', 0):
                      provision_finished = True
                  else:
                      # In case of nested logs, we have to make sure we parse the
                      # the logs correctly in order to determine whether the
                      # provisioned VM is running, since a story may contain logs
                      # of multiple machines
                      for log in job.get('logs', []):
                          if log.get('machine_name', '') == name and \
                              'machine_creation_finished' in log.values():
                              machine_id = log['machine_id']
                              error = log.get('error')
                              break
                      else:
                          sleep(5)
                          continue
  
                      if error:
                          provision_finished = True
                      else:
                          for log in job.get('logs', []):
                              if log.get('machine_id', '') == machine_id and \
                                  'post_deploy_finished' in log.values():
                                  provision_finished = True
                                  break
                          else:
                              provision_finished = False
  
                  if provision_finished:
                      error = job.get('error')
                      if error:
                          print "Finished with errors:"
                          logs = job.get('logs', [])
                          for log in logs:
                              error = log.get('error')
                              if error:
                                  print " - ", error
                          raise Exception("Create machine failed. Check the logs.")
                      elif verbose and not error:
                          print "Finished without errors!"
                      self.update_machines()
                      return job
  
                  elif time() - started_at > timeout:
                      print "Timed out!"
                      raise Exception("Create machine timed out. Check the logs.")
                      return job
  
                  sleep(5)