/*
 *============================================================================
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *============================================================================
 * Copyright (C) 2007 Tom Wilkie <tom.wilkie@gmail.com>
 *============================================================================
 */
package com.xensource.xenapi;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.xmlrpc.XmlRpcException;

/**
 * A virtual machine (or 'guest').
 *
 * @author Tom Wilkie <tom.wilkie@gmail.com>
 */
public class VM {

    /**
     * The XenAPI reference to this object.
     */
    protected final String ref;

    private VM(String ref) {
       this.ref = ref;
    }

    /**
     * This code helps ensure there is only one
     * VM instance per XenAPI reference.
     */
    private static final Map<String,SoftReference<VM>> cache = 
        new HashMap<String,SoftReference<VM>>();

    protected static synchronized VM getInstFromRef(String ref) {
        if(VM.cache.containsKey(ref)) {
            VM instance = 
                VM.cache.get(ref).get();
            if(instance != null) {
                return instance;
            }
        }

        VM instance = new VM(ref);
        VM.cache.put(ref, new SoftReference<VM>(instance));
        return instance;
    }

    /**
     * Represents all the fields in a VM
     */
    public static class Record  implements Types.Record{
        public String toString() {
            StringWriter writer = new StringWriter();
            PrintWriter print = new PrintWriter(writer);
            print.printf("%1$20s: %2$s\n", "uuid", this.uuid);
            print.printf("%1$20s: %2$s\n", "powerState", this.powerState);
            print.printf("%1$20s: %2$s\n", "nameLabel", this.nameLabel);
            print.printf("%1$20s: %2$s\n", "nameDescription", this.nameDescription);
            print.printf("%1$20s: %2$s\n", "userVersion", this.userVersion);
            print.printf("%1$20s: %2$s\n", "isATemplate", this.isATemplate);
            print.printf("%1$20s: %2$s\n", "autoPowerOn", this.autoPowerOn);
            print.printf("%1$20s: %2$s\n", "suspendVDI", this.suspendVDI);
            print.printf("%1$20s: %2$s\n", "residentOn", this.residentOn);
            print.printf("%1$20s: %2$s\n", "memoryStaticMax", this.memoryStaticMax);
            print.printf("%1$20s: %2$s\n", "memoryDynamicMax", this.memoryDynamicMax);
            print.printf("%1$20s: %2$s\n", "memoryDynamicMin", this.memoryDynamicMin);
            print.printf("%1$20s: %2$s\n", "memoryStaticMin", this.memoryStaticMin);
            print.printf("%1$20s: %2$s\n", "VCPUsParams", this.VCPUsParams);
            print.printf("%1$20s: %2$s\n", "VCPUsMax", this.VCPUsMax);
            print.printf("%1$20s: %2$s\n", "VCPUsAtStartup", this.VCPUsAtStartup);
            print.printf("%1$20s: %2$s\n", "actionsAfterShutdown", this.actionsAfterShutdown);
            print.printf("%1$20s: %2$s\n", "actionsAfterReboot", this.actionsAfterReboot);
            print.printf("%1$20s: %2$s\n", "actionsAfterCrash", this.actionsAfterCrash);
            print.printf("%1$20s: %2$s\n", "consoles", this.consoles);
            print.printf("%1$20s: %2$s\n", "VIFs", this.VIFs);
            print.printf("%1$20s: %2$s\n", "VBDs", this.VBDs);
            print.printf("%1$20s: %2$s\n", "crashDumps", this.crashDumps);
            print.printf("%1$20s: %2$s\n", "VTPMs", this.VTPMs);
            print.printf("%1$20s: %2$s\n", "PVBootloader", this.PVBootloader);
            print.printf("%1$20s: %2$s\n", "PVKernel", this.PVKernel);
            print.printf("%1$20s: %2$s\n", "PVRamdisk", this.PVRamdisk);
            print.printf("%1$20s: %2$s\n", "PVArgs", this.PVArgs);
            print.printf("%1$20s: %2$s\n", "PVBootloaderArgs", this.PVBootloaderArgs);
            print.printf("%1$20s: %2$s\n", "HVMBootPolicy", this.HVMBootPolicy);
            print.printf("%1$20s: %2$s\n", "HVMBootParams", this.HVMBootParams);
            print.printf("%1$20s: %2$s\n", "platform", this.platform);
            print.printf("%1$20s: %2$s\n", "PCIBus", this.PCIBus);
            print.printf("%1$20s: %2$s\n", "otherConfig", this.otherConfig);
            print.printf("%1$20s: %2$s\n", "domid", this.domid);
            print.printf("%1$20s: %2$s\n", "isControlDomain", this.isControlDomain);
            print.printf("%1$20s: %2$s\n", "metrics", this.metrics);
            print.printf("%1$20s: %2$s\n", "guestMetrics", this.guestMetrics);
            return writer.toString();
        }

        /**
         * Convert a VM.Record to a Map
         */
        public Map<String,Object> toMap() {
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("uuid", this.uuid);
            map.put("power_state", this.powerState);
            map.put("name_label", this.nameLabel);
            map.put("name_description", this.nameDescription);
            map.put("user_version", this.userVersion);
            map.put("is_a_template", this.isATemplate);
            map.put("auto_power_on", this.autoPowerOn);
            map.put("suspend_VDI", this.suspendVDI);
            map.put("resident_on", this.residentOn);
            map.put("memory_static_max", this.memoryStaticMax);
            map.put("memory_dynamic_max", this.memoryDynamicMax);
            map.put("memory_dynamic_min", this.memoryDynamicMin);
            map.put("memory_static_min", this.memoryStaticMin);
            map.put("VCPUs_params", this.VCPUsParams);
            map.put("VCPUs_max", this.VCPUsMax);
            map.put("VCPUs_at_startup", this.VCPUsAtStartup);
            map.put("actions_after_shutdown", this.actionsAfterShutdown);
            map.put("actions_after_reboot", this.actionsAfterReboot);
            map.put("actions_after_crash", this.actionsAfterCrash);
            map.put("consoles", this.consoles);
            map.put("VIFs", this.VIFs);
            map.put("VBDs", this.VBDs);
            map.put("crash_dumps", this.crashDumps);
            map.put("VTPMs", this.VTPMs);
            map.put("PV_bootloader", this.PVBootloader);
            map.put("PV_kernel", this.PVKernel);
            map.put("PV_ramdisk", this.PVRamdisk);
            map.put("PV_args", this.PVArgs);
            map.put("PV_bootloader_args", this.PVBootloaderArgs);
            map.put("HVM_boot_policy", this.HVMBootPolicy);
            map.put("HVM_boot_params", this.HVMBootParams);
            map.put("platform", this.platform);
            map.put("PCI_bus", this.PCIBus);
            map.put("other_config", this.otherConfig);
            map.put("domid", this.domid);
            map.put("is_control_domain", this.isControlDomain);
            map.put("metrics", this.metrics);
            map.put("guest_metrics", this.guestMetrics);
            return map;
        }

        /**
         * unique identifier/object reference
         */
        public String uuid;
        /**
         * Current power state of the machine
         */
        public Types.VmPowerState powerState;
        /**
         * a human-readable name
         */
        public String nameLabel;
        /**
         * a notes field containg human-readable description
         */
        public String nameDescription;
        /**
         * a user version number for this machine
         */
        public Long userVersion;
        /**
         * true if this is a template. Template VMs can never be started, they are used only for cloning other VMs
         */
        public Boolean isATemplate;
        /**
         * true if this VM should be started automatically after host boot
         */
        public Boolean autoPowerOn;
        /**
         * The VDI that a suspend image is stored on. (Only has meaning if VM is currently suspended)
         */
        public VDI suspendVDI;
        /**
         * the host the VM is currently resident on
         */
        public Host residentOn;
        /**
         * Statically-set (i.e. absolute) maximum (bytes)
         */
        public Long memoryStaticMax;
        /**
         * Dynamic maximum (bytes)
         */
        public Long memoryDynamicMax;
        /**
         * Dynamic minimum (bytes)
         */
        public Long memoryDynamicMin;
        /**
         * Statically-set (i.e. absolute) mininum (bytes)
         */
        public Long memoryStaticMin;
        /**
         * configuration parameters for the selected VCPU policy
         */
        public Map<String, String> VCPUsParams;
        /**
         * Max number of VCPUs
         */
        public Long VCPUsMax;
        /**
         * Boot number of VCPUs
         */
        public Long VCPUsAtStartup;
        /**
         * action to take after the guest has shutdown itself
         */
        public Types.OnNormalExit actionsAfterShutdown;
        /**
         * action to take after the guest has rebooted itself
         */
        public Types.OnNormalExit actionsAfterReboot;
        /**
         * action to take if the guest crashes
         */
        public Types.OnCrashBehaviour actionsAfterCrash;
        /**
         * virtual console devices
         */
        public Set<Console> consoles;
        /**
         * virtual network interfaces
         */
        public Set<VIF> VIFs;
        /**
         * virtual block devices
         */
        public Set<VBD> VBDs;
        /**
         * crash dumps associated with this VM
         */
        public Set<Crashdump> crashDumps;
        /**
         * virtual TPMs
         */
        public Set<VTPM> VTPMs;
        /**
         * name of or path to bootloader
         */
        public String PVBootloader;
        /**
         * path to the kernel
         */
        public String PVKernel;
        /**
         * path to the initrd
         */
        public String PVRamdisk;
        /**
         * kernel command-line arguments
         */
        public String PVArgs;
        /**
         * miscellaneous arguments for the bootloader
         */
        public String PVBootloaderArgs;
        /**
         * HVM boot policy
         */
        public String HVMBootPolicy;
        /**
         * HVM boot params
         */
        public Map<String, String> HVMBootParams;
        /**
         * platform-specific configuration
         */
        public Map<String, String> platform;
        /**
         * PCI bus path for pass-through devices
         */
        public String PCIBus;
        /**
         * additional configuration
         */
        public Map<String, String> otherConfig;
        /**
         * domain ID (if available, -1 otherwise)
         */
        public Long domid;
        /**
         * true if this is a control domain (domain 0 or a driver domain)
         */
        public Boolean isControlDomain;
        /**
         * metrics associated with this VM
         */
        public VMMetrics metrics;
        /**
         * metrics associated with the running guest
         */
        public VMGuestMetrics guestMetrics;
    }

    /**
     * Get a record containing the current state of the given VM.
     *
     * @return all fields from the object
     */
    public VM.Record getRecord() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_record";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVMRecord(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get a reference to the VM instance with the specified UUID.
     *
     * @param uuid UUID of object to return
     * @return reference to the object
     */
    public static VM getByUuid(String uuid) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_by_uuid";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(uuid)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Create a new VM instance, and return its handle.
     *
     * @param record All constructor arguments
     * @return reference to the newly created object
     */
    public static VM create(VM.Record record) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.create";
        String session = ConnectionHelper.instance().getSession();
        Map<String, Object> record_map = record.toMap();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(record_map)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Destroy the specified VM.  The VM is completely removed from the system.  This function can only be called when the VM is in the Halted State.
     *
     */
    public void destroy() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.destroy";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get all the VM instances with the given label.
     *
     * @param label label of object to return
     * @return references to objects with matching names
     */
    public static Set<VM> getByNameLabel(String label) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_by_name_label";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(label)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfVM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the uuid field of the given VM.
     *
     * @return value of the field
     */
    public String getUuid() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_uuid";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the power_state field of the given VM.
     *
     * @return value of the field
     */
    public Types.VmPowerState getPowerState() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_power_state";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVmPowerState(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the name/label field of the given VM.
     *
     * @return value of the field
     */
    public String getNameLabel() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_name_label";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the name/description field of the given VM.
     *
     * @return value of the field
     */
    public String getNameDescription() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_name_description";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the user_version field of the given VM.
     *
     * @return value of the field
     */
    public Long getUserVersion() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_user_version";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the is_a_template field of the given VM.
     *
     * @return value of the field
     */
    public Boolean getIsATemplate() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_is_a_template";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toBoolean(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the auto_power_on field of the given VM.
     *
     * @return value of the field
     */
    public Boolean getAutoPowerOn() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_auto_power_on";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toBoolean(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the suspend_VDI field of the given VM.
     *
     * @return value of the field
     */
    public VDI getSuspendVDI() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_suspend_VDI";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVDI(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the resident_on field of the given VM.
     *
     * @return value of the field
     */
    public Host getResidentOn() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_resident_on";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toHost(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the memory/static_max field of the given VM.
     *
     * @return value of the field
     */
    public Long getMemoryStaticMax() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_memory_static_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the memory/dynamic_max field of the given VM.
     *
     * @return value of the field
     */
    public Long getMemoryDynamicMax() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_memory_dynamic_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the memory/dynamic_min field of the given VM.
     *
     * @return value of the field
     */
    public Long getMemoryDynamicMin() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_memory_dynamic_min";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the memory/static_min field of the given VM.
     *
     * @return value of the field
     */
    public Long getMemoryStaticMin() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_memory_static_min";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VCPUs/params field of the given VM.
     *
     * @return value of the field
     */
    public Map<String, String> getVCPUsParams() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VCPUs_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toMapOfStringString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VCPUs/max field of the given VM.
     *
     * @return value of the field
     */
    public Long getVCPUsMax() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VCPUs_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VCPUs/at_startup field of the given VM.
     *
     * @return value of the field
     */
    public Long getVCPUsAtStartup() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VCPUs_at_startup";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the actions/after_shutdown field of the given VM.
     *
     * @return value of the field
     */
    public Types.OnNormalExit getActionsAfterShutdown() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_actions_after_shutdown";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toOnNormalExit(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the actions/after_reboot field of the given VM.
     *
     * @return value of the field
     */
    public Types.OnNormalExit getActionsAfterReboot() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_actions_after_reboot";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toOnNormalExit(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the actions/after_crash field of the given VM.
     *
     * @return value of the field
     */
    public Types.OnCrashBehaviour getActionsAfterCrash() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_actions_after_crash";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toOnCrashBehaviour(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the consoles field of the given VM.
     *
     * @return value of the field
     */
    public Set<Console> getConsoles() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_consoles";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfConsole(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VIFs field of the given VM.
     *
     * @return value of the field
     */
    public Set<VIF> getVIFs() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VIFs";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfVIF(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VBDs field of the given VM.
     *
     * @return value of the field
     */
    public Set<VBD> getVBDs() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VBDs";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfVBD(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the crash_dumps field of the given VM.
     *
     * @return value of the field
     */
    public Set<Crashdump> getCrashDumps() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_crash_dumps";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfCrashdump(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the VTPMs field of the given VM.
     *
     * @return value of the field
     */
    public Set<VTPM> getVTPMs() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_VTPMs";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfVTPM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PV/bootloader field of the given VM.
     *
     * @return value of the field
     */
    public String getPVBootloader() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PV_bootloader";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PV/kernel field of the given VM.
     *
     * @return value of the field
     */
    public String getPVKernel() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PV_kernel";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PV/ramdisk field of the given VM.
     *
     * @return value of the field
     */
    public String getPVRamdisk() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PV_ramdisk";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PV/args field of the given VM.
     *
     * @return value of the field
     */
    public String getPVArgs() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PV_args";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PV/bootloader_args field of the given VM.
     *
     * @return value of the field
     */
    public String getPVBootloaderArgs() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PV_bootloader_args";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the HVM/boot_policy field of the given VM.
     *
     * @return value of the field
     */
    public String getHVMBootPolicy() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_HVM_boot_policy";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the HVM/boot_params field of the given VM.
     *
     * @return value of the field
     */
    public Map<String, String> getHVMBootParams() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_HVM_boot_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toMapOfStringString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the platform field of the given VM.
     *
     * @return value of the field
     */
    public Map<String, String> getPlatform() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_platform";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toMapOfStringString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the PCI_bus field of the given VM.
     *
     * @return value of the field
     */
    public String getPCIBus() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_PCI_bus";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the other_config field of the given VM.
     *
     * @return value of the field
     */
    public Map<String, String> getOtherConfig() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_other_config";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toMapOfStringString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the domid field of the given VM.
     *
     * @return value of the field
     */
    public Long getDomid() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_domid";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toLong(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the is_control_domain field of the given VM.
     *
     * @return value of the field
     */
    public Boolean getIsControlDomain() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_is_control_domain";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toBoolean(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the metrics field of the given VM.
     *
     * @return value of the field
     */
    public VMMetrics getMetrics() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_metrics";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVMMetrics(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get the guest_metrics field of the given VM.
     *
     * @return value of the field
     */
    public VMGuestMetrics getGuestMetrics() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_guest_metrics";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVMGuestMetrics(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the name/label field of the given VM.
     *
     * @param label New value to set
     */
    public void setNameLabel(String label) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_name_label";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(label)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the name/description field of the given VM.
     *
     * @param description New value to set
     */
    public void setNameDescription(String description) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_name_description";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(description)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the user_version field of the given VM.
     *
     * @param userVersion New value to set
     */
    public void setUserVersion(Long userVersion) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_user_version";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(userVersion)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the is_a_template field of the given VM.
     *
     * @param isATemplate New value to set
     */
    public void setIsATemplate(Boolean isATemplate) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_is_a_template";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(isATemplate)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the auto_power_on field of the given VM.
     *
     * @param autoPowerOn New value to set
     */
    public void setAutoPowerOn(Boolean autoPowerOn) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_auto_power_on";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(autoPowerOn)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the memory/static_max field of the given VM.
     *
     * @param staticMax New value to set
     */
    public void setMemoryStaticMax(Long staticMax) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_static_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(staticMax)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the memory/dynamic_max field of the given VM.
     *
     * @param dynamicMax New value to set
     */
    public void setMemoryDynamicMax(Long dynamicMax) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_dynamic_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(dynamicMax)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the memory/dynamic_min field of the given VM.
     *
     * @param dynamicMin New value to set
     */
    public void setMemoryDynamicMin(Long dynamicMin) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_dynamic_min";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(dynamicMin)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the memory/static_min field of the given VM.
     *
     * @param staticMin New value to set
     */
    public void setMemoryStaticMin(Long staticMin) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_static_min";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(staticMin)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the VCPUs/params field of the given VM.
     *
     * @param params New value to set
     */
    public void setVCPUsParams(Map<String, String> params) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_VCPUs_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(params)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Add the given key-value pair to the VCPUs/params field of the given VM.
     *
     * @param key Key to add
     * @param value Value to add
     */
    public void addToVCPUsParams(String key, String value) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.add_to_VCPUs_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key), Marshalling.toXMLRPC(value)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Remove the given key and its corresponding value from the VCPUs/params field of the given VM.  If the key is not in that Map, then do nothing.
     *
     * @param key Key to remove
     */
    public void removeFromVCPUsParams(String key) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.remove_from_VCPUs_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the VCPUs/max field of the given VM.
     *
     * @param max New value to set
     */
    public void setVCPUsMax(Long max) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_VCPUs_max";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(max)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the VCPUs/at_startup field of the given VM.
     *
     * @param atStartup New value to set
     */
    public void setVCPUsAtStartup(Long atStartup) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_VCPUs_at_startup";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(atStartup)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the actions/after_shutdown field of the given VM.
     *
     * @param afterShutdown New value to set
     */
    public void setActionsAfterShutdown(Types.OnNormalExit afterShutdown) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_actions_after_shutdown";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(afterShutdown)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the actions/after_reboot field of the given VM.
     *
     * @param afterReboot New value to set
     */
    public void setActionsAfterReboot(Types.OnNormalExit afterReboot) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_actions_after_reboot";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(afterReboot)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the actions/after_crash field of the given VM.
     *
     * @param afterCrash New value to set
     */
    public void setActionsAfterCrash(Types.OnCrashBehaviour afterCrash) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_actions_after_crash";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(afterCrash)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PV/bootloader field of the given VM.
     *
     * @param bootloader New value to set
     */
    public void setPVBootloader(String bootloader) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PV_bootloader";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(bootloader)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PV/kernel field of the given VM.
     *
     * @param kernel New value to set
     */
    public void setPVKernel(String kernel) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PV_kernel";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(kernel)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PV/ramdisk field of the given VM.
     *
     * @param ramdisk New value to set
     */
    public void setPVRamdisk(String ramdisk) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PV_ramdisk";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(ramdisk)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PV/args field of the given VM.
     *
     * @param args New value to set
     */
    public void setPVArgs(String args) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PV_args";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(args)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PV/bootloader_args field of the given VM.
     *
     * @param bootloaderArgs New value to set
     */
    public void setPVBootloaderArgs(String bootloaderArgs) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PV_bootloader_args";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(bootloaderArgs)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the HVM/boot_policy field of the given VM.
     *
     * @param bootPolicy New value to set
     */
    public void setHVMBootPolicy(String bootPolicy) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_HVM_boot_policy";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(bootPolicy)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the HVM/boot_params field of the given VM.
     *
     * @param bootParams New value to set
     */
    public void setHVMBootParams(Map<String, String> bootParams) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_HVM_boot_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(bootParams)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Add the given key-value pair to the HVM/boot_params field of the given VM.
     *
     * @param key Key to add
     * @param value Value to add
     */
    public void addToHVMBootParams(String key, String value) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.add_to_HVM_boot_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key), Marshalling.toXMLRPC(value)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Remove the given key and its corresponding value from the HVM/boot_params field of the given VM.  If the key is not in that Map, then do nothing.
     *
     * @param key Key to remove
     */
    public void removeFromHVMBootParams(String key) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.remove_from_HVM_boot_params";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the platform field of the given VM.
     *
     * @param platform New value to set
     */
    public void setPlatform(Map<String, String> platform) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_platform";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(platform)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Add the given key-value pair to the platform field of the given VM.
     *
     * @param key Key to add
     * @param value Value to add
     */
    public void addToPlatform(String key, String value) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.add_to_platform";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key), Marshalling.toXMLRPC(value)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Remove the given key and its corresponding value from the platform field of the given VM.  If the key is not in that Map, then do nothing.
     *
     * @param key Key to remove
     */
    public void removeFromPlatform(String key) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.remove_from_platform";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the PCI_bus field of the given VM.
     *
     * @param PCIBus New value to set
     */
    public void setPCIBus(String PCIBus) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_PCI_bus";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(PCIBus)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set the other_config field of the given VM.
     *
     * @param otherConfig New value to set
     */
    public void setOtherConfig(Map<String, String> otherConfig) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_other_config";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(otherConfig)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Add the given key-value pair to the other_config field of the given VM.
     *
     * @param key Key to add
     * @param value Value to add
     */
    public void addToOtherConfig(String key, String value) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.add_to_other_config";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key), Marshalling.toXMLRPC(value)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Remove the given key and its corresponding value from the other_config field of the given VM.  If the key is not in that Map, then do nothing.
     *
     * @param key Key to remove
     */
    public void removeFromOtherConfig(String key) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.remove_from_other_config";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Clones the specified VM, making a new VM. Clone automatically exploits the capabilities of the underlying storage repository in which the VM's disk images are stored (e.g. Copy on Write).   This function can only be called when the VM is in the Halted State.
     *
     * @param newName The name of the cloned VM
     * @return The ID of the newly created VM.
     */
    public VM clone(String newName) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.SrFull,
       Types.OperationNotAllowed {
        String method_call = "VM.clone";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(newName)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toVM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("SR_FULL")) {
                throw new Types.SrFull((String) error.get(1), (String) error.get(2));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Start the specified VM.  This function can only be called with the VM is in the Halted State.
     *
     * @param startPaused Instantiate VM in paused state if set to true.
     */
    public void start(Boolean startPaused) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmHvmRequired,
       Types.VmIsTemplate,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed {
        String method_call = "VM.start";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(startPaused)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_HVM_REQUIRED")) {
                throw new Types.VmHvmRequired((String) error.get(1));
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Pause the specified VM. This can only be called when the specified VM is in the Running state.
     *
     */
    public void pause() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.pause";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Resume the specified VM. This can only be called when the specified VM is in the Paused state.
     *
     */
    public void unpause() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.unpause";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Attempt to cleanly shutdown the specified VM. (Note: this may not be supported---e.g. if a guest agent is not installed).

Once shutdown has been completed perform poweroff action specified in guest configuration.

This can only be called when the specified VM is in the Running state.
     *
     */
    public void cleanShutdown() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.clean_shutdown";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Attempt to cleanly shutdown the specified VM (Note: this may not be supported---e.g. if a guest agent is not installed).

Once shutdown has been completed perform reboot action specified in guest configuration.

This can only be called when the specified VM is in the Running state.
     *
     */
    public void cleanReboot() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.clean_reboot";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Stop executing the specified VM without attempting a clean shutdown. Then perform poweroff action specified in VM configuration.
     *
     */
    public void hardShutdown() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.hard_shutdown";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Stop executing the specified VM without attempting a clean shutdown. Then perform reboot action specified in VM configuration
     *
     */
    public void hardReboot() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.hard_reboot";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Suspend the specified VM to disk.  This can only be called when the specified VM is in the Running state.
     *
     */
    public void suspend() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.VmOtherOperationInProgress,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.suspend";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("VM_OTHER_OPERATION_IN_PROGRESS")) {
                throw new Types.VmOtherOperationInProgress((String) error.get(1));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Awaken the specified VM and resume it.  This can only be called when the specified VM is in the Suspended state.
     *
     * @param startPaused Resume VM in paused state if set to true.
     * @param force Attempt to force the VM to resume. If this flag is false then the VM may fail pre-resume safety checks (e.g. if the CPU the VM was running on looks substantially different to the current one)
     */
    public void resume(Boolean startPaused, Boolean force) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState,
       Types.OperationNotAllowed,
       Types.VmIsTemplate {
        String method_call = "VM.resume";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(startPaused), Marshalling.toXMLRPC(force)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
            if(error.get(0).equals("OPERATION_NOT_ALLOWED")) {
                throw new Types.OperationNotAllowed();
            }
            if(error.get(0).equals("VM_IS_TEMPLATE")) {
                throw new Types.VmIsTemplate((String) error.get(1));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set this VM's VCPUs/at_startup value, and set the same value on the VM, if running
     *
     * @param nvcpu The number of VCPUs
     */
    public void setVCPUsNumberLive(Long nvcpu) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_VCPUs_number_live";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(nvcpu)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Add the given key-value pair to VM.VCPUs_params, and apply that value on the running VM
     *
     * @param key The key
     * @param value The value
     */
    public void addToVCPUsParamsLive(String key, String value) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.add_to_VCPUs_params_live";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key), Marshalling.toXMLRPC(value)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set memory_dynamic_max in database and on running VM
     *
     * @param max The memory_dynamic_max value
     */
    public void setMemoryDynamicMaxLive(Long max) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_dynamic_max_live";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(max)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Set memory_dynamic_min in database and on running VM
     *
     * @param min The memory_dynamic_min value
     */
    public void setMemoryDynamicMinLive(Long min) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.set_memory_dynamic_min_live";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(min)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Send the given key as a sysrq to this VM.  The key is specified as a single character (a String of length 1).  This can only be called when the specified VM is in the Running state.
     *
     * @param key The key to send
     */
    public void sendSysrq(String key) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState {
        String method_call = "VM.send_sysrq";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(key)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Send the named trigger to this VM.  This can only be called when the specified VM is in the Running state.
     *
     * @param trigger The trigger to send
     */
    public void sendTrigger(String trigger) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState {
        String method_call = "VM.send_trigger";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(trigger)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Migrate the VM to another host.  This can only be called when the specified VM is in the Running state.
     *
     * @param dest The destination host
     * @param live Live migration
     * @param options Other parameters
     */
    public void migrate(String dest, Boolean live, Map<String, String> options) throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException,
       Types.VmBadPowerState {
        String method_call = "VM.migrate";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref), Marshalling.toXMLRPC(dest), Marshalling.toXMLRPC(live), Marshalling.toXMLRPC(options)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return;
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
            if(error.get(0).equals("VM_BAD_POWER_STATE")) {
                throw new Types.VmBadPowerState((String) error.get(1), (String) error.get(2), (String) error.get(3));
            }
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Returns a list of the allowed values that a VBD device field can take
     *
     * @return The allowed values
     */
    public Set<String> getAllowedVBDDevices() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_allowed_VBD_devices";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Returns a list of the allowed values that a VIF device field can take
     *
     * @return The allowed values
     */
    public Set<String> getAllowedVIFDevices() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_allowed_VIF_devices";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session), Marshalling.toXMLRPC(this.ref)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfString(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Return a list of all the VMs known to the system.
     *
     * @return references to all objects
     */
    public static Set<VM> getAll() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_all";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toSetOfVM(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

    /**
     * Get all the VM Records at once, in a single XML RPC call
     *
     * @return A map from VM to VM.Record
     */
    public static Map<VM, VM.Record> getAllRecords() throws
       Types.BadServerResponse,
       ConnectionHelper.NoConnectionOnThisThreadException,
       XmlRpcException {
        String method_call = "VM.get_all_records";
        String session = ConnectionHelper.instance().getSession();
        Object[] method_params = {Marshalling.toXMLRPC(session)};
        Map response = ConnectionHelper.instance().dispatch(
            method_call, method_params);
        if(response.get("Status").equals("Success")) {
            Object result = response.get("Value");
            return Types.toMapOfVMVMRecord(result);
        } else if(response.get("Status").equals("Failure")) {
            Vector<Object> error = (Vector<Object>) response.get("ErrorDescription");
        }
        throw new Types.BadServerResponse(response);
    }

}