diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 19bd3b5..9289b04 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -1266,7 +1266,7 @@ xenUnifiedDomainXMLToNative(virConnectPtr conn,
 
     if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
         int len = MAX_CONFIG_SIZE;
-        conf = xenXMDomainConfigFormat(conn, def);
+        conf = xenXMDomainConfigFormat(conn, def, priv->xendConfigVersion);
         if (!conf)
             goto cleanup;
 
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index 32c1b7e..371f954 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -65,8 +65,6 @@
    to sched.h, so we'll match that for now */
 #define XEN_MAX_PHYSICAL_CPU 1024
 
-static int xenXMConfigSetString(virConfPtr conf, const char *setting,
-                                const char *str);
 char * xenXMAutoAssignMac(void);
 static int xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
                                         unsigned int flags);
@@ -189,9 +187,10 @@ xenXMConfigReadFile(virConnectPtr conn, const char *filename) {
 static int
 xenXMConfigSaveFile(virConnectPtr conn, const char *filename, virDomainDefPtr def) {
     virConfPtr conf;
+    xenUnifiedPrivatePtr priv = conn->privateData;
     int ret;
 
-    if (!(conf = xenXMDomainConfigFormat(conn, def)))
+    if (!(conf = xenXMDomainConfigFormat(conn, def, priv->xendConfigVersion)))
         return -1;
 
     ret = virConfWriteFile(filename, conf);
@@ -1043,724 +1042,6 @@ int xenXMDomainCreate(virDomainPtr domain) {
     return (-1);
 }
 
-
-static
-int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
-    virConfValuePtr value = NULL;
-
-    if (VIR_ALLOC(value) < 0) {
-        virReportOOMError();
-        return -1;
-    }
-
-    value->type = VIR_CONF_LONG;
-    value->next = NULL;
-    value->l = l;
-
-    return virConfSetValue(conf, setting, value);
-}
-
-
-static
-int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
-    virConfValuePtr value = NULL;
-
-    if (VIR_ALLOC(value) < 0) {
-        virReportOOMError();
-        return -1;
-    }
-
-    value->type = VIR_CONF_STRING;
-    value->next = NULL;
-    if (!(value->str = strdup(str))) {
-        VIR_FREE(value);
-        virReportOOMError();
-        return -1;
-    }
-
-    return virConfSetValue(conf, setting, value);
-}
-
-
-static int xenXMDomainConfigFormatDisk(virConfValuePtr list,
-                                       virDomainDiskDefPtr disk,
-                                       int hvm,
-                                       int xendConfigVersion)
-{
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    virConfValuePtr val, tmp;
-
-    if(disk->src) {
-        if (disk->driverName) {
-            virBufferVSprintf(&buf, "%s:", disk->driverName);
-            if (STREQ(disk->driverName, "tap"))
-                virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
-        } else {
-            switch (disk->type) {
-            case VIR_DOMAIN_DISK_TYPE_FILE:
-                virBufferAddLit(&buf, "file:");
-                break;
-            case VIR_DOMAIN_DISK_TYPE_BLOCK:
-                virBufferAddLit(&buf, "phy:");
-                break;
-            default:
-                xenXMError(VIR_ERR_INTERNAL_ERROR,
-                           _("unsupported disk type %s"),
-                           virDomainDiskTypeToString(disk->type));
-                goto cleanup;
-            }
-        }
-        virBufferVSprintf(&buf, "%s", disk->src);
-    }
-    virBufferAddLit(&buf, ",");
-    if (hvm && xendConfigVersion == 1)
-        virBufferAddLit(&buf, "ioemu:");
-
-    virBufferVSprintf(&buf, "%s", disk->dst);
-    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
-        virBufferAddLit(&buf, ":cdrom");
-
-    if (disk->readonly)
-        virBufferAddLit(&buf, ",r");
-    else if (disk->shared)
-        virBufferAddLit(&buf, ",!");
-    else
-        virBufferAddLit(&buf, ",w");
-
-    if (virBufferError(&buf)) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    if (VIR_ALLOC(val) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    val->type = VIR_CONF_STRING;
-    val->str = virBufferContentAndReset(&buf);
-    tmp = list->list;
-    while (tmp && tmp->next)
-        tmp = tmp->next;
-    if (tmp)
-        tmp->next = val;
-    else
-        list->list = val;
-
-    return 0;
-
-cleanup:
-    virBufferFreeAndReset(&buf);
-    return -1;
-}
-
-static int xenXMDomainConfigFormatNet(virConnectPtr conn,
-                                      virConfValuePtr list,
-                                      virDomainNetDefPtr net,
-                                      int hvm)
-{
-    virBuffer buf = VIR_BUFFER_INITIALIZER;
-    virConfValuePtr val, tmp;
-    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
-
-    virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
-                      net->mac[0], net->mac[1],
-                      net->mac[2], net->mac[3],
-                      net->mac[4], net->mac[5]);
-
-    switch (net->type) {
-    case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname);
-        if (net->data.bridge.ipaddr)
-            virBufferVSprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
-        virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
-        break;
-
-    case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        if (net->data.ethernet.script)
-            virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
-        if (net->data.ethernet.ipaddr)
-            virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
-        break;
-
-    case VIR_DOMAIN_NET_TYPE_NETWORK:
-    {
-        virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
-        char *bridge;
-        if (!network) {
-            xenXMError(VIR_ERR_NO_NETWORK, "%s",
-                       net->data.network.name);
-            return -1;
-        }
-        bridge = virNetworkGetBridgeName(network);
-        virNetworkFree(network);
-        if (!bridge) {
-            xenXMError(VIR_ERR_INTERNAL_ERROR,
-                       _("network %s is not active"),
-                       net->data.network.name);
-            return -1;
-        }
-
-        virBufferVSprintf(&buf, ",bridge=%s", bridge);
-        virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
-    }
-    break;
-
-    default:
-        xenXMError(VIR_ERR_INTERNAL_ERROR,
-                   _("unsupported network type %d"),
-                   net->type);
-        goto cleanup;
-    }
-
-    if (!hvm) {
-        if (net->model != NULL)
-            virBufferVSprintf(&buf, ",model=%s", net->model);
-    }
-    else if (net->model == NULL) {
-        /*
-         * apparently type ioemu breaks paravirt drivers on HVM so skip this
-         * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
-         */
-        if (priv->xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
-            virBufferAddLit(&buf, ",type=ioemu");
-    }
-    else if (STREQ(net->model, "netfront")) {
-        virBufferAddLit(&buf, ",type=netfront");
-    }
-    else {
-        virBufferVSprintf(&buf, ",model=%s", net->model);
-        virBufferAddLit(&buf, ",type=ioemu");
-    }
-
-    if (net->ifname)
-        virBufferVSprintf(&buf, ",vifname=%s",
-                          net->ifname);
-
-    if (virBufferError(&buf)) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    if (VIR_ALLOC(val) < 0) {
-        virReportOOMError();
-        goto cleanup;
-    }
-
-    val->type = VIR_CONF_STRING;
-    val->str = virBufferContentAndReset(&buf);
-    tmp = list->list;
-    while (tmp && tmp->next)
-        tmp = tmp->next;
-    if (tmp)
-        tmp->next = val;
-    else
-        list->list = val;
-
-    return 0;
-
-cleanup:
-    virBufferFreeAndReset(&buf);
-    return -1;
-}
-
-
-
-static int
-xenXMDomainConfigFormatPCI(virConfPtr conf,
-                           virDomainDefPtr def)
-{
-
-    virConfValuePtr pciVal = NULL;
-    int hasPCI = 0;
-    int i;
-
-    for (i = 0 ; i < def->nhostdevs ; i++)
-        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
-            hasPCI = 1;
-
-    if (!hasPCI)
-        return 0;
-
-    if (VIR_ALLOC(pciVal) < 0) {
-        virReportOOMError();
-        return -1;
-    }
-
-    pciVal->type = VIR_CONF_LIST;
-    pciVal->list = NULL;
-
-    for (i = 0 ; i < def->nhostdevs ; i++) {
-        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
-            virConfValuePtr val, tmp;
-            char *buf;
-
-            if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
-                            def->hostdevs[i]->source.subsys.u.pci.domain,
-                            def->hostdevs[i]->source.subsys.u.pci.bus,
-                            def->hostdevs[i]->source.subsys.u.pci.slot,
-                            def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
-                virReportOOMError();
-                goto error;
-            }
-
-            if (VIR_ALLOC(val) < 0) {
-                VIR_FREE(buf);
-                virReportOOMError();
-                goto error;
-            }
-            val->type = VIR_CONF_STRING;
-            val->str = buf;
-            tmp = pciVal->list;
-            while (tmp && tmp->next)
-                tmp = tmp->next;
-            if (tmp)
-                tmp->next = val;
-            else
-                pciVal->list = val;
-        }
-    }
-
-    if (pciVal->list != NULL) {
-        int ret = virConfSetValue(conf, "pci", pciVal);
-        pciVal = NULL;
-        if (ret < 0)
-            return -1;
-    }
-    VIR_FREE(pciVal);
-
-    return 0;
-
-error:
-    virConfFreeValue(pciVal);
-    return -1;
-}
-
-
-/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
-   either 32, or 64 on a platform where long is big enough.  */
-verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
-
-virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
-                                   virDomainDefPtr def) {
-    virConfPtr conf = NULL;
-    int hvm = 0, i;
-    xenUnifiedPrivatePtr priv;
-    char *cpus = NULL;
-    const char *lifecycle;
-    char uuid[VIR_UUID_STRING_BUFLEN];
-    virConfValuePtr diskVal = NULL;
-    virConfValuePtr netVal = NULL;
-
-    priv = (xenUnifiedPrivatePtr) conn->privateData;
-
-    if (!(conf = virConfNew()))
-        goto cleanup;
-
-
-    if (xenXMConfigSetString(conf, "name", def->name) < 0)
-        goto no_memory;
-
-    virUUIDFormat(def->uuid, uuid);
-    if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
-        goto no_memory;
-
-    if (xenXMConfigSetInt(conf, "maxmem", VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
-        goto no_memory;
-
-    if (xenXMConfigSetInt(conf, "memory", VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
-        goto no_memory;
-
-    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
-        goto no_memory;
-    /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
-       either 32, or 64 on a platform where long is big enough.  */
-    if (def->vcpus < def->maxvcpus &&
-        xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
-        goto no_memory;
-
-    if ((def->cpumask != NULL) &&
-        ((cpus = virDomainCpuSetFormat(def->cpumask,
-                                       def->cpumasklen)) == NULL))
-        goto cleanup;
-
-    if (cpus &&
-        xenXMConfigSetString(conf, "cpus", cpus) < 0)
-        goto no_memory;
-    VIR_FREE(cpus);
-
-    hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
-
-    if (hvm) {
-        char boot[VIR_DOMAIN_BOOT_LAST+1];
-        if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
-            goto no_memory;
-
-        if (def->os.loader &&
-            xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
-            goto no_memory;
-
-        for (i = 0 ; i < def->os.nBootDevs ; i++) {
-            switch (def->os.bootDevs[i]) {
-            case VIR_DOMAIN_BOOT_FLOPPY:
-                boot[i] = 'a';
-                break;
-            case VIR_DOMAIN_BOOT_CDROM:
-                boot[i] = 'd';
-                break;
-            case VIR_DOMAIN_BOOT_NET:
-                boot[i] = 'n';
-                break;
-            case VIR_DOMAIN_BOOT_DISK:
-            default:
-                boot[i] = 'c';
-                break;
-            }
-        }
-        if (!def->os.nBootDevs) {
-            boot[0] = 'c';
-            boot[1] = '\0';
-        } else {
-            boot[def->os.nBootDevs] = '\0';
-        }
-
-        if (xenXMConfigSetString(conf, "boot", boot) < 0)
-            goto no_memory;
-
-        if (xenXMConfigSetInt(conf, "pae",
-                              (def->features &
-                               (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
-            goto no_memory;
-
-        if (xenXMConfigSetInt(conf, "acpi",
-                              (def->features &
-                               (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
-            goto no_memory;
-
-        if (xenXMConfigSetInt(conf, "apic",
-                              (def->features &
-                               (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
-            goto no_memory;
-
-        if (priv->xendConfigVersion >= 3)
-            if (xenXMConfigSetInt(conf, "hap",
-                                  (def->features &
-                                   (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
-                goto no_memory;
-
-        if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
-            if (def->clock.data.timezone) {
-                xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           "%s", _("configurable timezones are not supported"));
-                goto cleanup;
-            }
-
-            if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
-                goto no_memory;
-        } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
-            if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
-                goto no_memory;
-        } else {
-            /* XXX We could support Xen's rtc clock offset */
-            xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("unsupported clock offset '%s'"),
-                       virDomainClockOffsetTypeToString(def->clock.offset));
-            goto cleanup;
-        }
-
-        if (priv->xendConfigVersion == 1) {
-            for (i = 0 ; i < def->ndisks ; i++) {
-                if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-                    def->disks[i]->dst &&
-                    STREQ(def->disks[i]->dst, "hdc") &&
-                    def->disks[i]->src) {
-                    if (xenXMConfigSetString(conf, "cdrom",
-                                             def->disks[i]->src) < 0)
-                        goto no_memory;
-                    break;
-                }
-            }
-        }
-
-        /* XXX floppy disks */
-    } else {
-        if (def->os.bootloader &&
-            xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
-            goto no_memory;
-        if (def->os.bootloaderArgs &&
-            xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
-            goto no_memory;
-        if (def->os.kernel &&
-            xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
-            goto no_memory;
-        if (def->os.initrd &&
-            xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
-            goto no_memory;
-        if (def->os.cmdline &&
-            xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
-            goto no_memory;
-
-    }
-
-    if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
-        xenXMError(VIR_ERR_INTERNAL_ERROR,
-                   _("unexpected lifecycle action %d"), def->onPoweroff);
-        goto cleanup;
-    }
-    if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
-        goto no_memory;
-
-
-    if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
-        xenXMError(VIR_ERR_INTERNAL_ERROR,
-                   _("unexpected lifecycle action %d"), def->onReboot);
-        goto cleanup;
-    }
-    if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
-        goto no_memory;
-
-
-    if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
-        xenXMError(VIR_ERR_INTERNAL_ERROR,
-                   _("unexpected lifecycle action %d"), def->onCrash);
-        goto cleanup;
-    }
-    if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
-        goto no_memory;
-
-
-
-    if (hvm) {
-        if (def->emulator &&
-            xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
-            goto no_memory;
-
-        for (i = 0 ; i < def->ninputs ; i++) {
-            if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
-                if (xenXMConfigSetInt(conf, "usb", 1) < 0)
-                    goto no_memory;
-                if (xenXMConfigSetString(conf, "usbdevice",
-                                         def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
-                                         "mouse" : "tablet") < 0)
-                    goto no_memory;
-                break;
-            }
-        }
-    }
-
-    if (def->ngraphics == 1) {
-        if (priv->xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
-            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
-                if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
-                    goto no_memory;
-                if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
-                    goto no_memory;
-                if (def->graphics[0]->data.sdl.display &&
-                    xenXMConfigSetString(conf, "display",
-                                     def->graphics[0]->data.sdl.display) < 0)
-                    goto no_memory;
-                if (def->graphics[0]->data.sdl.xauth &&
-                    xenXMConfigSetString(conf, "xauthority",
-                                         def->graphics[0]->data.sdl.xauth) < 0)
-                    goto no_memory;
-            } else {
-                if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
-                    goto no_memory;
-                if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
-                    goto no_memory;
-                if (xenXMConfigSetInt(conf, "vncunused",
-                              def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
-                    goto no_memory;
-                if (!def->graphics[0]->data.vnc.autoport &&
-                    xenXMConfigSetInt(conf, "vncdisplay",
-                                  def->graphics[0]->data.vnc.port - 5900) < 0)
-                    goto no_memory;
-                if (def->graphics[0]->data.vnc.listenAddr &&
-                    xenXMConfigSetString(conf, "vnclisten",
-                                    def->graphics[0]->data.vnc.listenAddr) < 0)
-                    goto no_memory;
-                if (def->graphics[0]->data.vnc.auth.passwd &&
-                    xenXMConfigSetString(conf, "vncpasswd",
-                                        def->graphics[0]->data.vnc.auth.passwd) < 0)
-                    goto no_memory;
-                if (def->graphics[0]->data.vnc.keymap &&
-                    xenXMConfigSetString(conf, "keymap",
-                                        def->graphics[0]->data.vnc.keymap) < 0)
-                    goto no_memory;
-            }
-        } else {
-            virConfValuePtr vfb, disp;
-            char *vfbstr = NULL;
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
-                virBufferAddLit(&buf, "type=sdl");
-                if (def->graphics[0]->data.sdl.display)
-                    virBufferVSprintf(&buf, ",display=%s",
-                                      def->graphics[0]->data.sdl.display);
-                if (def->graphics[0]->data.sdl.xauth)
-                    virBufferVSprintf(&buf, ",xauthority=%s",
-                                      def->graphics[0]->data.sdl.xauth);
-            } else {
-                virBufferAddLit(&buf, "type=vnc");
-                virBufferVSprintf(&buf, ",vncunused=%d",
-                                  def->graphics[0]->data.vnc.autoport ? 1 : 0);
-                if (!def->graphics[0]->data.vnc.autoport)
-                    virBufferVSprintf(&buf, ",vncdisplay=%d",
-                                      def->graphics[0]->data.vnc.port - 5900);
-                if (def->graphics[0]->data.vnc.listenAddr)
-                    virBufferVSprintf(&buf, ",vnclisten=%s",
-                                      def->graphics[0]->data.vnc.listenAddr);
-                if (def->graphics[0]->data.vnc.auth.passwd)
-                    virBufferVSprintf(&buf, ",vncpasswd=%s",
-                                      def->graphics[0]->data.vnc.auth.passwd);
-                if (def->graphics[0]->data.vnc.keymap)
-                    virBufferVSprintf(&buf, ",keymap=%s",
-                                      def->graphics[0]->data.vnc.keymap);
-            }
-            if (virBufferError(&buf)) {
-                virBufferFreeAndReset(&buf);
-                goto no_memory;
-            }
-
-            vfbstr = virBufferContentAndReset(&buf);
-
-            if (VIR_ALLOC(vfb) < 0) {
-                VIR_FREE(vfbstr);
-                goto no_memory;
-            }
-
-            if (VIR_ALLOC(disp) < 0) {
-                VIR_FREE(vfb);
-                VIR_FREE(vfbstr);
-                goto no_memory;
-            }
-
-            vfb->type = VIR_CONF_LIST;
-            vfb->list = disp;
-            disp->type = VIR_CONF_STRING;
-            disp->str = vfbstr;
-
-            if (virConfSetValue(conf, "vfb", vfb) < 0)
-                goto no_memory;
-        }
-    }
-
-    /* analyze of the devices */
-    if (VIR_ALLOC(diskVal) < 0)
-        goto no_memory;
-    diskVal->type = VIR_CONF_LIST;
-    diskVal->list = NULL;
-
-    for (i = 0 ; i < def->ndisks ; i++) {
-        if (priv->xendConfigVersion == 1 &&
-            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
-            def->disks[i]->dst &&
-            STREQ(def->disks[i]->dst, "hdc")) {
-            continue;
-        }
-        if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
-            continue;
-
-        if (xenXMDomainConfigFormatDisk(diskVal, def->disks[i],
-                                        hvm, priv->xendConfigVersion) < 0)
-            goto cleanup;
-    }
-    if (diskVal->list != NULL) {
-        int ret = virConfSetValue(conf, "disk", diskVal);
-        diskVal = NULL;
-        if (ret < 0)
-            goto no_memory;
-    }
-    VIR_FREE(diskVal);
-
-    if (VIR_ALLOC(netVal) < 0)
-        goto no_memory;
-    netVal->type = VIR_CONF_LIST;
-    netVal->list = NULL;
-
-    for (i = 0 ; i < def->nnets ; i++) {
-        if (xenXMDomainConfigFormatNet(conn, netVal,
-                                       def->nets[i],
-                                       hvm) < 0)
-            goto cleanup;
-    }
-    if (netVal->list != NULL) {
-        int ret = virConfSetValue(conf, "vif", netVal);
-        netVal = NULL;
-        if (ret < 0)
-            goto no_memory;
-    }
-    VIR_FREE(netVal);
-
-    if (xenXMDomainConfigFormatPCI(conf, def) < 0)
-        goto cleanup;
-
-    if (hvm) {
-        if (def->nparallels) {
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-            char *str;
-            int ret;
-
-            ret = xenDaemonFormatSxprChr(def->parallels[0], &buf);
-            str = virBufferContentAndReset(&buf);
-            if (ret == 0)
-                ret = xenXMConfigSetString(conf, "parallel", str);
-            VIR_FREE(str);
-            if (ret < 0)
-                goto no_memory;
-        } else {
-            if (xenXMConfigSetString(conf, "parallel", "none") < 0)
-                goto no_memory;
-        }
-
-        if (def->nserials) {
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-            char *str;
-            int ret;
-
-            ret = xenDaemonFormatSxprChr(def->serials[0], &buf);
-            str = virBufferContentAndReset(&buf);
-            if (ret == 0)
-                ret = xenXMConfigSetString(conf, "serial", str);
-            VIR_FREE(str);
-            if (ret < 0)
-                goto no_memory;
-        } else {
-            if (xenXMConfigSetString(conf, "serial", "none") < 0)
-                goto no_memory;
-        }
-
-
-        if (def->sounds) {
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-            char *str = NULL;
-            int ret = xenDaemonFormatSxprSound(def, &buf);
-            str = virBufferContentAndReset(&buf);
-            if (ret == 0)
-                ret = xenXMConfigSetString(conf, "soundhw", str);
-
-            VIR_FREE(str);
-            if (ret < 0)
-                goto no_memory;
-        }
-    }
-
-    return conf;
-
-no_memory:
-    virReportOOMError();
-
-cleanup:
-    virConfFreeValue(diskVal);
-    virConfFreeValue(netVal);
-    VIR_FREE(cpus);
-    if (conf)
-        virConfFree(conf);
-    return (NULL);
-}
-
 /*
  * Create a config file for a domain, based on an XML
  * document describing its config
diff --git a/src/xen/xm_internal.h b/src/xen/xm_internal.h
index e89a711..695bb3e 100644
--- a/src/xen/xm_internal.h
+++ b/src/xen/xm_internal.h
@@ -61,8 +61,6 @@ int xenXMDomainCreate(virDomainPtr domain);
 virDomainPtr xenXMDomainDefineXML(virConnectPtr con, const char *xml);
 int xenXMDomainUndefine(virDomainPtr domain);
 
-virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, virDomainDefPtr def);
-
 int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer);
 
 int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart);
diff --git a/src/xenxs/xen_sxpr.h b/src/xenxs/xen_sxpr.h
index 0861c4b..5cff40e 100644
--- a/src/xenxs/xen_sxpr.h
+++ b/src/xenxs/xen_sxpr.h
@@ -32,12 +32,6 @@
 # include "domain_conf.h"
 # include "sexpr.h"
 
-# ifdef __sun
-#  define DEFAULT_VIF_SCRIPT "vif-vnic"
-# else
-#  define DEFAULT_VIF_SCRIPT "vif-bridge"
-# endif
-
 /* helper functions to get the dom id from a sexpr */
 int xenGetDomIdFromSxprString(const char *sexpr, int xendConfigVersion);
 int xenGetDomIdFromSxpr(const struct sexpr *root, int xendConfigVersion);
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index ee6116b..f01d767 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -1008,3 +1008,718 @@ cleanup:
     virDomainDefFree(def);
     return NULL;
 }
+
+
+static
+int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
+    virConfValuePtr value = NULL;
+
+    if (VIR_ALLOC(value) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    value->type = VIR_CONF_LONG;
+    value->next = NULL;
+    value->l = l;
+
+    return virConfSetValue(conf, setting, value);
+}
+
+
+static
+int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
+    virConfValuePtr value = NULL;
+
+    if (VIR_ALLOC(value) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    value->type = VIR_CONF_STRING;
+    value->next = NULL;
+    if (!(value->str = strdup(str))) {
+        VIR_FREE(value);
+        virReportOOMError();
+        return -1;
+    }
+
+    return virConfSetValue(conf, setting, value);
+}
+
+
+static int xenXMDomainConfigFormatDisk(virConfValuePtr list,
+                                       virDomainDiskDefPtr disk,
+                                       int hvm,
+                                       int xendConfigVersion)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    virConfValuePtr val, tmp;
+
+    if(disk->src) {
+        if (disk->driverName) {
+            virBufferVSprintf(&buf, "%s:", disk->driverName);
+            if (STREQ(disk->driverName, "tap"))
+                virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
+        } else {
+            switch (disk->type) {
+            case VIR_DOMAIN_DISK_TYPE_FILE:
+                virBufferAddLit(&buf, "file:");
+                break;
+            case VIR_DOMAIN_DISK_TYPE_BLOCK:
+                virBufferAddLit(&buf, "phy:");
+                break;
+            default:
+                XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                           _("unsupported disk type %s"),
+                           virDomainDiskTypeToString(disk->type));
+                goto cleanup;
+            }
+        }
+        virBufferVSprintf(&buf, "%s", disk->src);
+    }
+    virBufferAddLit(&buf, ",");
+    if (hvm && xendConfigVersion == 1)
+        virBufferAddLit(&buf, "ioemu:");
+
+    virBufferVSprintf(&buf, "%s", disk->dst);
+    if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+        virBufferAddLit(&buf, ":cdrom");
+
+    if (disk->readonly)
+        virBufferAddLit(&buf, ",r");
+    else if (disk->shared)
+        virBufferAddLit(&buf, ",!");
+    else
+        virBufferAddLit(&buf, ",w");
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC(val) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    val->type = VIR_CONF_STRING;
+    val->str = virBufferContentAndReset(&buf);
+    tmp = list->list;
+    while (tmp && tmp->next)
+        tmp = tmp->next;
+    if (tmp)
+        tmp->next = val;
+    else
+        list->list = val;
+
+    return 0;
+
+cleanup:
+    virBufferFreeAndReset(&buf);
+    return -1;
+}
+
+static int xenXMDomainConfigFormatNet(virConnectPtr conn,
+                                      virConfValuePtr list,
+                                      virDomainNetDefPtr net,
+                                      int hvm, int xendConfigVersion)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    virConfValuePtr val, tmp;
+
+    virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
+                      net->mac[0], net->mac[1],
+                      net->mac[2], net->mac[3],
+                      net->mac[4], net->mac[5]);
+
+    switch (net->type) {
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
+        virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname);
+        if (net->data.bridge.ipaddr)
+            virBufferVSprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
+        virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+        if (net->data.ethernet.script)
+            virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
+        if (net->data.ethernet.ipaddr)
+            virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+    {
+        virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
+        char *bridge;
+        if (!network) {
+            XENXS_ERROR(VIR_ERR_NO_NETWORK, "%s",
+                       net->data.network.name);
+            return -1;
+        }
+        bridge = virNetworkGetBridgeName(network);
+        virNetworkFree(network);
+        if (!bridge) {
+            XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                       _("network %s is not active"),
+                       net->data.network.name);
+            return -1;
+        }
+
+        virBufferVSprintf(&buf, ",bridge=%s", bridge);
+        virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
+    }
+    break;
+
+    default:
+        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                   _("unsupported network type %d"),
+                   net->type);
+        goto cleanup;
+    }
+
+    if (!hvm) {
+        if (net->model != NULL)
+            virBufferVSprintf(&buf, ",model=%s", net->model);
+    }
+    else if (net->model == NULL) {
+        /*
+         * apparently type ioemu breaks paravirt drivers on HVM so skip this
+         * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
+         */
+        if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
+            virBufferAddLit(&buf, ",type=ioemu");
+    }
+    else if (STREQ(net->model, "netfront")) {
+        virBufferAddLit(&buf, ",type=netfront");
+    }
+    else {
+        virBufferVSprintf(&buf, ",model=%s", net->model);
+        virBufferAddLit(&buf, ",type=ioemu");
+    }
+
+    if (net->ifname)
+        virBufferVSprintf(&buf, ",vifname=%s",
+                          net->ifname);
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC(val) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    val->type = VIR_CONF_STRING;
+    val->str = virBufferContentAndReset(&buf);
+    tmp = list->list;
+    while (tmp && tmp->next)
+        tmp = tmp->next;
+    if (tmp)
+        tmp->next = val;
+    else
+        list->list = val;
+
+    return 0;
+
+cleanup:
+    virBufferFreeAndReset(&buf);
+    return -1;
+}
+
+
+
+static int
+xenXMDomainConfigFormatPCI(virConfPtr conf,
+                           virDomainDefPtr def)
+{
+
+    virConfValuePtr pciVal = NULL;
+    int hasPCI = 0;
+    int i;
+
+    for (i = 0 ; i < def->nhostdevs ; i++)
+        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            hasPCI = 1;
+
+    if (!hasPCI)
+        return 0;
+
+    if (VIR_ALLOC(pciVal) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    pciVal->type = VIR_CONF_LIST;
+    pciVal->list = NULL;
+
+    for (i = 0 ; i < def->nhostdevs ; i++) {
+        if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+            def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+            virConfValuePtr val, tmp;
+            char *buf;
+
+            if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
+                            def->hostdevs[i]->source.subsys.u.pci.domain,
+                            def->hostdevs[i]->source.subsys.u.pci.bus,
+                            def->hostdevs[i]->source.subsys.u.pci.slot,
+                            def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
+                virReportOOMError();
+                goto error;
+            }
+
+            if (VIR_ALLOC(val) < 0) {
+                VIR_FREE(buf);
+                virReportOOMError();
+                goto error;
+            }
+            val->type = VIR_CONF_STRING;
+            val->str = buf;
+            tmp = pciVal->list;
+            while (tmp && tmp->next)
+                tmp = tmp->next;
+            if (tmp)
+                tmp->next = val;
+            else
+                pciVal->list = val;
+        }
+    }
+
+    if (pciVal->list != NULL) {
+        int ret = virConfSetValue(conf, "pci", pciVal);
+        pciVal = NULL;
+        if (ret < 0)
+            return -1;
+    }
+    VIR_FREE(pciVal);
+
+    return 0;
+
+error:
+    virConfFreeValue(pciVal);
+    return -1;
+}
+
+
+/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
+   either 32, or 64 on a platform where long is big enough.  */
+verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
+
+virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
+                                   virDomainDefPtr def,
+                                   int xendConfigVersion) {
+    virConfPtr conf = NULL;
+    int hvm = 0, i;
+    char *cpus = NULL;
+    const char *lifecycle;
+    char uuid[VIR_UUID_STRING_BUFLEN];
+    virConfValuePtr diskVal = NULL;
+    virConfValuePtr netVal = NULL;
+
+    if (!(conf = virConfNew()))
+        goto cleanup;
+
+
+    if (xenXMConfigSetString(conf, "name", def->name) < 0)
+        goto no_memory;
+
+    virUUIDFormat(def->uuid, uuid);
+    if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
+        goto no_memory;
+
+    if (xenXMConfigSetInt(conf, "maxmem", VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
+        goto no_memory;
+
+    if (xenXMConfigSetInt(conf, "memory", VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
+        goto no_memory;
+
+    if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
+        goto no_memory;
+    /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
+       either 32, or 64 on a platform where long is big enough.  */
+    if (def->vcpus < def->maxvcpus &&
+        xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
+        goto no_memory;
+
+    if ((def->cpumask != NULL) &&
+        ((cpus = virDomainCpuSetFormat(def->cpumask,
+                                       def->cpumasklen)) == NULL))
+        goto cleanup;
+
+    if (cpus &&
+        xenXMConfigSetString(conf, "cpus", cpus) < 0)
+        goto no_memory;
+    VIR_FREE(cpus);
+
+    hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
+
+    if (hvm) {
+        char boot[VIR_DOMAIN_BOOT_LAST+1];
+        if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
+            goto no_memory;
+
+        if (def->os.loader &&
+            xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
+            goto no_memory;
+
+        for (i = 0 ; i < def->os.nBootDevs ; i++) {
+            switch (def->os.bootDevs[i]) {
+            case VIR_DOMAIN_BOOT_FLOPPY:
+                boot[i] = 'a';
+                break;
+            case VIR_DOMAIN_BOOT_CDROM:
+                boot[i] = 'd';
+                break;
+            case VIR_DOMAIN_BOOT_NET:
+                boot[i] = 'n';
+                break;
+            case VIR_DOMAIN_BOOT_DISK:
+            default:
+                boot[i] = 'c';
+                break;
+            }
+        }
+        if (!def->os.nBootDevs) {
+            boot[0] = 'c';
+            boot[1] = '\0';
+        } else {
+            boot[def->os.nBootDevs] = '\0';
+        }
+
+        if (xenXMConfigSetString(conf, "boot", boot) < 0)
+            goto no_memory;
+
+        if (xenXMConfigSetInt(conf, "pae",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
+            goto no_memory;
+
+        if (xenXMConfigSetInt(conf, "acpi",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
+            goto no_memory;
+
+        if (xenXMConfigSetInt(conf, "apic",
+                              (def->features &
+                               (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
+            goto no_memory;
+
+        if (xendConfigVersion >= 3)
+            if (xenXMConfigSetInt(conf, "hap",
+                                  (def->features &
+                                   (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
+                goto no_memory;
+
+        if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
+            if (def->clock.data.timezone) {
+                XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+                           "%s", _("configurable timezones are not supported"));
+                goto cleanup;
+            }
+
+            if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
+                goto no_memory;
+        } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
+            if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
+                goto no_memory;
+        } else {
+            /* XXX We could support Xen's rtc clock offset */
+            XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unsupported clock offset '%s'"),
+                       virDomainClockOffsetTypeToString(def->clock.offset));
+            goto cleanup;
+        }
+
+        if (xendConfigVersion == 1) {
+            for (i = 0 ; i < def->ndisks ; i++) {
+                if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+                    def->disks[i]->dst &&
+                    STREQ(def->disks[i]->dst, "hdc") &&
+                    def->disks[i]->src) {
+                    if (xenXMConfigSetString(conf, "cdrom",
+                                             def->disks[i]->src) < 0)
+                        goto no_memory;
+                    break;
+                }
+            }
+        }
+
+        /* XXX floppy disks */
+    } else {
+        if (def->os.bootloader &&
+            xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
+            goto no_memory;
+        if (def->os.bootloaderArgs &&
+            xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
+            goto no_memory;
+        if (def->os.kernel &&
+            xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
+            goto no_memory;
+        if (def->os.initrd &&
+            xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
+            goto no_memory;
+        if (def->os.cmdline &&
+            xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
+            goto no_memory;
+
+    }
+
+    if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
+        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                   _("unexpected lifecycle action %d"), def->onPoweroff);
+        goto cleanup;
+    }
+    if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
+        goto no_memory;
+
+
+    if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
+        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                   _("unexpected lifecycle action %d"), def->onReboot);
+        goto cleanup;
+    }
+    if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
+        goto no_memory;
+
+
+    if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
+        XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+                   _("unexpected lifecycle action %d"), def->onCrash);
+        goto cleanup;
+    }
+    if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
+        goto no_memory;
+
+
+
+    if (hvm) {
+        if (def->emulator &&
+            xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
+            goto no_memory;
+
+        for (i = 0 ; i < def->ninputs ; i++) {
+            if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+                if (xenXMConfigSetInt(conf, "usb", 1) < 0)
+                    goto no_memory;
+                if (xenXMConfigSetString(conf, "usbdevice",
+                                         def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
+                                         "mouse" : "tablet") < 0)
+                    goto no_memory;
+                break;
+            }
+        }
+    }
+
+    if (def->ngraphics == 1) {
+        if (xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
+            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
+                if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
+                    goto no_memory;
+                if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
+                    goto no_memory;
+                if (def->graphics[0]->data.sdl.display &&
+                    xenXMConfigSetString(conf, "display",
+                                     def->graphics[0]->data.sdl.display) < 0)
+                    goto no_memory;
+                if (def->graphics[0]->data.sdl.xauth &&
+                    xenXMConfigSetString(conf, "xauthority",
+                                         def->graphics[0]->data.sdl.xauth) < 0)
+                    goto no_memory;
+            } else {
+                if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
+                    goto no_memory;
+                if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
+                    goto no_memory;
+                if (xenXMConfigSetInt(conf, "vncunused",
+                              def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
+                    goto no_memory;
+                if (!def->graphics[0]->data.vnc.autoport &&
+                    xenXMConfigSetInt(conf, "vncdisplay",
+                                  def->graphics[0]->data.vnc.port - 5900) < 0)
+                    goto no_memory;
+                if (def->graphics[0]->data.vnc.listenAddr &&
+                    xenXMConfigSetString(conf, "vnclisten",
+                                    def->graphics[0]->data.vnc.listenAddr) < 0)
+                    goto no_memory;
+                if (def->graphics[0]->data.vnc.auth.passwd &&
+                    xenXMConfigSetString(conf, "vncpasswd",
+                                        def->graphics[0]->data.vnc.auth.passwd) < 0)
+                    goto no_memory;
+                if (def->graphics[0]->data.vnc.keymap &&
+                    xenXMConfigSetString(conf, "keymap",
+                                        def->graphics[0]->data.vnc.keymap) < 0)
+                    goto no_memory;
+            }
+        } else {
+            virConfValuePtr vfb, disp;
+            char *vfbstr = NULL;
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
+                virBufferAddLit(&buf, "type=sdl");
+                if (def->graphics[0]->data.sdl.display)
+                    virBufferVSprintf(&buf, ",display=%s",
+                                      def->graphics[0]->data.sdl.display);
+                if (def->graphics[0]->data.sdl.xauth)
+                    virBufferVSprintf(&buf, ",xauthority=%s",
+                                      def->graphics[0]->data.sdl.xauth);
+            } else {
+                virBufferAddLit(&buf, "type=vnc");
+                virBufferVSprintf(&buf, ",vncunused=%d",
+                                  def->graphics[0]->data.vnc.autoport ? 1 : 0);
+                if (!def->graphics[0]->data.vnc.autoport)
+                    virBufferVSprintf(&buf, ",vncdisplay=%d",
+                                      def->graphics[0]->data.vnc.port - 5900);
+                if (def->graphics[0]->data.vnc.listenAddr)
+                    virBufferVSprintf(&buf, ",vnclisten=%s",
+                                      def->graphics[0]->data.vnc.listenAddr);
+                if (def->graphics[0]->data.vnc.auth.passwd)
+                    virBufferVSprintf(&buf, ",vncpasswd=%s",
+                                      def->graphics[0]->data.vnc.auth.passwd);
+                if (def->graphics[0]->data.vnc.keymap)
+                    virBufferVSprintf(&buf, ",keymap=%s",
+                                      def->graphics[0]->data.vnc.keymap);
+            }
+            if (virBufferError(&buf)) {
+                virBufferFreeAndReset(&buf);
+                goto no_memory;
+            }
+
+            vfbstr = virBufferContentAndReset(&buf);
+
+            if (VIR_ALLOC(vfb) < 0) {
+                VIR_FREE(vfbstr);
+                goto no_memory;
+            }
+
+            if (VIR_ALLOC(disp) < 0) {
+                VIR_FREE(vfb);
+                VIR_FREE(vfbstr);
+                goto no_memory;
+            }
+
+            vfb->type = VIR_CONF_LIST;
+            vfb->list = disp;
+            disp->type = VIR_CONF_STRING;
+            disp->str = vfbstr;
+
+            if (virConfSetValue(conf, "vfb", vfb) < 0)
+                goto no_memory;
+        }
+    }
+
+    /* analyze of the devices */
+    if (VIR_ALLOC(diskVal) < 0)
+        goto no_memory;
+    diskVal->type = VIR_CONF_LIST;
+    diskVal->list = NULL;
+
+    for (i = 0 ; i < def->ndisks ; i++) {
+        if (xendConfigVersion == 1 &&
+            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+            def->disks[i]->dst &&
+            STREQ(def->disks[i]->dst, "hdc")) {
+            continue;
+        }
+        if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+            continue;
+
+        if (xenXMDomainConfigFormatDisk(diskVal, def->disks[i],
+                                        hvm, xendConfigVersion) < 0)
+            goto cleanup;
+    }
+    if (diskVal->list != NULL) {
+        int ret = virConfSetValue(conf, "disk", diskVal);
+        diskVal = NULL;
+        if (ret < 0)
+            goto no_memory;
+    }
+    VIR_FREE(diskVal);
+
+    if (VIR_ALLOC(netVal) < 0)
+        goto no_memory;
+    netVal->type = VIR_CONF_LIST;
+    netVal->list = NULL;
+
+    for (i = 0 ; i < def->nnets ; i++) {
+        if (xenXMDomainConfigFormatNet(conn, netVal,
+                                       def->nets[i],
+                                       hvm, xendConfigVersion) < 0)
+            goto cleanup;
+    }
+    if (netVal->list != NULL) {
+        int ret = virConfSetValue(conf, "vif", netVal);
+        netVal = NULL;
+        if (ret < 0)
+            goto no_memory;
+    }
+    VIR_FREE(netVal);
+
+    if (xenXMDomainConfigFormatPCI(conf, def) < 0)
+        goto cleanup;
+
+    if (hvm) {
+        if (def->nparallels) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            char *str;
+            int ret;
+
+            ret = xenDaemonFormatSxprChr(def->parallels[0], &buf);
+            str = virBufferContentAndReset(&buf);
+            if (ret == 0)
+                ret = xenXMConfigSetString(conf, "parallel", str);
+            VIR_FREE(str);
+            if (ret < 0)
+                goto no_memory;
+        } else {
+            if (xenXMConfigSetString(conf, "parallel", "none") < 0)
+                goto no_memory;
+        }
+
+        if (def->nserials) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            char *str;
+            int ret;
+
+            ret = xenDaemonFormatSxprChr(def->serials[0], &buf);
+            str = virBufferContentAndReset(&buf);
+            if (ret == 0)
+                ret = xenXMConfigSetString(conf, "serial", str);
+            VIR_FREE(str);
+            if (ret < 0)
+                goto no_memory;
+        } else {
+            if (xenXMConfigSetString(conf, "serial", "none") < 0)
+                goto no_memory;
+        }
+
+
+        if (def->sounds) {
+            virBuffer buf = VIR_BUFFER_INITIALIZER;
+            char *str = NULL;
+            int ret = xenDaemonFormatSxprSound(def, &buf);
+            str = virBufferContentAndReset(&buf);
+            if (ret == 0)
+                ret = xenXMConfigSetString(conf, "soundhw", str);
+
+            VIR_FREE(str);
+            if (ret < 0)
+                goto no_memory;
+        }
+    }
+
+    return conf;
+
+no_memory:
+    virReportOOMError();
+
+cleanup:
+    virConfFreeValue(diskVal);
+    virConfFreeValue(netVal);
+    VIR_FREE(cpus);
+    if (conf)
+        virConfFree(conf);
+    return (NULL);
+}
\ No newline at end of file
diff --git a/src/xenxs/xen_xm.h b/src/xenxs/xen_xm.h
index 5eb1b1f..1114ada 100644
--- a/src/xenxs/xen_xm.h
+++ b/src/xenxs/xen_xm.h
@@ -30,6 +30,9 @@
 # include "conf.h"
 # include "domain_conf.h"
 
+virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, virDomainDefPtr def,
+                                   int xendConfigVersion);
+
 virDomainDefPtr xenXMDomainConfigParse(virConfPtr conf, int xendConfigVersion,
                                        virCapsPtr caps);
 
diff --git a/src/xenxs/xenxs_private.h b/src/xenxs/xenxs_private.h
index 4310ea1..0efebba 100644
--- a/src/xenxs/xenxs_private.h
+++ b/src/xenxs/xenxs_private.h
@@ -48,6 +48,12 @@
 
 # define MIN_XEN_GUEST_SIZE 64  /* 64 megabytes */
 
+# ifdef __sun
+#  define DEFAULT_VIF_SCRIPT "vif-vnic"
+# else
+#  define DEFAULT_VIF_SCRIPT "vif-bridge"
+# endif
+
 #define VIR_FROM_THIS VIR_FROM_NONE
 
 #define XENXS_ERROR(code, ...)                                                \
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index a825c17..9673e37 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -75,7 +75,7 @@ static int testCompareParseXML(const char *xmcfg, const char *xml,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto fail;
 
-    if (!(conf = xenXMDomainConfigFormat(conn, def)))
+    if (!(conf = xenXMDomainConfigFormat(conn, def, xendConfigVersion)))
         goto fail;
 
     if (virConfWriteMem(gotxmcfgPtr, &wrote, conf) < 0)
