func resourceVMDelete(d *schema.ResourceData, meta interface{}) error {
	vm, err := vbox.GetMachine(d.Id())
	if err != nil {
		return err
	}
	return vm.Delete()
}
func resourceVMUpdate(d *schema.ResourceData, meta interface{}) error {
	/* TODO: allow partial updates */

	vm, err := vbox.GetMachine(d.Id())
	if err != nil {
		return err
	}

	if err := vm.Poweroff(); err != nil {
		return err
	}

	/* Modify VM */
	err = tf_to_vbox(d, vm)
	if err != nil {
		return err
	}
	err = vm.Modify()
	if err != nil {
		return err
	}

	if err := powerOnAndWait(d, vm, meta); err != nil {
		return err
	}

	return resourceVMRead(d, meta)
}
func resourceVMRead(d *schema.ResourceData, meta interface{}) error {
	vm, err := vbox.GetMachine(d.Id())
	if err != nil {
		/* VM no longer exist */
		if err == vbox.ErrMachineNotExist {
			d.SetId("")
			return nil
		}
		return err
	}

	// if vm.State != vbox.Running {
	// 	setState(d, vm.State)
	// 	return nil
	// }

	setState(d, vm.State)
	d.Set("name", vm.Name)
	d.Set("cpus", vm.CPUs)
	bytes := uint64(vm.Memory) * humanize.MiByte
	repr := humanize.IBytes(bytes)
	d.Set("memory", strings.ToLower(repr))

	userData, err := vm.GetExtraData("user_data")
	if err != nil {
		return err
	}
	if userData != nil && *userData != "" {
		d.Set("user_data", *userData)
	}

	err = net_vbox_to_tf(vm, d)
	if err != nil {
		return err
	}

	/* Set connection info to first non NAT IPv4 address */
	for i, nic := range vm.NICs {
		if nic.Network == vbox.NICNetNAT {
			continue
		}
		availKey := fmt.Sprintf("network_adapter.%d.ipv4_address_available", i)
		if d.Get(availKey).(string) != "yes" {
			continue
		}
		ipv4Key := fmt.Sprintf("network_adapter.%d.ipv4_address", i)
		ipv4 := d.Get(ipv4Key).(string)
		if ipv4 == "" {
			continue
		}
		d.SetConnInfo(map[string]string{
			"type": "ssh",
			"host": ipv4,
		})
		break
	}

	return nil
}
func resourceVMExists(d *schema.ResourceData, meta interface{}) (bool, error) {
	name := d.Get("name").(string)
	_, err := vbox.GetMachine(name)
	if err == nil {
		return true, nil
	} else if err == vbox.ErrMachineNotExist {
		return false, nil
	} else {
		log.Printf("[ERROR] Checking existence of VM '%s'\n", name)
		return false, err
	}
}
func newVMStateRefreshFunc(
	d *schema.ResourceData, attribute string, meta interface{}) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		err := resourceVMRead(d, meta)
		if err != nil {
			return nil, "", err
		}

		// See if we can access our attribute
		if attr, ok := d.GetOk(attribute); ok {
			// Retrieve the VM properties
			vm, err := vbox.GetMachine(d.Id())
			if err != nil {
				return nil, "", fmt.Errorf("Error retrieving VM: %s", err)
			}

			return &vm, attr.(string), nil
		}

		return nil, "", nil
	}
}