/*
 *============================================================================
 * 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.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Vector;
import java.io.IOException;

/**
 * This class holds vital marshalling functions,
 * enum types and exceptions.
 *
 * @author Tom Wilkie <tom.wilkie@gmail.com>
 */
public class Types {

    /**
     * Interface for all Record classes
     */
    public static interface Record {
        /**
         * Convert a Record to a Map
         */
        Map<String,Object> toMap();
    }

    /**
     * Base class for all XenAPI Exceptions
     */
    public static class XenAPIException extends IOException {
    }

    /**
     * Thrown if the response from the server contains an invalid status.
     */
    public static class BadServerResponse extends XenAPIException {
        public final Map response;
        public BadServerResponse(Map response) {
            this.response = response;
        }

        public String toString() {
            try {
                Object[] errDesc = (Object[]) this.response.get("ErrorDescription");
                return java.util.Arrays.deepToString(errDesc);
            } catch (Exception e) {
                return this.response.toString();
            }
        }
    }

    enum ConsoleProtocol {VT100, RFB, RDP};

    enum VbdMode {RO, RW};

    enum VbdType {CD, DISK};

    enum OnNormalExit {DESTROY, RESTART};

    enum OnCrashBehaviour {DESTROY, COREDUMP_AND_DESTROY, RESTART, COREDUMP_AND_RESTART, PRESERVE, RENAME_RESTART};

    enum VmPowerState {HALTED, PAUSED, RUNNING, SUSPENDED, UNKNOWN};

    enum TaskStatusType {PENDING, SUCCESS, FAILURE, CANCELLING, CANCELLED};

    enum EventOperation {ADD, DEL, MOD};

    enum VdiType {SYSTEM, USER, EPHEMERAL, SUSPEND, CRASHDUMP};


    /**
     * You tried to call a method with the incorrect number of parameters.  The fully-qualified method name that you used, and the number of received and expected parameters are returned.
     */
    public static class MessageParameterCountMismatch extends XenAPIException {
        public final String method;
        public final String expected;
        public final String received;

        /**
         * Create a new MessageParameterCountMismatch
         *
         * @param method
         * @param expected
         * @param received
         */
        public MessageParameterCountMismatch(String method, String expected, String received) {
            super();
            this.method = method;
            this.expected = expected;
            this.received = received;
        }

        public String toString() {
            return "You tried to call a method with the incorrect number of parameters.  The fully-qualified method name that you used, and the number of received and expected parameters are returned.";
        }
    }

    /**
     * You attempted to set a value that is not supported by this implementation.  The fully-qualified field name and the value that you tried to set are returned.  Also returned is a developer-only diagnostic reason.
     */
    public static class ValueNotSupported extends XenAPIException {
        public final String field;
        public final String value;
        public final String reason;

        /**
         * Create a new ValueNotSupported
         *
         * @param field
         * @param value
         * @param reason
         */
        public ValueNotSupported(String field, String value, String reason) {
            super();
            this.field = field;
            this.value = value;
            this.reason = reason;
        }

        public String toString() {
            return "You attempted to set a value that is not supported by this implementation.  The fully-qualified field name and the value that you tried to set are returned.  Also returned is a developer-only diagnostic reason.";
        }
    }

    /**
     * This session is not registered to receive events.  You must call event.register before event.next.  The session handle you are using is echoed.
     */
    public static class SessionNotRegistered extends XenAPIException {
        public final String handle;

        /**
         * Create a new SessionNotRegistered
         *
         * @param handle
         */
        public SessionNotRegistered(String handle) {
            super();
            this.handle = handle;
        }

        public String toString() {
            return "This session is not registered to receive events.  You must call event.register before event.next.  The session handle you are using is echoed.";
        }
    }

    /**
     * The operation could not proceed because necessary VDIs were already locked at the storage level.
     */
    public static class SrVdiLockingFailed extends XenAPIException {

        /**
         * Create a new SrVdiLockingFailed
         */
        public SrVdiLockingFailed() {
            super();
        }

        public String toString() {
            return "The operation could not proceed because necessary VDIs were already locked at the storage level.";
        }
    }

    /**
     * You tried to call a method that does not exist.  The method name that you used is echoed.
     */
    public static class MessageMethodUnknown extends XenAPIException {
        public final String method;

        /**
         * Create a new MessageMethodUnknown
         *
         * @param method
         */
        public MessageMethodUnknown(String method) {
            super();
            this.method = method;
        }

        public String toString() {
            return "You tried to call a method that does not exist.  The method name that you used is echoed.";
        }
    }

    /**
     * The SR is still connected to a host via a PBD. It cannot be destroyed.
     */
    public static class SrHasPbd extends XenAPIException {
        public final String sr;

        /**
         * Create a new SrHasPbd
         *
         * @param sr
         */
        public SrHasPbd(String sr) {
            super();
            this.sr = sr;
        }

        public String toString() {
            return "The SR is still connected to a host via a PBD. It cannot be destroyed.";
        }
    }

    /**
     * Another operation involving the VM is currently in progress
     */
    public static class VmOtherOperationInProgress extends XenAPIException {
        public final String vm;

        /**
         * Create a new VmOtherOperationInProgress
         *
         * @param vm
         */
        public VmOtherOperationInProgress(String vm) {
            super();
            this.vm = vm;
        }

        public String toString() {
            return "Another operation involving the VM is currently in progress";
        }
    }

    /**
     * The SR is full. Requested new size exceeds the maximum size
     */
    public static class SrFull extends XenAPIException {
        public final String requested;
        public final String maximum;

        /**
         * Create a new SrFull
         *
         * @param requested
         * @param maximum
         */
        public SrFull(String requested, String maximum) {
            super();
            this.requested = requested;
            this.maximum = maximum;
        }

        public String toString() {
            return "The SR is full. Requested new size exceeds the maximum size";
        }
    }

    /**
     * The operation attempted is not valid for a template VM
     */
    public static class VmIsTemplate extends XenAPIException {
        public final String vm;

        /**
         * Create a new VmIsTemplate
         *
         * @param vm
         */
        public VmIsTemplate(String vm) {
            super();
            this.vm = vm;
        }

        public String toString() {
            return "The operation attempted is not valid for a template VM";
        }
    }

    /**
     * You attempted to run a VM on a host which doesn't have access to an SR needed by the VM. The VM has at least one VBD attached to a VDI in the SR.
     */
    public static class VmRequiresSr extends XenAPIException {
        public final String vm;
        public final String sr;

        /**
         * Create a new VmRequiresSr
         *
         * @param vm
         * @param sr
         */
        public VmRequiresSr(String vm, String sr) {
            super();
            this.vm = vm;
            this.sr = sr;
        }

        public String toString() {
            return "You attempted to run a VM on a host which doesn't have access to an SR needed by the VM. The VM has at least one VBD attached to a VDI in the SR.";
        }
    }

    /**
     * Some events have been lost from the queue and cannot be retrieved.
     */
    public static class EventsLost extends XenAPIException {

        /**
         * Create a new EventsLost
         */
        public EventsLost() {
            super();
        }

        public String toString() {
            return "Some events have been lost from the queue and cannot be retrieved.";
        }
    }

    /**
     * The device name is invalid
     */
    public static class InvalidDevice extends XenAPIException {
        public final String device;

        /**
         * Create a new InvalidDevice
         *
         * @param device
         */
        public InvalidDevice(String device) {
            super();
            this.device = device;
        }

        public String toString() {
            return "The device name is invalid";
        }
    }

    /**
     * You attempted to run a VM on a host which doesn't have a PIF on a Network needed by the VM. The VM has at least one VIF attached to the Network.
     */
    public static class VmRequiresNetwork extends XenAPIException {
        public final String vm;
        public final String network;

        /**
         * Create a new VmRequiresNetwork
         *
         * @param vm
         * @param network
         */
        public VmRequiresNetwork(String vm, String network) {
            super();
            this.vm = vm;
            this.network = network;
        }

        public String toString() {
            return "You attempted to run a VM on a host which doesn't have a PIF on a Network needed by the VM. The VM has at least one VIF attached to the Network.";
        }
    }

    /**
     * The server failed to handle your request, due to an internal error.  The given message may give details useful for debugging the problem.
     */
    public static class InternalError extends XenAPIException {
        public final String message;

        /**
         * Create a new InternalError
         *
         * @param message
         */
        public InternalError(String message) {
            super();
            this.message = message;
        }

        public String toString() {
            return "The server failed to handle your request, due to an internal error.  The given message may give details useful for debugging the problem.";
        }
    }

    /**
     * You tried to create a PIF, but the network you tried to attach it to is already attached to some other PIF, and so the creation failed.
     */
    public static class NetworkAlreadyConnected extends XenAPIException {
        public final String network;
        public final String connectedPIF;

        /**
         * Create a new NetworkAlreadyConnected
         *
         * @param network
         * @param connectedPIF
         */
        public NetworkAlreadyConnected(String network, String connectedPIF) {
            super();
            this.network = network;
            this.connectedPIF = connectedPIF;
        }

        public String toString() {
            return "You tried to create a PIF, but the network you tried to attach it to is already attached to some other PIF, and so the creation failed.";
        }
    }

    /**
     * The credentials given by the user are incorrect, so access has been denied, and you have not been issued a session handle.
     */
    public static class SessionAuthenticationFailed extends XenAPIException {

        /**
         * Create a new SessionAuthenticationFailed
         */
        public SessionAuthenticationFailed() {
            super();
        }

        public String toString() {
            return "The credentials given by the user are incorrect, so access has been denied, and you have not been issued a session handle.";
        }
    }

    /**
     * This patch has already been applied
     */
    public static class PatchAlreadyApplied extends XenAPIException {
        public final String patch;

        /**
         * Create a new PatchAlreadyApplied
         *
         * @param patch
         */
        public PatchAlreadyApplied(String patch) {
            super();
            this.patch = patch;
        }

        public String toString() {
            return "This patch has already been applied";
        }
    }

    /**
     * The device is not currently attached
     */
    public static class DeviceAlreadyDetached extends XenAPIException {
        public final String vbd;

        /**
         * Create a new DeviceAlreadyDetached
         *
         * @param vbd
         */
        public DeviceAlreadyDetached(String vbd) {
            super();
            this.vbd = vbd;
        }

        public String toString() {
            return "The device is not currently attached";
        }
    }

    /**
     * You gave an invalid session handle.  It may have been invalidated by a server restart, or timed out.  You should get a new session handle, using one of the session.login_ calls.  This error does not invalidate the current connection.  The handle parameter echoes the bad value given.
     */
    public static class SessionInvalid extends XenAPIException {
        public final String handle;

        /**
         * Create a new SessionInvalid
         *
         * @param handle
         */
        public SessionInvalid(String handle) {
            super();
            this.handle = handle;
        }

        public String toString() {
            return "You gave an invalid session handle.  It may have been invalidated by a server restart, or timed out.  You should get a new session handle, using one of the session.login_ calls.  This error does not invalidate the current connection.  The handle parameter echoes the bad value given.";
        }
    }

    /**
     * You gave an invalid handle.  The object may have recently been deleted.  The class parameter gives the type of reference given, and the handle parameter echoes the bad value given.
     */
    public static class HandleInvalid extends XenAPIException {
        public final String clazz;
        public final String handle;

        /**
         * Create a new HandleInvalid
         *
         * @param clazz
         * @param handle
         */
        public HandleInvalid(String clazz, String handle) {
            super();
            this.clazz = clazz;
            this.handle = handle;
        }

        public String toString() {
            return "You gave an invalid handle.  The object may have recently been deleted.  The class parameter gives the type of reference given, and the handle parameter echoes the bad value given.";
        }
    }

    /**
     * The device is already attached to a VM
     */
    public static class DeviceAlreadyAttached extends XenAPIException {
        public final String vbd;

        /**
         * Create a new DeviceAlreadyAttached
         *
         * @param vbd
         */
        public DeviceAlreadyAttached(String vbd) {
            super();
            this.vbd = vbd;
        }

        public String toString() {
            return "The device is already attached to a VM";
        }
    }

    /**
     * The SR could not be connected because the driver was not recognised.
     */
    public static class SrUnknownDriver extends XenAPIException {
        public final String driver;

        /**
         * Create a new SrUnknownDriver
         *
         * @param driver
         */
        public SrUnknownDriver(String driver) {
            super();
            this.driver = driver;
        }

        public String toString() {
            return "The SR could not be connected because the driver was not recognised.";
        }
    }

    /**
     * You tried to create a VLAN, but the tag you gave was invalid -- it mmust be between 0 and 4095.  The parameter echoes the VLAN tag you gave.
     */
    public static class VlanTagInvalid extends XenAPIException {
        public final String VLAN;

        /**
         * Create a new VlanTagInvalid
         *
         * @param VLAN
         */
        public VlanTagInvalid(String VLAN) {
            super();
            this.VLAN = VLAN;
        }

        public String toString() {
            return "You tried to create a VLAN, but the tag you gave was invalid -- it mmust be between 0 and 4095.  The parameter echoes the VLAN tag you gave.";
        }
    }

    /**
     * HVM is required for this operation
     */
    public static class VmHvmRequired extends XenAPIException {
        public final String vm;

        /**
         * Create a new VmHvmRequired
         *
         * @param vm
         */
        public VmHvmRequired(String vm) {
            super();
            this.vm = vm;
        }

        public String toString() {
            return "HVM is required for this operation";
        }
    }

    /**
     * Another operation involving the VDI is currently in progress
     */
    public static class VdiOtherOperationInProgress extends XenAPIException {
        public final String vdi;

        /**
         * Create a new VdiOtherOperationInProgress
         *
         * @param vdi
         */
        public VdiOtherOperationInProgress(String vdi) {
            super();
            this.vdi = vdi;
        }

        public String toString() {
            return "Another operation involving the VDI is currently in progress";
        }
    }

    /**
     * You attempted an operation on a VM that was judged to be unsafe by the server. This can happen if the VM would run on a CPU that has a potentially incompatable set of feature flags to those the VM requires. If you want to override this warning then use the 'force' option.
     */
    public static class VmUnsafeBoot extends XenAPIException {
        public final String vm;

        /**
         * Create a new VmUnsafeBoot
         *
         * @param vm
         */
        public VmUnsafeBoot(String vm) {
            super();
            this.vm = vm;
        }

        public String toString() {
            return "You attempted an operation on a VM that was judged to be unsafe by the server. This can happen if the VM would run on a CPU that has a potentially incompatable set of feature flags to those the VM requires. If you want to override this warning then use the 'force' option.";
        }
    }

    /**
     * You tried to add a key-value pair to a map, but that key is already there.  The key, current value, and the new value that you tried to set are all echoed.
     */
    public static class MapDuplicateKey extends XenAPIException {
        public final String key;
        public final String currentValue;
        public final String newValue;

        /**
         * Create a new MapDuplicateKey
         *
         * @param key
         * @param currentValue
         * @param newValue
         */
        public MapDuplicateKey(String key, String currentValue, String newValue) {
            super();
            this.key = key;
            this.currentValue = currentValue;
            this.newValue = newValue;
        }

        public String toString() {
            return "You tried to add a key-value pair to a map, but that key is already there.  The key, current value, and the new value that you tried to set are all echoed.";
        }
    }

    /**
     * You attempted an operation on a VM that was not in an appropriate power state at the time; for example, you attempted to start a VM that was already running.  The parameters returned are the VM's handle, and the expected and actual VM state at the time of the call.
     */
    public static class VmBadPowerState extends XenAPIException {
        public final String vm;
        public final String expected;
        public final String actual;

        /**
         * Create a new VmBadPowerState
         *
         * @param vm
         * @param expected
         * @param actual
         */
        public VmBadPowerState(String vm, String expected, String actual) {
            super();
            this.vm = vm;
            this.expected = expected;
            this.actual = actual;
        }

        public String toString() {
            return "You attempted an operation on a VM that was not in an appropriate power state at the time; for example, you attempted to start a VM that was already running.  The parameters returned are the VM's handle, and the expected and actual VM state at the time of the call.";
        }
    }

    /**
     * The function is not implemented
     */
    public static class NotImplemented extends XenAPIException {
        public final String function;

        /**
         * Create a new NotImplemented
         *
         * @param function
         */
        public NotImplemented(String function) {
            super();
            this.function = function;
        }

        public String toString() {
            return "The function is not implemented";
        }
    }

    /**
     * A device with the name given already exists on the selected VM
     */
    public static class DeviceAlreadyExists extends XenAPIException {
        public final String device;

        /**
         * Create a new DeviceAlreadyExists
         *
         * @param device
         */
        public DeviceAlreadyExists(String device) {
            super();
            this.device = device;
        }

        public String toString() {
            return "A device with the name given already exists on the selected VM";
        }
    }

    /**
     * The uploaded patch file is invalid
     */
    public static class InvalidPatch extends XenAPIException {

        /**
         * Create a new InvalidPatch
         */
        public InvalidPatch() {
            super();
        }

        public String toString() {
            return "The uploaded patch file is invalid";
        }
    }

    /**
     * The network contains active PIFs and cannot be deleted
     */
    public static class NetworkContainsPif extends XenAPIException {
        public final String pifs;

        /**
         * Create a new NetworkContainsPif
         *
         * @param pifs
         */
        public NetworkContainsPif(String pifs) {
            super();
            this.pifs = pifs;
        }

        public String toString() {
            return "The network contains active PIFs and cannot be deleted";
        }
    }

    /**
     * You tried to destroy a PIF, but it represents an aspect of the physical host configuration, and so cannot be destroyed.  The parameter echoes the PIF handle you gave.
     */
    public static class PifIsPhysical extends XenAPIException {
        public final String PIF;

        /**
         * Create a new PifIsPhysical
         *
         * @param PIF
         */
        public PifIsPhysical(String PIF) {
            super();
            this.PIF = PIF;
        }

        public String toString() {
            return "You tried to destroy a PIF, but it represents an aspect of the physical host configuration, and so cannot be destroyed.  The parameter echoes the PIF handle you gave.";
        }
    }

    /**
     * You attempted an operation which involves a host which could not be contacted.
     */
    public static class HostOffline extends XenAPIException {
        public final String host;

        /**
         * Create a new HostOffline
         *
         * @param host
         */
        public HostOffline(String host) {
            super();
            this.host = host;
        }

        public String toString() {
            return "You attempted an operation which involves a host which could not be contacted.";
        }
    }

    /**
     * You attempted an operation that was not allowed.
     */
    public static class OperationNotAllowed extends XenAPIException {

        /**
         * Create a new OperationNotAllowed
         */
        public OperationNotAllowed() {
            super();
        }

        public String toString() {
            return "You attempted an operation that was not allowed.";
        }
    }

    /**
     * You tried to create a PIF, but it already exists
     */
    public static class PifVlanExists extends XenAPIException {
        public final String PIF;

        /**
         * Create a new PifVlanExists
         *
         * @param PIF
         */
        public PifVlanExists(String PIF) {
            super();
            this.PIF = PIF;
        }

        public String toString() {
            return "You tried to create a PIF, but it already exists";
        }
    }

    /**
     * An error occurred during the migration process.
     */
    public static class VmMigrateFailed extends XenAPIException {
        public final String vm;
        public final String source;
        public final String destination;
        public final String msg;

        /**
         * Create a new VmMigrateFailed
         *
         * @param vm
         * @param source
         * @param destination
         * @param msg
         */
        public VmMigrateFailed(String vm, String source, String destination, String msg) {
            super();
            this.vm = vm;
            this.source = source;
            this.destination = destination;
            this.msg = msg;
        }

        public String toString() {
            return "An error occurred during the migration process.";
        }
    }

    /**
     * The value given is invalid
     */
    public static class InvalidValue extends XenAPIException {
        public final String field;
        public final String value;

        /**
         * Create a new InvalidValue
         *
         * @param field
         * @param value
         */
        public InvalidValue(String field, String value) {
            super();
            this.field = field;
            this.value = value;
        }

        public String toString() {
            return "The value given is invalid";
        }
    }

    /**
     * The network contains active VIFs and cannot be deleted
     */
    public static class NetworkContainsVif extends XenAPIException {
        public final String vifs;

        /**
         * Create a new NetworkContainsVif
         *
         * @param vifs
         */
        public NetworkContainsVif(String vifs) {
            super();
            this.vifs = vifs;
        }

        public String toString() {
            return "The network contains active VIFs and cannot be deleted";
        }
    }


    public static String toString(Object object) {
        return (String) object;
    }

    public static Long toLong(Object object) {
        return Long.valueOf((String) object);
    }

    public static Double toDouble(Object object) {
        return (Double) object;
    }

    public static Boolean toBoolean(Object object) {
        return (Boolean) object;
    }

    public static Date toDate(Object object) {
        return (Date) object;
    }

    public static Types.ConsoleProtocol toConsoleProtocol(Object object) {
        return ConsoleProtocol.valueOf(((String) object).toUpperCase());
    }

    public static Types.EventOperation toEventOperation(Object object) {
        return EventOperation.valueOf(((String) object).toUpperCase());
    }

    public static Types.OnCrashBehaviour toOnCrashBehaviour(Object object) {
        return OnCrashBehaviour.valueOf(((String) object).toUpperCase());
    }

    public static Types.OnNormalExit toOnNormalExit(Object object) {
        return OnNormalExit.valueOf(((String) object).toUpperCase());
    }

    public static Types.TaskStatusType toTaskStatusType(Object object) {
        return TaskStatusType.valueOf(((String) object).toUpperCase());
    }

    public static Types.VbdMode toVbdMode(Object object) {
        return VbdMode.valueOf(((String) object).toUpperCase());
    }

    public static Types.VbdType toVbdType(Object object) {
        return VbdType.valueOf(((String) object).toUpperCase());
    }

    public static Types.VdiType toVdiType(Object object) {
        return VdiType.valueOf(((String) object).toUpperCase());
    }

    public static Types.VmPowerState toVmPowerState(Object object) {
        return VmPowerState.valueOf(((String) object).toUpperCase());
    }

    public static Set<String> toSetOfString(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<String> result = new HashSet<String>();
        for(Object item: items) {
            String typed = toString(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<PBD> toSetOfPBD(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<PBD> result = new HashSet<PBD>();
        for(Object item: items) {
            PBD typed = toPBD(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<PIF> toSetOfPIF(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<PIF> result = new HashSet<PIF>();
        for(Object item: items) {
            PIF typed = toPIF(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<PIFMetrics> toSetOfPIFMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<PIFMetrics> result = new HashSet<PIFMetrics>();
        for(Object item: items) {
            PIFMetrics typed = toPIFMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<SR> toSetOfSR(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<SR> result = new HashSet<SR>();
        for(Object item: items) {
            SR typed = toSR(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VBD> toSetOfVBD(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VBD> result = new HashSet<VBD>();
        for(Object item: items) {
            VBD typed = toVBD(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VBDMetrics> toSetOfVBDMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VBDMetrics> result = new HashSet<VBDMetrics>();
        for(Object item: items) {
            VBDMetrics typed = toVBDMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VDI> toSetOfVDI(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VDI> result = new HashSet<VDI>();
        for(Object item: items) {
            VDI typed = toVDI(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VIF> toSetOfVIF(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VIF> result = new HashSet<VIF>();
        for(Object item: items) {
            VIF typed = toVIF(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VIFMetrics> toSetOfVIFMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VIFMetrics> result = new HashSet<VIFMetrics>();
        for(Object item: items) {
            VIFMetrics typed = toVIFMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VM> toSetOfVM(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VM> result = new HashSet<VM>();
        for(Object item: items) {
            VM typed = toVM(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VMGuestMetrics> toSetOfVMGuestMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VMGuestMetrics> result = new HashSet<VMGuestMetrics>();
        for(Object item: items) {
            VMGuestMetrics typed = toVMGuestMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VMMetrics> toSetOfVMMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VMMetrics> result = new HashSet<VMMetrics>();
        for(Object item: items) {
            VMMetrics typed = toVMMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<VTPM> toSetOfVTPM(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<VTPM> result = new HashSet<VTPM>();
        for(Object item: items) {
            VTPM typed = toVTPM(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Console> toSetOfConsole(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Console> result = new HashSet<Console>();
        for(Object item: items) {
            Console typed = toConsole(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Crashdump> toSetOfCrashdump(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Crashdump> result = new HashSet<Crashdump>();
        for(Object item: items) {
            Crashdump typed = toCrashdump(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Debug> toSetOfDebug(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Debug> result = new HashSet<Debug>();
        for(Object item: items) {
            Debug typed = toDebug(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Host> toSetOfHost(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Host> result = new HashSet<Host>();
        for(Object item: items) {
            Host typed = toHost(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<HostCpu> toSetOfHostCpu(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<HostCpu> result = new HashSet<HostCpu>();
        for(Object item: items) {
            HostCpu typed = toHostCpu(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<HostMetrics> toSetOfHostMetrics(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<HostMetrics> result = new HashSet<HostMetrics>();
        for(Object item: items) {
            HostMetrics typed = toHostMetrics(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Network> toSetOfNetwork(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Network> result = new HashSet<Network>();
        for(Object item: items) {
            Network typed = toNetwork(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Task> toSetOfTask(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Task> result = new HashSet<Task>();
        for(Object item: items) {
            Task typed = toTask(item);
            result.add(typed);
        }
        return result;
    }

    public static Set<Event.Record> toSetOfEventRecord(Object object) {
        Vector<Object> items = (Vector<Object>) object;
        Set<Event.Record> result = new HashSet<Event.Record>();
        for(Object item: items) {
            Event.Record typed = toEventRecord(item);
            result.add(typed);
        }
        return result;
    }

    public static Map<String, String> toMapOfStringString(Object object) {
        Map map = (Map) object;
        Map<String,String> result = new Hashtable<String,String>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            String key = toString(entry.getKey());
            String value = toString(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Long, Long> toMapOfLongLong(Object object) {
        Map map = (Map) object;
        Map<Long,Long> result = new Hashtable<Long,Long>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Long key = toLong(entry.getKey());
            Long value = toLong(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Long, Double> toMapOfLongDouble(Object object) {
        Map map = (Map) object;
        Map<Long,Double> result = new Hashtable<Long,Double>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Long key = toLong(entry.getKey());
            Double value = toDouble(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Long, Set<String>> toMapOfLongSetOfString(Object object) {
        Map map = (Map) object;
        Map<Long,Set<String>> result = new Hashtable<Long,Set<String>>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Long key = toLong(entry.getKey());
            Set<String> value = toSetOfString(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<PBD, PBD.Record> toMapOfPBDPBDRecord(Object object) {
        Map map = (Map) object;
        Map<PBD,PBD.Record> result = new Hashtable<PBD,PBD.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            PBD key = toPBD(entry.getKey());
            PBD.Record value = toPBDRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<PIF, PIF.Record> toMapOfPIFPIFRecord(Object object) {
        Map map = (Map) object;
        Map<PIF,PIF.Record> result = new Hashtable<PIF,PIF.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            PIF key = toPIF(entry.getKey());
            PIF.Record value = toPIFRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<PIFMetrics, PIFMetrics.Record> toMapOfPIFMetricsPIFMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<PIFMetrics,PIFMetrics.Record> result = new Hashtable<PIFMetrics,PIFMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            PIFMetrics key = toPIFMetrics(entry.getKey());
            PIFMetrics.Record value = toPIFMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<SR, SR.Record> toMapOfSRSRRecord(Object object) {
        Map map = (Map) object;
        Map<SR,SR.Record> result = new Hashtable<SR,SR.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            SR key = toSR(entry.getKey());
            SR.Record value = toSRRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VBD, VBD.Record> toMapOfVBDVBDRecord(Object object) {
        Map map = (Map) object;
        Map<VBD,VBD.Record> result = new Hashtable<VBD,VBD.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VBD key = toVBD(entry.getKey());
            VBD.Record value = toVBDRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VBDMetrics, VBDMetrics.Record> toMapOfVBDMetricsVBDMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<VBDMetrics,VBDMetrics.Record> result = new Hashtable<VBDMetrics,VBDMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VBDMetrics key = toVBDMetrics(entry.getKey());
            VBDMetrics.Record value = toVBDMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VDI, VDI.Record> toMapOfVDIVDIRecord(Object object) {
        Map map = (Map) object;
        Map<VDI,VDI.Record> result = new Hashtable<VDI,VDI.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VDI key = toVDI(entry.getKey());
            VDI.Record value = toVDIRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VIF, VIF.Record> toMapOfVIFVIFRecord(Object object) {
        Map map = (Map) object;
        Map<VIF,VIF.Record> result = new Hashtable<VIF,VIF.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VIF key = toVIF(entry.getKey());
            VIF.Record value = toVIFRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VIFMetrics, VIFMetrics.Record> toMapOfVIFMetricsVIFMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<VIFMetrics,VIFMetrics.Record> result = new Hashtable<VIFMetrics,VIFMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VIFMetrics key = toVIFMetrics(entry.getKey());
            VIFMetrics.Record value = toVIFMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VM, VM.Record> toMapOfVMVMRecord(Object object) {
        Map map = (Map) object;
        Map<VM,VM.Record> result = new Hashtable<VM,VM.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VM key = toVM(entry.getKey());
            VM.Record value = toVMRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VMGuestMetrics, VMGuestMetrics.Record> toMapOfVMGuestMetricsVMGuestMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<VMGuestMetrics,VMGuestMetrics.Record> result = new Hashtable<VMGuestMetrics,VMGuestMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VMGuestMetrics key = toVMGuestMetrics(entry.getKey());
            VMGuestMetrics.Record value = toVMGuestMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VMMetrics, VMMetrics.Record> toMapOfVMMetricsVMMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<VMMetrics,VMMetrics.Record> result = new Hashtable<VMMetrics,VMMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VMMetrics key = toVMMetrics(entry.getKey());
            VMMetrics.Record value = toVMMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<VTPM, VTPM.Record> toMapOfVTPMVTPMRecord(Object object) {
        Map map = (Map) object;
        Map<VTPM,VTPM.Record> result = new Hashtable<VTPM,VTPM.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            VTPM key = toVTPM(entry.getKey());
            VTPM.Record value = toVTPMRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Console, Console.Record> toMapOfConsoleConsoleRecord(Object object) {
        Map map = (Map) object;
        Map<Console,Console.Record> result = new Hashtable<Console,Console.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Console key = toConsole(entry.getKey());
            Console.Record value = toConsoleRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Crashdump, Crashdump.Record> toMapOfCrashdumpCrashdumpRecord(Object object) {
        Map map = (Map) object;
        Map<Crashdump,Crashdump.Record> result = new Hashtable<Crashdump,Crashdump.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Crashdump key = toCrashdump(entry.getKey());
            Crashdump.Record value = toCrashdumpRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Debug, Debug.Record> toMapOfDebugDebugRecord(Object object) {
        Map map = (Map) object;
        Map<Debug,Debug.Record> result = new Hashtable<Debug,Debug.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Debug key = toDebug(entry.getKey());
            Debug.Record value = toDebugRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Event, Event.Record> toMapOfEventEventRecord(Object object) {
        Map map = (Map) object;
        Map<Event,Event.Record> result = new Hashtable<Event,Event.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Event key = toEvent(entry.getKey());
            Event.Record value = toEventRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Host, Host.Record> toMapOfHostHostRecord(Object object) {
        Map map = (Map) object;
        Map<Host,Host.Record> result = new Hashtable<Host,Host.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Host key = toHost(entry.getKey());
            Host.Record value = toHostRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<HostCpu, HostCpu.Record> toMapOfHostCpuHostCpuRecord(Object object) {
        Map map = (Map) object;
        Map<HostCpu,HostCpu.Record> result = new Hashtable<HostCpu,HostCpu.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            HostCpu key = toHostCpu(entry.getKey());
            HostCpu.Record value = toHostCpuRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<HostMetrics, HostMetrics.Record> toMapOfHostMetricsHostMetricsRecord(Object object) {
        Map map = (Map) object;
        Map<HostMetrics,HostMetrics.Record> result = new Hashtable<HostMetrics,HostMetrics.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            HostMetrics key = toHostMetrics(entry.getKey());
            HostMetrics.Record value = toHostMetricsRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Network, Network.Record> toMapOfNetworkNetworkRecord(Object object) {
        Map map = (Map) object;
        Map<Network,Network.Record> result = new Hashtable<Network,Network.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Network key = toNetwork(entry.getKey());
            Network.Record value = toNetworkRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Session, Session.Record> toMapOfSessionSessionRecord(Object object) {
        Map map = (Map) object;
        Map<Session,Session.Record> result = new Hashtable<Session,Session.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Session key = toSession(entry.getKey());
            Session.Record value = toSessionRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<Task, Task.Record> toMapOfTaskTaskRecord(Object object) {
        Map map = (Map) object;
        Map<Task,Task.Record> result = new Hashtable<Task,Task.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            Task key = toTask(entry.getKey());
            Task.Record value = toTaskRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static Map<User, User.Record> toMapOfUserUserRecord(Object object) {
        Map map = (Map) object;
        Map<User,User.Record> result = new Hashtable<User,User.Record>();
        Set<Map.Entry> entries = map.entrySet();
        for(Map.Entry entry: entries) {
            User key = toUser(entry.getKey());
            User.Record value = toUserRecord(entry.getValue());
            result.put(key, value);
        }
        return result;
    }

    public static PBD toPBD(Object object) {
        return PBD.getInstFromRef((String) object);
    }

    public static PIF toPIF(Object object) {
        return PIF.getInstFromRef((String) object);
    }

    public static PIFMetrics toPIFMetrics(Object object) {
        return PIFMetrics.getInstFromRef((String) object);
    }

    public static SR toSR(Object object) {
        return SR.getInstFromRef((String) object);
    }

    public static VBD toVBD(Object object) {
        return VBD.getInstFromRef((String) object);
    }

    public static VBDMetrics toVBDMetrics(Object object) {
        return VBDMetrics.getInstFromRef((String) object);
    }

    public static VDI toVDI(Object object) {
        return VDI.getInstFromRef((String) object);
    }

    public static VIF toVIF(Object object) {
        return VIF.getInstFromRef((String) object);
    }

    public static VIFMetrics toVIFMetrics(Object object) {
        return VIFMetrics.getInstFromRef((String) object);
    }

    public static VM toVM(Object object) {
        return VM.getInstFromRef((String) object);
    }

    public static VMGuestMetrics toVMGuestMetrics(Object object) {
        return VMGuestMetrics.getInstFromRef((String) object);
    }

    public static VMMetrics toVMMetrics(Object object) {
        return VMMetrics.getInstFromRef((String) object);
    }

    public static VTPM toVTPM(Object object) {
        return VTPM.getInstFromRef((String) object);
    }

    public static Console toConsole(Object object) {
        return Console.getInstFromRef((String) object);
    }

    public static Crashdump toCrashdump(Object object) {
        return Crashdump.getInstFromRef((String) object);
    }

    public static Debug toDebug(Object object) {
        return Debug.getInstFromRef((String) object);
    }

    public static Event toEvent(Object object) {
        return Event.getInstFromRef((String) object);
    }

    public static Host toHost(Object object) {
        return Host.getInstFromRef((String) object);
    }

    public static HostCpu toHostCpu(Object object) {
        return HostCpu.getInstFromRef((String) object);
    }

    public static HostMetrics toHostMetrics(Object object) {
        return HostMetrics.getInstFromRef((String) object);
    }

    public static Network toNetwork(Object object) {
        return Network.getInstFromRef((String) object);
    }

    public static Session toSession(Object object) {
        return Session.getInstFromRef((String) object);
    }

    public static Task toTask(Object object) {
        return Task.getInstFromRef((String) object);
    }

    public static User toUser(Object object) {
        return User.getInstFromRef((String) object);
    }

    public static PBD.Record toPBDRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        PBD.Record record = new PBD.Record();
        record.uuid = toString(map.get("uuid"));
        record.host = toHost(map.get("host"));
        record.SR = toSR(map.get("SR"));
        record.deviceConfig = toMapOfStringString(map.get("device_config"));
        record.currentlyAttached = toBoolean(map.get("currently_attached"));
        return record;
    }

    public static PIF.Record toPIFRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        PIF.Record record = new PIF.Record();
        record.uuid = toString(map.get("uuid"));
        record.device = toString(map.get("device"));
        record.network = toNetwork(map.get("network"));
        record.host = toHost(map.get("host"));
        record.MAC = toString(map.get("MAC"));
        record.MTU = toLong(map.get("MTU"));
        record.VLAN = toLong(map.get("VLAN"));
        record.metrics = toPIFMetrics(map.get("metrics"));
        return record;
    }

    public static PIFMetrics.Record toPIFMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        PIFMetrics.Record record = new PIFMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.ioReadKbs = toDouble(map.get("io_read_kbs"));
        record.ioWriteKbs = toDouble(map.get("io_write_kbs"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static SR.Record toSRRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        SR.Record record = new SR.Record();
        record.uuid = toString(map.get("uuid"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.VDIs = toSetOfVDI(map.get("VDIs"));
        record.PBDs = toSetOfPBD(map.get("PBDs"));
        record.virtualAllocation = toLong(map.get("virtual_allocation"));
        record.physicalUtilisation = toLong(map.get("physical_utilisation"));
        record.physicalSize = toLong(map.get("physical_size"));
        record.type = toString(map.get("type"));
        record.contentType = toString(map.get("content_type"));
        record.shared = toBoolean(map.get("shared"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        return record;
    }

    public static VBD.Record toVBDRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VBD.Record record = new VBD.Record();
        record.uuid = toString(map.get("uuid"));
        record.VM = toVM(map.get("VM"));
        record.VDI = toVDI(map.get("VDI"));
        record.device = toString(map.get("device"));
        record.userdevice = toString(map.get("userdevice"));
        record.bootable = toBoolean(map.get("bootable"));
        record.mode = toVbdMode(map.get("mode"));
        record.type = toVbdType(map.get("type"));
        record.storageLock = toBoolean(map.get("storage_lock"));
        record.currentlyAttached = toBoolean(map.get("currently_attached"));
        record.statusCode = toLong(map.get("status_code"));
        record.statusDetail = toString(map.get("status_detail"));
        record.runtimeProperties = toMapOfStringString(map.get("runtime_properties"));
        record.qosAlgorithmType = toString(map.get("qos_algorithm_type"));
        record.qosAlgorithmParams = toMapOfStringString(map.get("qos_algorithm_params"));
        record.qosSupportedAlgorithms = toSetOfString(map.get("qos_supported_algorithms"));
        record.metrics = toVBDMetrics(map.get("metrics"));
        return record;
    }

    public static VBDMetrics.Record toVBDMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VBDMetrics.Record record = new VBDMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.ioReadKbs = toDouble(map.get("io_read_kbs"));
        record.ioWriteKbs = toDouble(map.get("io_write_kbs"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static VDI.Record toVDIRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VDI.Record record = new VDI.Record();
        record.uuid = toString(map.get("uuid"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.SR = toSR(map.get("SR"));
        record.VBDs = toSetOfVBD(map.get("VBDs"));
        record.crashDumps = toSetOfCrashdump(map.get("crash_dumps"));
        record.virtualSize = toLong(map.get("virtual_size"));
        record.physicalUtilisation = toLong(map.get("physical_utilisation"));
        record.type = toVdiType(map.get("type"));
        record.sharable = toBoolean(map.get("sharable"));
        record.readOnly = toBoolean(map.get("read_only"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        record.storageLock = toBoolean(map.get("storage_lock"));
        return record;
    }

    public static VIF.Record toVIFRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VIF.Record record = new VIF.Record();
        record.uuid = toString(map.get("uuid"));
        record.device = toString(map.get("device"));
        record.network = toNetwork(map.get("network"));
        record.VM = toVM(map.get("VM"));
        record.MAC = toString(map.get("MAC"));
        record.MTU = toLong(map.get("MTU"));
        record.currentlyAttached = toBoolean(map.get("currently_attached"));
        record.statusCode = toLong(map.get("status_code"));
        record.statusDetail = toString(map.get("status_detail"));
        record.runtimeProperties = toMapOfStringString(map.get("runtime_properties"));
        record.qosAlgorithmType = toString(map.get("qos_algorithm_type"));
        record.qosAlgorithmParams = toMapOfStringString(map.get("qos_algorithm_params"));
        record.qosSupportedAlgorithms = toSetOfString(map.get("qos_supported_algorithms"));
        record.metrics = toVIFMetrics(map.get("metrics"));
        return record;
    }

    public static VIFMetrics.Record toVIFMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VIFMetrics.Record record = new VIFMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.ioReadKbs = toDouble(map.get("io_read_kbs"));
        record.ioWriteKbs = toDouble(map.get("io_write_kbs"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static VM.Record toVMRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VM.Record record = new VM.Record();
        record.uuid = toString(map.get("uuid"));
        record.powerState = toVmPowerState(map.get("power_state"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.userVersion = toLong(map.get("user_version"));
        record.isATemplate = toBoolean(map.get("is_a_template"));
        record.autoPowerOn = toBoolean(map.get("auto_power_on"));
        record.suspendVDI = toVDI(map.get("suspend_VDI"));
        record.residentOn = toHost(map.get("resident_on"));
        record.memoryStaticMax = toLong(map.get("memory_static_max"));
        record.memoryDynamicMax = toLong(map.get("memory_dynamic_max"));
        record.memoryDynamicMin = toLong(map.get("memory_dynamic_min"));
        record.memoryStaticMin = toLong(map.get("memory_static_min"));
        record.VCPUsParams = toMapOfStringString(map.get("VCPUs_params"));
        record.VCPUsMax = toLong(map.get("VCPUs_max"));
        record.VCPUsAtStartup = toLong(map.get("VCPUs_at_startup"));
        record.actionsAfterShutdown = toOnNormalExit(map.get("actions_after_shutdown"));
        record.actionsAfterReboot = toOnNormalExit(map.get("actions_after_reboot"));
        record.actionsAfterCrash = toOnCrashBehaviour(map.get("actions_after_crash"));
        record.consoles = toSetOfConsole(map.get("consoles"));
        record.VIFs = toSetOfVIF(map.get("VIFs"));
        record.VBDs = toSetOfVBD(map.get("VBDs"));
        //record.crashDumps = toSetOfCrashdump(map.get("crash_dumps"));
        record.VTPMs = toSetOfVTPM(map.get("VTPMs"));
        record.PVBootloader = toString(map.get("PV_bootloader"));
        record.PVKernel = toString(map.get("PV_kernel"));
        record.PVRamdisk = toString(map.get("PV_ramdisk"));
        record.PVArgs = toString(map.get("PV_args"));
        record.PVBootloaderArgs = toString(map.get("PV_bootloader_args"));
        record.HVMBootPolicy = toString(map.get("HVM_boot_policy"));
        record.HVMBootParams = toMapOfStringString(map.get("HVM_boot_params"));
        record.platform = toMapOfStringString(map.get("platform"));
        record.PCIBus = toString(map.get("PCI_bus"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        record.domid = toLong(map.get("domid"));
        record.isControlDomain = toBoolean(map.get("is_control_domain"));
        record.metrics = toVMMetrics(map.get("metrics"));
        record.guestMetrics = toVMGuestMetrics(map.get("guest_metrics"));
        return record;
    }

    public static VMGuestMetrics.Record toVMGuestMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VMGuestMetrics.Record record = new VMGuestMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.osVersion = toMapOfStringString(map.get("os_version"));
        record.PVDriversVersion = toMapOfStringString(map.get("PV_drivers_version"));
        record.memory = toMapOfStringString(map.get("memory"));
        record.disks = toMapOfStringString(map.get("disks"));
        record.networks = toMapOfStringString(map.get("networks"));
        record.other = toMapOfStringString(map.get("other"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static VMMetrics.Record toVMMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VMMetrics.Record record = new VMMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.memoryActual = toLong(map.get("memory_actual"));
        record.VCPUsNumber = toLong(map.get("VCPUs_number"));
        record.VCPUsUtilisation = toMapOfLongDouble(map.get("VCPUs_utilisation"));
        record.VCPUsCPU = toMapOfLongLong(map.get("VCPUs_CPU"));
        record.VCPUsParams = toMapOfStringString(map.get("VCPUs_params"));
        record.VCPUsFlags = toMapOfLongSetOfString(map.get("VCPUs_flags"));
        record.state = toSetOfString(map.get("state"));
        record.startTime = toDate(map.get("start_time"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static VTPM.Record toVTPMRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        VTPM.Record record = new VTPM.Record();
        record.uuid = toString(map.get("uuid"));
        record.VM = toVM(map.get("VM"));
        record.backend = toVM(map.get("backend"));
        return record;
    }

    public static Console.Record toConsoleRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Console.Record record = new Console.Record();
        record.uuid = toString(map.get("uuid"));
        record.protocol = toConsoleProtocol(map.get("protocol"));
        record.location = toString(map.get("location"));
        record.VM = toVM(map.get("VM"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        return record;
    }

    public static Crashdump.Record toCrashdumpRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Crashdump.Record record = new Crashdump.Record();
        record.uuid = toString(map.get("uuid"));
        record.VM = toVM(map.get("VM"));
        record.VDI = toVDI(map.get("VDI"));
        return record;
    }

    public static Debug.Record toDebugRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Debug.Record record = new Debug.Record();
        return record;
    }

    public static Event.Record toEventRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Event.Record record = new Event.Record();
        record.id = toLong(map.get("id"));
        record.timestamp = toDate(map.get("timestamp"));
        record.clazz = toString(map.get("class"));
        record.operation = toEventOperation(map.get("operation"));
        record.ref = toString(map.get("ref"));
        record.objUuid = toString(map.get("obj_uuid"));
        return record;
    }

    public static Host.Record toHostRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Host.Record record = new Host.Record();
        record.uuid = toString(map.get("uuid"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.APIVersionMajor = toLong(map.get("API_version_major"));
        record.APIVersionMinor = toLong(map.get("API_version_minor"));
        record.APIVersionVendor = toString(map.get("API_version_vendor"));
        record.APIVersionVendorImplementation = toMapOfStringString(map.get("API_version_vendor_implementation"));
        record.enabled = toBoolean(map.get("enabled"));
        record.softwareVersion = toMapOfStringString(map.get("software_version"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        record.capabilities = toSetOfString(map.get("capabilities"));
        record.cpuConfiguration = toMapOfStringString(map.get("cpu_configuration"));
        record.schedPolicy = toString(map.get("sched_policy"));
        record.supportedBootloaders = toSetOfString(map.get("supported_bootloaders"));
        record.residentVMs = toSetOfVM(map.get("resident_VMs"));
        record.logging = toMapOfStringString(map.get("logging"));
        record.PIFs = toSetOfPIF(map.get("PIFs"));
        record.suspendImageSr = toSR(map.get("suspend_image_sr"));
        record.crashDumpSr = toSR(map.get("crash_dump_sr"));
        record.PBDs = toSetOfPBD(map.get("PBDs"));
        record.hostCPUs = toSetOfHostCpu(map.get("host_CPUs"));
        record.metrics = toHostMetrics(map.get("metrics"));
        return record;
    }

    public static HostCpu.Record toHostCpuRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        HostCpu.Record record = new HostCpu.Record();
        record.uuid = toString(map.get("uuid"));
        record.host = toHost(map.get("host"));
        record.number = toLong(map.get("number"));
        record.vendor = toString(map.get("vendor"));
        record.speed = toLong(map.get("speed"));
        record.modelname = toString(map.get("modelname"));
        record.stepping = toString(map.get("stepping"));
        record.flags = toString(map.get("flags"));
        record.features = toString(map.get("features"));
        record.utilisation = toDouble(map.get("utilisation"));
        return record;
    }

    public static HostMetrics.Record toHostMetricsRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        HostMetrics.Record record = new HostMetrics.Record();
        record.uuid = toString(map.get("uuid"));
        record.memoryTotal = toLong(map.get("memory_total"));
        record.memoryFree = toLong(map.get("memory_free"));
        record.lastUpdated = toDate(map.get("last_updated"));
        return record;
    }

    public static Network.Record toNetworkRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Network.Record record = new Network.Record();
        record.uuid = toString(map.get("uuid"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.VIFs = toSetOfVIF(map.get("VIFs"));
        record.PIFs = toSetOfPIF(map.get("PIFs"));
        record.otherConfig = toMapOfStringString(map.get("other_config"));
        return record;
    }

    public static Session.Record toSessionRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Session.Record record = new Session.Record();
        record.uuid = toString(map.get("uuid"));
        record.thisHost = toHost(map.get("this_host"));
        record.thisUser = toUser(map.get("this_user"));
        record.lastActive = toLong(map.get("last_active"));
        return record;
    }

    public static Task.Record toTaskRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        Task.Record record = new Task.Record();
        record.uuid = toString(map.get("uuid"));
        record.nameLabel = toString(map.get("name_label"));
        record.nameDescription = toString(map.get("name_description"));
        record.status = toTaskStatusType(map.get("status"));
        record.session = toSession(map.get("session"));
        record.residentOn = toHost(map.get("resident_on"));
        record.progress = toDouble(map.get("progress"));
        record.type = toString(map.get("type"));
        record.result = toString(map.get("result"));
        record.errorInfo = toSetOfString(map.get("error_info"));
        return record;
    }

    public static User.Record toUserRecord(Object object) {
        Map<String,Object> map = (Map<String,Object>) object;
        User.Record record = new User.Record();
        record.uuid = toString(map.get("uuid"));
        record.shortName = toString(map.get("short_name"));
        record.fullname = toString(map.get("fullname"));
        return record;
    }

}
