Revert "[VMware] vSphere advanced capabilities and Full OVF properties support"
diff --git a/api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java b/api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java
index d923694..7d1e238 100644
--- a/api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java
+++ b/api/src/main/java/com/cloud/agent/api/StoragePoolInfo.java
@@ -28,7 +28,6 @@
     StoragePoolType poolType;
     long capacityBytes;
     long availableBytes;
-    String name;
     Map<String, String> details;
 
     protected StoragePoolInfo() {
@@ -68,34 +67,14 @@
         return host;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setLocalPath(String localPath) {
-        this.localPath = localPath;
-    }
-
     public String getLocalPath() {
         return localPath;
     }
 
-    public void setHostPath(String hostPath) {
-        this.hostPath = hostPath;
-    }
-
     public String getHostPath() {
         return hostPath;
     }
 
-    public void setPoolType(StoragePoolType poolType) {
-        this.poolType = poolType;
-    }
-
     public StoragePoolType getPoolType() {
         return poolType;
     }
diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
index 8d4f780..15d6358 100644
--- a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
+++ b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java
@@ -22,15 +22,8 @@
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
-import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.Transformer;
@@ -39,28 +32,15 @@
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
-import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.exception.InternalErrorException;
-import com.cloud.utils.Pair;
-import com.cloud.utils.compression.CompressionUtil;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.w3c.dom.traversal.DocumentTraversal;
-import org.w3c.dom.traversal.NodeFilter;
-import org.w3c.dom.traversal.NodeIterator;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
@@ -93,11 +73,10 @@
     }
 
     /**
-     * Get the text value of a node's child with name or suffix "childNodeName", null if not present
+     * Get the text value of a node's child with name "childNodeName", null if not present
      * Example:
      * <Node>
      *    <childNodeName>Text value</childNodeName>
-     *    <rasd:childNodeName>Text value</rasd:childNodeName>
      * </Node>
      */
     private String getChildNodeValue(Node node, String childNodeName) {
@@ -105,9 +84,7 @@
             NodeList childNodes = node.getChildNodes();
             for (int i = 0; i < childNodes.getLength(); i++) {
                 Node value = childNodes.item(i);
-                // Also match if the child's name has a suffix:
-                // Example: <rasd:AllocationUnits>
-                if (value != null && (value.getNodeName().equals(childNodeName)) || value.getNodeName().endsWith(":" + childNodeName)) {
+                if (value != null && value.getNodeName().equals(childNodeName)) {
                     return value.getTextContent();
                 }
             }
@@ -116,93 +93,44 @@
     }
 
     /**
-     * Check if the attribute is present on the element, otherwise check preprending ':'
-     */
-    private String getNodeAttribute(Element element, String prefix, String attr) {
-        if (element == null) {
-            return null;
-        }
-        if (element.hasAttribute(prefix + ":" + attr)) {
-            return element.getAttribute(prefix + ":" + attr);
-        }
-        else if (element.hasAttribute(attr)) {
-            return element.getAttribute(attr);
-        }
-
-        NamedNodeMap attributes = element.getAttributes();
-        if (attributes == null || attributes.getLength() == 0) {
-            return null;
-        }
-        for (int i = 0; i < attributes.getLength(); i++) {
-            Node node = attributes.item(i);
-            if (node != null && node.getNodeName().endsWith(":" + attr)) {
-                return node.getTextContent();
-            }
-        }
-        return null;
-    }
-
-    /**
      * Create OVFProperty class from the parsed node. Note that some fields may not be present.
      * The key attribute is required
      */
-    protected OVFPropertyTO createOVFPropertyFromNode(Node node, int index, String category) {
-        Element element = (Element) node;
-        String key = getNodeAttribute(element, "ovf","key");
+    protected OVFPropertyTO createOVFPropertyFromNode(Node node) {
+        Element property = (Element) node;
+        String key = property.getAttribute("ovf:key");
         if (StringUtils.isBlank(key)) {
             return null;
         }
 
-        String value = getNodeAttribute(element, "ovf","value");
-        String type = getNodeAttribute(element, "ovf","type");
-        String qualifiers = getNodeAttribute(element, "ovf","qualifiers");
-        String userConfigurableStr = getNodeAttribute(element, "ovf","userConfigurable");
+        String value = property.getAttribute("ovf:value");
+        String type = property.getAttribute("ovf:type");
+        String qualifiers = property.getAttribute("ovf:qualifiers");
+        String userConfigurableStr = property.getAttribute("ovf:userConfigurable");
         boolean userConfigurable = StringUtils.isNotBlank(userConfigurableStr) &&
                 userConfigurableStr.equalsIgnoreCase("true");
-        String passStr = getNodeAttribute(element, "ovf","password");
+        String passStr = property.getAttribute("ovf:password");
         boolean password = StringUtils.isNotBlank(passStr) && passStr.equalsIgnoreCase("true");
         String label = getChildNodeValue(node, "Label");
         String description = getChildNodeValue(node, "Description");
-        s_logger.debug("Creating OVF property index " + index + (category == null ? "" : " for category " + category)
-                + " with key = " + key);
-        return new OVFPropertyTO(key, type, value, qualifiers, userConfigurable,
-                label, description, password, index, category);
+        return new OVFPropertyTO(key, type, value, qualifiers, userConfigurable, label, description, password);
     }
 
     /**
-     * Retrieve OVF properties from a parsed OVF file including its category (if available) and in-order,
-     * with attribute 'ovf:userConfigurable' set to true.
+     * Retrieve OVF properties from a parsed OVF file, with attribute 'ovf:userConfigurable' set to true
      */
-    public List<OVFPropertyTO> getConfigurableOVFPropertiesFromDocument(Document doc) {
+    private List<OVFPropertyTO> getConfigurableOVFPropertiesFromDocument(Document doc) {
         List<OVFPropertyTO> props = new ArrayList<>();
-        if (doc == null) {
-            return props;
-        }
-        int propertyIndex = 0;
-        NodeList productSections = doc.getElementsByTagName("ProductSection");
-        if (productSections != null) {
-            String lastCategoryFound = null;
-            for (int i = 0; i < productSections.getLength(); i++) {
-                Node node = productSections.item(i);
+        NodeList properties = doc.getElementsByTagName("Property");
+        if (properties != null) {
+            for (int i = 0; i < properties.getLength(); i++) {
+                Node node = properties.item(i);
                 if (node == null) {
                     continue;
                 }
-                NodeList childNodes = node.getChildNodes();
-                for (int j = 0; j < childNodes.getLength(); j++) {
-                    Node child = childNodes.item(j);
-                    if (child == null) {
-                        continue;
-                    }
-                    if (child.getNodeName().equalsIgnoreCase("Category")) {
-                        lastCategoryFound = child.getTextContent();
-                        s_logger.info("Category found " + lastCategoryFound);
-                    } else if (child.getNodeName().equalsIgnoreCase("Property")) {
-                        OVFPropertyTO prop = createOVFPropertyFromNode(child, propertyIndex, lastCategoryFound);
-                        if (prop != null && prop.isUserConfigurable()) {
-                            props.add(prop);
-                            propertyIndex++;
-                        }
-                    }
+                OVFPropertyTO prop = createOVFPropertyFromNode(node);
+                if (prop != null && prop.isUserConfigurable()) {
+                    props.add(prop);
                 }
             }
         }
@@ -210,237 +138,128 @@
     }
 
     /**
+     * Get properties from OVF file located on ovfFilePath
+     */
+    public List<OVFPropertyTO> getOVFPropertiesFromFile(String ovfFilePath) throws ParserConfigurationException, IOException, SAXException {
+        if (StringUtils.isBlank(ovfFilePath)) {
+            return new ArrayList<>();
+        }
+        File ovfFile = new File(ovfFilePath);
+        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(ovfFile);
+        return getConfigurableOVFPropertiesFromDocument(doc);
+    }
+
+    /**
      * Get properties from OVF XML string
      */
-    protected List<OVFPropertyTO> getOVFPropertiesFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
+    protected List<OVFPropertyTO> getOVFPropertiesXmlString(final String ovfFilePath) throws ParserConfigurationException, IOException, SAXException {
+        InputSource is = new InputSource(new StringReader(ovfFilePath));
         final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
         return getConfigurableOVFPropertiesFromDocument(doc);
     }
 
-    protected Pair<String, String> getOperatingSystemInfoFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
-        return getOperatingSystemInfoFromDocument(doc);
-    }
-
-    protected List<OVFConfigurationTO> getOVFDeploymentOptionsFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
-        return getDeploymentOptionsFromDocumentTree(doc);
-    }
-
-    protected List<OVFVirtualHardwareItemTO> getOVFVirtualHardwareSectionFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
-        return getVirtualHardwareItemsFromDocumentTree(doc);
-    }
-
-    protected OVFVirtualHardwareSectionTO getVirtualHardwareSectionFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
-        return getVirtualHardwareSectionFromDocument(doc);
-    }
-
-    protected List<OVFEulaSectionTO> getOVFEulaSectionFromXmlString(final String ovfString) throws ParserConfigurationException, IOException, SAXException {
-        InputSource is = new InputSource(new StringReader(ovfString));
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
-        return getEulaSectionsFromDocument(doc);
-    }
-
-    public List<DatadiskTO> getOVFVolumeInfoFromFile(final String ovfFilePath, final String configurationId) throws InternalErrorException {
+    public List<DatadiskTO> getOVFVolumeInfo(final String ovfFilePath) {
         if (StringUtils.isBlank(ovfFilePath)) {
-            return new ArrayList<>();
+            return new ArrayList<DatadiskTO>();
         }
-        Document doc = getDocumentFromFile(ovfFilePath);
-
-        return getOVFVolumeInfoFromFile(ovfFilePath, doc, configurationId);
-    }
-
-    public List<DatadiskTO> getOVFVolumeInfoFromFile(String ovfFilePath, Document doc, String configurationId) throws InternalErrorException {
-        if (org.apache.commons.lang.StringUtils.isBlank(ovfFilePath)) {
-            return null;
-        }
+        ArrayList<OVFFile> vf = new ArrayList<OVFFile>();
+        ArrayList<OVFDisk> vd = new ArrayList<OVFDisk>();
 
         File ovfFile = new File(ovfFilePath);
-        List<OVFVirtualHardwareItemTO> hardwareItems = getVirtualHardwareItemsFromDocumentTree(doc);
-        List<OVFFile> files = extractFilesFromOvfDocumentTree(ovfFile, doc);
-        List<OVFDisk> disks = extractDisksFromOvfDocumentTree(doc);
-
-        List<OVFVirtualHardwareItemTO> diskHardwareItems = hardwareItems.stream()
-                .filter(x -> x.getResourceType() == OVFVirtualHardwareItemTO.HardwareResourceType.DiskDrive &&
-                        hardwareItemContainsConfiguration(x, configurationId))
-                .collect(Collectors.toList());
-        List<DatadiskTO> diskTOs = matchHardwareItemsToDiskAndFilesInformation(diskHardwareItems, files, disks, ovfFile.getParent());
-        return diskTOs;
-    }
-
-    private String extractDiskIdFromDiskHostResource(String hostResource) {
-        if (hostResource.startsWith("ovf:/disk/")) {
-            return hostResource.replace("ovf:/disk/", "");
-        }
-        String[] resourceParts = hostResource.split("/");
-        return resourceParts[resourceParts.length - 1];
-    }
-
-    private OVFDisk getDiskDefinitionFromDiskId(String diskId, List<OVFDisk> disks) {
-        for (OVFDisk disk : disks) {
-            if (disk._diskId.equalsIgnoreCase(diskId)) {
-                return disk;
-            }
-        }
-        return null;
-    }
-
-    private List<DatadiskTO> matchHardwareItemsToDiskAndFilesInformation(List<OVFVirtualHardwareItemTO> diskHardwareItems,
-                                                                         List<OVFFile> files, List<OVFDisk> disks,
-                                                                         String ovfParentPath) throws InternalErrorException {
-        List<DatadiskTO> diskTOs = new LinkedList<>();
-        int diskNumber = 0;
-        for (OVFVirtualHardwareItemTO diskItem : diskHardwareItems) {
-            if (StringUtils.isBlank(diskItem.getHostResource())) {
-                s_logger.error("Missing disk information for hardware item " + diskItem.getElementName() + " " + diskItem.getInstanceId());
-                continue;
-            }
-            String diskId = extractDiskIdFromDiskHostResource(diskItem.getHostResource());
-            OVFDisk diskDefinition = getDiskDefinitionFromDiskId(diskId, disks);
-            if (diskDefinition == null) {
-                s_logger.error("Missing disk definition for disk ID " + diskId);
-            }
-            OVFFile fileDefinition = getFileDefinitionFromDiskDefinition(diskDefinition._fileRef, files);
-            DatadiskTO datadiskTO = generateDiskTO(fileDefinition, diskDefinition, ovfParentPath, diskNumber, diskItem);
-            diskTOs.add(datadiskTO);
-            diskNumber++;
-        }
-        List<OVFFile> isoFiles = files.stream().filter(x -> x.isIso).collect(Collectors.toList());
-        for (OVFFile isoFile : isoFiles) {
-            DatadiskTO isoTO = generateDiskTO(isoFile, null, ovfParentPath, diskNumber, null);
-            diskTOs.add(isoTO);
-            diskNumber++;
-        }
-        return diskTOs;
-    }
-
-    private DatadiskTO generateDiskTO(OVFFile file, OVFDisk disk, String ovfParentPath, int diskNumber,
-                                      OVFVirtualHardwareItemTO diskItem) throws InternalErrorException {
-        String path = file != null ? ovfParentPath + File.separator + file._href : null;
-        if (StringUtils.isNotBlank(path)) {
-            File f = new File(path);
-            if (!f.exists() || f.isDirectory()) {
-                s_logger.error("One of the attached disk or iso does not exists " + path);
-                throw new InternalErrorException("One of the attached disk or iso as stated on OVF does not exists " + path);
-            }
-        }
-        Long capacity = disk != null ? disk._capacity : file._size;
-        Long fileSize = file != null ? file._size : 0L;
-
-        String controller = "";
-        String controllerSubType = "";
-        if (disk != null) {
-            OVFDiskController cDiskController = disk._controller;
-            controller = cDiskController == null ? "" : disk._controller._name;
-            controllerSubType = cDiskController == null ? "" : disk._controller._subType;
-        }
-
-        boolean isIso = file != null && file.isIso;
-        boolean bootable = file != null && file._bootable;
-        String diskId = disk == null ? file._id : disk._diskId;
-        String configuration = diskItem != null ? diskItem.getConfigurationIds() : null;
-        return new DatadiskTO(path, capacity, fileSize, diskId,
-                isIso, bootable, controller, controllerSubType, diskNumber, configuration);
-    }
-
-    protected List<OVFDisk> extractDisksFromOvfDocumentTree(Document doc) {
-        NodeList disks = doc.getElementsByTagName("Disk");
-        NodeList ovfDisks = doc.getElementsByTagName("ovf:Disk");
-        NodeList items = doc.getElementsByTagName("Item");
-
-        int totalDisksLength = disks.getLength() + ovfDisks.getLength();
-        ArrayList<OVFDisk> vd = new ArrayList<>();
-        for (int i = 0; i < totalDisksLength; i++) {
-            Element disk;
-            if (i >= disks.getLength()) {
-                int pos = i - disks.getLength();
-                disk = (Element) ovfDisks.item(pos);
-            } else {
-                disk = (Element) disks.item(i);
-            }
-
-            if (disk == null) {
-                continue;
-            }
-            OVFDisk od = new OVFDisk();
-            String virtualSize = getNodeAttribute(disk, "ovf", "capacity");
-            od._capacity = NumberUtils.toLong(virtualSize, 0L);
-            String allocationUnits = getNodeAttribute(disk,"ovf","capacityAllocationUnits");
-            od._diskId = getNodeAttribute(disk,"ovf","diskId");
-            od._fileRef = getNodeAttribute(disk,"ovf","fileRef");
-            od._populatedSize = NumberUtils.toLong(getNodeAttribute(disk,"ovf","populatedSize"));
-
-            if ((od._capacity != 0) && (allocationUnits != null)) {
-                long units = 1;
-                if (allocationUnits.equalsIgnoreCase("KB") || allocationUnits.equalsIgnoreCase("KiloBytes") || allocationUnits.equalsIgnoreCase("byte * 2^10")) {
-                    units = ResourceType.bytesToKiB;
-                } else if (allocationUnits.equalsIgnoreCase("MB") || allocationUnits.equalsIgnoreCase("MegaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^20")) {
-                    units = ResourceType.bytesToMiB;
-                } else if (allocationUnits.equalsIgnoreCase("GB") || allocationUnits.equalsIgnoreCase("GigaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^30")) {
-                    units = ResourceType.bytesToGiB;
-                }
-                od._capacity = od._capacity * units;
-            }
-            od._controller = getControllerType(items, od._diskId);
-            vd.add(od);
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace(String.format("found %d disk definitions",vd.size()));
-        }
-        return vd;
-    }
-
-    protected List<OVFFile> extractFilesFromOvfDocumentTree(File ovfFile, Document doc) {
-        NodeList files = doc.getElementsByTagName("File");
-        ArrayList<OVFFile> vf = new ArrayList<>();
-        boolean toggle = true;
-        for (int j = 0; j < files.getLength(); j++) {
-            Element file = (Element)files.item(j);
-            OVFFile of = new OVFFile();
-            of._href = getNodeAttribute(file,"ovf","href");
-            if (of._href.endsWith("vmdk") || of._href.endsWith("iso")) {
-                of._id = getNodeAttribute(file,"ovf","id");
-                String size = getNodeAttribute(file,"ovf", "size");
-                if (StringUtils.isNotBlank(size)) {
-                    of._size = Long.parseLong(size);
-                } else {
-                    String dataDiskPath = ovfFile.getParent() + File.separator + of._href;
-                    File this_file = new File(dataDiskPath);
-                    of._size = this_file.length();
-                }
-                of.isIso = of._href.endsWith("iso");
-                if (toggle && !of.isIso) {
-                    of._bootable = true;
-                    toggle = !toggle;
-                }
-                vf.add(of);
-            }
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace(String.format("found %d file definitions in %s",vf.size(), ovfFile.getPath()));
-        }
-        return vf;
-    }
-
-    public Document getDocumentFromFile(String ovfFilePath) {
-        if (org.apache.commons.lang.StringUtils.isBlank(ovfFilePath)) {
-            return null;
-        }
-        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newDefaultInstance();
         try {
-            DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
-            return builder.parse(new File(ovfFilePath));
+            final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(ovfFilePath));
+            NodeList disks = doc.getElementsByTagName("Disk");
+            NodeList files = doc.getElementsByTagName("File");
+            NodeList items = doc.getElementsByTagName("Item");
+            boolean toggle = true;
+            for (int j = 0; j < files.getLength(); j++) {
+                Element file = (Element)files.item(j);
+                OVFFile of = new OVFFile();
+                of._href = file.getAttribute("ovf:href");
+                if (of._href.endsWith("vmdk") || of._href.endsWith("iso")) {
+                    of._id = file.getAttribute("ovf:id");
+                    String size = file.getAttribute("ovf:size");
+                    if (StringUtils.isNotBlank(size)) {
+                        of._size = Long.parseLong(size);
+                    } else {
+                        String dataDiskPath = ovfFile.getParent() + File.separator + of._href;
+                        File this_file = new File(dataDiskPath);
+                        of._size = this_file.length();
+                    }
+                    of.isIso = of._href.endsWith("iso");
+                    if (toggle && !of.isIso) {
+                        of._bootable = true;
+                        toggle = !toggle;
+                    }
+                    vf.add(of);
+                }
+            }
+            for (int i = 0; i < disks.getLength(); i++) {
+                Element disk = (Element)disks.item(i);
+                OVFDisk od = new OVFDisk();
+                String virtualSize = disk.getAttribute("ovf:capacity");
+                od._capacity = NumberUtils.toLong(virtualSize, 0L);
+                String allocationUnits = disk.getAttribute("ovf:capacityAllocationUnits");
+                od._diskId = disk.getAttribute("ovf:diskId");
+                od._fileRef = disk.getAttribute("ovf:fileRef");
+                od._populatedSize = NumberUtils.toLong(disk.getAttribute("ovf:populatedSize"));
+
+                if ((od._capacity != 0) && (allocationUnits != null)) {
+
+                    long units = 1;
+                    if (allocationUnits.equalsIgnoreCase("KB") || allocationUnits.equalsIgnoreCase("KiloBytes") || allocationUnits.equalsIgnoreCase("byte * 2^10")) {
+                        units = ResourceType.bytesToKiB;
+                    } else if (allocationUnits.equalsIgnoreCase("MB") || allocationUnits.equalsIgnoreCase("MegaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^20")) {
+                        units = ResourceType.bytesToMiB;
+                    } else if (allocationUnits.equalsIgnoreCase("GB") || allocationUnits.equalsIgnoreCase("GigaBytes") || allocationUnits.equalsIgnoreCase("byte * 2^30")) {
+                        units = ResourceType.bytesToGiB;
+                    }
+                    od._capacity = od._capacity * units;
+                }
+                od._controller = getControllerType(items, od._diskId);
+                vd.add(od);
+            }
+
         } catch (SAXException | IOException | ParserConfigurationException e) {
             s_logger.error("Unexpected exception caught while parsing ovf file:" + ovfFilePath, e);
             throw new CloudRuntimeException(e);
         }
+
+        List<DatadiskTO> disksTO = new ArrayList<DatadiskTO>();
+        for (OVFFile of : vf) {
+            if (StringUtils.isBlank(of._id)){
+                s_logger.error("The ovf file info is incomplete file info");
+                throw new CloudRuntimeException("The ovf file info has incomplete file info");
+            }
+            OVFDisk cdisk = getDisk(of._id, vd);
+            if (cdisk == null && !of.isIso){
+                s_logger.error("The ovf file info has incomplete disk info");
+                throw new CloudRuntimeException("The ovf file info has incomplete disk info");
+            }
+            Long capacity = cdisk == null ? of._size : cdisk._capacity;
+            String controller = "";
+            String controllerSubType = "";
+            if (cdisk != null) {
+                OVFDiskController cDiskController = cdisk._controller;
+                controller = cDiskController == null ? "" : cdisk._controller._name;
+                controllerSubType = cDiskController == null ? "" : cdisk._controller._subType;
+            }
+
+            String dataDiskPath = ovfFile.getParent() + File.separator + of._href;
+            File f = new File(dataDiskPath);
+            if (!f.exists() || f.isDirectory()) {
+                s_logger.error("One of the attached disk or iso does not exists " + dataDiskPath);
+                throw new CloudRuntimeException("One of the attached disk or iso as stated on OVF does not exists " + dataDiskPath);
+            }
+            disksTO.add(new DatadiskTO(dataDiskPath, capacity, of._size, of._id, of.isIso, of._bootable, controller, controllerSubType));
+        }
+        //check if first disk is an iso move it to the end
+        DatadiskTO fd = disksTO.get(0);
+        if (fd.isIso()) {
+            disksTO.remove(0);
+            disksTO.add(fd);
+        }
+        return disksTO;
     }
 
     private OVFDiskController getControllerType(final NodeList itemList, final String diskId) {
@@ -511,61 +330,55 @@
         return dc;
     }
 
-    public void rewriteOVFFileForSingleDisk(final String origOvfFilePath, final String newOvfFilePath, final String diskName) {
-        final Document doc = getDocumentFromFile(origOvfFilePath);
-
-        NodeList disks = doc.getElementsByTagName("Disk");
-        NodeList files = doc.getElementsByTagName("File");
-        NodeList items = doc.getElementsByTagName("Item");
-        String keepfile = null;
-        List<Element> toremove = new ArrayList<>();
-        for (int j = 0; j < files.getLength(); j++) {
-            Element file = (Element)files.item(j);
-            String href = getNodeAttribute(file,"ovf", "href");
-            if (diskName.equals(href)) {
-                keepfile = getNodeAttribute(file,"ovf","id");
-            } else {
-                toremove.add(file);
+    public void rewriteOVFFile(final String origOvfFilePath, final String newOvfFilePath, final String diskName) {
+        try {
+            final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(origOvfFilePath));
+            NodeList disks = doc.getElementsByTagName("Disk");
+            NodeList files = doc.getElementsByTagName("File");
+            NodeList items = doc.getElementsByTagName("Item");
+            String keepfile = null;
+            List<Element> toremove = new ArrayList<Element>();
+            for (int j = 0; j < files.getLength(); j++) {
+                Element file = (Element)files.item(j);
+                String href = file.getAttribute("ovf:href");
+                if (diskName.equals(href)) {
+                    keepfile = file.getAttribute("ovf:id");
+                } else {
+                    toremove.add(file);
+                }
             }
-        }
-        String keepdisk = null;
-        for (int i = 0; i < disks.getLength(); i++) {
-            Element disk = (Element)disks.item(i);
-            String fileRef = getNodeAttribute(disk,"ovf","fileRef");
-            if (keepfile == null) {
-                s_logger.info("FATAL: OVA format error");
-            } else if (keepfile.equals(fileRef)) {
-                keepdisk = getNodeAttribute(disk,"ovf","diskId");
-            } else {
-                toremove.add(disk);
+            String keepdisk = null;
+            for (int i = 0; i < disks.getLength(); i++) {
+                Element disk = (Element)disks.item(i);
+                String fileRef = disk.getAttribute("ovf:fileRef");
+                if (keepfile == null) {
+                    s_logger.info("FATAL: OVA format error");
+                } else if (keepfile.equals(fileRef)) {
+                    keepdisk = disk.getAttribute("ovf:diskId");
+                } else {
+                    toremove.add(disk);
+                }
             }
-        }
-        for (int k = 0; k < items.getLength(); k++) {
-            Element item = (Element) items.item(k);
-            NodeList cn = item.getChildNodes();
-            for (int l = 0; l < cn.getLength(); l++) {
-                if (cn.item(l) instanceof Element) {
-                    Element el = (Element) cn.item(l);
-                    if ("rasd:HostResource".equals(el.getNodeName())
-                            && !(el.getTextContent().contains("ovf:/file/" + keepdisk) || el.getTextContent().contains("ovf:/disk/" + keepdisk))) {
-                        toremove.add(item);
-                        break;
+            for (int k = 0; k < items.getLength(); k++) {
+                Element item = (Element)items.item(k);
+                NodeList cn = item.getChildNodes();
+                for (int l = 0; l < cn.getLength(); l++) {
+                    if (cn.item(l) instanceof Element) {
+                        Element el = (Element)cn.item(l);
+                        if ("rasd:HostResource".equals(el.getNodeName())
+                                && !(el.getTextContent().contains("ovf:/file/" + keepdisk) || el.getTextContent().contains("ovf:/disk/" + keepdisk))) {
+                            toremove.add(item);
+                            break;
+                        }
                     }
                 }
             }
-        }
 
-        for (Element rme : toremove) {
-            if (rme.getParentNode() != null) {
-                rme.getParentNode().removeChild(rme);
+            for (Element rme : toremove) {
+                if (rme.getParentNode() != null) {
+                    rme.getParentNode().removeChild(rme);
+                }
             }
-        }
-
-        writeDocumentToFile(newOvfFilePath, doc);
-    }
-
-    private void writeDocumentToFile(String newOvfFilePath, Document doc) {
-        try {
 
             final StringWriter writer = new StringWriter();
             final StreamResult result = new StreamResult(writer);
@@ -576,346 +389,21 @@
             PrintWriter outfile = new PrintWriter(newOvfFilePath);
             outfile.write(writer.toString());
             outfile.close();
-        } catch (IOException | TransformerException e) {
-            s_logger.info("Unexpected exception caught while rewriting OVF:" + e.getMessage(), e);
+        } catch (SAXException | IOException | ParserConfigurationException | TransformerException e) {
+            s_logger.info("Unexpected exception caught while removing network elements from OVF:" + e.getMessage(), e);
             throw new CloudRuntimeException(e);
         }
     }
 
-    OVFFile getFileDefinitionFromDiskDefinition(String fileRef, List<OVFFile> files) {
-        for (OVFFile file : files) {
-            if (file._id.equals(fileRef)) {
-                return file;
+    OVFDisk getDisk(String fileRef, List<OVFDisk> disks) {
+        for (OVFDisk disk : disks) {
+            if (disk._fileRef.equals(fileRef)) {
+                return disk;
             }
         }
         return null;
     }
 
-    public List<OVFNetworkTO> getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException {
-        if (doc == null) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("no document to parse; returning no prerequiste networks");
-            }
-            return Collections.emptyList();
-        }
-
-        Map<String, OVFNetworkTO> nets = getNetworksFromDocumentTree(doc);
-
-        checkForOnlyOneSystemNode(doc);
-
-        matchNicsToNets(nets, doc);
-
-        return new ArrayList<>(nets.values());
-    }
-
-    private void matchNicsToNets(Map<String, OVFNetworkTO> nets, Node systemElement) {
-        final DocumentTraversal traversal = (DocumentTraversal) systemElement;
-        final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true);
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace(String.format("starting out with %d network-prerequisites, parsing hardware",nets.size()));
-        }
-        int nicCount = 0;
-        for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
-            final Element e = (Element) n;
-            if ("rasd:Connection".equals(e.getTagName())) {
-                nicCount++;
-                String name = e.getTextContent(); // should be in our nets
-                if(nets.get(name) == null) {
-                    if(s_logger.isInfoEnabled()) {
-                        s_logger.info(String.format("found a nic definition without a network definition byname %s, adding it to the list.", name));
-                    }
-                    nets.put(name, new OVFNetworkTO());
-                }
-                OVFNetworkTO thisNet = nets.get(name);
-                if (e.getParentNode() != null) {
-                    fillNicPrerequisites(thisNet,e.getParentNode());
-                }
-            }
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace(String.format("ending up with %d network-prerequisites, parsed %d nics", nets.size(), nicCount));
-        }
-    }
-
-    /**
-     * get all the stuff from parent node
-     *
-     * @param nic the object to carry through the system
-     * @param parentNode the xml container node for nic data
-     */
-    private void fillNicPrerequisites(OVFNetworkTO nic, Node parentNode) {
-        String addressOnParentStr = getChildNodeValue(parentNode, "AddressOnParent");
-        String automaticAllocationStr = getChildNodeValue(parentNode, "AutomaticAllocation");
-        String description = getChildNodeValue(parentNode, "Description");
-        String elementName = getChildNodeValue(parentNode, "ElementName");
-        String instanceIdStr = getChildNodeValue(parentNode, "InstanceID");
-        String resourceSubType = getChildNodeValue(parentNode, "ResourceSubType");
-        String resourceType = getChildNodeValue(parentNode, "ResourceType");
-
-        try {
-            int addressOnParent = Integer.parseInt(addressOnParentStr);
-            nic.setAddressOnParent(addressOnParent);
-        } catch (NumberFormatException e) {
-            s_logger.warn("Encountered element of type \"AddressOnParent\", that could not be parse to an integer number: " + addressOnParentStr);
-        }
-
-        boolean automaticAllocation = StringUtils.isNotBlank(automaticAllocationStr) && Boolean.parseBoolean(automaticAllocationStr);
-        nic.setAutomaticAllocation(automaticAllocation);
-        nic.setNicDescription(description);
-        nic.setElementName(elementName);
-
-        try {
-            int instanceId = Integer.parseInt(instanceIdStr);
-            nic.setInstanceID(instanceId);
-        } catch (NumberFormatException e) {
-            s_logger.warn("Encountered element of type \"InstanceID\", that could not be parse to an integer number: " + instanceIdStr);
-        }
-
-        nic.setResourceSubType(resourceSubType);
-        nic.setResourceType(resourceType);
-    }
-
-    private void checkForOnlyOneSystemNode(Document doc) throws InternalErrorException {
-        // get hardware VirtualSystem, for now we support only one of those
-        NodeList systemElements = doc.getElementsByTagName("VirtualSystem");
-        if (systemElements.getLength() != 1) {
-            String msg = "found " + systemElements.getLength() + " system definitions in OVA, can only handle exactly one.";
-            s_logger.warn(msg);
-            throw new InternalErrorException(msg);
-        }
-    }
-
-    private Map<String, OVFNetworkTO> getNetworksFromDocumentTree(Document doc) {
-        NodeList networkElements = doc.getElementsByTagName("Network");
-        Map<String, OVFNetworkTO> nets = new HashMap<>();
-        for (int i = 0; i < networkElements.getLength(); i++) {
-
-            Element networkElement = (Element)networkElements.item(i);
-            String networkName = getNodeAttribute(networkElement,"ovf","name");
-
-            String description = getChildNodeValue(networkElement, "Description");
-
-            OVFNetworkTO network = new OVFNetworkTO();
-            network.setName(networkName);
-            network.setNetworkDescription(description);
-
-            nets.put(networkName,network);
-        }
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace(String.format("found %d networks in template", nets.size()));
-        }
-        return nets;
-    }
-
-    private boolean hardwareItemContainsConfiguration(OVFVirtualHardwareItemTO item, String configurationId) {
-        if (StringUtils.isBlank(configurationId) || StringUtils.isBlank(item.getConfigurationIds())) {
-            return true;
-        }
-        String configurationIds = item.getConfigurationIds();
-        if (StringUtils.isNotBlank(configurationIds)) {
-            String[] configurations = configurationIds.split(" ");
-            List<String> confList = Arrays.asList(configurations);
-            return confList.contains(configurationId);
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the virtual hardware section and its deployment options as configurations
-     */
-    public OVFVirtualHardwareSectionTO getVirtualHardwareSectionFromDocument(Document doc) {
-        List<OVFConfigurationTO> configurations = getDeploymentOptionsFromDocumentTree(doc);
-        List<OVFVirtualHardwareItemTO> items = getVirtualHardwareItemsFromDocumentTree(doc);
-        if (CollectionUtils.isNotEmpty(configurations)) {
-            for (OVFConfigurationTO configuration : configurations) {
-                List<OVFVirtualHardwareItemTO> confItems = items.stream().
-                        filter(x -> StringUtils.isNotBlank(x.getConfigurationIds())
-                                && hardwareItemContainsConfiguration(x, configuration.getId()))
-                        .collect(Collectors.toList());
-                configuration.setHardwareItems(confItems);
-            }
-        }
-        List<OVFVirtualHardwareItemTO> commonItems = null;
-        if (CollectionUtils.isNotEmpty(items)) {
-            commonItems = items.stream().filter(x -> StringUtils.isBlank(x.getConfigurationIds())).collect(Collectors.toList());
-        }
-        String minimumHardwareVersion = getMinimumHardwareVersionFromDocumentTree(doc);
-        return new OVFVirtualHardwareSectionTO(configurations, commonItems, minimumHardwareVersion);
-    }
-
-    private String getMinimumHardwareVersionFromDocumentTree(Document doc) {
-        String version = null;
-        if (doc != null) {
-            NodeList systemNodeList = doc.getElementsByTagName("System");
-            if (systemNodeList.getLength() != 0) {
-                Node systemItem = systemNodeList.item(0);
-                String hardwareVersions = getChildNodeValue(systemItem, "VirtualSystemType");
-                if (StringUtils.isNotBlank(hardwareVersions)) {
-                    String[] versions = hardwareVersions.split(",");
-                    // Order the hardware versions and retrieve the minimum version
-                    List<String> versionsList = Arrays.stream(versions).sorted().collect(Collectors.toList());
-                    version = versionsList.get(0);
-                }
-            }
-        }
-        return version;
-    }
-
-    private List<OVFConfigurationTO> getDeploymentOptionsFromDocumentTree(Document doc) {
-        List<OVFConfigurationTO> options = new ArrayList<>();
-        if (doc == null) {
-            return options;
-        }
-        NodeList deploymentOptionSection = doc.getElementsByTagName("DeploymentOptionSection");
-        if (deploymentOptionSection.getLength() == 0) {
-            return options;
-        }
-        Node hardwareSectionNode = deploymentOptionSection.item(0);
-        NodeList childNodes = hardwareSectionNode.getChildNodes();
-        int index = 0;
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node node = childNodes.item(i);
-            if (node != null && node.getNodeName().equals("Configuration")) {
-                Element configuration = (Element) node;
-                String configurationId = getNodeAttribute(configuration,"ovf","id");
-                String description = getChildNodeValue(configuration, "Description");
-                String label = getChildNodeValue(configuration, "Label");
-                OVFConfigurationTO option = new OVFConfigurationTO(configurationId, label, description, index);
-                options.add(option);
-                index++;
-            }
-        }
-        return options;
-    }
-
-    private List<OVFVirtualHardwareItemTO> getVirtualHardwareItemsFromDocumentTree(Document doc) {
-        List<OVFVirtualHardwareItemTO> items = new LinkedList<>();
-        if (doc == null) {
-            return items;
-        }
-        NodeList hardwareSection = doc.getElementsByTagName("VirtualHardwareSection");
-        if (hardwareSection.getLength() == 0) {
-            return items;
-        }
-        Node hardwareSectionNode = hardwareSection.item(0);
-        NodeList childNodes = hardwareSectionNode.getChildNodes();
-        for (int i = 0; i < childNodes.getLength(); i++) {
-            Node node = childNodes.item(i);
-            if (node != null && node.getNodeName().equals("Item")) {
-                Element configuration = (Element) node;
-                String configurationIds = getNodeAttribute(configuration, "ovf", "configuration");
-                String allocationUnits = getChildNodeValue(configuration, "AllocationUnits");
-                String description = getChildNodeValue(configuration, "Description");
-                String elementName = getChildNodeValue(configuration, "ElementName");
-                String instanceID = getChildNodeValue(configuration, "InstanceID");
-                String limit = getChildNodeValue(configuration, "Limit");
-                String reservation = getChildNodeValue(configuration, "Reservation");
-                String resourceType = getChildNodeValue(configuration, "ResourceType");
-                String virtualQuantity = getChildNodeValue(configuration, "VirtualQuantity");
-                String hostResource = getChildNodeValue(configuration, "HostResource");
-                String addressOnParent = getChildNodeValue(configuration, "AddressOnParent");
-                String parent = getChildNodeValue(configuration, "Parent");
-                OVFVirtualHardwareItemTO item = new OVFVirtualHardwareItemTO();
-                item.setConfigurationIds(configurationIds);
-                item.setAllocationUnits(allocationUnits);
-                item.setDescription(description);
-                item.setElementName(elementName);
-                item.setInstanceId(instanceID);
-                item.setLimit(getLongValueFromString(limit));
-                item.setReservation(getLongValueFromString(reservation));
-                Integer resType = getIntValueFromString(resourceType);
-                if (resType != null) {
-                    item.setResourceType(OVFVirtualHardwareItemTO.getResourceTypeFromId(resType));
-                }
-                item.setVirtualQuantity(getLongValueFromString(virtualQuantity));
-                item.setHostResource(hostResource);
-                item.setAddressOnParent(addressOnParent);
-                item.setParent(parent);
-                items.add(item);
-            }
-        }
-        return items;
-    }
-
-    private Long getLongValueFromString(String value) {
-        if (StringUtils.isNotBlank(value)) {
-            try {
-                return Long.parseLong(value);
-            } catch (NumberFormatException e) {
-                s_logger.debug("Could not parse the value: " + value + ", ignoring it");
-            }
-        }
-        return null;
-    }
-
-    private Integer getIntValueFromString(String value) {
-        if (StringUtils.isNotBlank(value)) {
-            try {
-                return Integer.parseInt(value);
-            } catch (NumberFormatException e) {
-                s_logger.debug("Could not parse the value: " + value + ", ignoring it");
-            }
-        }
-        return null;
-    }
-
-    protected byte[] compressOVFEula(String license) throws IOException {
-        CompressionUtil compressionUtil = new CompressionUtil();
-        return compressionUtil.compressString(license);
-    }
-
-    public List<OVFEulaSectionTO> getEulaSectionsFromDocument(Document doc) {
-        List<OVFEulaSectionTO> eulas = new LinkedList<>();
-        if (doc == null) {
-            return eulas;
-        }
-        NodeList eulaSections = doc.getElementsByTagName("EulaSection");
-        int eulaIndex = 0;
-        if (eulaSections.getLength() > 0) {
-            for (int index = 0; index < eulaSections.getLength(); index++) {
-                Node eulaNode = eulaSections.item(index);
-                NodeList eulaChildNodes = eulaNode.getChildNodes();
-                String eulaInfo = null;
-                String eulaLicense = null;
-                for (int i = 0; i < eulaChildNodes.getLength(); i++) {
-                    Node eulaItem = eulaChildNodes.item(i);
-                    if (eulaItem.getNodeName().equalsIgnoreCase("Info")) {
-                        eulaInfo = eulaItem.getTextContent();
-                    } else if (eulaItem.getNodeName().equalsIgnoreCase("License")) {
-                        eulaLicense = eulaItem.getTextContent();
-                    }
-                }
-                byte[] compressedLicense = new byte[0];
-                try {
-                    compressedLicense = compressOVFEula(eulaLicense);
-                } catch (IOException e) {
-                    s_logger.error("Could not compress the license for info " + eulaInfo);
-                    continue;
-                }
-                OVFEulaSectionTO eula = new OVFEulaSectionTO(eulaInfo, compressedLicense, eulaIndex);
-                eulas.add(eula);
-                eulaIndex++;
-            }
-        }
-
-        return eulas;
-    }
-
-    public Pair<String, String> getOperatingSystemInfoFromDocument(Document doc) {
-        if (doc == null) {
-            return null;
-        }
-        NodeList guesOsList = doc.getElementsByTagName("OperatingSystemSection");
-        if (guesOsList.getLength() == 0) {
-            return null;
-        }
-        Node guestOsNode = guesOsList.item(0);
-        Element guestOsElement = (Element) guestOsNode;
-        String osType = getNodeAttribute(guestOsElement, "vmw", "osType");
-        String description = getChildNodeValue(guestOsNode, "Description");
-        return new Pair<>(osType, description);
-    }
-
     class OVFFile {
         // <File ovf:href="i-2-8-VM-disk2.vmdk" ovf:id="file1" ovf:size="69120" />
         public String _href;
@@ -929,6 +417,7 @@
         //<Disk ovf:capacity="50" ovf:capacityAllocationUnits="byte * 2^20" ovf:diskId="vmdisk2" ovf:fileRef="file2"
         //ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="43319296" />
         public Long _capacity;
+        public String _capacityUnit;
         public String _diskId;
         public String _fileRef;
         public Long _populatedSize;
diff --git a/api/src/main/java/com/cloud/dc/VsphereStoragePolicy.java b/api/src/main/java/com/cloud/agent/api/storage/OVFProperty.java
similarity index 74%
rename from api/src/main/java/com/cloud/dc/VsphereStoragePolicy.java
rename to api/src/main/java/com/cloud/agent/api/storage/OVFProperty.java
index ca0ed54..ac9ae77 100644
--- a/api/src/main/java/com/cloud/dc/VsphereStoragePolicy.java
+++ b/api/src/main/java/com/cloud/agent/api/storage/OVFProperty.java
@@ -1,3 +1,4 @@
+//
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -14,18 +15,19 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-package com.cloud.dc;
+//
 
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
+package com.cloud.agent.api.storage;
 
-public interface VsphereStoragePolicy extends Identity, InternalIdentity {
+public interface OVFProperty {
 
-    long getZoneId();
-
-    String getPolicyId();
-
-    String getName();
-
+    Long getTemplateId();
+    String getKey();
+    String getType();
+    String getValue();
+    String getQualifiers();
+    Boolean isUserConfigurable();
+    String getLabel();
     String getDescription();
-}
+    Boolean isPassword();
+}
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java b/api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java
similarity index 90%
rename from api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java
rename to api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java
index 32c6255..abf743a 100644
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java
+++ b/api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java
@@ -17,7 +17,7 @@
 // under the License.
 //
 
-package com.cloud.agent.api.to.deployasis;
+package com.cloud.agent.api.storage;
 
 import com.cloud.agent.api.LogLevel;
 
@@ -30,7 +30,7 @@
  * Choose "Remote HTTP and SSH Client Routes" to route only traffic destined for the management client(s), when they are on remote networks.</Description>
  *       </Property>
  */
-public class OVFPropertyTO implements TemplateDeployAsIsInformationTO {
+public class OVFPropertyTO implements OVFProperty {
 
     private String key;
     private String type;
@@ -41,14 +41,18 @@
     private String label;
     private String description;
     private Boolean password;
-    private int index;
-    private String category;
 
     public OVFPropertyTO() {
     }
 
+    public OVFPropertyTO(String key, String value, boolean password) {
+        this.key = key;
+        this.value = value;
+        this.password = password;
+    }
+
     public OVFPropertyTO(String key, String type, String value, String qualifiers, boolean userConfigurable,
-                       String label, String description, boolean password, int index, String category) {
+                       String label, String description, boolean password) {
         this.key = key;
         this.type = type;
         this.value = value;
@@ -57,10 +61,9 @@
         this.label = label;
         this.description = description;
         this.password = password;
-        this.index = index;
-        this.category = category;
     }
 
+    @Override
     public Long getTemplateId() {
         return null;
     }
@@ -128,12 +131,4 @@
     public void setPassword(Boolean password) {
         this.password = password;
     }
-
-    public String getCategory() {
-        return category;
-    }
-
-    public int getIndex() {
-        return index;
-    }
 }
diff --git a/api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java b/api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java
index 31a02b0..1d3f91e 100644
--- a/api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/DatadiskTO.java
@@ -27,14 +27,18 @@
     private boolean isIso;
     private String diskController;
     private String diskControllerSubType;
-    private int diskNumber;
-    private String configuration;
 
     public DatadiskTO() {
     }
 
-    public DatadiskTO(String path, long virtualSize, long fileSize, String diskId, boolean isIso, boolean bootable,
-                      String controller, String controllerSubType, int diskNumber, String configuration) {
+    public DatadiskTO(String path, long virtualSize, long fileSize, boolean bootable) {
+        this.path = path;
+        this.virtualSize = virtualSize;
+        this.fileSize = fileSize;
+        this.bootable = bootable;
+    }
+
+    public DatadiskTO(String path, long virtualSize, long fileSize, String diskId, boolean isIso, boolean bootable, String controller, String controllerSubType) {
         this.path = path;
         this.virtualSize = virtualSize;
         this.fileSize = fileSize;
@@ -43,8 +47,6 @@
         this.isIso = isIso;
         this.diskController = controller;
         this.diskControllerSubType = controllerSubType;
-        this.diskNumber = diskNumber;
-        this.configuration = configuration;
     }
 
     public String getPath() {
@@ -103,11 +105,4 @@
         this.diskControllerSubType = diskControllerSubType;
     }
 
-    public int getDiskNumber() {
-        return this.diskNumber;
-    }
-
-    public String getConfiguration() {
-        return configuration;
-    }
 }
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java b/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java
deleted file mode 100644
index 9400de0..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to;
-
-import com.cloud.agent.api.LogLevel;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * TO class sent to the hypervisor layer with the information needed to handle deploy-as-is VM deployments
- */
-public class DeployAsIsInfoTO {
-
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private Map<String, String> properties = new HashMap<>();
-    private Map<Integer, String> nicAdapterMap = new HashMap();
-
-    public DeployAsIsInfoTO() {
-    }
-
-    public DeployAsIsInfoTO(Map<String, String> properties, Map<Integer, String> nicAdapterMap) {
-        this.properties = properties;
-        this.nicAdapterMap = nicAdapterMap;
-    }
-
-    public Map<String, String> getProperties() {
-        return properties;
-    }
-
-    public Map<Integer, String> getNicAdapterMap() {
-        return nicAdapterMap;
-    }
-}
diff --git a/api/src/main/java/com/cloud/agent/api/to/OVFInformationTO.java b/api/src/main/java/com/cloud/agent/api/to/OVFInformationTO.java
deleted file mode 100644
index 6c6c61d..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/OVFInformationTO.java
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.agent.api.to;
-
-import com.cloud.agent.api.LogLevel;
-import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
-import com.cloud.utils.Pair;
-
-import java.util.List;
-
-/**
- * Placeholder class for all the subclasses obtained from the OVF parsing
- */
-public class OVFInformationTO {
-
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private List<OVFPropertyTO> properties;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private List<OVFNetworkTO> networks;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private List<DatadiskTO> disks;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private OVFVirtualHardwareSectionTO hardwareSection;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private List<OVFEulaSectionTO> eulaSections;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private Pair<String, String> guestOsInfo;
-
-    public OVFInformationTO() {
-    }
-
-    public List<OVFPropertyTO> getProperties() {
-        return properties;
-    }
-
-    public void setProperties(List<OVFPropertyTO> properties) {
-        this.properties = properties;
-    }
-
-    public List<OVFNetworkTO> getNetworks() {
-        return networks;
-    }
-
-    public void setNetworks(List<OVFNetworkTO> networks) {
-        this.networks = networks;
-    }
-
-    public List<DatadiskTO> getDisks() {
-        return disks;
-    }
-
-    public void setDisks(List<DatadiskTO> disks) {
-        this.disks = disks;
-    }
-
-    public OVFVirtualHardwareSectionTO getHardwareSection() {
-        return hardwareSection;
-    }
-
-    public void setHardwareSection(OVFVirtualHardwareSectionTO hardwareSection) {
-        this.hardwareSection = hardwareSection;
-    }
-
-    public List<OVFEulaSectionTO> getEulaSections() {
-        return eulaSections;
-    }
-
-    public void setEulaSections(List<OVFEulaSectionTO> eulaSections) {
-        this.eulaSections = eulaSections;
-    }
-
-    public Pair<String, String> getGuestOsInfo() {
-        return guestOsInfo;
-    }
-
-    public void setGuestOsInfo(Pair<String, String> guestOsInfo) {
-        this.guestOsInfo = guestOsInfo;
-    }
-}
diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
index efc735c..dceacf0 100644
--- a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
+++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java
@@ -20,7 +20,10 @@
 import java.util.Map;
 import java.util.HashMap;
 
+import com.cloud.agent.api.LogLevel;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.Pair;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.Type;
 
@@ -78,7 +81,8 @@
 
     Map<String, String> guestOsDetails = new HashMap<String, String>();
     Map<String, String> extraConfig = new HashMap<>();
-    DeployAsIsInfoTO deployAsIsInfo;
+    @LogLevel(LogLevel.Log4jLevel.Off)
+    Pair<String, List<OVFPropertyTO>> ovfProperties;
 
     public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader,
             String os, boolean enableHA, boolean limitCpuUse, String vncPassword) {
@@ -372,6 +376,13 @@
         return extraConfig;
     }
 
+    public Pair<String, List<OVFPropertyTO>> getOvfProperties() {
+        return ovfProperties;
+    }
+
+    public void setOvfProperties(Pair<String, List<OVFPropertyTO>> ovfProperties) {
+        this.ovfProperties = ovfProperties;
+    }
     public String getBootType() {
         return bootType;
     }
@@ -391,12 +402,4 @@
     public void setEnterHardwareSetup(boolean enterHardwareSetup) {
         this.enterHardwareSetup = enterHardwareSetup;
     }
-
-    public DeployAsIsInfoTO getDeployAsIsInfo() {
-        return deployAsIsInfo;
-    }
-
-    public void setDeployAsIsInfo(DeployAsIsInfoTO deployAsIsInfo) {
-        this.deployAsIsInfo = deployAsIsInfo;
-    }
 }
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java
deleted file mode 100644
index aa3c603..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.agent.api.to.deployasis;
-
-import java.util.List;
-
-/**
- * This class represents a template deployment option (configuration) parsed from the OVF
- */
-public class OVFConfigurationTO implements TemplateDeployAsIsInformationTO {
-
-    private final String id;
-    private final String label;
-    private final String description;
-    private List<OVFVirtualHardwareItemTO> hardwareItems;
-    private int index;
-
-    public OVFConfigurationTO(String id, String label, String description, int index) {
-        this.id = id;
-        this.label = label;
-        this.description = description;
-        this.index = index;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setHardwareItems(List<OVFVirtualHardwareItemTO> items) {
-        this.hardwareItems = items;
-    }
-
-    public List<OVFVirtualHardwareItemTO> getHardwareItems() {
-        return hardwareItems;
-    }
-
-    public int getIndex() {
-        return index;
-    }
-}
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java
deleted file mode 100644
index 8936617..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.agent.api.to.deployasis;
-
-import com.cloud.agent.api.LogLevel;
-
-/**
- * End-user licence agreement
- */
-public class OVFEulaSectionTO implements TemplateDeployAsIsInformationTO {
-    private String info;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private byte[] compressedLicense;
-    private int index;
-
-    public OVFEulaSectionTO(String info, byte[] license, int eulaIndex) {
-        this.info = info;
-        this.compressedLicense = license;
-        this.index = eulaIndex;
-    }
-
-    public String getInfo() {
-        return this.info;
-    }
-
-    public byte[] getCompressedLicense() {
-        return this.compressedLicense;
-    }
-
-    public int getIndex() {
-        return index;
-    }
-}
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java
deleted file mode 100644
index 9b05dbc..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to.deployasis;
-
-/**
- * container for the network prerequisites as found in the appliance template
- *
- * for OVA:
- * {code}
- * <Network ovf:name="Management0-0">
- *   <Description>Management Network Interface</Description>
- * </Network>
- * {code}
- * {code}
- * <Item>
- *   <rasd:AddressOnParent>7</rasd:AddressOnParent>
- *   <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
- *   <rasd:Connection>Management0-0</rasd:Connection>
- *   <rasd:Description>E1000 Ethernet adapter on "Management Network"</rasd:Description>
- *   <rasd:ElementName>Network adapter 1</rasd:ElementName>
- *   <rasd:InstanceID>6</rasd:InstanceID>
- *   <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
- *   <rasd:ResourceType>10</rasd:ResourceType>
- * </Item>
- * {code}
- */
-public class OVFNetworkTO implements TemplateDeployAsIsInformationTO {
-    String name;
-    String networkDescription;
-
-    int addressOnParent;
-    boolean automaticAllocation;
-    String nicDescription;
-    String elementName;
-    int InstanceID;
-    String resourceSubType;
-    String resourceType;
-
-    public int getAddressOnParent() {
-        return addressOnParent;
-    }
-
-    public void setAddressOnParent(int addressOnParent) {
-        this.addressOnParent = addressOnParent;
-    }
-
-    public boolean isAutomaticAllocation() {
-        return automaticAllocation;
-    }
-
-    public void setAutomaticAllocation(boolean automaticAllocation) {
-        this.automaticAllocation = automaticAllocation;
-    }
-
-    public String getNicDescription() {
-        return nicDescription;
-    }
-
-    public void setNicDescription(String nicDescription) {
-        this.nicDescription = nicDescription;
-    }
-
-    public String getElementName() {
-        return elementName;
-    }
-
-    public void setElementName(String elementName) {
-        this.elementName = elementName;
-    }
-
-    public int getInstanceID() {
-        return InstanceID;
-    }
-
-    public void setInstanceID(int instanceID) {
-        InstanceID = instanceID;
-    }
-
-    public String getResourceSubType() {
-        return resourceSubType;
-    }
-
-    public void setResourceSubType(String resourceSubType) {
-        this.resourceSubType = resourceSubType;
-    }
-
-    public String getResourceType() {
-        return resourceType;
-    }
-
-    public void setResourceType(String resourceType) {
-        this.resourceType = resourceType;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getNetworkDescription() {
-        return networkDescription;
-    }
-
-    public void setNetworkDescription(String networkDescription) {
-        this.networkDescription = networkDescription;
-    }
-}
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java
deleted file mode 100644
index f178c23..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java
+++ /dev/null
@@ -1,371 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.to.deployasis;
-
-/**
- * A hardware item class representing a hardware item read from the OVF.
- * From: https://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData.xsd
- */
-public class OVFVirtualHardwareItemTO implements TemplateDeployAsIsInformationTO{
-
-    /**
-     * The hardware item type
-     * From: https://schemas.dmtf.org/wbem/cim-html/2/CIM_ResourceAllocationSettingData.html
-     */
-    public enum HardwareResourceType {
-        Other("Other", 1),
-        ComputerSystem ("Computer System", 2),
-        Processor("Processor", 3),
-        Memory("Memory", 4),
-        IDEController("IDE Controller", 5),
-        ParallelSCSIHBA("Parallel SCSI HBA", 6),
-        FC_HBA("FC HBA", 7),
-        iSCSI_HBA("iSCSI HBA", 8),
-        IB_HCA("IB HCA", 9),
-        EthernetAdapter("Ethernet Adaptor", 10),
-        OtherNetworkAdapter("Other Network Adaptor", 11),
-        IO_Slot("I/O Slot", 12),
-        IO_Device("I/O Device", 13),
-        FloppyDrive("Floppy Drive", 14),
-        CD_Drive("CD Drive", 15),
-        DVD_Drive("DVD Drive", 16),
-        DiskDrive("Disk Drive", 17),
-        TapeDrive("Tape Drive", 18),
-        StorageExtent("Storage Extent", 19),
-        OtherStorageDevice("Other Storage Device", 20),
-        SerialPort("Serial Port", 21),
-        ParallelPort("Parallel Port", 22),
-        USBController("USB Controller", 23),
-        GraphicsController("Graphics Controller", 24),
-        IEEE_1394_Controller("IEEE 1394 Controller", 25),
-        PartitionableUnit("Partitionable Unit", 26),
-        BasePartitionableUnit("base Partitionable Unit", 27),
-        PowerSupply("Power", 28),
-        CoolingCapacity("Cooling Capacity", 29),
-        EthernetSwitchPort("Ethernet Switch Port", 30),
-        LogicalDisk("Logical Disk", 31),
-        StorageVolume("Storage Volume", 32),
-        EthernetConnection("Ethernet Connection", 33),
-        DMTF_reserved("DMTF Reserved", 35),
-        VendorReserved("Vendor Reserved", 32768);
-
-        private String name;
-        private int id;
-
-        HardwareResourceType(String name, int id) {
-            this.name = name;
-            this.id = id;
-        }
-
-        public String getName() {
-            return name;
-        }
-    }
-
-    public static HardwareResourceType getResourceTypeFromId(int id) {
-        if (id <= 33) {
-            for (HardwareResourceType type : HardwareResourceType.values()) {
-                if (type.id == id) {
-                    return type;
-                }
-            }
-        } else if (id <= 32767) {
-            return HardwareResourceType.DMTF_reserved;
-        }
-        return HardwareResourceType.VendorReserved;
-    }
-
-    public enum CustomerVisibility {
-        Unknown, PassedThrough, Virtualized, NotRepresented, DMTFReserved, VendorReserved;
-    }
-
-    public enum MappingBehavior {
-        Unknown, NotSupported, Dedicated, SoftAffinity, HardAffinity, DMTFReserved, VendorReserved;
-    }
-
-    private String address;
-    private String addressOnParent;
-    private String allocationUnits;
-    private boolean automaticAllocation;
-    private boolean automaticDeallocation;
-    private String caption;
-    private String changeableType;
-    private String componentSetting;
-    private String configurationName;
-    private String connection;
-    private CustomerVisibility customerVisibility;
-    private String description;
-    private String elementName;
-    private Long generation;
-    private String hostResource;
-    private String instanceId;
-    private Long limit;
-    private MappingBehavior mappingBehavior;
-    private String otherResourceType;
-    private String parent;
-    private String poolId;
-    private Long reservation;
-    private String resourceSubtype;
-    private HardwareResourceType resourceType;
-    private String soId;
-    private String soOrgId;
-    private Long virtualQuantity;
-    private String virtualQuantityUnits;
-    private int weight;
-
-    private String configurationIds;
-
-    public String getConfigurationIds() {
-        return configurationIds;
-    }
-
-    public void setConfigurationIds(String configurationIds) {
-        this.configurationIds = configurationIds;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-
-    public void setAddress(String address) {
-        this.address = address;
-    }
-
-    public String getAddressOnParent() {
-        return addressOnParent;
-    }
-
-    public void setAddressOnParent(String addressOnParent) {
-        this.addressOnParent = addressOnParent;
-    }
-
-    public String getAllocationUnits() {
-        return allocationUnits;
-    }
-
-    public void setAllocationUnits(String allocationUnits) {
-        this.allocationUnits = allocationUnits;
-    }
-
-    public boolean isAutomaticAllocation() {
-        return automaticAllocation;
-    }
-
-    public void setAutomaticAllocation(boolean automaticAllocation) {
-        this.automaticAllocation = automaticAllocation;
-    }
-
-    public boolean isAutomaticDeallocation() {
-        return automaticDeallocation;
-    }
-
-    public void setAutomaticDeallocation(boolean automaticDeallocation) {
-        this.automaticDeallocation = automaticDeallocation;
-    }
-
-    public String getCaption() {
-        return caption;
-    }
-
-    public void setCaption(String caption) {
-        this.caption = caption;
-    }
-
-    public String getChangeableType() {
-        return changeableType;
-    }
-
-    public void setChangeableType(String changeableType) {
-        this.changeableType = changeableType;
-    }
-
-    public String getComponentSetting() {
-        return componentSetting;
-    }
-
-    public void setComponentSetting(String componentSetting) {
-        this.componentSetting = componentSetting;
-    }
-
-    public String getConfigurationName() {
-        return configurationName;
-    }
-
-    public void setConfigurationName(String configurationName) {
-        this.configurationName = configurationName;
-    }
-
-    public String getConnection() {
-        return connection;
-    }
-
-    public void setConnection(String connection) {
-        this.connection = connection;
-    }
-
-    public CustomerVisibility getCustomerVisibility() {
-        return customerVisibility;
-    }
-
-    public void setCustomerVisibility(CustomerVisibility customerVisibility) {
-        this.customerVisibility = customerVisibility;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getElementName() {
-        return elementName;
-    }
-
-    public void setElementName(String elementName) {
-        this.elementName = elementName;
-    }
-
-    public Long getGeneration() {
-        return generation;
-    }
-
-    public void setGeneration(Long generation) {
-        this.generation = generation;
-    }
-
-    public String getHostResource() {
-        return hostResource;
-    }
-
-    public void setHostResource(String hostResource) {
-        this.hostResource = hostResource;
-    }
-
-    public String getInstanceId() {
-        return instanceId;
-    }
-
-    public void setInstanceId(String instanceId) {
-        this.instanceId = instanceId;
-    }
-
-    public Long getLimit() {
-        return limit;
-    }
-
-    public void setLimit(Long limit) {
-        this.limit = limit;
-    }
-
-    public MappingBehavior getMappingBehavior() {
-        return mappingBehavior;
-    }
-
-    public void setMappingBehavior(MappingBehavior mappingBehavior) {
-        this.mappingBehavior = mappingBehavior;
-    }
-
-    public String getOtherResourceType() {
-        return otherResourceType;
-    }
-
-    public void setOtherResourceType(String otherResourceType) {
-        this.otherResourceType = otherResourceType;
-    }
-
-    public String getParent() {
-        return parent;
-    }
-
-    public void setParent(String parent) {
-        this.parent = parent;
-    }
-
-    public String getPoolId() {
-        return poolId;
-    }
-
-    public void setPoolId(String poolId) {
-        this.poolId = poolId;
-    }
-
-    public Long getReservation() {
-        return reservation;
-    }
-
-    public void setReservation(Long reservation) {
-        this.reservation = reservation;
-    }
-
-    public String getResourceSubtype() {
-        return resourceSubtype;
-    }
-
-    public void setResourceSubtype(String resourceSubtype) {
-        this.resourceSubtype = resourceSubtype;
-    }
-
-    public HardwareResourceType getResourceType() {
-        return resourceType;
-    }
-
-    public void setResourceType(HardwareResourceType resourceType) {
-        this.resourceType = resourceType;
-    }
-
-    public String getSoId() {
-        return soId;
-    }
-
-    public void setSoId(String soId) {
-        this.soId = soId;
-    }
-
-    public String getSoOrgId() {
-        return soOrgId;
-    }
-
-    public void setSoOrgId(String soOrgId) {
-        this.soOrgId = soOrgId;
-    }
-
-    public Long getVirtualQuantity() {
-        return virtualQuantity;
-    }
-
-    public void setVirtualQuantity(Long virtualQuantity) {
-        this.virtualQuantity = virtualQuantity;
-    }
-
-    public String getVirtualQuantityUnits() {
-        return virtualQuantityUnits;
-    }
-
-    public void setVirtualQuantityUnits(String virtualQuantityUnits) {
-        this.virtualQuantityUnits = virtualQuantityUnits;
-    }
-
-    public int getWeight() {
-        return weight;
-    }
-
-    public void setWeight(int weight) {
-        this.weight = weight;
-    }
-}
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java
deleted file mode 100644
index 4cdbf68..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.agent.api.to.deployasis;
-
-import java.util.List;
-
-public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformationTO {
-
-    public OVFVirtualHardwareSectionTO() {
-    }
-
-    private String minimiumHardwareVersion;
-    private List<OVFConfigurationTO> configurations;
-    private List<OVFVirtualHardwareItemTO> commonHardwareItems;
-
-    public OVFVirtualHardwareSectionTO(List<OVFConfigurationTO> configurations, List<OVFVirtualHardwareItemTO> commonHardwareItems,
-                                       String minimumHardwareVersion) {
-        this.configurations = configurations;
-        this.commonHardwareItems = commonHardwareItems;
-        this.minimiumHardwareVersion = minimumHardwareVersion;
-    }
-
-    public List<OVFConfigurationTO> getConfigurations() {
-        return configurations;
-    }
-
-    public List<OVFVirtualHardwareItemTO> getCommonHardwareItems() {
-        return commonHardwareItems;
-    }
-
-    public String getMinimiumHardwareVersion() {
-        return minimiumHardwareVersion;
-    }
-}
\ No newline at end of file
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java
deleted file mode 100644
index 9080b92..0000000
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.agent.api.to.deployasis;
-
-import java.io.Serializable;
-
-public interface TemplateDeployAsIsInformationTO extends Serializable {
-}
diff --git a/api/src/main/java/com/cloud/deploy/DeployDestination.java b/api/src/main/java/com/cloud/deploy/DeployDestination.java
index 91b2068..18503fe 100644
--- a/api/src/main/java/com/cloud/deploy/DeployDestination.java
+++ b/api/src/main/java/com/cloud/deploy/DeployDestination.java
@@ -36,11 +36,6 @@
     Host _host;
     Map<Volume, StoragePool> _storage;
 
-    /**
-     * Display volume <-> storage pool mapping by default
-     */
-    boolean displayStorage = true;
-
     public DataCenter getDataCenter() {
         return _dc;
     }
@@ -68,10 +63,9 @@
         _host = host;
     }
 
-    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host, Map<Volume, StoragePool> storage, boolean displayStorage) {
+    public DeployDestination(DataCenter dc, Pod pod, Cluster cluster, Host host, Map<Volume, StoragePool> storage) {
         this(dc, pod, cluster, host);
         _storage = storage;
-        this.displayStorage = displayStorage;
     }
 
     public DeployDestination() {
@@ -145,7 +139,7 @@
         destination.append("Cluster(").append(clusterId).append(")").append("-");
         destination.append("Host(").append(hostId).append(")").append("-");
         destination.append("Storage(");
-        if (displayStorage && _storage != null) {
+        if (_storage != null) {
             StringBuffer storageBuf = new StringBuffer();
             //String storageStr = "";
             for (Volume vol : _storage.keySet()) {
@@ -166,8 +160,4 @@
         }
         return destination.append(")]").toString();
     }
-
-    public boolean isDisplayStorage() {
-        return displayStorage;
-    }
 }
diff --git a/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java b/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java
deleted file mode 100644
index 23d286f..0000000
--- a/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis;
-
-public interface DeployAsIsConstants {
-
-    String PROPERTY_PREFIX = "property-";
-    String NETWORK_PREFIX = "network-";
-    String CONFIGURATION_PREFIX = "configuration-";
-    String HARDWARE_ITEM_PREFIX = "hardware-item-";
-    String EULA_PREFIX = "eula-";
-
-    String DEFAULT_GUEST_OS_DEPLOY_AS_IS = "OVF Configured OS";
-}
diff --git a/api/src/main/java/com/cloud/event/EventTypes.java b/api/src/main/java/com/cloud/event/EventTypes.java
index 852198b..d723f56 100644
--- a/api/src/main/java/com/cloud/event/EventTypes.java
+++ b/api/src/main/java/com/cloud/event/EventTypes.java
@@ -619,9 +619,6 @@
     public static final String EVENT_POD_ROLLING_MAINTENANCE = "POD.ROLLING.MAINTENANCE";
     public static final String EVENT_ZONE_ROLLING_MAINTENANCE = "ZONE.ROLLING.MAINTENANCE";
 
-    // Storage Policies
-    public static final String EVENT_IMPORT_VCENTER_STORAGE_POLICIES = "IMPORT.VCENTER.STORAGE.POLICIES";
-
     static {
 
         // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@@ -1029,8 +1026,6 @@
         entityEventDetails.put(EVENT_CLUSTER_ROLLING_MAINTENANCE, ClusterResponse.class);
         entityEventDetails.put(EVENT_HOST_ROLLING_MAINTENANCE, HostResponse.class);
 
-        entityEventDetails.put(EVENT_IMPORT_VCENTER_STORAGE_POLICIES, "StoragePolicies");
-
         entityEventDetails.put(EVENT_IMAGE_STORE_DATA_MIGRATE, ImageStore.class);
     }
 
diff --git a/api/src/main/java/com/cloud/storage/Storage.java b/api/src/main/java/com/cloud/storage/Storage.java
index 7a229b6..82bc5f6 100644
--- a/api/src/main/java/com/cloud/storage/Storage.java
+++ b/api/src/main/java/com/cloud/storage/Storage.java
@@ -16,11 +16,11 @@
 // under the License.
 package com.cloud.storage;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.commons.lang.NotImplementedException;
+
 public class Storage {
     public static enum ImageFormat {
         QCOW2(true, true, false, "qcow2"),
@@ -135,8 +135,7 @@
         OCFS2(true, false),
         SMB(true, false),
         Gluster(true, false),
-        ManagedNFS(true, false),
-        DatastoreCluster(true, true); // for VMware, to abstract pool of clusters
+        ManagedNFS(true, false);
 
         private final boolean shared;
         private final boolean overprovisioning;
diff --git a/api/src/main/java/com/cloud/storage/StoragePool.java b/api/src/main/java/com/cloud/storage/StoragePool.java
index 6c65ca1..3a2d3bd 100644
--- a/api/src/main/java/com/cloud/storage/StoragePool.java
+++ b/api/src/main/java/com/cloud/storage/StoragePool.java
@@ -106,6 +106,4 @@
     Hypervisor.HypervisorType getHypervisor();
 
     boolean isManaged();
-
-    Long getParent();
 }
diff --git a/api/src/main/java/com/cloud/storage/Volume.java b/api/src/main/java/com/cloud/storage/Volume.java
index 5979697..5fd78ef 100644
--- a/api/src/main/java/com/cloud/storage/Volume.java
+++ b/api/src/main/java/com/cloud/storage/Volume.java
@@ -235,6 +235,4 @@
     boolean isDisplayVolume();
 
     boolean isDisplay();
-
-    boolean isDeployAsIs();
 }
diff --git a/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
index 95d1ebf..5177e51 100644
--- a/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
+++ b/api/src/main/java/com/cloud/template/VirtualMachineTemplate.java
@@ -138,6 +138,4 @@
     void incrUpdatedCount();
 
     Date getUpdated();
-
-    boolean isDeployAsIs();
 }
diff --git a/api/src/main/java/com/cloud/vm/DiskProfile.java b/api/src/main/java/com/cloud/vm/DiskProfile.java
index 175a92a..2b76c68 100644
--- a/api/src/main/java/com/cloud/vm/DiskProfile.java
+++ b/api/src/main/java/com/cloud/vm/DiskProfile.java
@@ -100,10 +100,6 @@
         return name;
     }
 
-    public void setTags(String[] tags) {
-        this.tags = tags;
-    }
-
     /**
      * @return tags for the disk. This can be used to match it to different storage pools.
      */
diff --git a/api/src/main/java/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java
index cd2215c..47021c8 100644
--- a/api/src/main/java/com/cloud/vm/NicProfile.java
+++ b/api/src/main/java/com/cloud/vm/NicProfile.java
@@ -52,8 +52,6 @@
     Integer networkRate;
     boolean isSecurityGroupEnabled;
 
-    Integer orderIndex;
-
     // IPv4
     String iPv4Address;
     String iPv4Netmask;
@@ -383,14 +381,6 @@
         this.requestedIPv6 = requestedIPv6;
     }
 
-    public Integer getOrderIndex() {
-        return orderIndex;
-    }
-
-    public void setOrderIndex(Integer orderIndex) {
-        this.orderIndex = orderIndex;
-    }
-
     //
     // OTHER METHODS
     //
@@ -420,8 +410,6 @@
         broadcastUri = null;
         isolationUri = null;
 
-        orderIndex = null;
-
     }
 
     @Override
diff --git a/api/src/main/java/com/cloud/vm/VmDetailConstants.java b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
index 9991e1f..3812aa2 100644
--- a/api/src/main/java/com/cloud/vm/VmDetailConstants.java
+++ b/api/src/main/java/com/cloud/vm/VmDetailConstants.java
@@ -63,6 +63,4 @@
     String IP6_ADDRESS = "ip6Address";
     String DISK = "disk";
     String DISK_OFFERING = "diskOffering";
-
-    String DEPLOY_AS_IS_CONFIGURATION = "configurationId";
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
index ba1f176..88f083b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java
@@ -185,7 +185,6 @@
     public static final String ICMP_TYPE = "icmptype";
     public static final String ID = "id";
     public static final String IDS = "ids";
-    public static final String INDEX = "index";
     public static final String PREVIOUS_ACL_RULE_ID = "previousaclruleid";
     public static final String NEXT_ACL_RULE_ID = "nextaclruleid";
     public static final String MOVE_ACL_CONSISTENCY_HASH = "aclconsistencyhash";
@@ -263,7 +262,7 @@
     public static final String OUTOFBANDMANAGEMENT_POWERSTATE = "outofbandmanagementpowerstate";
     public static final String OUTOFBANDMANAGEMENT_ENABLED = "outofbandmanagementenabled";
     public static final String OUTPUT = "output";
-    public static final String PROPERTIES = "properties";
+    public static final String OVF_PROPERTIES = "ovfproperties";
     public static final String PARAMS = "params";
     public static final String PARENT_ID = "parentid";
     public static final String PARENT_DOMAIN_ID = "parentdomainid";
@@ -825,11 +824,6 @@
     public static final String BOOT_TYPE = "boottype";
     public static final String BOOT_MODE = "bootmode";
     public static final String BOOT_INTO_SETUP = "bootintosetup";
-    public static final String DEPLOY_AS_IS = "deployasis";
-    public static final String DEPLOY_AS_IS_DETAILS = "deployasisdetails";
-    public static final String CROSS_ZONES = "crossZones";
-    public static final String TEMPLATETYPE = "templatetype";
-    public static final String SOURCETEMPLATEID = "sourcetemplateid";
 
     public enum BootType {
         UEFI, BIOS;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
index a830777..f0ca5fb 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
@@ -28,7 +28,6 @@
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DiskOfferingResponse;
 import org.apache.cloudstack.api.response.DomainResponse;
-import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
@@ -152,9 +151,6 @@
             since = "4.14")
     private String cacheMode;
 
-    @Parameter(name = ApiConstants.STORAGE_POLICY, type = CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,required = false, description = "Name of the storage policy defined at vCenter, this is applicable only for VMware", since = "4.15")
-    private Long storagePolicy;
-
 /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -277,9 +273,6 @@
         return cacheMode;
     }
 
-    public Long getStoragePolicy() {
-        return storagePolicy;
-    }
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 745e6a0..5015f7c 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -31,7 +31,6 @@
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
-import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.collections.CollectionUtils;
@@ -217,9 +216,6 @@
             since = "4.13")
     private Integer minMemory;
 
-    @Parameter(name = ApiConstants.STORAGE_POLICY, type = CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,required = false, description = "Name of the storage policy defined at vCenter, this is applicable only for VMware", since = "4.15")
-    private Long storagePolicy;
-
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -422,10 +418,6 @@
         return minMemory;
     }
 
-    public Long getStoragePolicy() {
-        return storagePolicy;
-    }
-
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
index 5f924f2..10321cc 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vm/ImportUnmanagedInstanceCmd.java
@@ -204,9 +204,6 @@
             for (Map<String, String> entry : (Collection<Map<String, String>>)nicNetworkList.values()) {
                 String nic = entry.get(VmDetailConstants.NIC);
                 String networkUuid = entry.get(VmDetailConstants.NETWORK);
-                if (LOGGER.isTraceEnabled()) {
-                    LOGGER.trace(String.format("nic, '%s', goes on net, '%s'", nic, networkUuid));
-                }
                 if (Strings.isNullOrEmpty(nic) || Strings.isNullOrEmpty(networkUuid) || _entityMgr.findByUuid(Network.class, networkUuid) == null) {
                     throw new InvalidParameterValueException(String.format("Network ID: %s for NIC ID: %s is invalid", networkUuid, nic));
                 }
@@ -222,14 +219,11 @@
             for (Map<String, String> entry : (Collection<Map<String, String>>)nicIpAddressList.values()) {
                 String nic = entry.get(VmDetailConstants.NIC);
                 String ipAddress = Strings.emptyToNull(entry.get(VmDetailConstants.IP4_ADDRESS));
-                if (LOGGER.isTraceEnabled()) {
-                    LOGGER.trace(String.format("nic, '%s', gets ip, '%s'", nic, ipAddress));
-                }
                 if (Strings.isNullOrEmpty(nic)) {
                     throw new InvalidParameterValueException(String.format("NIC ID: '%s' is invalid for IP address mapping", nic));
                 }
                 if (Strings.isNullOrEmpty(ipAddress)) {
-                    throw new InvalidParameterValueException(String.format("Empty address for NIC ID: %s is invalid", nic));
+                    throw new InvalidParameterValueException(String.format("IP address '%s' for NIC ID: %s is invalid", ipAddress, nic));
                 }
                 if (!Strings.isNullOrEmpty(ipAddress) && !ipAddress.equals("auto") && !NetUtils.isValidIp4(ipAddress)) {
                     throw new InvalidParameterValueException(String.format("IP address '%s' for NIC ID: %s is invalid", ipAddress, nic));
@@ -245,15 +239,12 @@
         Map<String, Long> dataDiskToDiskOfferingMap = new HashMap<>();
         if (MapUtils.isNotEmpty(dataDiskToDiskOfferingList)) {
             for (Map<String, String> entry : (Collection<Map<String, String>>)dataDiskToDiskOfferingList.values()) {
-                String disk = entry.get(VmDetailConstants.DISK);
+                String nic = entry.get(VmDetailConstants.DISK);
                 String offeringUuid = entry.get(VmDetailConstants.DISK_OFFERING);
-                if (LOGGER.isTraceEnabled()) {
-                    LOGGER.trace(String.format("disk, '%s', gets offering, '%s'", disk, offeringUuid));
+                if (Strings.isNullOrEmpty(nic) || Strings.isNullOrEmpty(offeringUuid) || _entityMgr.findByUuid(DiskOffering.class, offeringUuid) == null) {
+                    throw new InvalidParameterValueException(String.format("Disk offering ID: %s for disk ID: %s is invalid", offeringUuid, nic));
                 }
-                if (Strings.isNullOrEmpty(disk) || Strings.isNullOrEmpty(offeringUuid) || _entityMgr.findByUuid(DiskOffering.class, offeringUuid) == null) {
-                    throw new InvalidParameterValueException(String.format("Disk offering ID: %s for disk ID: %s is invalid", offeringUuid, disk));
-                }
-                dataDiskToDiskOfferingMap.put(disk, _entityMgr.findByUuid(DiskOffering.class, offeringUuid).getId());
+                dataDiskToDiskOfferingMap.put(nic, _entityMgr.findByUuid(DiskOffering.class, offeringUuid).getId());
             }
         }
         return dataDiskToDiskOfferingMap;
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
index 91cac09..dcb1730 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/offering/ListServiceOfferingsCmd.java
@@ -65,24 +65,6 @@
             since = "4.13")
     private Long zoneId;
 
-    @Parameter(name = ApiConstants.CPU_NUMBER,
-            type = CommandType.INTEGER,
-            description = "the CPU number that listed offerings must support",
-            since = "4.15")
-    private Integer cpuNumber;
-
-    @Parameter(name = ApiConstants.MEMORY,
-            type = CommandType.INTEGER,
-            description = "the RAM memory that listed offering must support",
-            since = "4.15")
-    private Integer memory;
-
-    @Parameter(name = ApiConstants.CPU_SPEED,
-            type = CommandType.INTEGER,
-            description = "the CPU speed that listed offerings must support",
-            since = "4.15")
-    private Integer cpuSpeed;
-
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -111,18 +93,6 @@
         return zoneId;
     }
 
-    public Integer getCpuNumber() {
-        return cpuNumber;
-    }
-
-    public Integer getMemory() {
-        return memory;
-    }
-
-    public Integer getCpuSpeed() {
-        return cpuSpeed;
-    }
-
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplateOVFProperties.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplateOVFProperties.java
new file mode 100644
index 0000000..2a620c9
--- /dev/null
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplateOVFProperties.java
@@ -0,0 +1,68 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.template;
+
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.TemplateOVFPropertyResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.context.CallContext;
+
+@APICommand(name = ListTemplateOVFProperties.APINAME,
+        description = "List template OVF properties if available.",
+        responseObject = TemplateOVFPropertyResponse.class,
+        authorized = {RoleType.Admin, RoleType.DomainAdmin, RoleType.ResourceAdmin, RoleType.User})
+public class ListTemplateOVFProperties extends BaseListCmd {
+
+    public static final String APINAME = "listTemplateOvfProperties";
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = TemplateResponse.class,
+            description = "the template ID", required = true)
+    private Long templateId;
+
+    public Long getTemplateId() {
+        return templateId;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
+        ListResponse<TemplateOVFPropertyResponse> response = _queryService.listTemplateOVFProperties(this);
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+
+    @Override
+    public String getCommandName() {
+        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return CallContext.current().getCallingAccount().getId();
+    }
+}
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
index 5ef66c5..5630d7f 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java
@@ -16,12 +16,8 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.template;
 
-import com.cloud.exception.InvalidParameterValueException;
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 
-import java.util.ArrayList;
-import java.util.EnumSet;
 import java.util.List;
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiCommandJobType;
@@ -86,36 +82,10 @@
     @Parameter(name = ApiConstants.PARENT_TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "list datadisk templates by parent template id", since = "4.4")
     private Long parentTemplateId;
 
-    @Parameter(name = ApiConstants.DETAILS,
-            type = CommandType.LIST,
-            collectionType = CommandType.STRING,
-            since = "4.15",
-            description = "comma separated list of template details requested, value can be a list of [ all, min]")
-    private List<String> viewDetails;
-
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
 
-    public EnumSet<ApiConstants.DomainDetails> getDetails() throws InvalidParameterValueException {
-        EnumSet<ApiConstants.DomainDetails> dv;
-        if (CollectionUtils.isEmpty(viewDetails)) {
-            dv = EnumSet.of(ApiConstants.DomainDetails.all);
-        } else {
-            try {
-                ArrayList<ApiConstants.DomainDetails> dc = new ArrayList<>();
-                for (String detail : viewDetails) {
-                    dc.add(ApiConstants.DomainDetails.valueOf(detail));
-                }
-                dv = EnumSet.copyOf(dc);
-            } catch (IllegalArgumentException e) {
-                throw new InvalidParameterValueException("The details parameter contains a non permitted value. The allowed values are " +
-                        EnumSet.allOf(ApiConstants.DomainDetails.class));
-            }
-        }
-        return dv;
-    }
-
     public String getHypervisor() {
         return hypervisor;
     }
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
index 74053ee..7e0002d 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java
@@ -86,8 +86,8 @@
     @Parameter(name = ApiConstants.OS_TYPE_ID,
                type = CommandType.UUID,
                entityType = GuestOSResponse.class,
-               required = false,
-               description = "the ID of the OS Type that best represents the OS of this template. Not applicable with VMware, as we honour what is defined in the template")
+               required = true,
+               description = "the ID of the OS Type that best represents the OS of this template.")
     private Long osTypeId;
 
     @Parameter(name = ApiConstants.PASSWORD_ENABLED,
@@ -274,10 +274,6 @@
         return directDownload == null ? false : directDownload;
     }
 
-    public Boolean isDeployAsIs() {
-        return hypervisor != null && hypervisor.equalsIgnoreCase(Hypervisor.HypervisorType.VMware.toString());
-    }
-
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
@@ -340,9 +336,5 @@
             throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
                     "Parameter directdownload is only allowed for KVM templates");
         }
-
-        if (!getHypervisor().equalsIgnoreCase(Hypervisor.HypervisorType.VMware.toString()) && osTypeId == null) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please provide a guest OS type");
-        }
     }
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
index 6d7cc9c..b4514b1 100644
--- a/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
+++ b/api/src/main/java/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java
@@ -52,7 +52,6 @@
 import org.apache.cloudstack.api.response.UserVmResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.log4j.Logger;
 
@@ -73,8 +72,6 @@
 import com.cloud.utils.net.Dhcp;
 import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VmDetailConstants;
-import com.google.common.base.Strings;
 
 @APICommand(name = "deployVirtualMachine", description = "Creates and automatically starts a virtual machine based on a service offering, disk offering, and template.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted, entityType = {VirtualMachine.class},
         requestHasSensitiveInfo = false, responseHasSensitiveInfo = true)
@@ -116,10 +113,10 @@
     @Parameter(name = ApiConstants.NETWORK_IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = NetworkResponse.class, description = "list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter")
     private List<Long> networkIds;
 
-    @Parameter(name = ApiConstants.BOOT_TYPE, type = CommandType.STRING, required = false, description = "Guest VM Boot option either custom[UEFI] or default boot [BIOS]. Not applicable with VMware, as we honour what is defined in the template.", since = "4.14.0.0")
+    @Parameter(name = ApiConstants.BOOT_TYPE, type = CommandType.STRING, required = false, description = "Guest VM Boot option either custom[UEFI] or default boot [BIOS]", since = "4.14.0.0")
     private String bootType;
 
-    @Parameter(name = ApiConstants.BOOT_MODE, type = CommandType.STRING, required = false, description = "Boot Mode [Legacy] or [Secure] Applicable when Boot Type Selected is UEFI, otherwise Legacy only for BIOS. Not applicable with VMware, as we honour what is defined in the template.", since = "4.14.0.0")
+    @Parameter(name = ApiConstants.BOOT_MODE, type = CommandType.STRING, required = false, description = "Boot Mode [Legacy] or [Secure] Applicable when Boot Type Selected is UEFI, otherwise Legacy By default for BIOS", since = "4.14.0.0")
     private String bootMode;
 
     @Parameter(name = ApiConstants.BOOT_INTO_SETUP, type = CommandType.BOOLEAN, required = false, description = "Boot into hardware setup or not (ignored if startVm = false, only valid for vmware)", since = "4.15.0.0")
@@ -224,16 +221,10 @@
     @Parameter(name = ApiConstants.COPY_IMAGE_TAGS, type = CommandType.BOOLEAN, since = "4.13", description = "if true the image tags (if any) will be copied to the VM, default value is false")
     private Boolean copyImageTags;
 
-    @Parameter(name = ApiConstants.PROPERTIES, type = CommandType.MAP, since = "4.15",
-            description = "used to specify the vApp properties.")
+    @Parameter(name = ApiConstants.OVF_PROPERTIES, type = CommandType.MAP, since = "4.13",
+            description = "used to specify the OVF properties.")
     @LogLevel(LogLevel.Log4jLevel.Off)
-    private Map vAppProperties;
-
-    @Parameter(name = ApiConstants.NIC_NETWORK_LIST, type = CommandType.MAP, since = "4.15",
-            description = "VMware only: used to specify network mapping of a vApp VMware template registered \"as-is\"." +
-                    " Example nicnetworklist[0].ip=Nic-101&nicnetworklist[0].network=uuid")
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private Map vAppNetworks;
+    private Map vmOvfProperties;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
@@ -265,7 +256,8 @@
         return domainId;
     }
 
-    public ApiConstants.BootType  getBootType() {
+    private ApiConstants.BootType  getBootType() {
+
         if (StringUtils.isNotBlank(bootType)) {
             try {
                 String type = bootType.trim().toUpperCase();
@@ -319,10 +311,11 @@
         return null;
     }
 
-    public Map<String, String> getVmProperties() {
+
+    public Map<String, String> getVmOVFProperties() {
         Map<String, String> map = new HashMap<>();
-        if (MapUtils.isNotEmpty(vAppProperties)) {
-            Collection parameterCollection = vAppProperties.values();
+        if (MapUtils.isNotEmpty(vmOvfProperties)) {
+            Collection parameterCollection = vmOvfProperties.values();
             Iterator iterator = parameterCollection.iterator();
             while (iterator.hasNext()) {
                 HashMap<String, String> entry = (HashMap<String, String>)iterator.next();
@@ -332,32 +325,6 @@
         return map;
     }
 
-    public Map<Integer, Long> getVmNetworkMap() {
-        Map<Integer, Long> map = new HashMap<>();
-        if (MapUtils.isNotEmpty(vAppNetworks)) {
-            Collection parameterCollection = vAppNetworks.values();
-            Iterator iterator = parameterCollection.iterator();
-            while (iterator.hasNext()) {
-                HashMap<String, String> entry = (HashMap<String, String>) iterator.next();
-                Integer nic;
-                try {
-                    nic = Integer.valueOf(entry.get(VmDetailConstants.NIC));
-                } catch (NumberFormatException nfe) {
-                    nic = null;
-                }
-                String networkUuid = entry.get(VmDetailConstants.NETWORK);
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace(String.format("nic, '%s', goes on net, '%s'", nic, networkUuid));
-                }
-                if (nic == null || Strings.isNullOrEmpty(networkUuid) || _entityMgr.findByUuid(Network.class, networkUuid) == null) {
-                    throw new InvalidParameterValueException(String.format("Network ID: %s for NIC ID: %s is invalid", networkUuid, nic));
-                }
-                map.put(nic, _entityMgr.findByUuid(Network.class, networkUuid).getId());
-            }
-        }
-        return map;
-    }
-
     public String getGroup() {
         return group;
     }
@@ -407,13 +374,6 @@
     }
 
     public List<Long> getNetworkIds() {
-        if (MapUtils.isNotEmpty(vAppNetworks)) {
-            if (CollectionUtils.isNotEmpty(networkIds) || ipAddress != null || getIp6Address() != null || MapUtils.isNotEmpty(ipToNetworkList)) {
-                throw new InvalidParameterValueException(String.format("%s can't be specified along with %s, %s, %s", ApiConstants.NIC_NETWORK_LIST, ApiConstants.NETWORK_IDS, ApiConstants.IP_ADDRESS, ApiConstants.IP_NETWORK_LIST));
-            } else {
-                return new ArrayList<>();
-            }
-        }
        if (ipToNetworkList != null && !ipToNetworkList.isEmpty()) {
            if ((networkIds != null && !networkIds.isEmpty()) || ipAddress != null || getIp6Address() != null) {
                throw new InvalidParameterValueException("ipToNetworkMap can't be specified along with networkIds or ipAddress");
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java
index 5398dd3..8c0fd70 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/DiskOfferingResponse.java
@@ -151,10 +151,6 @@
     @Param(description = "whether to display the offering to the end user or not.")
     private Boolean displayOffering;
 
-    @SerializedName("vspherestoragepolicy")
-    @Param(description = "the vsphere storage policy tagged to the disk offering in case of VMware", since = "4.15")
-    private String vsphereStoragePolicy;
-
     public Boolean getDisplayOffering() {
         return displayOffering;
     }
@@ -355,12 +351,4 @@
     public void setIopsWriteRateMaxLength(Long iopsWriteRateMaxLength) {
         this.iopsWriteRateMaxLength = iopsWriteRateMaxLength;
     }
-
-    public String getVsphereStoragePolicy() {
-        return vsphereStoragePolicy;
-    }
-
-    public void setVsphereStoragePolicy(String vsphereStoragePolicy) {
-        this.vsphereStoragePolicy = vsphereStoragePolicy;
-    }
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
index e13735b..9d5e9ee 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
@@ -196,10 +196,6 @@
     @Param(description = "the cache mode to use for this disk offering. none, writeback or writethrough", since = "4.14")
     private String cacheMode;
 
-    @SerializedName("vspherestoragepolicy")
-    @Param(description = "the vsphere storage policy tagged to the service offering in case of VMware", since = "4.15")
-    private String vsphereStoragePolicy;
-
     public ServiceOfferingResponse() {
     }
 
@@ -459,13 +455,4 @@
     public void setCacheMode(String cacheMode) {
         this.cacheMode = cacheMode;
     }
-
-    public String getVsphereStoragePolicy() {
-        return vsphereStoragePolicy;
-    }
-
-    public void setVsphereStoragePolicy(String vsphereStoragePolicy) {
-        this.vsphereStoragePolicy = vsphereStoragePolicy;
-    }
-
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/TemplateOVFPropertyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TemplateOVFPropertyResponse.java
index ebe0d1c..83455a3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/TemplateOVFPropertyResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/TemplateOVFPropertyResponse.java
@@ -16,14 +16,14 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
+import com.cloud.agent.api.storage.OVFProperty;
 import com.cloud.serializer.Param;
 import com.google.gson.annotations.SerializedName;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
 
-/**
- * the placeholder of parameters to fill for deployment
- */
+@EntityReference(value = OVFProperty.class)
 public class TemplateOVFPropertyResponse extends BaseResponse {
 
     @SerializedName(ApiConstants.KEY)
@@ -58,27 +58,6 @@
     @Param(description = "the ovf property label")
     private String description;
 
-    @SerializedName(ApiConstants.INDEX)
-    @Param(description = "the ovf property index")
-    private Integer index;
-
-    @SerializedName(ApiConstants.CATEGORY)
-    @Param(description = "the ovf property category")
-    private String category;
-
-    @Override
-    public boolean equals(Object other) {
-        if (!(other instanceof TemplateOVFPropertyResponse)) {
-            return false;
-        }
-        return key != null && key.equals(((TemplateOVFPropertyResponse)other).key);
-    }
-
-    @Override
-    public int hashCode() {
-        return key.hashCode();
-    }
-
     public String getKey() {
         return key;
     }
@@ -142,20 +121,4 @@
     public void setPassword(Boolean password) {
         this.password = password;
     }
-
-    public Integer getIndex() {
-        return index;
-    }
-
-    public void setIndex(Integer index) {
-        this.index = index;
-    }
-
-    public String getCategory() {
-        return category;
-    }
-
-    public void setCategory(String category) {
-        this.category = category;
-    }
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java
index 6e69923..094fe2a 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java
@@ -17,7 +17,6 @@
 package org.apache.cloudstack.api.response;
 
 import java.util.Date;
-import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -56,7 +55,7 @@
     @Param(description = "the date this template was created")
     private Date created;
 
-    @SerializedName(ApiConstants.REMOVED)
+    @SerializedName("removed")
     @Param(description = "the date this template was removed")
     private Date removed;
 
@@ -81,7 +80,7 @@
     @Param(description = "true if this template is a featured template, false otherwise")
     private boolean featured;
 
-    @SerializedName(ApiConstants.CROSS_ZONES)
+    @SerializedName("crossZones")
     @Param(description = "true if the template is managed across all Zones, false otherwise")
     private boolean crossZones;
 
@@ -123,7 +122,7 @@
     @Param(description = "the physical size of the template")
     private Long physicalSize;
 
-    @SerializedName(ApiConstants.TEMPLATETYPE)
+    @SerializedName("templatetype")
     @Param(description = "the type of the template")
     private String templateType;
 
@@ -147,7 +146,7 @@
     @Param(description = "checksum of the template")
     private String checksum;
 
-    @SerializedName(ApiConstants.SOURCETEMPLATEID)
+    @SerializedName("sourcetemplateid")
     @Param(description = "the template ID of the parent template if present")
     private String sourcetemplateId;
 
@@ -155,7 +154,7 @@
     @Param(description = "the ID of the secondary storage host for the template")
     private String hostId;
 
-    @SerializedName(ApiConstants.HOST_NAME)
+    @SerializedName("hostname")
     @Param(description = "the name of the secondary storage host for the template")
     private String hostName;
 
@@ -173,7 +172,7 @@
 
     @SerializedName(ApiConstants.DETAILS)
     @Param(description = "additional key/value details tied with template")
-    private Map<String, String> details;
+    private Map details;
 
     @SerializedName(ApiConstants.DOWNLOAD_DETAILS)
     @Param(description = "Lists the download progress of a template across all secondary storages")
@@ -195,24 +194,12 @@
     @Param(description = "KVM Only: true if template is directly downloaded to Primary Storage bypassing Secondary Storage")
     private Boolean directDownload;
 
-    @SerializedName(ApiConstants.DEPLOY_AS_IS)
-    @Param(description = "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.",
-            since = "4.15")
-    private Boolean deployAsIs;
-
-    @SerializedName(ApiConstants.DEPLOY_AS_IS_DETAILS)
-    @Param(description = "VMware only: additional key/value details tied with deploy-as-is template",
-            since = "4.15")
-    private Map<String, String> deployAsIsDetails;
-
     @SerializedName("parenttemplateid")
     @Param(description = "if Datadisk template, then id of the root disk template this template belongs to")
-    @Deprecated(since = "4.15")
     private String parentTemplateId;
 
     @SerializedName("childtemplates")
     @Param(description = "if root disk template, then ids of the datas disk templates this template owns")
-    @Deprecated(since = "4.15")
     private Set<ChildTemplateResponse> childTemplates;
 
     @SerializedName(ApiConstants.REQUIRES_HVM)
@@ -373,21 +360,14 @@
         this.projectName = projectName;
     }
 
-    public Map<String, String> getDetails() {
+    public Map getDetails() {
         return this.details;
     }
 
-    public void setDetails(Map<String, String> details) {
+    public void setDetails(Map details) {
         this.details = details;
     }
 
-    public void addDetail(String key, String value) {
-        if (this.details == null) {
-            setDetails(new HashMap<>());
-        }
-        this.details.put(key,value);
-    }
-
     public void setTags(Set<ResourceTagResponse> tags) {
         this.tags = tags;
     }
@@ -416,10 +396,6 @@
         return directDownload;
     }
 
-    public void setDeployAsIs(Boolean deployAsIs) {
-        this.deployAsIs = deployAsIs;
-    }
-
     public void setParentTemplateId(String parentTemplateId) {
         this.parentTemplateId = parentTemplateId;
     }
@@ -435,19 +411,4 @@
     public void setRequiresHvm(Boolean requiresHvm) {
         this.requiresHvm = requiresHvm;
     }
-
-    public Map<String, String> getDeployAsIsDetails() {
-        return this.deployAsIsDetails;
-    }
-
-    public void setDeployAsIsDetails(Map<String, String> details) {
-        this.deployAsIsDetails = details;
-    }
-
-    public void addDeployAsIsDetail(String key, String value) {
-        if (this.deployAsIsDetails == null) {
-            setDeployAsIsDetails(new HashMap<>());
-        }
-        this.deployAsIsDetails.put(key,value);
-    }
 }
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VsphereStoragePoliciesResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VsphereStoragePoliciesResponse.java
deleted file mode 100644
index 63c49f1..0000000
--- a/api/src/main/java/org/apache/cloudstack/api/response/VsphereStoragePoliciesResponse.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.response;
-
-import com.cloud.dc.VsphereStoragePolicy;
-import com.cloud.serializer.Param;
-import com.google.gson.annotations.SerializedName;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
-import org.apache.cloudstack.api.EntityReference;
-
-
-@EntityReference(value = VsphereStoragePolicy.class)
-public class VsphereStoragePoliciesResponse extends BaseResponse {
-
-    @SerializedName(ApiConstants.ID)
-    @Param(description = "the ID of the Storage Policy")
-    private String id;
-
-    @SerializedName(ApiConstants.ZONE_ID)
-    @Param(description = "the ID of the Zone")
-    private String zoneId;
-
-    @SerializedName(ApiConstants.POLICY_ID)
-    @Param(description = "the identifier of the Storage Policy in vSphere DataCenter")
-    private String policyId;
-
-    @SerializedName(ApiConstants.NAME)
-    @Param(description = "the name of the Storage Policy")
-    private String name;
-
-    @SerializedName(ApiConstants.DESCRIPTION)
-    @Param(description = "the description of the Storage Policy")
-    private String description;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public String getZoneId() {
-        return zoneId;
-    }
-
-    public void setZoneId(String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    public String getPolicyId() {
-        return policyId;
-    }
-
-    public void setPolicyId(String policyId) {
-        this.policyId = policyId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-}
diff --git a/api/src/main/java/org/apache/cloudstack/query/QueryService.java b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
index 717af5d..0a400ed 100644
--- a/api/src/main/java/org/apache/cloudstack/query/QueryService.java
+++ b/api/src/main/java/org/apache/cloudstack/query/QueryService.java
@@ -44,6 +44,7 @@
 import org.apache.cloudstack.api.command.user.resource.ListDetailOptionsCmd;
 import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
 import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplateOVFProperties;
 import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
 import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
@@ -73,6 +74,7 @@
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.StorageTagResponse;
+import org.apache.cloudstack.api.response.TemplateOVFPropertyResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -171,5 +173,7 @@
 
     ListResponse<ManagementServerResponse> listManagementServers(ListMgmtsCmd cmd);
 
+    ListResponse<TemplateOVFPropertyResponse> listTemplateOVFProperties(ListTemplateOVFProperties cmd);
+
     List<RouterHealthCheckResultResponse> listRouterHealthChecks(GetRouterHealthCheckResultsCmd cmd);
 }
diff --git a/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java b/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java
index 5e7b7cf..8aa9852 100644
--- a/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java
+++ b/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java
@@ -16,12 +16,6 @@
 // under the License.
 package com.cloud.agent.api.storage;
 
-import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
-import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
-import com.cloud.utils.Pair;
 import org.junit.Assert;
 import org.junit.Test;
 import org.xml.sax.SAXException;
@@ -46,708 +40,16 @@
             "</Property>" +
         "</ProductSection>";
 
-    private String ovfFileDeploymentOptionsSection =
-            "<DeploymentOptionSection>\n" +
-                    "    <Info>Deployment Configuration information</Info>\n" +
-                    "    <Configuration ovf:id=\"ASAv5\">\n" +
-                    "      <Label>100 Mbps (ASAv5)</Label>\n" +
-                    "      <Description>Use this option to deploy an ASAv with a maximum throughput of 100 Mbps (uses 1 vCPU and 2 GB of memory).</Description>\n" +
-                    "    </Configuration>\n" +
-                    "    <Configuration ovf:id=\"ASAv10\">\n" +
-                    "      <Label>1 Gbps (ASAv10)</Label>\n" +
-                    "      <Description>Use this option to deploy an ASAv with a maximum throughput of 1 Gbps (uses 1 vCPU and 2 GB of memory).</Description>\n" +
-                    "    </Configuration>\n" +
-                    "    <Configuration ovf:id=\"ASAv30\">\n" +
-                    "      <Label>2 Gbps (ASAv30)</Label>\n" +
-                    "      <Description>Use this option to deploy an ASAv with a maximum throughput of 2 Gbps (uses 4 vCPUs and 8 GB of memory).</Description>\n" +
-                    "    </Configuration>\n" +
-                    "  </DeploymentOptionSection>";
-
-    private String ovfFileVirtualHardwareSection =
-            "<VirtualSystem>\n" +
-            "<OperatingSystemSection ovf:id=\"100\" vmw:osType=\"other26xLinux64Guest\">\n" +
-            "      <Info>The kind of installed guest operating system</Info>\n" +
-            "      <Description>Other 2.6x Linux (64-bit)</Description>\n" +
-            "</OperatingSystemSection>\n" +
-            "<VirtualHardwareSection ovf:transport=\"iso\">\n" +
-            "      <Info>Virtual hardware requirements</Info>\n" +
-            "      <System>\n" +
-            "        <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>\n" +
-            "        <vssd:InstanceID>0</vssd:InstanceID>\n" +
-            "        <vssd:VirtualSystemIdentifier>ASAv</vssd:VirtualSystemIdentifier>\n" +
-            "        <vssd:VirtualSystemType>vmx-08,vmx-09</vssd:VirtualSystemType>\n" +
-            "      </System>\n" +
-            "      <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
-            "        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
-            "        <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
-            "        <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>1</rasd:InstanceID>\n" +
-            "        <rasd:Limit>5000</rasd:Limit>\n" +
-            "        <rasd:Reservation>1000</rasd:Reservation>\n" +
-            "        <rasd:ResourceType>3</rasd:ResourceType>\n" +
-            "        <rasd:VirtualQuantity>1</rasd:VirtualQuantity>\n" +
-            "      </Item>\n" +
-            "      <Item ovf:configuration=\"ASAv30\">\n" +
-            "        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>\n" +
-            "        <rasd:Description>Number of Virtual CPUs</rasd:Description>\n" +
-            "        <rasd:ElementName>4 virtual CPU(s)</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>1</rasd:InstanceID>\n" +
-            "        <rasd:Limit>20000</rasd:Limit>\n" +
-            "        <rasd:Reservation>1000</rasd:Reservation>\n" +
-            "        <rasd:ResourceType>3</rasd:ResourceType>\n" +
-            "        <rasd:VirtualQuantity>4</rasd:VirtualQuantity>\n" +
-            "      </Item>\n" +
-            "      <Item ovf:configuration=\"ASAv5 ASAv10\">\n" +
-            "        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
-            "        <rasd:Description>Memory Size</rasd:Description>\n" +
-            "        <rasd:ElementName>2048MB of memory</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>2</rasd:InstanceID>\n" +
-            "        <rasd:Limit>2048</rasd:Limit>\n" +
-            "        <rasd:Reservation>2048</rasd:Reservation>\n" +
-            "        <rasd:ResourceType>4</rasd:ResourceType>\n" +
-            "        <rasd:VirtualQuantity>2048</rasd:VirtualQuantity>\n" +
-            "      </Item>\n" +
-            "      <Item ovf:configuration=\"ASAv30\">\n" +
-            "        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>\n" +
-            "        <rasd:Description>Memory Size</rasd:Description>\n" +
-            "        <rasd:ElementName>8192MB of memory</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>2</rasd:InstanceID>\n" +
-            "        <rasd:Limit>8192</rasd:Limit>\n" +
-            "        <rasd:Reservation>8192</rasd:Reservation>\n" +
-            "        <rasd:ResourceType>4</rasd:ResourceType>\n" +
-            "        <rasd:VirtualQuantity>8192</rasd:VirtualQuantity>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:Address>0</rasd:Address>\n" +
-            "        <rasd:Description>SCSI Controller</rasd:Description>\n" +
-            "        <rasd:ElementName>SCSI controller 0</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>3</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>6</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:Address>0</rasd:Address>\n" +
-            "        <rasd:Description>IDE Controller</rasd:Description>\n" +
-            "        <rasd:ElementName>IDE 0</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>4</rasd:InstanceID>\n" +
-            "        <rasd:ResourceType>5</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item ovf:required=\"false\">\n" +
-            "        <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>5</rasd:InstanceID>\n" +
-            "        <rasd:Parent>4</rasd:Parent>\n" +
-            "        <rasd:ResourceType>15</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item ovf:required=\"false\">\n" +
-            "        <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:ElementName>CD/DVD Drive</rasd:ElementName>\n" +
-            "        <rasd:HostResource>ovf:/file/file3</rasd:HostResource>\n" +
-            "        <rasd:InstanceID>18</rasd:InstanceID>\n" +
-            "        <rasd:Parent>4</rasd:Parent>\n" +
-            "        <rasd:ResourceType>15</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>7</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>Management0-0</rasd:Connection>\n" +
-            "        <rasd:Description>E1000 Ethernet adapter on \"Management Network\"</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 1</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>6</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>0</rasd:AddressOnParent>\n" +
-            "        <rasd:ElementName>Hard disk 1</rasd:ElementName>\n" +
-            "        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>\n" +
-            "        <rasd:InstanceID>7</rasd:InstanceID>\n" +
-            "        <rasd:Parent>3</rasd:Parent>\n" +
-            "        <rasd:ResourceType>17</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>1</rasd:AddressOnParent>\n" +
-            "        <rasd:ElementName>Hard disk 2</rasd:ElementName>\n" +
-            "        <rasd:HostResource>ovf:/disk/vmdisk2</rasd:HostResource>\n" +
-            "        <rasd:InstanceID>8</rasd:InstanceID>\n" +
-            "        <rasd:Parent>3</rasd:Parent>\n" +
-            "        <rasd:ResourceType>17</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>8</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-0</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 2</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>9</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>9</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-1</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 3</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>10</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>10</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-2</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 4</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>11</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>11</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-3</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 5</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>12</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>12</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-4</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 6</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>13</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>13</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-5</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 7</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>14</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>14</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-6</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 8</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>15</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>15</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-7</rasd:Connection>\n" +
-            "        <rasd:Description>General purpose E1000 Ethernet adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 9</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>16</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <Item>\n" +
-            "        <rasd:AddressOnParent>16</rasd:AddressOnParent>\n" +
-            "        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>\n" +
-            "        <rasd:Connection>GigabitEthernet0-8</rasd:Connection>\n" +
-            "        <rasd:Description>Default HA failover E1000 Ethernet adapter, or additional standalone general purpose adapter</rasd:Description>\n" +
-            "        <rasd:ElementName>Network adapter 10</rasd:ElementName>\n" +
-            "        <rasd:InstanceID>17</rasd:InstanceID>\n" +
-            "        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>\n" +
-            "        <rasd:ResourceType>10</rasd:ResourceType>\n" +
-            "      </Item>\n" +
-            "      <vmw:ExtraConfig vmw:key=\"monitor_control.pseudo_perfctr\" vmw:value=\"TRUE\"></vmw:ExtraConfig>\n" +
-            "    </VirtualHardwareSection>\n" +
-            "</VirtualSystem>";
-
-    private String eulaSections =
-            "<VirtualSystem>\n" +
-            "<EulaSection>\n" +
-            "      <Info>end-user license agreement</Info>\n" +
-            "      <License>END USER LICENSE AGREEMENT\n" +
-            "\n" +
-            "IMPORTANT: PLEASE READ THIS END USER LICENSE AGREEMENT CAREFULLY. IT IS VERY IMPORTANT THAT YOU CHECK THAT YOU ARE PURCHASING CISCO SOFTWARE OR EQUIPMENT FROM AN APPROVED SOURCE AND THAT YOU, OR THE ENTITY YOU REPRESENT (COLLECTIVELY, THE \"CUSTOMER\") HAVE BEEN REGISTERED AS THE END USER FOR THE PURPOSES OF THIS CISCO END USER LICENSE AGREEMENT. IF YOU ARE NOT REGISTERED AS THE END USER YOU HAVE NO LICENSE TO USE THE SOFTWARE AND THE LIMITED WARRANTY IN THIS END USER LICENSE AGREEMENT DOES NOT APPLY. ASSUMING YOU HAVE PURCHASED FROM AN APPROVED SOURCE, DOWNLOADING, INSTALLING OR USING CISCO OR CISCO-SUPPLIED SOFTWARE CONSTITUTES ACCEPTANCE OF THIS AGREEMENT.\n" +
-            "\n" +
-            "CISCO SYSTEMS, INC. OR ITS AFFILIATE LICENSING THE SOFTWARE (\"CISCO\") IS WILLING TO LICENSE THIS SOFTWARE TO YOU ONLY UPON THE CONDITION THAT YOU PURCHASED THE SOFTWARE FROM AN APPROVED SOURCE AND THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS END USER LICENSE AGREEMENT PLUS ANY ADDITIONAL LIMITATIONS ON THE LICENSE SET FORTH IN A SUPPLEMENTAL LICENSE AGREEMENT ACCOMPANYING THE PRODUCT, MADE AVAILABLE AT THE TIME OF YOUR ORDER, OR POSTED ON THE CISCO WEBSITE AT www.cisco.com/go/terms (COLLECTIVELY THE \"AGREEMENT\"). TO THE EXTENT OF ANY CONFLICT BETWEEN THE TERMS OF THIS END USER LICENSE AGREEMENT AND ANY SUPPLEMENTAL LICENSE AGREEMENT, THE SUPPLEMENTAL LICENSE AGREEMENT SHALL APPLY. BY DOWNLOADING, INSTALLING, OR USING THE SOFTWARE, YOU ARE REPRESENTING THAT YOU PURCHASED THE SOFTWARE FROM AN APPROVED SOURCE AND BINDING YOURSELF TO THE AGREEMENT. IF YOU DO " +
-                    "NOT AGREE TO ALL OF THE TERMS OF THE AGREEMENT, THEN CISCO IS UNWILLING TO LICENSE THE SOFTWARE TO YOU AND (A) YOU MAY NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE, AND (B) YOU MAY RETURN THE SOFTWARE (INCLUDING ANY UNOPENED CD PACKAGE AND ANY WRITTEN MATERIALS) FOR A FULL REFUND, OR, IF THE SOFTWARE AND WRITTEN MATERIALS ARE SUPPLIED AS PART OF ANOTHER PRODUCT, YOU MAY RETURN THE ENTIRE PRODUCT FOR A FULL REFUND. YOUR RIGHT TO RETURN AND REFUND EXPIRES 30 DAYS AFTER PURCHASE FROM AN APPROVED SOURCE, AND APPLIES ONLY IF YOU ARE THE ORIGINAL AND REGISTERED END USER PURCHASER. FOR THE PURPOSES OF THIS END USER LICENSE AGREEMENT, AN \"APPROVED SOURCE\" MEANS (A) CISCO; OR (B) A DISTRIBUTOR OR SYSTEMS INTEGRATOR AUTHORIZED BY CISCO TO DISTRIBUTE / SELL CISCO EQUIPMENT, SOFTWARE AND SERVICES WITHIN YOUR TERRITORY TO END " +
-                    "USERS; OR (C) A RESELLER AUTHORIZED BY ANY SUCH DISTRIBUTOR OR SYSTEMS INTEGRATOR IN ACCORDANCE WITH THE TERMS OF THE DISTRIBUTOR'S AGREEMENT WITH CISCO TO DISTRIBUTE / SELL THE CISCO EQUIPMENT, SOFTWARE AND SERVICES WITHIN YOUR TERRITORY TO END USERS.\n" +
-            "\n" +
-            "THE FOLLOWING TERMS OF THE AGREEMENT GOVERN CUSTOMER'S USE OF THE SOFTWARE (DEFINED BELOW), EXCEPT TO THE EXTENT: (A) THERE IS A SEPARATE SIGNED CONTRACT BETWEEN CUSTOMER AND CISCO GOVERNING CUSTOMER'S USE OF THE SOFTWARE, OR (B) THE SOFTWARE INCLUDES A SEPARATE \"CLICK-ACCEPT\" LICENSE AGREEMENT OR THIRD PARTY LICENSE AGREEMENT AS PART OF THE INSTALLATION OR DOWNLOAD PROCESS GOVERNING CUSTOMER'S USE OF THE SOFTWARE. TO THE EXTENT OF A CONFLICT BETWEEN THE PROVISIONS OF THE FOREGOING DOCUMENTS, THE ORDER OF PRECEDENCE SHALL BE (1)THE SIGNED CONTRACT, (2) THE CLICK-ACCEPT AGREEMENT OR THIRD PARTY LICENSE AGREEMENT, AND (3) THE AGREEMENT. FOR PURPOSES OF THE AGREEMENT, \"SOFTWARE\" SHALL MEAN COMPUTER PROGRAMS, INCLUDING FIRMWARE AND COMPUTER PROGRAMS EMBEDDED IN CISCO EQUIPMENT, AS PROVIDED TO CUSTOMER BY AN APPROVED SOURCE, AND ANY UPGRADES, UPDATES, BUG FIXES " +
-                    "OR MODIFIED VERSIONS THERETO (COLLECTIVELY, \"UPGRADES\"), ANY OF THE SAME WHICH HAS BEEN RELICENSED UNDER THE CISCO SOFTWARE TRANSFER AND RE-LICENSING POLICY (AS MAY BE AMENDED BY CISCO FROM TIME TO TIME) OR BACKUP COPIES OF ANY OF THE FOREGOING.\n" +
-            "\n" +
-            "License. Conditioned upon compliance with the terms and conditions of the Agreement, Cisco grants to Customer a nonexclusive and nontransferable license to use for Customer's internal business purposes the Software and the Documentation for which Customer has paid the required license fees to an Approved Source. \"Documentation\" means written information (whether contained in user or technical manuals, training materials, specifications or otherwise) pertaining to the Software and made available by an Approved Source with the Software in any manner (including on CD-Rom, or on-line). In order to use the Software, Customer may be required to input a registration number or product authorization key and register Customer's copy of the Software online at Cisco's website to obtain the necessary license key or license file.\n" +
-            "\n" +
-            "Customer's license to use the Software shall be limited to, and Customer shall not use the Software in excess of, a single hardware chassis or card or such other limitations as are set forth in the applicable Supplemental License Agreement or in the applicable purchase order which has been accepted by an Approved Source and for which Customer has paid to an Approved Source the required license fee (the \"Purchase Order\").\n" +
-            "\n" +
-            "Unless otherwise expressly provided in the Documentation or any applicable Supplemental License Agreement, Customer shall use the Software solely as embedded in, for execution on, or (where the applicable Documentation permits installation on non-Cisco equipment) for communication with Cisco equipment owned or leased by Customer and used for Customer's internal business purposes. No other licenses are granted by implication, estoppel or otherwise.\n" +
-            "\n" +
-            "For evaluation or beta copies for which Cisco does not charge a license fee, the above requirement to pay license fees does not apply.\n" +
-            "\n" +
-            "General Limitations. This is a license, not a transfer of title, to the Software and Documentation, and Cisco retains ownership of all copies of the Software and Documentation. Customer acknowledges that the Software and Documentation contain trade secrets of Cisco or its suppliers or licensors, including but not limited to the specific internal design and structure of individual programs and associated interface information. Except as otherwise expressly provided under the Agreement, Customer shall only use the Software in connection with the use of Cisco equipment purchased by the Customer from an Approved Source and Customer shall have no right, and Customer specifically agrees not to:\n" +
-            "\n" +
-            "(i) transfer, assign or sublicense its license rights to any other person or entity (other than in compliance with any Cisco relicensing/transfer policy then in force), or use the Software on Cisco equipment not purchased by the Customer from an Approved Source or on secondhand Cisco equipment, and Customer acknowledges that any attempted transfer, assignment, sublicense or use shall be void;\n" +
-            "\n" +
-            "(ii) make error corrections to or otherwise modify or adapt the Software or create derivative works based upon the Software, or permit third parties to do the same;\n" +
-            "\n" +
-            "(iii) reverse engineer or decompile, decrypt, disassemble or otherwise reduce the Software to human-readable form, except to the extent otherwise expressly permitted under applicable law notwithstanding this restriction or except to the extent that Cisco is legally required to permit such specific activity pursuant to any applicable open source license;\n" +
-            "\n" +
-            "(iv) publish any results of benchmark tests run on the Software;\n" +
-            "\n" +
-            "(v) use or permit the Software to be used to perform services for third parties, whether on a service bureau or time sharing basis or otherwise, without the express written authorization of Cisco; or\n" +
-            "\n" +
-            "(vi) disclose, provide, or otherwise make available trade secrets contained within the Software and Documentation in any form to any third party without the prior written consent of Cisco. Customer shall implement reasonable security measures to protect such trade secrets.\n" +
-            "\n" +
-            "To the extent required by applicable law, and at Customer's written request, Cisco shall provide Customer with the interface information needed to achieve interoperability between the Software and another independently created program, on payment of Cisco's applicable fee, if any. Customer shall observe strict obligations of confidentiality with respect to such information and shall use such information in compliance with any applicable terms and conditions upon which Cisco makes such information available.\n" +
-            "\n" +
-            "Software, Upgrades and Additional Copies. NOTWITHSTANDING ANY OTHER PROVISION OF THE AGREEMENT: (1) CUSTOMER HAS NO LICENSE OR RIGHT TO MAKE OR USE ANY ADDITIONAL COPIES OR UPGRADES UNLESS CUSTOMER, AT THE TIME OF MAKING OR ACQUIRING SUCH COPY OR UPGRADE, ALREADY HOLDS A VALID LICENSE TO THE ORIGINAL SOFTWARE AND HAS PAID THE APPLICABLE FEE TO AN APPROVED SOURCE FOR THE UPGRADE OR ADDITIONAL COPIES; (2) USE OF UPGRADES IS LIMITED TO CISCO EQUIPMENT SUPPLIED BY AN APPROVED SOURCE FOR WHICH CUSTOMER IS THE ORIGINAL END USER PURCHASER OR LESSEE OR OTHERWISE HOLDS A VALID LICENSE TO USE THE SOFTWARE WHICH IS BEING UPGRADED; AND (3) THE MAKING AND USE OF ADDITIONAL COPIES IS LIMITED TO NECESSARY BACKUP PURPOSES ONLY.\n" +
-            "\n" +
-            "Proprietary Notices. Customer agrees to maintain and reproduce all copyright, proprietary, and other notices on all copies, in any form, of the Software in the same form and manner that such copyright and other proprietary notices are included on the Software. Except as expressly authorized in the Agreement, Customer shall not make any copies or duplicates of any Software without the prior written permission of Cisco.\n" +
-            "\n" +
-            "Term and Termination. The Agreement and the license granted herein shall remain effective until terminated. Customer may terminate the Agreement and the license at any time by destroying all copies of Software and any Documentation. Customer's rights under the Agreement will terminate immediately without notice from Cisco if Customer fails to comply with any provision of the Agreement. Upon termination, Customer shall destroy all copies of Software and Documentation in its possession or control. All confidentiality obligations of Customer, all restrictions and limitations imposed on the Customer under the section titled \"General Limitations\" and all limitations of liability and disclaimers and restrictions of warranty shall survive termination of this Agreement. In addition, the provisions of the sections titled \"U.S. Government End User Purchasers\" and \"General Terms Applicable to the Limited Warranty Statement " +
-                    "and End User License Agreement\" shall survive termination of the Agreement.\n" +
-            "\n" +
-            "Customer Records. Customer grants to Cisco and its independent accountants the right to examine Customer's books, records and accounts during Customer's normal business hours to verify compliance with this Agreement. In the event such audit discloses non-compliance with this Agreement, Customer shall promptly pay to Cisco the appropriate license fees, plus the reasonable cost of conducting the audit.\n" +
-            "\n" +
-            "Export, Re-Export, Transfer and Use Controls. The Software, Documentation and technology or direct products thereof (hereafter referred to as Software and Technology), supplied by Cisco under the Agreement are subject to export controls under the laws and regulations of the United States (\"U.S.\") and any other applicable countries' laws and regulations. Customer shall comply with such laws and regulations governing export, re-export, import, transfer and use of Cisco Software and Technology and will obtain all required U.S. and local authorizations, permits, or licenses. Cisco and Customer each agree to provide the other information, support documents, and assistance as may reasonably be required by the other in connection with securing authorizations or licenses. Information regarding compliance with export, re-export, transfer and use may be located at the following URL: " +
-                    "www.cisco.com/web/about/doing_business/legal/global_export_trade/general_export/contract_compliance.html\n" +
-            "\n" +
-            "U.S. Government End User Purchasers. The Software and Documentation qualify as \"commercial items,\" as that term is defined at Federal Acquisition Regulation (\"FAR\") (48 C.F.R.) 2.101, consisting of \"commercial computer software\" and \"commercial computer software documentation\" as such terms are used in FAR 12.212. Consistent with FAR 12.212 and DoD FAR Supp. 227.7202-1 through 227.7202-4, and notwithstanding any other FAR or other contractual clause to the contrary in any agreement into which the Agreement may be incorporated, Customer may provide to Government end user or, if the Agreement is direct, Government end user will acquire, the Software and Documentation with only those rights set forth in the Agreement. Use of either the Software or Documentation or both constitutes agreement by the Government that the Software and Documentation are \"commercial computer software\" and \"commercial computer " +
-                    "software documentation,\" and constitutes acceptance of the rights and restrictions herein.\n" +
-            "\n" +
-            "Identified Components; Additional Terms. The Software may contain or be delivered with one or more components, which may include third-party components, identified by Cisco in the Documentation, readme.txt file, third-party click-accept or elsewhere (e.g. on www.cisco.com) (the \"Identified Component(s)\") as being subject to different license agreement terms, disclaimers of warranties, limited warranties or other terms and conditions (collectively, \"Additional Terms\") than those set forth herein. You agree to the applicable Additional Terms for any such Identified Component(s).\n" +
-            "\n" +
-            "Limited Warranty\n" +
-            "\n" +
-            "Subject to the limitations and conditions set forth herein, Cisco warrants that commencing from the date of shipment to Customer (but in case of resale by an Approved Source other than Cisco, commencing not more than ninety (90) days after original shipment by Cisco), and continuing for a period of the longer of (a) ninety (90) days or (b) the warranty period (if any) expressly set forth as applicable specifically to software in the warranty card accompanying the product of which the Software is a part (the \"Product\") (if any): (a) the media on which the Software is furnished will be free of defects in materials and workmanship under normal use; and (b) the Software substantially conforms to the Documentation. The date of shipment of a Product by Cisco is set forth on the packaging material in which the Product is shipped. Except for the foregoing, the Software is provided \"AS IS\". This limited warranty extends only to the " +
-                    "Software purchased from an Approved Source by a Customer who is the first registered end user. Customer's sole and exclusive remedy and the entire liability of Cisco and its suppliers under this limited warranty will be (i) replacement of defective media and/or (ii) at Cisco's option, repair, replacement, or refund of the purchase price of the Software, in both cases subject to the condition that any error or defect constituting a breach of this limited warranty is reported to the Approved Source supplying the Software to Customer, within the warranty period. Cisco or the Approved Source supplying the Software to Customer may, at its option, require return of the Software and/or Documentation as a condition to the remedy. In no event does Cisco warrant that the Software is error free or that Customer will be able to operate the Software without problems or interruptions. In addition, due to the continual development of new " +
-                    "techniques for intruding upon and attacking networks, Cisco does not warrant that the Software or any equipment, system or network on which the Software is used will be free of vulnerability to intrusion or attack.\n" +
-            "\n" +
-            "Restrictions. This warranty does not apply if the Software, Product or any other equipment upon which the Software is authorized to be used (a) has been altered, except by Cisco or its authorized representative, (b) has not been installed, operated, repaired, or maintained in accordance with instructions supplied by Cisco, (c) has been subjected to abnormal physical or electrical stress, abnormal environmental conditions, misuse, negligence, or accident; or (d) is licensed for beta, evaluation, testing or demonstration purposes. The Software warranty also does not apply to (e) any temporary Software modules; (f) any Software not posted on Cisco's Software Center; (g) any Software that Cisco expressly provides on an \"AS IS\" basis on Cisco's Software Center; (h) any Software for which an Approved Source does not receive a license fee; and (i) Software supplied by any third party which is not an Approved Source.\n" +
-            "\n" +
-            "DISCLAIMER OF WARRANTY\n" +
-            "\n" +
-            "EXCEPT AS SPECIFIED IN THIS WARRANTY SECTION, ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS, AND WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, SATISFACTORY QUALITY, NON-INTERFERENCE, ACCURACY OF INFORMATIONAL CONTENT, OR ARISING FROM A COURSE OF DEALING, LAW, USAGE, OR TRADE PRACTICE, ARE HEREBY EXCLUDED TO THE EXTENT ALLOWED BY APPLICABLE LAW AND ARE EXPRESSLY DISCLAIMED BY CISCO, ITS SUPPLIERS AND LICENSORS. TO THE EXTENT THAT ANY OF THE SAME CANNOT BE EXCLUDED, SUCH IMPLIED CONDITION, REPRESENTATION AND/OR WARRANTY IS LIMITED IN DURATION TO THE EXPRESS WARRANTY PERIOD REFERRED TO IN THE \"LIMITED WARRANTY\" SECTION ABOVE. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY LASTS, THE ABOVE LIMITATION MAY NOT APPLY IN SUCH STATES. THIS WARRANTY GIVES CUSTOMER SPECIFIC LEGAL RIGHTS, " +
-                    "AND CUSTOMER MAY ALSO HAVE OTHER RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION. This disclaimer and exclusion shall apply even if the express warranty set forth above fails of its essential purpose.\n" +
-            "\n" +
-            "Disclaimer of Liabilities-Limitation of Liability. IF YOU ACQUIRED THE SOFTWARE IN THE UNITED STATES, LATIN AMERICA, CANADA, JAPAN OR THE CARIBBEAN, NOTWITHSTANDING ANYTHING ELSE IN THE AGREEMENT TO THE CONTRARY, ALL LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS COLLECTIVELY, TO CUSTOMER, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY OR OTHERWISE, SHALL NOT EXCEED THE PRICE PAID BY CUSTOMER TO ANY APPROVED SOURCE FOR THE SOFTWARE THAT GAVE RISE TO THE CLAIM OR IF THE SOFTWARE IS PART OF ANOTHER PRODUCT, THE PRICE PAID FOR SUCH OTHER PRODUCT. THIS LIMITATION OF LIABILITY FOR SOFTWARE IS CUMULATIVE AND NOT PER INCIDENT (I.E. THE EXISTENCE OF TWO OR MORE CLAIMS WILL NOT ENLARGE THIS LIMIT).\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN EUROPE, THE MIDDLE EAST, AFRICA, ASIA OR OCEANIA, NOTWITHSTANDING ANYTHING ELSE IN THE AGREEMENT TO THE CONTRARY, ALL LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS COLLECTIVELY, TO CUSTOMER, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY OR OTHERWISE, SHALL NOT EXCEED THE PRICE PAID BY CUSTOMER TO CISCO FOR THE SOFTWARE THAT GAVE RISE TO THE CLAIM OR IF THE SOFTWARE IS PART OF ANOTHER PRODUCT, THE PRICE PAID FOR SUCH OTHER PRODUCT. THIS LIMITATION OF LIABILITY FOR SOFTWARE IS CUMULATIVE AND NOT PER INCIDENT (I.E. THE EXISTENCE OF TWO OR MORE CLAIMS WILL NOT ENLARGE THIS LIMIT). NOTHING IN THE AGREEMENT SHALL LIMIT (I) THE LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS TO CUSTOMER FOR PERSONAL INJURY OR DEATH CAUSED BY THEIR NEGLIGENCE, (II) CISCO'S LIABILITY FOR FRAUDULENT" +
-            " MISREPRESENTATION, OR (III) ANY LIABILITY OF CISCO WHICH CANNOT BE EXCLUDED UNDER APPLICABLE LAW.\n" +
-            "\n" +
-            "Disclaimer of Liabilities-Waiver of Consequential Damages and Other Losses. IF YOU ACQUIRED THE SOFTWARE IN THE UNITED STATES, LATIN AMERICA, THE CARIBBEAN OR CANADA, REGARDLESS OF WHETHER ANY REMEDY SET FORTH HEREIN FAILS OF ITS ESSENTIAL PURPOSE OR OTHERWISE, IN NO EVENT WILL CISCO OR ITS SUPPLIERS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE OR OTHERWISE AND EVEN IF CISCO OR ITS SUPPLIERS OR LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN JAPAN, EXCEPT FOR LIABILITY ARISING OUT OF OR IN CONNECTION WITH DEATH OR PERSONAL INJURY, FRAUDULENT MISREPRESENTATION, AND REGARDLESS OF WHETHER ANY REMEDY SET FORTH HEREIN FAILS OF ITS ESSENTIAL PURPOSE OR OTHERWISE, IN NO EVENT WILL CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE OR OTHERWISE AND EVEN IF CISCO OR ANY APPROVED SOURCE OR THEIR SUPPLIERS OR LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN EUROPE, THE MIDDLE EAST, AFRICA, ASIA OR OCEANIA, IN NO EVENT WILL CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS, BE LIABLE FOR ANY LOST REVENUE, LOST PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES, HOWSOEVER ARISING, INCLUDING, WITHOUT LIMITATION, IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF, IN EACH CASE, CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS, HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT FULLY APPLY TO YOU. THE FOREGOING EXCLUSION SHALL NOT APPLY TO ANY LIABILITY ARISING OUT OF OR IN " +
-            "CONNECTION WITH: (I) DEATH OR PERSONAL INJURY, (II) FRAUDULENT MISREPRESENTATION, OR (III) CISCO'S LIABILITY IN CONNECTION WITH ANY TERMS THAT CANNOT BE EXCLUDED UNDER APPLICABLE LAW.\n" +
-            "\n" +
-            "Customer acknowledges and agrees that Cisco has set its prices and entered into the Agreement in reliance upon the disclaimers of warranty and the limitations of liability set forth herein, that the same reflect an allocation of risk between the parties (including the risk that a contract remedy may fail of its essential purpose and cause consequential loss), and that the same form an essential basis of the bargain between the parties.\n" +
-            "\n" +
-            "Controlling Law, Jurisdiction. If you acquired, by reference to the address on the purchase order accepted by the Approved Source, the Software in the United States, Latin America, or the Caribbean, the Agreement and warranties (\"Warranties\") are controlled by and construed under the laws of the State of California, United States of America, notwithstanding any conflicts of law provisions; and the state and federal courts of California shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in Canada, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the Province of Ontario, Canada, notwithstanding any conflicts of law provisions; and the courts of the Province of Ontario shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in " +
-            "Europe, the Middle East, Africa, Asia or Oceania (excluding Australia), unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of England, notwithstanding any conflicts of law provisions; and the English courts shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. In addition, if the Agreement is controlled by the laws of England, no person who is not a party to the Agreement shall be entitled to enforce or take the benefit of any of its terms under the Contracts (Rights of Third Parties) Act 1999. If you acquired the Software in Japan, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of Japan, notwithstanding any conflicts of law provisions; and the Tokyo District Court of Japan shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. " +
-            "If you acquired the Software in Australia, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the State of New South Wales, Australia, notwithstanding any conflicts of law provisions; and the State and federal courts of New South Wales shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in any other country, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the State of California, United States of America, notwithstanding any conflicts of law provisions; and the state and federal courts of California shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties.\n" +
-            "\n" +
-            "For all countries referred to above, the parties specifically disclaim the application of the UN Convention on Contracts for the International Sale of Goods. Notwithstanding the foregoing, either party may seek interim injunctive relief in any court of appropriate jurisdiction with respect to any alleged breach of such party's intellectual property or proprietary rights. If any portion hereof is found to be void or unenforceable, the remaining provisions of the Agreement and Warranties shall remain in full force and effect. Except as expressly provided herein, the Agreement constitutes the entire agreement between the parties with respect to the license of the Software and Documentation and supersedes any conflicting or additional terms contained in any Purchase Order or elsewhere, all of which terms are excluded. The Agreement has been written in the English language, and the parties agree that the English version will govern.\n" +
-            "\n" +
-            "Product warranty terms and other information applicable to Cisco products are available at the following URL: www.cisco.com/go/warranty\n" +
-            "\n" +
-            "Cisco and the Cisco logo are trademarks or registered trademarks of Cisco and/or its affiliates in the U.S. and other countries. To view a list of Cisco trademarks, go to this URL: www.cisco.com/go/trademarks. Third-party trademarks mentioned are the property of their respective owners. The use of the word partner does not imply a partnership relationship between Cisco and any other company. (1110R)\n" +
-            "\n" +
-            "© 1998, 2001, 2003, 2008-2014 Cisco Systems, Inc. All rights reserved.</License>\n" +
-            "</EulaSection>\n" +
-            "<EulaSection>\n" +
-            "      <Info>supplemental end-user license agreement</Info>\n" +
-            "      <License>SUPPLEMENTAL END USER LICENSE AGREEMENT FOR VIRTUAL SOFTWARE PRODUCTS\n" +
-            "\n" +
-            "IMPORTANT: READ CAREFULLY\n" +
-            "\n" +
-            "This Supplemental End User License Agreement (\"SEULA\") contains additional terms and conditions for the Software licensed under the End User License Agreement (\"EULA\") between you and Cisco (collectively, the \"Agreement\"). Capitalized terms used in this SEULA but not defined will have the meanings assigned to them in the EULA. To the extent that there is a conflict between the terms and conditions of the EULA and this SEULA, the terms and conditions of this SEULA will take precedence. In addition to the limitations set forth in the EULA on your access and use of the Software, you agree to comply at all times with the terms and conditions provided in this SEULA.\n" +
-            "\n" +
-            "DOWNLOADING, INSTALLING, OR USING THE SOFTWARE CONSTITUTES ACCEPTANCE OF THE AGREEMENT, AND YOU ARE BINDING YOURSELF AND THE BUSINESS ENTITY THAT YOU REPRESENT (COLLECTIVELY, \"CUSTOMER\") TO THE AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THE AGREEMENT, THEN CISCO IS UNWILLING TO LICENSE THE SOFTWARE TO YOU AND (A) YOU MAY NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE, AND (B) YOU MAY RETURN THE SOFTWARE (INCLUDING ANY UNOPENED CD PACKAGE AND ANY WRITTEN MATERIALS) FOR A FULL REFUND, OR, IF THE SOFTWARE AND WRITTEN MATERIALS ARE SUPPLIED AS PART OF ANOTHER PRODUCT, YOU MAY RETURN THE ENTIRE PRODUCT FOR A FULL REFUND. YOUR RIGHT TO RETURN AND REFUND EXPIRES 30 DAYS AFTER PURCHASE FROM CISCO OR AN AUTHORIZED CISCO RESELLER, AND APPLIES ONLY IF YOU ARE THE ORIGINAL END USER PURCHASER.\n" +
-            "\n" +
-            "Definitions\n" +
-            "\"CPU\" means a central processing unit that encompasses part of a Server.\n" +
-            "\"Failover Pair\"  means a primary Instance and a standby Instance with the same Software configuration where the standby Instance can take over in case of failure of the primary Instance.\n" +
-            "\"Instance\" means a single copy of the Software. Each copy of the Software loaded into memory is an Instance.\n" +
-            "\"Server\" means a single physical computer or device on a network that manages or provides network resources for multiple users.\n" +
-            "\"Service Provider\" means a company that provides information technology services to  external end user customers.\n" +
-            "\"Software\" means Cisco's Adaptive Security Virtual Appliance (\"ASAv\"), Adaptive Security Appliance 1000V Cloud Firewall Software (\"ASA 1000V\"), Nexus 1000V series switch products, Virtual Security Gateway products, or other Cisco virtual software products that Cisco includes under this SEULA.\n" +
-            "\"vCPU\" means a virtual central processing resource assigned to the VM by the underlying virtualization technology.\n" +
-            "\"Virtual Machine\" or \"VM\" means a software container that can run its own operating system and execute applications like a Server.\n" +
-            "\n" +
-            "Additional License Terms and Conditions\n" +
-            "1. Cisco hereby grants Customer the right to install and use the Software on single or multiple Cisco or non-Cisco Servers or on Virtual Machines. In order to use the Software Customer may be required to input a registration number or product activation key and register each Instance online at Cisco's website in order to obtain the necessary entitlements.\n" +
-            "2. Customer shall pay a unit license fee to Cisco or an authorized Cisco reseller, as applicable, for each Instance installed on a Cisco or non-Cisco Server CPU, vCPU or Virtual Machine, as determined by Cisco.\n" +
-            "3. For the ASA 1000V, Customer is licensed the number of Instances equal to the number of CPUs covered by the unit license fee. If Customer deploys a Failover Pair, then the fee for the additional standby Instance is included in the fee for each primary Instance.\n" +
-            "4. If Customer is a Service Provider, Customer may use the Software under the terms of this Agreement for the purpose of delivering hosted information technology services to Customer's end user customers, subject to payment of the required license fee(s).\n" +
-            "5. Customer may also use the Software under the terms of this Agreement to deliver hosted information technology services to Customer affiliates, subject to payment of the required license fee(s).\n" +
-            "6. If the Software is subject to Cisco's Smart Licensing program, Cisco will be able to assess if Customer is using the Software within the limits and entitlements paid for by Customer. If the Smart Licensing program is applicable, Customer will be required to enter into a separate terms of service agreement relating to Smart Licensing.</License>\n" +
-            "</EulaSection>\n" +
-            "</VirtualSystem>";
-
-    private String productSectionWithCategories =
-            "<VirtualSystem ovf:id=\"VMware-vCenter-Server-Appliance\">\n" +
-            "<ProductSection ovf:required=\"false\">\n" +
-            "      <Info>Appliance ISV branding information</Info>\n" +
-            "      <Product>VMware vCenter Server Appliance</Product>\n" +
-            "      <Vendor>VMware Inc.</Vendor>\n" +
-            "      <!--\n" +
-            "            Version is the actual product version in the\n" +
-            "            form X.X.X.X where X is an unsigned 16-bit integer.\n" +
-            "\n" +
-            "            FullVersion is a descriptive version string\n" +
-            "            including, for example, alpha or beta designations\n" +
-            "            and other release criteria.\n" +
-            "        -->\n" +
-            "\n" +
-            "\n" +
-            "      <Version>6.7.0.44000</Version>\n" +
-            "      <FullVersion>6.7.0.44000 build 16046470</FullVersion>\n" +
-            "      <ProductUrl/>\n" +
-            "      <VendorUrl>http://www.vmware.com</VendorUrl>\n" +
-            "      <AppUrl>https://${vami.ip0.VMware_vCenter_Server_Appliance}:5480/</AppUrl>\n" +
-            "      <Category>Application</Category>\n" +
-            "      <Category vmw:uioptional=\"false\">Networking Configuration</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.addr.family\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network IP Address Family</Label>\n" +
-            "        <Description>Network IP address family (i.e., &apos;ipv4&apos; or &apos;ipv6&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.mode\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network Mode</Label>\n" +
-            "        <Description>Network mode (i.e., &apos;static&apos;, &apos;dhcp&apos;, or &apos;autoconf&apos; (IPv6 only).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.addr\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network IP Address</Label>\n" +
-            "        <Description>Network IP address.  Only provide this when mode is &apos;static&apos;.  Can be IPv4 or IPv6 based on specified address family.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.prefix\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network Prefix</Label>\n" +
-            "        <Description>Network prefix length.  Only provide this when mode is &apos;static&apos;.  0-32 for IPv4.  0-128 for IPv6.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.gateway\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network Default Gateway</Label>\n" +
-            "        <Description>IP address of default gateway.  Can be &apos;default&apos; when using IPv6.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.dns.servers\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network DNS Servers</Label>\n" +
-            "        <Description>Comma separated list of IP addresses of DNS servers.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.pnid\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Host Network Identity</Label>\n" +
-            "        <Description>Network identity (IP address or fully-qualified domain name) services should use when advertising themselves.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.net.ports\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"{}\">\n" +
-            "        <Label>Custom Network Ports</Label>\n" +
-            "        <Description>A string encoding a JSON object mapping port names to port numbers.</Description>\n" +
-            "      </Property>\n" +
-            "      <Category vmw:uioptional=\"false\">SSO Configuration</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.username\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"administrator@vsphere.local\">\n" +
-            "        <Label>Directory Username</Label>\n" +
-            "        <Description>For the first instance of the identity domain, this is the username with Administrator privileges. Otherwise, this is the username of the replication partner.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"true\">\n" +
-            "        <Label>Directory Password</Label>\n" +
-            "        <Description>For the first instance of the identity domain, this is the password given to the Administrator account.  Otherwise, this is the password of the Administrator account of the replication partner.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.domain-name\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"vsphere.local\">\n" +
-            "        <Label>Directory Domain Name</Label>\n" +
-            "        <Description>For the first instance of the identity domain, this is the name of the newly created domain.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.site-name\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"Default-First-Site\">\n" +
-            "        <Label>Site Name</Label>\n" +
-            "        <Description>Name of site.  Use &apos;Default-First-Site&apos; to define a new site.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.first-instance\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"True\">\n" +
-            "        <Label>New Identity Domain</Label>\n" +
-            "        <Description>If this parameter is set to True, the VMware directory instance is setup as the first instance of a new identity domain. Otherwise, the instance is setup as a replication partner.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vmdir.replication-partner-hostname\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Directory Replication Partner</Label>\n" +
-            "        <Description>The hostname of the VMware directory replication partner.  This value is ignored for the first instance of the identity domain.</Description>\n" +
-            "      </Property>\n" +
-            "      <Category vmw:uioptional=\"false\">Database Configuration</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.type\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"embedded\">\n" +
-            "        <Label>Database Type</Label>\n" +
-            "        <Description>String indicating whether the database is &apos;embedded&apos; or &apos;external&apos;.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.user\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database User</Label>\n" +
-            "        <Description>String naming the account to use when connecting to external database (ignored when db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database Password</Label>\n" +
-            "        <Description>String providing the password to use when connecting to external database (ignored when db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.servername\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database Server</Label>\n" +
-            "        <Description>String naming the the hostname of the server on which the external database is running (ignored when db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.serverport\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database Port</Label>\n" +
-            "        <Description>String describing the port on the host on which the external database is running (ignored when db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.provider\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database Provider</Label>\n" +
-            "        <Description>String describing the external database provider. The only supported value is &apos;oracle&apos; (ignored when the db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.db.instance\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Database Instance</Label>\n" +
-            "        <Description>String describing the external database instance. Values could be anything depending on what the database instance name the DBA creates in the external db. (ignored when the db.type is &apos;embedded&apos;).</Description>\n" +
-            "      </Property>\n" +
-            "      <Category vmw:uioptional=\"false\">System Configuration</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.root.passwd\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"true\">\n" +
-            "        <Label>Root Password</Label>\n" +
-            "        <Description>Password to assign to root account.  If blank, password can be set on the console.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.root.shell\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Root Shell</Label>\n" +
-            "        <Description>This property is not changeable.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.ssh.enabled\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"False\">\n" +
-            "        <Label>SSH Enabled</Label>\n" +
-            "        <Description>Set whether SSH-based remote login is enabled.  This configuration can be changed after deployment.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.time.tools-sync\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"False\">\n" +
-            "        <Label>Tools-based Time Synchronization Enabled</Label>\n" +
-            "        <Description>Set whether VMware tools based time synchronization should be used. This parameter is ignored if appliance.ntp.servers is not empty.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.appliance.ntp.servers\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>NTP Servers</Label>\n" +
-            "        <Description>A comma-seperated list of hostnames or IP addresses of NTP Servers</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.deployment.node.type\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"embedded\">\n" +
-            "        <Label>Deployment Type</Label>\n" +
-            "        <Description>Type of appliance to deploy (i.e. &apos;embedded&apos;, &apos;infrastructure&apos; or &apos;management&apos;).</Description>\n" +
-            "        <Value ovf:configuration=\"management-xlarge\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-large\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-medium\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-small\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-tiny\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-xlarge-lstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-large-lstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-medium-lstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-small-lstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-tiny-lstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-xlarge-xlstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-large-xlstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-medium-xlstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-small-xlstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"management-tiny-xlstorage\" ovf:value=\"management\"/>\n" +
-            "        <Value ovf:configuration=\"infrastructure\" ovf:value=\"infrastructure\"/>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.system.vm0.hostname\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Platform Services Controller</Label>\n" +
-            "        <Description>When deploying a vCenter Server Node, please provide the FQDN or IP address of a Platform Services Controller (leave blank otherwise).  The choice of FQDN versus IP address is decided based on the Platform Services Controller&apos;s own notion of its network identity.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.system.vm0.port\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"443\">\n" +
-            "        <Label>HTTPS Port on Platform Services Controller</Label>\n" +
-            "        <Description>When deploying a vCenter Server pointing to an external platform services controller, please provide the HTTPS port of the external platform services controller if a custom port number is being used. The default HTTPS port number is 443.</Description>\n" +
-            "      </Property>\n" +
-            "      <Category vmw:uioptional=\"true\">Upgrade Configuration</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.vpxd.ip\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Source Hostname</Label>\n" +
-            "        <Description>IP/hostname of the appliance to upgrade. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.ma.port\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"9123\">\n" +
-            "        <Label>Migration Assistant Port</Label>\n" +
-            "        <Description>Port used by Migration Assistant on source vCenter Server.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.vpxd.user\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Source vCenter Username</Label>\n" +
-            "        <Description>vCenter username for the appliance to upgrade. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.vpxd.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Source vCenter Password</Label>\n" +
-            "        <Description>vCenter password for the appliance to upgrade. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.guest.user\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Source OS Username</Label>\n" +
-            "        <Description>Username for the appliance operating system to upgrade.  Usually root. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.guest.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Source OS Password</Label>\n" +
-            "        <Description>Password for the appliance operating system to upgrade. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.guestops.host.addr\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Management Host Hostname</Label>\n" +
-            "        <Description>URL that consists of the IP address or FQDN and https port of the vCenter Server instance or ESXi host that manages the appliance to upgrade. Https port is an optional parameter which by default is 443. Example: 10.10.10.10, //10.10.10.10:444, //[2001:db8:a0b:12f0::1]:444. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.guestops.host.user\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Management Host Username</Label>\n" +
-            "        <Description>Username for the host that manages appliance to upgrade.  Can be  either vCenter or ESX host.  Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.guestops.host.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Management Host Password</Label>\n" +
-            "        <Description>Password for the host that manages appliance to upgrade.  Can be  either vCenter or ESX host.  Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.ssl.thumbprint\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Management Host Thumbprint</Label>\n" +
-            "        <Description>Thumbprint for the SSL certificate of the host that manages the appliance to upgrade. Set only for upgrade.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.platform\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"linux\">\n" +
-            "        <Label>Upgrade Source Platform</Label>\n" +
-            "        <Description>Source host platform. Optional. Set only for upgrade</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.source.export.directory\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"/var/tmp\">\n" +
-            "        <Label>Upgrade Source Export Folder</Label>\n" +
-            "        <Description>Folder on the source appliance, where to store migrate data. Optional. Set only for upgrade</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.import.directory\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"/storage/seat/cis-export-folder\">\n" +
-            "        <Label>Upgrade Destination Export Folder</Label>\n" +
-            "        <Description>Folder where exported source data will be stored in the appliance. Optional. Set only for upgrade</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.upgrade.user.options\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Upgrade Advanced Options</Label>\n" +
-            "        <Description>Advanced upgrade settings specified in json format. Optional. Set only for upgrade</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.ad.domain-name\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Active Directory domain name</Label>\n" +
-            "        <Description>Active Directory domain to join.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.ad.domain.username\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Active Directory domain admin user</Label>\n" +
-            "        <Description>Active Directory domain admin user. This username will be used to join the machine to the domain.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.ad.domain.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Active Directory domain admin user password</Label>\n" +
-            "        <Description>Active Directory domain admin user password. This password will be used to join the machine to the domain.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.management.addr\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>vCenter Server managing target appliance</Label>\n" +
-            "        <Description>FQDN or IP address of the vCenter Server managing that target appliance. Used when upgrading a source appliance in VCHA cluster.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.management.port\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"443\">\n" +
-            "        <Label>Port of the vCenter Server managing target appliance</Label>\n" +
-            "        <Description>Https port of the vCenter Server managing that target appliance. Used when upgrading a source appliance in VCHA cluster. If not specified, port 443 will be used by default.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.management.user\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Username for the vCenter Server managing target appliance</Label>\n" +
-            "        <Description>User able to authenticate in vCenter Server managing that target appliance. The user must have the privilege Global.VCServer. Used when upgrading a source appliance in VCHA cluster.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.management.password\" ovf:password=\"true\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Password for the vCenter Server managing target appliance</Label>\n" +
-            "        <Description>Password for administrator user authenticating to the vCenter Server managing target appliance. Used when upgrading a source appliance in VCHA cluster.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.management.thumbprint\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Thumbprint for the SSL certificate of the vCenter Server managing target appliance</Label>\n" +
-            "        <Description>Thumbprint for the SSL certificate of the host that manages the appliance to upgrade. Used when upgrading a source appliance in VCHA cluster.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.ha.placement\" ovf:type=\"string\" ovf:userConfigurable=\"true\" ovf:value=\"\">\n" +
-            "        <Label>Path to the compute resource where target appliance will be deployed on management vCenter Server</Label>\n" +
-            "        <Description>Path to host/cluster/resource pool where target appliance will be deployed on management vCenter Server. Used when upgrading a source appliance in VCHA cluster. Example: /my_datacenter/my_folder/my_host_or_cluster/my_resource_pool</Description>\n" +
-            "      </Property>\n" +
-            "      <Category vmw:uioptional=\"true\">Miscellaneous</Category>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.netdump.enabled\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"True\">\n" +
-            "        <Label>ESXi Dump Collector Enabled</Label>\n" +
-            "        <Description>Set whether ESXi Dump Collector service is enabled.  This configuration can be changed after deployment.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.silentinstall\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"False\">\n" +
-            "        <Label>Do Silent Install</Label>\n" +
-            "        <Description>If this parameter is set to True, no questions will be posted during install or upgrade. Otherwise, the install process will wait for a reply if there is a pending question.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.clientlocale\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"en\">\n" +
-            "        <Label>The Client Locale</Label>\n" +
-            "        <Description>This parameter specifies the client locale. Supported locales are en, fr, ja, ko, zh_CN and zh_TW. English is assumed if locale is unknown.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.feature.states\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>Feature switch states</Label>\n" +
-            "        <Description>Specify feature switch states which need to be added or modified in feature switch state config file. Format: key1=value1, key2=value2</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.ceip_enabled\" ovf:type=\"boolean\" ovf:userConfigurable=\"true\" ovf:value=\"False\">\n" +
-            "        <Label>CEIP enabled</Label>\n" +
-            "        <Description>VMware’s Customer Experience Improvement Program (&quot;CEIP&quot;) provides VMware with information that enables VMware to improve its products and services, to fix problems, and to advise you on how best to deploy and use our products. As part of the CEIP, VMware collects technical information about your organization’s use of VMware products and services on a regular basis in association with your organization’s VMware license key(s). This information does not personally identify any individual. For more details about the Program and how VMware uses the information it collects through CEIP, please see the product documentation at http://www.vmware.com/info?id=1399. If you want to participate in VMware’s CEIP for this product, set this property to True. You may join or leave VMware’s CEIP for this product at any time.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.deployment.autoconfig\" ovf:type=\"boolean\" ovf:userConfigurable=\"false\" ovf:value=\"False\">\n" +
-            "        <Label>Auto Start Services</Label>\n" +
-            "        <Description>If this parameter is set to True, the appliance will be configured after deployment using the specified OVF configuration parameters. If set to False, the appliance should be configured post-deployment using the VMware Appliance Management Interface.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.mac-allocation-scheme.prefix\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>MAC address allocation scheme prefix</Label>\n" +
-            "        <Description>If a valid MAC address prefix is provided, then all MAC addresses assigned by vCenter Server will begin with this prefix instead of the VMware OUI. This property cannot co-exist with mac-allocation-scheme.ranges</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.mac-allocation-scheme.prefix-length\" ovf:type=\"uint8\" ovf:userConfigurable=\"false\" ovf:value=\"0\">\n" +
-            "        <Label>MAC address allocation scheme prefix length</Label>\n" +
-            "        <Description>This property is mandatory whenever a custom MAC prefix is provided.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"guestinfo.cis.vpxd.mac-allocation-scheme.ranges\" ovf:type=\"string\" ovf:userConfigurable=\"false\" ovf:value=\"\">\n" +
-            "        <Label>MAC address allocation scheme ranges</Label>\n" +
-            "        <Description>If valid MAC address range is provided, then vCenter Server will assign MAC addresses from this range instead of allocating VMware OUI based MAC address. The address range must be provided in the format &quot;BeginAddress1-EndAddress1,...,BeginAddressN-EndAddressN&quot;. This property cannot co-exist with mac-allocation-scheme.prefix.</Description>\n" +
-            "      </Property>\n" +
-            "</ProductSection>\n" +
-            "<ProductSection ovf:class=\"vami\" ovf:instance=\"VMware-vCenter-Server-Appliance\" ovf:required=\"false\">\n" +
-            "      <Info>VAMI Properties</Info>\n" +
-            "      <Category>Networking Properties</Category>\n" +
-            "      <Property ovf:key=\"domain\" ovf:type=\"string\" ovf:userConfigurable=\"true\">\n" +
-            "        <Label>Domain Name</Label>\n" +
-            "        <Description>The domain name of this VM. Leave blank if DHCP is desired.</Description>\n" +
-            "      </Property>\n" +
-            "      <Property ovf:key=\"searchpath\" ovf:type=\"string\" ovf:userConfigurable=\"true\">\n" +
-            "        <Label>Domain Search Path</Label>\n" +
-            "        <Description>The domain search path (comma or space separated domain names) for this VM. Leave blank if DHCP is desired.</Description>\n" +
-            "      </Property>\n" +
-            "</ProductSection>\n" +
-            "<ProductSection ovf:class=\"vm\" ovf:required=\"false\">\n" +
-            "      <Info>VM specific properties</Info>\n" +
-            "      <Property ovf:key=\"vmname\" ovf:type=\"string\" ovf:value=\"VMware-vCenter-Server-Appliance\"/>\n" +
-            "</ProductSection>\n" +
-            "</VirtualSystem>";
-
     private OVFHelper ovfHelper = new OVFHelper();
 
     @Test
     public void testGetOVFPropertiesValidOVF() throws IOException, SAXException, ParserConfigurationException {
-        List<OVFPropertyTO> props = ovfHelper.getOVFPropertiesFromXmlString(ovfFileProductSection);
+        List<OVFPropertyTO> props = ovfHelper.getOVFPropertiesXmlString(ovfFileProductSection);
         Assert.assertEquals(2, props.size());
     }
 
     @Test(expected = SAXParseException.class)
     public void testGetOVFPropertiesInvalidOVF() throws IOException, SAXException, ParserConfigurationException {
-        ovfHelper.getOVFPropertiesFromXmlString(ovfFileProductSection + "xxxxxxxxxxxxxxxxx");
-    }
-
-    @Test
-    public void testGetOVFDeploymentOptionsValidOVF() throws IOException, SAXException, ParserConfigurationException {
-        List<OVFConfigurationTO> options = ovfHelper.getOVFDeploymentOptionsFromXmlString(ovfFileDeploymentOptionsSection);
-        Assert.assertEquals(3, options.size());
-    }
-
-    @Test
-    public void testGetOVFVirtualHardwareSectionValidOVF() throws IOException, SAXException, ParserConfigurationException {
-        List<OVFVirtualHardwareItemTO> items = ovfHelper.getOVFVirtualHardwareSectionFromXmlString(ovfFileVirtualHardwareSection);
-        Assert.assertEquals(20, items.size());
-    }
-
-    @Test
-    public void testGetOVFEulaSectionValidOVF() throws IOException, SAXException, ParserConfigurationException {
-        List<OVFEulaSectionTO> eulas = ovfHelper.getOVFEulaSectionFromXmlString(eulaSections);
-        Assert.assertEquals(2, eulas.size());
-    }
-
-    @Test
-    public void testGetOVFPropertiesWithCategories() throws IOException, SAXException, ParserConfigurationException {
-        List<OVFPropertyTO> props = ovfHelper.getOVFPropertiesFromXmlString(productSectionWithCategories);
-        Assert.assertEquals(18, props.size());
-    }
-
-    @Test
-    public void testGetOperatingSystemInfo() throws IOException, SAXException, ParserConfigurationException {
-        Pair<String, String> guestOsPair = ovfHelper.getOperatingSystemInfoFromXmlString(ovfFileVirtualHardwareSection);
-        Assert.assertEquals("other26xLinux64Guest", guestOsPair.first());
-        Assert.assertEquals("Other 2.6x Linux (64-bit)", guestOsPair.second());
-    }
-
-    @Test
-    public void testGetMinimumHardwareVersion() throws IOException, SAXException, ParserConfigurationException {
-        OVFVirtualHardwareSectionTO hardwareSection = ovfHelper.getVirtualHardwareSectionFromXmlString(ovfFileVirtualHardwareSection);
-        Assert.assertEquals("vmx-08", hardwareSection.getMinimiumHardwareVersion());
+        ovfHelper.getOVFPropertiesXmlString(ovfFileProductSection + "xxxxxxxxxxxxxxxxx");
     }
 }
diff --git a/api/src/test/java/com/cloud/storage/StorageTest.java b/api/src/test/java/com/cloud/storage/StorageTest.java
index 61909e7..332a806 100644
--- a/api/src/test/java/com/cloud/storage/StorageTest.java
+++ b/api/src/test/java/com/cloud/storage/StorageTest.java
@@ -45,7 +45,6 @@
         Assert.assertTrue(StoragePoolType.SMB.isShared());
         Assert.assertTrue(StoragePoolType.Gluster.isShared());
         Assert.assertTrue(StoragePoolType.ManagedNFS.isShared());
-        Assert.assertTrue(StoragePoolType.DatastoreCluster.isShared());
     }
 
     @Test
@@ -67,6 +66,5 @@
         Assert.assertFalse(StoragePoolType.SMB.supportsOverProvisioning());
         Assert.assertFalse(StoragePoolType.Gluster.supportsOverProvisioning());
         Assert.assertFalse(StoragePoolType.ManagedNFS.supportsOverProvisioning());
-        Assert.assertTrue(StoragePoolType.DatastoreCluster.supportsOverProvisioning());
     }
 }
diff --git a/core/pom.xml b/core/pom.xml
index d33d686..ff63e50 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -51,5 +51,9 @@
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java
index be84cce..6e6dadc 100644
--- a/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java
+++ b/core/src/main/java/com/cloud/agent/api/ModifyStoragePoolAnswer.java
@@ -19,8 +19,6 @@
 
 package com.cloud.agent.api;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Map;
 
 import com.cloud.storage.template.TemplateProp;
@@ -29,8 +27,6 @@
     private StoragePoolInfo poolInfo;
     private Map<String, TemplateProp> templateInfo;
     private String localDatastoreName;
-    private String poolType;
-    private List<ModifyStoragePoolAnswer> datastoreClusterChildren = new ArrayList<>();;
 
     public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateProp> tInfo) {
         super(cmd);
@@ -65,20 +61,4 @@
     public String getLocalDatastoreName() {
         return localDatastoreName;
     }
-
-    public String getPoolType() {
-        return poolType;
-    }
-
-    public void setPoolType(String poolType) {
-        this.poolType = poolType;
-    }
-
-    public List<ModifyStoragePoolAnswer> getDatastoreClusterChildren() {
-        return datastoreClusterChildren;
-    }
-
-    public void setDatastoreClusterChildren(List<ModifyStoragePoolAnswer> datastoreClusterChildren) {
-        this.datastoreClusterChildren = datastoreClusterChildren;
-    }
 }
diff --git a/core/src/main/java/com/cloud/agent/api/ValidateVcenterDetailsCommand.java b/core/src/main/java/com/cloud/agent/api/ValidateVcenterDetailsCommand.java
deleted file mode 100644
index d1d1393..0000000
--- a/core/src/main/java/com/cloud/agent/api/ValidateVcenterDetailsCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.agent.api;
-
-public class ValidateVcenterDetailsCommand extends Command {
-
-    String vCenterServerAddress;
-
-    public ValidateVcenterDetailsCommand(String vCenterServerAddress) {
-        this.vCenterServerAddress = vCenterServerAddress;
-    }
-
-    public String getvCenterServerAddress() {
-        return vCenterServerAddress;
-    }
-
-    public void setvCenterServerAddress(String vCenterServerAddress) {
-        this.vCenterServerAddress = vCenterServerAddress;
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-}
diff --git a/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java
index 0c63731..9859c3f 100644
--- a/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java
+++ b/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java
@@ -20,11 +20,11 @@
 package com.cloud.agent.api.storage;
 
 import java.io.File;
+import java.util.List;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.LogLevel;
-import com.cloud.agent.api.to.OVFInformationTO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 
@@ -38,9 +38,8 @@
     private long templateSize = 0L;
     private long templatePhySicalSize = 0L;
     private String checkSum;
-
     @LogLevel(LogLevel.Log4jLevel.Off)
-    private OVFInformationTO ovfInformationTO;
+    private List<OVFPropertyTO> ovfProperties;
 
     public String getCheckSum() {
         return checkSum;
@@ -151,11 +150,11 @@
         return templatePhySicalSize;
     }
 
-    public OVFInformationTO getOvfInformationTO() {
-        return ovfInformationTO;
+    public List<OVFPropertyTO> getOvfProperties() {
+        return ovfProperties;
     }
 
-    public void setOvfInformationTO(OVFInformationTO ovfInformationTO) {
-        this.ovfInformationTO = ovfInformationTO;
+    public void setOvfProperties(List<OVFPropertyTO> ovfProperties) {
+        this.ovfProperties = ovfProperties;
     }
 }
diff --git a/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java b/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java
index a6dfbfe..0e22ea2 100644
--- a/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java
+++ b/core/src/main/java/com/cloud/agent/api/storage/GetDatadisksCommand.java
@@ -21,12 +21,10 @@
 
 public final class GetDatadisksCommand extends Command {
     private DataTO data;
-    private String configurationId;
 
-    public GetDatadisksCommand(DataTO data, String configurationId) {
+    public GetDatadisksCommand(DataTO data) {
         super();
         this.data = data;
-        this.configurationId = configurationId;
     }
 
     protected GetDatadisksCommand() {
@@ -42,7 +40,4 @@
         return data;
     }
 
-    public String getConfigurationId() {
-        return configurationId;
-    }
 }
\ No newline at end of file
diff --git a/core/src/main/java/com/cloud/resource/ServerResource.java b/core/src/main/java/com/cloud/resource/ServerResource.java
index 16ac00e..9030db7 100644
--- a/core/src/main/java/com/cloud/resource/ServerResource.java
+++ b/core/src/main/java/com/cloud/resource/ServerResource.java
@@ -31,7 +31,6 @@
  * ServerResource is a generic container to execute commands sent
  */
 public interface ServerResource extends Manager {
-
     /**
      * @return Host.Type type of the computing server we have.
      */
diff --git a/core/src/main/java/com/cloud/storage/resource/StorageProcessor.java b/core/src/main/java/com/cloud/storage/resource/StorageProcessor.java
index d86a1a6..f940e22 100644
--- a/core/src/main/java/com/cloud/storage/resource/StorageProcessor.java
+++ b/core/src/main/java/com/cloud/storage/resource/StorageProcessor.java
@@ -21,7 +21,6 @@
 
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
@@ -34,9 +33,6 @@
 import com.cloud.agent.api.Answer;
 
 public interface StorageProcessor {
-
-    String REQUEST_TEMPLATE_RELOAD = "request template reload";
-
     public Answer copyTemplateToPrimaryStorage(CopyCommand cmd);
 
     public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd);
@@ -80,6 +76,4 @@
     public Answer handleDownloadTemplateToPrimaryStorage(DirectDownloadCommand cmd);
 
     Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd);
-
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd);
 }
diff --git a/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
index 910eb3d..17b9b70 100644
--- a/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
+++ b/core/src/main/java/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
@@ -21,7 +21,6 @@
 
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.storage.command.AttachCommand;
@@ -72,8 +71,6 @@
             return processor.resignature((ResignatureCommand) command);
         } else if (command instanceof DirectDownloadCommand) {
             return processor.handleDownloadTemplateToPrimaryStorage((DirectDownloadCommand) command);
-        } else if (command instanceof CheckDataStoreStoragePolicyComplainceCommand) {
-            return processor.CheckDataStoreStoragePolicyComplaince((CheckDataStoreStoragePolicyComplainceCommand) command);
         }
 
         return new Answer((Command)command, false, "not implemented yet");
diff --git a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
index 8315ff4..d771c67 100644
--- a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
+++ b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java
@@ -20,23 +20,14 @@
 package com.cloud.storage.template;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
 import javax.naming.ConfigurationException;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 
-import com.cloud.agent.api.to.OVFInformationTO;
-import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
-import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -50,13 +41,9 @@
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.script.Script;
-import org.xml.sax.SAXException;
 
-/**
- * processes the content of an OVA for registration of a template
- */
 public class OVAProcessor extends AdapterBase implements Processor {
-    private static final Logger LOGGER = Logger.getLogger(OVAProcessor.class);
+    private static final Logger s_logger = Logger.getLogger(OVAProcessor.class);
     StorageLayer _storage;
 
     @Override
@@ -66,150 +53,73 @@
 
     @Override
     public FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException {
-        if (! conversionChecks(format)){
+        if (format != null) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("We currently don't handle conversion from " + format + " to OVA.");
+            }
             return null;
         }
 
-        LOGGER.info("Template processing. templatePath: " + templatePath + ", templateName: " + templateName);
+        s_logger.info("Template processing. templatePath: " + templatePath + ", templateName: " + templateName);
         String templateFilePath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
         if (!_storage.exists(templateFilePath)) {
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("Unable to find the vmware template file: " + templateFilePath);
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Unable to find the vmware template file: " + templateFilePath);
             }
             return null;
         }
 
-        String templateFileFullPath = unpackOva(templatePath, templateName, processTimeout);
-
-        setFileSystemAccessRights(templatePath);
-
-        FormatInfo info = createFormatInfo(templatePath, templateName, templateFilePath, templateFileFullPath);
-
-        return info;
-    }
-
-    private FormatInfo createFormatInfo(String templatePath, String templateName, String templateFilePath, String templateFileFullPath) throws InternalErrorException {
-        FormatInfo info = new FormatInfo();
-        info.format = ImageFormat.OVA;
-        info.filename = templateName + "." + ImageFormat.OVA.getFileExtension();
-        info.size = _storage.getSize(templateFilePath);
-        info.virtualSize = getTemplateVirtualSize(templatePath, info.filename);
-        validateOva(templateFileFullPath, info);
-
-        return info;
-    }
-
-    /**
-     * side effect; properties are added to the info
-     *
-     * @throws InternalErrorException on an invalid ova contents
-     */
-    private void validateOva(String templateFileFullPath, FormatInfo info) throws InternalErrorException {
-        String ovfFilePath = getOVFFilePath(templateFileFullPath);
-        OVFHelper ovfHelper = new OVFHelper();
-        Document doc = ovfHelper.getDocumentFromFile(ovfFilePath);
-
-        OVFInformationTO ovfInformationTO = createOvfInformationTO(ovfHelper, doc, ovfFilePath);
-        info.ovfInformationTO = ovfInformationTO;
-    }
-
-    private OVFInformationTO createOvfInformationTO(OVFHelper ovfHelper, Document doc, String ovfFilePath) throws InternalErrorException {
-        OVFInformationTO ovfInformationTO = new OVFInformationTO();
-
-        List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfoFromFile(ovfFilePath, doc, null);
-        if (CollectionUtils.isNotEmpty(disks)) {
-            if (LOGGER.isTraceEnabled()) {
-                LOGGER.trace(String.format("Found %d disks in template %s", disks.size(), ovfFilePath));
-            }
-            ovfInformationTO.setDisks(disks);
-        }
-        List<OVFNetworkTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc);
-        if (CollectionUtils.isNotEmpty(nets)) {
-            LOGGER.info("Found " + nets.size() + " prerequisite networks");
-            ovfInformationTO.setNetworks(nets);
-        } else if (LOGGER.isTraceEnabled()) {
-            LOGGER.trace(String.format("no net prerequisites found in template %s", ovfFilePath));
-        }
-        List<OVFPropertyTO> ovfProperties = ovfHelper.getConfigurableOVFPropertiesFromDocument(doc);
-        if (CollectionUtils.isNotEmpty(ovfProperties)) {
-            LOGGER.info("Found " + ovfProperties.size() + " configurable OVF properties");
-            ovfInformationTO.setProperties(ovfProperties);
-        } else if (LOGGER.isTraceEnabled()) {
-            LOGGER.trace(String.format("no ovf properties found in template %s", ovfFilePath));
-        }
-        OVFVirtualHardwareSectionTO hardwareSection = ovfHelper.getVirtualHardwareSectionFromDocument(doc);
-        List<OVFConfigurationTO> configurations = hardwareSection.getConfigurations();
-        if (CollectionUtils.isNotEmpty(configurations)) {
-            LOGGER.info("Found " + configurations.size() + " deployment option configurations");
-        }
-        List<OVFVirtualHardwareItemTO> hardwareItems = hardwareSection.getCommonHardwareItems();
-        if (CollectionUtils.isNotEmpty(hardwareItems)) {
-            LOGGER.info("Found " + hardwareItems.size() + " virtual hardware items");
-        }
-        if (StringUtils.isNotBlank(hardwareSection.getMinimiumHardwareVersion())) {
-            LOGGER.info("Found minimum hardware version " + hardwareSection.getMinimiumHardwareVersion());
-        }
-        ovfInformationTO.setHardwareSection(hardwareSection);
-        List<OVFEulaSectionTO> eulaSections = ovfHelper.getEulaSectionsFromDocument(doc);
-        if (CollectionUtils.isNotEmpty(eulaSections)) {
-            LOGGER.info("Found " + eulaSections.size() + " license agreements");
-            ovfInformationTO.setEulaSections(eulaSections);
-        }
-        Pair<String, String> guestOsPair = ovfHelper.getOperatingSystemInfoFromDocument(doc);
-        if (guestOsPair != null) {
-            LOGGER.info("Found guest OS information: " + guestOsPair.first() + " - " + guestOsPair.second());
-            ovfInformationTO.setGuestOsInfo(guestOsPair);
-        }
-        return ovfInformationTO;
-    }
-
-    private void setFileSystemAccessRights(String templatePath) {
-        Script command;
-        String result;
-
-        command = new Script("chmod", 0, LOGGER);
-        command.add("-R");
-        command.add("666", templatePath);
-        result = command.execute();
-        if (result != null) {
-            LOGGER.warn("Unable to set permissions for files in " + templatePath + " due to " + result);
-        }
-        command = new Script("chmod", 0, LOGGER);
-        command.add("777", templatePath);
-        result = command.execute();
-        if (result != null) {
-            LOGGER.warn("Unable to set permissions for " + templatePath + " due to " + result);
-        }
-    }
-
-    private String unpackOva(String templatePath, String templateName, long processTimeout) throws InternalErrorException {
-        LOGGER.info("Template processing - untar OVA package. templatePath: " + templatePath + ", templateName: " + templateName);
+        s_logger.info("Template processing - untar OVA package. templatePath: " + templatePath + ", templateName: " + templateName);
         String templateFileFullPath = templatePath + File.separator + templateName + "." + ImageFormat.OVA.getFileExtension();
         File templateFile = new File(templateFileFullPath);
-        Script command = new Script("tar", processTimeout, LOGGER);
+        Script command = new Script("tar", processTimeout, s_logger);
         command.add("--no-same-owner");
         command.add("--no-same-permissions");
         command.add("-xf", templateFileFullPath);
         command.setWorkDir(templateFile.getParent());
         String result = command.execute();
         if (result != null) {
-            LOGGER.info("failed to untar OVA package due to " + result + ". templatePath: " + templatePath + ", templateName: " + templateName);
+            s_logger.info("failed to untar OVA package due to " + result + ". templatePath: " + templatePath + ", templateName: " + templateName);
             throw new InternalErrorException("failed to untar OVA package");
         }
-        return templateFileFullPath;
-    }
 
-    private boolean conversionChecks(ImageFormat format) {
-        if (format != null) {
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("We currently don't handle conversion from " + format + " to OVA.");
+        command = new Script("chmod", 0, s_logger);
+        command.add("-R");
+        command.add("666", templatePath);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to set permissions for files in " + templatePath + " due to " + result);
+        }
+        command = new Script("chmod", 0, s_logger);
+        command.add("777", templatePath);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to set permissions for " + templatePath + " due to " + result);
+        }
+
+        FormatInfo info = new FormatInfo();
+        info.format = ImageFormat.OVA;
+        info.filename = templateName + "." + ImageFormat.OVA.getFileExtension();
+        info.size = _storage.getSize(templateFilePath);
+        info.virtualSize = getTemplateVirtualSize(templatePath, info.filename);
+
+        //vaidate ova
+        String ovfFile = getOVFFilePath(templateFileFullPath);
+        try {
+            OVFHelper ovfHelper = new OVFHelper();
+            List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfo(ovfFile);
+            List<OVFPropertyTO> ovfProperties = ovfHelper.getOVFPropertiesFromFile(ovfFile);
+            if (CollectionUtils.isNotEmpty(ovfProperties)) {
+                s_logger.info("Found " + ovfProperties.size() + " configurable OVF properties");
+                info.ovfProperties = ovfProperties;
             }
-            return false;
+        } catch (Exception e) {
+            s_logger.info("The ovf file " + ovfFile + " is invalid ", e);
+            throw new InternalErrorException("OVA package has bad ovf file " + e.getMessage(), e);
         }
-        if (LOGGER.isTraceEnabled()) {
-            LOGGER.trace("We are handling format " + format + ".");
-        }
-        return true;
+        // delete original OVA file
+        // templateFile.delete();
+        return info;
     }
 
     @Override
@@ -218,43 +128,34 @@
             long size = getTemplateVirtualSize(file.getParent(), file.getName());
             return size;
         } catch (Exception e) {
-            LOGGER.info("[ignored]"
+            s_logger.info("[ignored]"
                     + "failed to get virtual template size for ova: " + e.getLocalizedMessage());
         }
         return file.length();
     }
 
-    /**
-     * gets the virtual size from the OVF file meta data.
-     *
-     * @return the accumulative virtual size of the disk definitions in the OVF
-     * @throws InternalErrorException
-     */
     public long getTemplateVirtualSize(String templatePath, String templateName) throws InternalErrorException {
+        // get the virtual size from the OVF file meta data
         long virtualSize = 0;
         String templateFileFullPath = templatePath.endsWith(File.separator) ? templatePath : templatePath + File.separator;
         templateFileFullPath += templateName.endsWith(ImageFormat.OVA.getFileExtension()) ? templateName : templateName + "." + ImageFormat.OVA.getFileExtension();
         String ovfFileName = getOVFFilePath(templateFileFullPath);
         if (ovfFileName == null) {
             String msg = "Unable to locate OVF file in template package directory: " + templatePath;
-            LOGGER.error(msg);
+            s_logger.error(msg);
             throw new InternalErrorException(msg);
         }
         try {
             Document ovfDoc = null;
             ovfDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(ovfFileName));
-            NodeList diskElements = ovfDoc.getElementsByTagName("Disk");
-            for (int i = 0; i < diskElements.getLength(); i++) {
-                Element disk = (Element)diskElements.item(i);
-                long diskSize = Long.parseLong(disk.getAttribute("ovf:capacity"));
-                String allocationUnits = disk.getAttribute("ovf:capacityAllocationUnits");
-                diskSize = OVFHelper.getDiskVirtualSize(diskSize, allocationUnits, ovfFileName);
-                virtualSize += diskSize;
-            }
+            Element disk = (Element)ovfDoc.getElementsByTagName("Disk").item(0);
+            virtualSize = Long.parseLong(disk.getAttribute("ovf:capacity"));
+            String allocationUnits = disk.getAttribute("ovf:capacityAllocationUnits");
+            virtualSize = OVFHelper.getDiskVirtualSize(virtualSize, allocationUnits, ovfFileName);
             return virtualSize;
-        } catch (InternalErrorException | IOException | NumberFormatException | ParserConfigurationException | SAXException e) {
+        } catch (Exception e) {
             String msg = "getTemplateVirtualSize: Unable to parse OVF XML document " + templatePath + " to get the virtual disk " + templateName + " size due to " + e;
-            LOGGER.error(msg);
+            s_logger.error(msg);
             throw new InternalErrorException(msg);
         }
     }
@@ -286,9 +187,9 @@
                 }
             }
             return new Pair<Long, Long>(virtualSize, fileSize);
-        } catch (InternalErrorException | IOException | NumberFormatException | ParserConfigurationException | SAXException e) {
+        } catch (Exception e) {
             String msg = "getDiskDetails: Unable to parse OVF XML document " + ovfFilePath + " to get the virtual disk " + diskName + " size due to " + e;
-            LOGGER.error(msg);
+            s_logger.error(msg);
             throw new InternalErrorException(msg);
         }
     }
@@ -317,4 +218,4 @@
 
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/core/src/main/java/com/cloud/storage/template/Processor.java b/core/src/main/java/com/cloud/storage/template/Processor.java
index d8c0dfb..4bb714a 100644
--- a/core/src/main/java/com/cloud/storage/template/Processor.java
+++ b/core/src/main/java/com/cloud/storage/template/Processor.java
@@ -21,8 +21,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.List;
 
-import com.cloud.agent.api.to.OVFInformationTO;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.utils.component.Adapter;
@@ -47,13 +48,13 @@
 
     FormatInfo process(String templatePath, ImageFormat format, String templateName, long processTimeout) throws InternalErrorException;
 
-    class FormatInfo {
+    public static class FormatInfo {
         public ImageFormat format;
         public long size;
         public long virtualSize;
         public String filename;
         public boolean isCorrupted;
-        public OVFInformationTO ovfInformationTO;
+        public List<OVFPropertyTO> ovfProperties;
     }
 
     long getVirtualSize(File file) throws IOException;
diff --git a/core/src/main/java/org/apache/cloudstack/storage/command/CheckDataStoreStoragePolicyComplainceCommand.java b/core/src/main/java/org/apache/cloudstack/storage/command/CheckDataStoreStoragePolicyComplainceCommand.java
deleted file mode 100644
index f9544b8..0000000
--- a/core/src/main/java/org/apache/cloudstack/storage/command/CheckDataStoreStoragePolicyComplainceCommand.java
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-
-package org.apache.cloudstack.storage.command;
-
-import com.cloud.agent.api.to.StorageFilerTO;
-
-public class CheckDataStoreStoragePolicyComplainceCommand extends StorageSubSystemCommand {
-
-    String storagePolicyId;
-    private StorageFilerTO storagePool;
-
-    public CheckDataStoreStoragePolicyComplainceCommand(String storagePolicyId, StorageFilerTO storagePool) {
-        super();
-
-        this.storagePolicyId = storagePolicyId;
-        this.storagePool = storagePool;
-    }
-
-    @Override
-    public void setExecuteInSequence(boolean inSeq) {
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-
-
-    public String getStoragePolicyId() {
-        return storagePolicyId;
-    }
-
-    public void setStoragePolicyId(String storagePolicyId) {
-        this.storagePolicyId = storagePolicyId;
-    }
-
-    public StorageFilerTO getStoragePool() {
-        return storagePool;
-    }
-
-    public void setStoragePool(StorageFilerTO storagePool) {
-        this.storagePool = storagePool;
-    }
-}
diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
index 7dab8d9..1572efe 100644
--- a/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
+++ b/core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java
@@ -39,7 +39,7 @@
     public static final String REMOVE_AFTER_COPY = PrimaryDataStore.REMOVE_AFTER_COPY;
     public static final String VOLUME_SIZE = PrimaryDataStore.VOLUME_SIZE;
 
-    private String uuid;
+    private final String uuid;
     private final String name;
     private String type;
     private final long id;
@@ -75,10 +75,6 @@
         return this.uuid;
     }
 
-    public void setUuid(String uuid) {
-        this.uuid = uuid;
-    }
-
     @Override
     public String getUrl() {
         return this.url;
diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java
index b184a74..cc2eaad 100644
--- a/core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java
+++ b/core/src/main/java/org/apache/cloudstack/storage/to/TemplateObjectTO.java
@@ -47,8 +47,6 @@
     private boolean bootable;
     private String uniqueName;
     private boolean directDownload;
-    private boolean deployAsIs;
-    private String deployAsIsConfiguration;
 
     public TemplateObjectTO() {
 
@@ -84,8 +82,6 @@
             this.imageDataStore = template.getDataStore().getTO();
         }
         this.hypervisorType = template.getHypervisorType();
-        this.deployAsIs = template.isDeployAsIs();
-        this.deployAsIsConfiguration = template.getDeployAsIsConfiguration();
     }
 
     @Override
@@ -248,18 +244,6 @@
         this.directDownload = directDownload;
     }
 
-    public boolean isDeployAsIs() {
-        return deployAsIs;
-    }
-
-    public String getDeployAsIsConfiguration() {
-        return deployAsIsConfiguration;
-    }
-
-    public void setDeployAsIsConfiguration(String deployAsIsConfiguration) {
-        this.deployAsIsConfiguration = deployAsIsConfiguration;
-    }
-
     @Override
     public String toString() {
         return new StringBuilder("TemplateTO[id=").append(id).append("|origUrl=").append(origUrl).append("|name").append(name).append("]").toString();
diff --git a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java
index 6cd27b1..e47d13e 100644
--- a/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java
+++ b/core/src/main/java/org/apache/cloudstack/storage/to/VolumeObjectTO.java
@@ -62,9 +62,6 @@
     private Hypervisor.HypervisorType hypervisorType;
     private MigrationOptions migrationOptions;
     private boolean directDownload;
-    private boolean deployAsIs;
-    private String updatedDataStoreUUID;
-    private String vSphereStoragePolicyId;
 
     public VolumeObjectTO() {
 
@@ -105,8 +102,6 @@
         setDeviceId(volume.getDeviceId());
         this.migrationOptions = volume.getMigrationOptions();
         this.directDownload = volume.isDirectDownload();
-        this.deployAsIs = volume.isDeployAsIs();
-        this.vSphereStoragePolicyId = volume.getvSphereStoragePolicyId();
     }
 
     public String getUuid() {
@@ -318,24 +313,4 @@
     public boolean isDirectDownload() {
         return directDownload;
     }
-
-    public boolean isDeployAsIs() {
-        return deployAsIs;
-    }
-
-    public String getUpdatedDataStoreUUID() {
-        return updatedDataStoreUUID;
-    }
-
-    public void setUpdatedDataStoreUUID(String updatedDataStoreUUID) {
-        this.updatedDataStoreUUID = updatedDataStoreUUID;
-    }
-
-    public String getvSphereStoragePolicyId() {
-        return vSphereStoragePolicyId;
-    }
-
-    public void setvSphereStoragePolicyId(String vSphereStoragePolicyId) {
-        this.vSphereStoragePolicyId = vSphereStoragePolicyId;
-    }
 }
diff --git a/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java b/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java
deleted file mode 100644
index ded45f8..0000000
--- a/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.agent.api.storage;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.OVFInformationTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.serializer.GsonHelper;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.google.gson.Gson;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DownloadAnswerTest {
-    Gson gson = GsonHelper.getGson();
-
-    VMTemplateStorageResourceAssoc.Status status = VMTemplateStorageResourceAssoc.Status.DOWNLOADED;
-    DownloadAnswer answer = new DownloadAnswer("nothin wrong", status);
-
-    @Test
-    public void redeserialise ()
-    {
-        String json = gson.toJson(answer);
-        DownloadAnswer received = gson.fromJson(json, DownloadAnswer.class);
-        Assert.assertEquals(received,answer);
-    }
-    @Test
-    public void properties ()
-    {
-        List<OVFPropertyTO> properties = new ArrayList<>();
-        properties.add(new OVFPropertyTO());
-        List<OVFNetworkTO> networks = new ArrayList<>();
-        networks.add(new OVFNetworkTO());
-
-        OVFInformationTO informationTO = new OVFInformationTO();
-        informationTO.setProperties(properties);
-        informationTO.setNetworks(networks);
-        answer.setOvfInformationTO(informationTO);
-
-        String json = gson.toJson(answer);
-        Answer received = gson.fromJson(json, Answer.class);
-        Assert.assertEquals(received,answer);
-    }
-}
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
index 4bdef10..edc90aa 100644
--- a/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
+++ b/core/src/test/java/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java
@@ -138,11 +138,6 @@
         public boolean isManaged() { return false; }
 
         @Override
-        public Long getParent() {
-            return 0L;
-        }
-
-        @Override
         public Long getPodId() {
             return 0L;
         }
diff --git a/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
index 8b25501..4d49c99 100644
--- a/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
+++ b/core/src/test/java/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java
@@ -177,11 +177,6 @@
             public boolean isManaged() { return false; }
 
             @Override
-            public Long getParent() {
-                return 0L;
-            }
-
-            @Override
             public Long getPodId() {
                 return 0L;
             }
diff --git a/core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java b/core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
index e134a94..576419a 100644
--- a/core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
+++ b/core/src/test/java/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java
@@ -139,11 +139,6 @@
         public boolean isManaged() { return false; }
 
         @Override
-        public Long getParent() {
-            return 0L;
-        }
-
-        @Override
         public Long getPodId() {
             return 0L;
         }
diff --git a/deps/install-non-oss.sh b/deps/install-non-oss.sh
index 01da6da..a387050 100755
--- a/deps/install-non-oss.sh
+++ b/deps/install-non-oss.sh
@@ -39,9 +39,3 @@
 
 # From https://my.vmware.com/group/vmware/details?downloadGroup=WEBCLIENTSDK67U2&productId=742
 mvn install:install-file -Dfile=vim25_67.jar        -DgroupId=com.cloud.com.vmware -DartifactId=vmware-vim25    -Dversion=6.7   -Dpackaging=jar
-
-# From https://my.vmware.com/group/vmware/get-download?downloadGroup=VS-MGMT-SDK65
-mvn install:install-file -Dfile=pbm_65.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-pbm -Dversion=6.5 -Dpackaging=jar
-
-# From https://my.vmware.com/group/vmware/details?downloadGroup=WEBCLIENTSDK67U2&productId=742
-mvn install:install-file -Dfile=pbm_67.jar -DgroupId=com.cloud.com.vmware -DartifactId=vmware-pbm -Dversion=6.7 -Dpackaging=jar
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
index 44e993f..9458de7 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/VolumeOrchestrationService.java
@@ -18,7 +18,6 @@
  */
 package org.apache.cloudstack.engine.orchestration.service;
 
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -85,8 +84,6 @@
 
     String getVmNameOnVolume(Volume volume);
 
-    StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId);
-
     VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, UserVm vm) throws StorageUnavailableException;
 
     Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException;
@@ -120,11 +117,8 @@
 
     boolean canVmRestartOnAnotherServer(long vmId);
 
-    /**
-     * Allocate a volume or multiple volumes in case of template is registered with the 'deploy-as-is' option, allowing multiple disks
-     */
-    List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
-                                               Account owner);
+    DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
+        Account owner);
 
     String getVmNameFromVolumeId(long volumeId);
 
@@ -134,7 +128,7 @@
 
     StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
 
-    void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID);
+    void updateVolumeDiskChain(long volumeId, String path, String chainInfo);
 
     /**
      * Imports an existing volume for a VM into database. Useful while ingesting an unmanaged VM.
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java
index 82c3dd1..5a18b3c 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/service/api/OrchestrationService.java
@@ -55,7 +55,7 @@
      * @param memory memory to allocate in bytes
      * @param computeTags tags for the compute
      * @param rootDiskTags tags for the root disk
-     * @param networkNicMap map networks to nic profiles that this VM should join
+     * @param networks networks that this VM should join
      * @param rootDiskSize size the root disk in case of templates.
      * @return VirtualMachineEntity
      */
@@ -65,7 +65,7 @@
         @QueryParam("host-name") String hostName, @QueryParam("display-name") String displayName, @QueryParam("hypervisor") String hypervisor,
         @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize,
         @QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
-        @QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
+        @QueryParam("network-nic-map") Map<String, NicProfile> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan,
         @QueryParam("root-disk-size") Long rootDiskSize, @QueryParam("extra-dhcp-option-map") Map<String, Map<Integer, String>> extraDhcpOptionMap,
         @QueryParam("datadisktemplate-diskoffering-map") Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap) throws InsufficientCapacityException;
 
@@ -74,7 +74,7 @@
         @QueryParam("host-name") String hostName, @QueryParam("display-name") String displayName, @QueryParam("hypervisor") String hypervisor,
         @QueryParam("os") String os, @QueryParam("cpu") int cpu, @QueryParam("speed") int speed, @QueryParam("ram") long memory, @QueryParam("disk-size") Long diskSize,
         @QueryParam("compute-tags") List<String> computeTags, @QueryParam("root-disk-tags") List<String> rootDiskTags,
-        @QueryParam("network-nic-map") Map<String, List<NicProfile>> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan, @QueryParam("extra-dhcp-option-map") Map<String,  Map<Integer, String>> extraDhcpOptionMap) throws InsufficientCapacityException;
+        @QueryParam("network-nic-map") Map<String, NicProfile> networkNicMap, @QueryParam("deploymentplan") DeploymentPlan plan, @QueryParam("extra-dhcp-option-map") Map<String,  Map<Integer, String>> extraDhcpOptionMap) throws InsufficientCapacityException;
 
     @POST
     NetworkEntity createNetwork(String id, String name, String domainName, String cidr, String gateway);
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
index 5546571..a399758 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStore.java
@@ -23,9 +23,7 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
 
 public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
-    DataObject create(DataObject dataObject, String configuration);
-
-    DataObject create(DataObject dataObject, boolean createEntryInTempSpoolRef, String configuration);
+    DataObject create(DataObject dataObject, boolean createEntryInTempSpoolRef);
 
     VolumeInfo getVolume(long id);
 
@@ -33,7 +31,7 @@
 
     boolean exists(DataObject data);
 
-    TemplateInfo getTemplate(long templateId, String configuration);
+    TemplateInfo getTemplate(long templateId);
 
     SnapshotInfo getSnapshot(long snapshotId);
 
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
index 3e072e8..7f2f4dc 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java
@@ -58,6 +58,4 @@
     Map<String, String> getDetails();
 
     PrimaryDataStoreLifeCycle getLifeCycle();
-
-    Long getParent();
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
index 46f8f5e..dfdbd8a 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
@@ -51,6 +51,4 @@
     List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
 
     static int RETURN_UPTO_ALL = -1;
-
-    List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan);
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
index 4d258f3..b213625 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java
@@ -27,7 +27,7 @@
 
     TemplateInfo getReadyTemplateOnImageStore(long templateId, Long zoneId);
 
-    TemplateInfo getTemplate(DataObject obj, DataStore store, String configuration);
+    TemplateInfo getTemplate(DataObject obj, DataStore store);
 
     TemplateInfo getTemplate(long templateId, DataStoreRole storeRole);
 
@@ -40,6 +40,4 @@
     TemplateInfo getReadyBypassedTemplateOnPrimaryStore(long templateId, Long poolId, Long hostId);
 
     boolean isTemplateMarkedForDirectDownload(long templateId);
-
-    TemplateInfo getTemplateOnPrimaryStorage(long templateId, DataStore store, String configuration);
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
index 1e4a1b7..0f7cc6f 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java
@@ -27,8 +27,4 @@
     String getInstallPath();
 
     boolean isDirectDownload();
-
-    boolean isDeployAsIs();
-
-    String getDeployAsIsConfiguration();
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
index df13f95..f70a781 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
@@ -18,7 +18,6 @@
  */
 package org.apache.cloudstack.engine.subsystem.api.storage;
 
-import com.cloud.agent.api.to.DatadiskTO;
 import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.command.CommandResult;
@@ -26,8 +25,6 @@
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.storage.StoragePool;
 
-import java.util.List;
-
 public interface TemplateService {
 
     class TemplateApiResult extends CommandResult {
@@ -50,7 +47,7 @@
 
     AsyncCallFuture<TemplateApiResult> createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store);
 
-    boolean createOvaDataDiskTemplates(TemplateInfo parentTemplate, boolean deployAsIs);
+    boolean createOvaDataDiskTemplates(TemplateInfo parentTemplate);
 
     AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(TemplateInfo template);
 
@@ -75,6 +72,4 @@
     void associateCrosszoneTemplatesToZone(long dcId);
 
     AsyncCallFuture<TemplateApiResult> createDatadiskTemplateAsync(TemplateInfo parentTemplate, TemplateInfo dataDiskTemplate, String path, String diskId, long fileSize, boolean bootable);
-
-    List<DatadiskTO> getTemplateDatadisksOnImageStore(TemplateInfo templateInfo, String configurationId);
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
index b138122..f4a7381 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java
@@ -83,10 +83,4 @@
     boolean isDirectDownload();
 
     void setDirectDownload(boolean directDownload);
-
-    boolean isDeployAsIs();
-
-    String getDeployAsIsConfiguration();
-
-    public String getvSphereStoragePolicyId();
 }
diff --git a/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
index 88d908d..5a0be95 100644
--- a/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
+++ b/engine/api/src/main/java/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
@@ -51,7 +51,7 @@
 
     void deleteExtractUrl(String installPath, String url, Upload.Type volume);
 
-    List<DatadiskTO> getDataDiskTemplates(DataObject obj, String configurationId);
+    List<DatadiskTO> getDataDiskTemplates(DataObject obj);
 
     Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, String diskId, long fileSize, boolean bootable, AsyncCompletionCallback<CreateCmdResult> callback);
 }
diff --git a/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java
index 0e24592..0f52206 100644
--- a/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java
+++ b/engine/components-api/src/main/java/com/cloud/storage/StorageManager.java
@@ -212,8 +212,6 @@
 
     boolean storagePoolHasEnoughSpaceForResize(StoragePool pool, long currentSize, long newSiz);
 
-    boolean isStoragePoolComplaintWithStoragePolicy(List<Volume> volumes, StoragePool pool) throws StorageUnavailableException;
-
     boolean registerHostListener(String providerUuid, HypervisorHostListener listener);
 
     void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException, StorageConflictException;
@@ -238,6 +236,4 @@
 
     DiskTO getDiskWithThrottling(DataTO volTO, Volume.Type volumeType, long deviceId, String path, long offeringId, long diskOfferingId);
 
-    boolean isStoragePoolDatastoreClusterParent(StoragePool pool);
-
 }
diff --git a/engine/components-api/src/main/java/com/cloud/template/TemplateManager.java b/engine/components-api/src/main/java/com/cloud/template/TemplateManager.java
index 35fed56..2dc6296 100644
--- a/engine/components-api/src/main/java/com/cloud/template/TemplateManager.java
+++ b/engine/components-api/src/main/java/com/cloud/template/TemplateManager.java
@@ -18,9 +18,7 @@
 
 import java.util.List;
 
-import com.cloud.agent.api.to.DatadiskTO;
 import com.cloud.deploy.DeployDestination;
-import com.cloud.storage.DataStoreRole;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
 import org.apache.cloudstack.framework.config.ConfigKey;
@@ -135,5 +133,4 @@
     public static final String MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT = "Message.RegisterPublicTemplate.Event";
     public static final String MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT = "Message.ResetTemplatePermission.Event";
 
-    List<DatadiskTO> getTemplateDisksOnImageStore(Long templateId, DataStoreRole role, String configurationId);
 }
diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
index 8e9ec45..14b3078 100755
--- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -40,7 +40,6 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
@@ -345,8 +344,6 @@
     private NetworkDetailsDao networkDetailsDao;
     @Inject
     private SecurityGroupManager _securityGroupManager;
-    @Inject
-    private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
 
     VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this);
 
@@ -417,8 +414,6 @@
             final LinkedHashMap<? extends Network, List<? extends NicProfile>> auxiliaryNetworks, final DeploymentPlan plan, final HypervisorType hyperType, final Map<String, Map<Integer, String>> extraDhcpOptions, final Map<Long, DiskOffering> datadiskTemplateToDiskOfferingMap)
                     throws InsufficientCapacityException {
 
-        s_logger.info(String.format("allocating virtual machine from template:%s with hostname:%s and %d networks", template.getUuid(), vmInstanceName, auxiliaryNetworks.size()));
-
         final VMInstanceVO vm = _vmDao.findVMByInstanceName(vmInstanceName);
         final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
 
@@ -460,7 +455,7 @@
                 } else if (template.getFormat() == ImageFormat.BAREMETAL) {
                     // Do nothing
                 } else {
-                    volumeMgr.allocateTemplatedVolumes(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
+                    volumeMgr.allocateTemplatedVolume(Type.ROOT, "ROOT-" + vmFinal.getId(), rootDiskOfferingInfo.getDiskOffering(), rootDiskOfferingInfo.getSize(),
                             rootDiskOfferingInfo.getMinIops(), rootDiskOfferingInfo.getMaxIops(), template, vmFinal, owner);
                 }
 
@@ -597,9 +592,6 @@
         //remove the overcommit details from the uservm details
         userVmDetailsDao.removeDetails(vm.getId());
 
-        // Remove deploy as-is (if any)
-        userVmDeployAsIsDetailsDao.removeDetails(vm.getId());
-
         // send hypervisor-dependent commands before removing
         final List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm);
         if (finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0) {
@@ -1112,9 +1104,7 @@
 
                 if (dest != null) {
                     avoids.addHost(dest.getHost().getId());
-                    if (!template.isDeployAsIs()) {
-                        journal.record("Deployment found ", vmProfile, dest);
-                    }
+                    journal.record("Deployment found ", vmProfile, dest);
                 }
 
                 long destHostId = dest.getHost().getId();
@@ -1146,7 +1136,7 @@
 
                 try {
                     resetVmNicsDeviceId(vm.getId());
-                    _networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null, dest.getStorageForDisks(), dest.isDisplayStorage()), ctx);
+                    _networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null, dest.getStorageForDisks()), ctx);
                     if (vm.getHypervisorType() != HypervisorType.BareMetal) {
                         volumeMgr.prepare(vmProfile, dest);
                     }
@@ -1478,18 +1468,14 @@
             if (disk.getType() != Volume.Type.ISO) {
                 final VolumeObjectTO vol = (VolumeObjectTO)disk.getData();
                 final VolumeVO volume = _volsDao.findById(vol.getId());
-                if (vmSpec.getDeployAsIsInfo() != null && StringUtils.isNotBlank(vol.getPath())) {
-                    volume.setPath(vol.getPath());
-                    _volsDao.update(volume.getId(), volume);
-                }
 
                 // Use getPath() from VolumeVO to get a fresh copy of what's in the DB.
                 // Before doing this, in a certain situation, getPath() from VolumeObjectTO
                 // returned null instead of an actual path (because it was out of date with the DB).
                 if(vol.getPath() != null) {
-                    volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo(), vol.getUpdatedDataStoreUUID());
+                    volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo());
                 } else {
-                    volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo(), vol.getUpdatedDataStoreUUID());
+                    volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo());
                 }
             }
         }
@@ -1672,11 +1658,9 @@
                 }
 
                 guru.finalizeStop(profile, answer);
-                if (vm.getType() == VirtualMachine.Type.User) {
-                    final UserVmVO userVm = _userVmDao.findById(vm.getId());
-                    userVm.setPowerState(PowerState.PowerOff);
-                    _userVmDao.update(userVm.getId(), userVm);
-                }
+                final UserVmVO userVm = _userVmDao.findById(vm.getId());
+                userVm.setPowerState(PowerState.PowerOff);
+                _userVmDao.update(userVm.getId(), userVm);
             } else {
                 s_logger.error("Invalid answer received in response to a StopCommand for " + vm.getInstanceName());
                 return false;
@@ -2484,7 +2468,7 @@
             throw new CloudRuntimeException("Unable to find the host to migrate from: " + srcHostId);
         }
 
-        if (fromHost.getClusterId().longValue() != dest.getCluster().getId() && vm.getHypervisorType() != HypervisorType.VMware) {
+        if (fromHost.getClusterId().longValue() != dest.getCluster().getId()) {
             final List<VolumeVO> volumes = _volsDao.findCreatedByInstance(vm.getId());
             for (final VolumeVO volume : volumes) {
                 if (!_storagePoolDao.findById(volume.getPoolId()).getScope().equals(ScopeType.ZONE)) {
@@ -2971,8 +2955,7 @@
                     final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
                     boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
                     vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
-                            vm.getUuid(), defaultNic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows,
-                            VirtualMachineManager.getHypervisorHostname(destination.getHost() != null ? destination.getHost().getName() : ""));
+                            vm.getUuid(), defaultNic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows, VirtualMachineManager.getHypervisorHostname(destination.getHost().getName()));
                     String vmName = vm.getInstanceName();
                     String configDriveIsoRootFolder = "/tmp";
                     String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso";
diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java
index 1d7deca..5bcea9a 100644
--- a/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java
+++ b/engine/orchestration/src/main/java/com/cloud/vm/VmWorkMigrate.java
@@ -64,19 +64,14 @@
 
         Map<Volume, StoragePool> vols = null;
 
-        boolean displayStorage = true;
         if (storage != null) {
             vols = new HashMap<Volume, StoragePool>(storage.size());
             for (Map.Entry<String, String> entry : storage.entrySet()) {
-                Volume volume = s_entityMgr.findByUuid(Volume.class, entry.getKey());
-                if (displayStorage && volume.isDeployAsIs()) {
-                    displayStorage = false;
-                }
-                vols.put(volume, s_entityMgr.findByUuid(StoragePool.class, entry.getValue()));
+                vols.put(s_entityMgr.findByUuid(Volume.class, entry.getKey()), s_entityMgr.findByUuid(StoragePool.class, entry.getValue()));
             }
         }
 
-        DeployDestination dest = new DeployDestination(zone, pod, cluster, host, vols, displayStorage);
+        DeployDestination dest = new DeployDestination(zone, pod, cluster, host, vols);
         return dest;
     }
 
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
index c6f8e41..91e9b6f 100644
--- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/CloudOrchestrator.java
@@ -20,6 +20,7 @@
 
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -155,7 +156,7 @@
 
     @Override
     public VirtualMachineEntity createVirtualMachine(String id, String owner, String templateId, String hostName, String displayName, String hypervisor, int cpu,
-        int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan,
+        int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, NicProfile> networkNicMap, DeploymentPlan plan,
         Long rootDiskSize, Map<String, Map<Integer, String>> extraDhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap) throws InsufficientCapacityException {
 
         // VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks,
@@ -165,7 +166,7 @@
         for (String uuid : networkNicMap.keySet()) {
             NetworkVO network = _networkDao.findByUuid(uuid);
             if(network != null){
-                networkIpMap.put(network, networkNicMap.get(uuid));
+                networkIpMap.put(network, new ArrayList<NicProfile>(Arrays.asList(networkNicMap.get(uuid))));
             }
         }
 
@@ -254,7 +255,7 @@
 
     @Override
     public VirtualMachineEntity createVirtualMachineFromScratch(String id, String owner, String isoId, String hostName, String displayName, String hypervisor, String os,
-        int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, List<NicProfile>> networkNicMap, DeploymentPlan plan, Map<String, Map<Integer, String>> extraDhcpOptionMap)
+        int cpu, int speed, long memory, Long diskSize, List<String> computeTags, List<String> rootDiskTags, Map<String, NicProfile> networkNicMap, DeploymentPlan plan, Map<String, Map<Integer, String>> extraDhcpOptionMap)
         throws InsufficientCapacityException {
 
         // VirtualMachineEntityImpl vmEntity = new VirtualMachineEntityImpl(id, owner, hostName, displayName, cpu, speed, memory, computeTags, rootDiskTags, networks, vmEntityManager);
@@ -306,7 +307,7 @@
         for (String uuid : networkNicMap.keySet()) {
             NetworkVO network = _networkDao.findByUuid(uuid);
             if(network != null){
-                networkIpMap.put(network, networkNicMap.get(uuid));
+                networkIpMap.put(network, new ArrayList<NicProfile>(Arrays.asList(networkNicMap.get(uuid))));
             }
         }
 
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 892ae2b..e12dca0 100644
--- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.engine.orchestration;
 
-import static org.apache.commons.lang.StringUtils.isNotBlank;
-
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -40,10 +38,12 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
+import com.cloud.event.EventTypes;
+import com.cloud.event.UsageEventUtils;
+import com.cloud.network.dao.NetworkDetailVO;
+import com.cloud.network.dao.NetworkDetailsDao;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.api.ApiConstants;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
 import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
@@ -88,8 +88,6 @@
 import com.cloud.deploy.DeployDestination;
 import com.cloud.deploy.DeploymentPlan;
 import com.cloud.domain.Domain;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.ConnectionException;
 import com.cloud.exception.InsufficientAddressCapacityException;
@@ -131,8 +129,6 @@
 import com.cloud.network.dao.NetworkAccountDao;
 import com.cloud.network.dao.NetworkAccountVO;
 import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkDetailVO;
-import com.cloud.network.dao.NetworkDetailsDao;
 import com.cloud.network.dao.NetworkDomainDao;
 import com.cloud.network.dao.NetworkDomainVO;
 import com.cloud.network.dao.NetworkServiceMapDao;
@@ -235,6 +231,8 @@
 import com.cloud.vm.dao.VMInstanceDao;
 import com.google.common.base.Strings;
 
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
 /**
  * NetworkManagerImpl implements NetworkManager.
  */
@@ -303,8 +301,6 @@
     VpcVirtualNetworkApplianceService _routerService;
     @Inject
     UserVmManager _userVmMgr;
-    @Inject
-    TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
 
     List<NetworkGuru> networkGurus;
 
@@ -649,8 +645,8 @@
     @Override
     @DB
     public List<? extends Network> setupNetwork(final Account owner, final NetworkOffering offering, final Network predefined, final DeploymentPlan plan, final String name,
-                                                final String displayText, final boolean errorIfAlreadySetup, final Long domainId, final ACLType aclType, final Boolean subdomainAccess, final Long vpcId,
-                                                final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException {
+            final String displayText, final boolean errorIfAlreadySetup, final Long domainId, final ACLType aclType, final Boolean subdomainAccess, final Long vpcId,
+            final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException {
 
         final Account locked = _accountDao.acquireInLockTable(owner.getId());
         if (locked == null) {
@@ -660,8 +656,8 @@
         try {
             if (predefined == null
                     || offering.getTrafficType() != TrafficType.Guest && predefined.getCidr() == null && predefined.getBroadcastUri() == null && !(predefined
-                    .getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch || predefined
-                    .getBroadcastDomainType() == BroadcastDomainType.Vxlan)) {
+                            .getBroadcastDomainType() == BroadcastDomainType.Vlan || predefined.getBroadcastDomainType() == BroadcastDomainType.Lswitch || predefined
+                            .getBroadcastDomainType() == BroadcastDomainType.Vxlan)) {
                 final List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
                 if (configs.size() > 0) {
                     if (s_logger.isDebugEnabled()) {
@@ -751,129 +747,12 @@
     @Override
     @DB
     public void allocate(final VirtualMachineProfile vm, final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks, final Map<String, Map<Integer, String>> extraDhcpOptions) throws InsufficientCapacityException,
-            ConcurrentOperationException {
+    ConcurrentOperationException {
 
         Transaction.execute(new TransactionCallbackWithExceptionNoReturn<InsufficientCapacityException>() {
             @Override
             public void doInTransactionWithoutResult(final TransactionStatus status) throws InsufficientCapacityException {
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace(String.format("allocating networks for %s(template %s); %d networks",vm.getInstanceName(), vm.getTemplate().getUuid(), networks.size()));
-                }
                 int deviceId = 0;
-                int size;
-                size = determineNumberOfNicsRequired();
-
-                final boolean[] deviceIds = new boolean[size];
-                Arrays.fill(deviceIds, false);
-
-                List<Pair<Network, NicProfile>> profilesList = getOrderedNetworkNicProfileMapping(networks);
-                final List<NicProfile> nics = new ArrayList<NicProfile>(size);
-                NicProfile defaultNic = null;
-                Network nextNetwork = null;
-                for (Pair <Network, NicProfile> networkNicPair : profilesList) {
-                    nextNetwork = networkNicPair.first();
-                    Pair<NicProfile, Integer> newDeviceInfo = addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(networkNicPair.second(), deviceIds, deviceId, nextNetwork, nics, defaultNic);
-                    defaultNic = newDeviceInfo.first();
-                    deviceId = newDeviceInfo.second();
-                }
-                createExtraNics(size, nics, nextNetwork);
-
-                if (nics.size() == 1) {
-                    nics.get(0).setDefaultNic(true);
-                }
-            }
-
-            /**
-             * private transaction method to check and add devices to the nic list and update the info
-             */
-            Pair<NicProfile,Integer> addRequestedNicToNicListWithDeviceNumberAndRetrieveDefaultDevice(NicProfile requested, boolean[] deviceIds, int deviceId, Network nextNetwork, List<NicProfile> nics, NicProfile defaultNic)
-                    throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapacityException {
-                Pair<NicProfile, Integer> rc = new Pair<>(null,null);
-                Boolean isDefaultNic = false;
-                if (vm != null && requested != null && requested.isDefaultNic()) {
-                    isDefaultNic = true;
-                }
-
-                while (deviceIds[deviceId] && deviceId < deviceIds.length) {
-                    deviceId++;
-                }
-
-                final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, nextNetwork, isDefaultNic, deviceId, vm);
-                NicProfile vmNic = null;
-                if (vmNicPair != null) {
-                    vmNic = vmNicPair.first();
-                    if (vmNic == null) {
-                        return rc;
-                    }
-                    deviceId = vmNicPair.second();
-                }
-
-                final int devId = vmNic.getDeviceId();
-                if (devId >= deviceIds.length) {
-                    throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
-                }
-                if (deviceIds[devId]) {
-                    throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
-                }
-
-                deviceIds[devId] = true;
-
-                if (vmNic.isDefaultNic()) {
-                    if (defaultNic != null) {
-                        throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
-                    }
-                    defaultNic = vmNic;
-                }
-
-                nics.add(vmNic);
-                vm.addNic(vmNic);
-                saveExtraDhcpOptions(nextNetwork.getUuid(), vmNic.getId(), extraDhcpOptions);
-                rc.first(defaultNic);
-                rc.second(deviceId);
-                return rc;
-            }
-
-            /**
-             * private transaction method to get oredered list of Network and NicProfile pair
-             * @return ordered list of Network and NicProfile pair
-             * @param networks the map od networks to nic profiles list
-             */
-            private List<Pair<Network, NicProfile>> getOrderedNetworkNicProfileMapping(final LinkedHashMap<? extends Network, List<? extends NicProfile>> networks) {
-                List<Pair<Network, NicProfile>> profilesList = new ArrayList<>();
-                for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
-                    List<? extends NicProfile> requestedProfiles = network.getValue();
-                    if (requestedProfiles == null) {
-                        requestedProfiles = new ArrayList<NicProfile>();
-                    }
-                    if (requestedProfiles.isEmpty()) {
-                        requestedProfiles.add(null);
-                    }
-                    for (final NicProfile requested : requestedProfiles) {
-                        profilesList.add(new Pair<Network, NicProfile>(network.getKey(), requested));
-                    }
-                }
-                profilesList.sort(new Comparator<Pair<Network, NicProfile>>() {
-                    @Override
-                    public int compare(Pair<Network, NicProfile> pair1, Pair<Network, NicProfile> pair2) {
-                        int profile1Order = Integer.MAX_VALUE;
-                        int profile2Order = Integer.MAX_VALUE;
-                        if (pair1 != null && pair1.second() != null && pair1.second().getOrderIndex() != null) {
-                            profile1Order = pair1.second().getOrderIndex();
-                        }
-                        if (pair2 != null && pair2.second() != null && pair2.second().getOrderIndex() != null) {
-                            profile2Order = pair2.second().getOrderIndex();
-                        }
-                        return profile1Order - profile2Order;
-                    }
-                });
-                return profilesList;
-            }
-
-            /**
-             * private transaction method to run over the objects and determine nic requirements
-             * @return the total numer of nics required
-             */
-            private int determineNumberOfNicsRequired() {
                 int size = 0;
                 for (final Network ntwk : networks.keySet()) {
                     final List<? extends NicProfile> profiles = networks.get(ntwk);
@@ -884,35 +763,71 @@
                     }
                 }
 
-                List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId());
-                if (size < netprereqs.size()) {
-                    size = netprereqs.size();
-                }
-                return size;
-            }
+                final boolean[] deviceIds = new boolean[size];
+                Arrays.fill(deviceIds, false);
 
-            /**
-             * private transaction method to add nics as required
-             * @param size the number needed
-             * @param nics the list of nics present
-             * @param finalNetwork the network to add the nics to
-             * @throws InsufficientVirtualNetworkCapacityException great
-             * @throws InsufficientAddressCapacityException also magnificent, as the name sugests
-             */
-            private void createExtraNics(int size, List<NicProfile> nics, Network finalNetwork) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException {
+                final List<NicProfile> nics = new ArrayList<NicProfile>(size);
+                NicProfile defaultNic = null;
+
+                for (final Map.Entry<? extends Network, List<? extends NicProfile>> network : networks.entrySet()) {
+                    final Network config = network.getKey();
+                    List<? extends NicProfile> requestedProfiles = network.getValue();
+                    if (requestedProfiles == null) {
+                        requestedProfiles = new ArrayList<NicProfile>();
+                    }
+                    if (requestedProfiles.isEmpty()) {
+                        requestedProfiles.add(null);
+                    }
+
+                    for (final NicProfile requested : requestedProfiles) {
+                        Boolean isDefaultNic = false;
+                        if (vm != null && requested != null && requested.isDefaultNic()) {
+                            isDefaultNic = true;
+                        }
+
+                        while (deviceIds[deviceId] && deviceId < deviceIds.length) {
+                            deviceId++;
+                        }
+
+                        final Pair<NicProfile, Integer> vmNicPair = allocateNic(requested, config, isDefaultNic, deviceId, vm);
+                        NicProfile vmNic = null;
+                        if (vmNicPair != null) {
+                            vmNic = vmNicPair.first();
+                            if (vmNic == null) {
+                                continue;
+                            }
+                            deviceId = vmNicPair.second();
+                        }
+
+                        final int devId = vmNic.getDeviceId();
+                        if (devId >= deviceIds.length) {
+                            throw new IllegalArgumentException("Device id for nic is too large: " + vmNic);
+                        }
+                        if (deviceIds[devId]) {
+                            throw new IllegalArgumentException("Conflicting device id for two different nics: " + vmNic);
+                        }
+
+                        deviceIds[devId] = true;
+
+                        if (vmNic.isDefaultNic()) {
+                            if (defaultNic != null) {
+                                throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vmNic);
+                            }
+                            defaultNic = vmNic;
+                        }
+
+                        nics.add(vmNic);
+                        vm.addNic(vmNic);
+                        saveExtraDhcpOptions(config.getUuid(), vmNic.getId(), extraDhcpOptions);
+                    }
+                }
                 if (nics.size() != size) {
                     s_logger.warn("Number of nics " + nics.size() + " doesn't match number of requested nics " + size);
-                    if (nics.size() > size) {
-                        throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
-                    } else {
-                        if (finalNetwork == null) {
-                            throw new CloudRuntimeException(String.format("can not assign network to %d remaining required NICs", size - nics.size()));
-                        }
-                        // create extra
-                        for ( int extraNicNum = nics.size() ; extraNicNum < size; extraNicNum ++) {
-                            final Pair<NicProfile, Integer> vmNicPair = allocateNic(new NicProfile(), finalNetwork, false, extraNicNum, vm);
-                        }
-                    }
+                    throw new CloudRuntimeException("Number of nics " + nics.size() + " doesn't match number of requested networks " + size);
+                }
+
+                if (nics.size() == 1) {
+                    nics.get(0).setDefaultNic(true);
                 }
             }
         });
@@ -1170,7 +1085,7 @@
     }
 
     Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context, final boolean isRouter) throws ConcurrentOperationException,
-            ResourceUnavailableException, InsufficientCapacityException {
+    ResourceUnavailableException, InsufficientCapacityException {
         Pair<NetworkGuru, NetworkVO> implemented = null;
         if (!isRouter) {
             implemented = implementNetwork(networkId, dest, context);
@@ -1190,7 +1105,7 @@
     @Override
     @DB
     public Pair<NetworkGuru, NetworkVO> implementNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException,
-            ResourceUnavailableException, InsufficientCapacityException {
+    ResourceUnavailableException, InsufficientCapacityException {
         final Pair<NetworkGuru, NetworkVO> implemented = new Pair<NetworkGuru, NetworkVO>(null, null);
 
         NetworkVO network = _networksDao.findById(networkId);
@@ -1481,7 +1396,7 @@
     }
 
     protected boolean prepareElement(final NetworkElement element, final Network network, final NicProfile profile, final VirtualMachineProfile vmProfile, final DeployDestination dest,
-                                     final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
+            final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
         element.prepare(network, profile, vmProfile, dest, context);
         if (vmProfile.getType() == Type.User && element.getProvider() != null) {
             if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dhcp)
@@ -1667,11 +1582,11 @@
                 if (element instanceof RedundantResource) {
                     resourceCount= ((RedundantResource) element).getResourceCount(network);
                     break;
+                    }
                 }
             }
-        }
         return resourceCount;
-    }
+        }
 
     @Override
     public void configureExtraDhcpOptions(Network network, long nicId, Map<Integer, String> extraDhcpOptions) {
@@ -1713,12 +1628,12 @@
                     _networkModel.getNetworkTag(vm.getHypervisorType(), network));
             for (final NetworkElement element : networkElements) {
                 if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.UserData) && element instanceof UserDataServiceProvider) {
-                    if (element instanceof ConfigDriveNetworkElement && !migrationSuccessful || element instanceof VirtualRouterElement && migrationSuccessful) {
-                        final UserDataServiceProvider sp = (UserDataServiceProvider) element;
-                        if (!sp.saveHypervisorHostname(profile, network, vm, dest)) {
-                            throw new CloudRuntimeException("Failed to Add hypervisor hostname");
+                        if (element instanceof ConfigDriveNetworkElement && !migrationSuccessful || element instanceof VirtualRouterElement && migrationSuccessful) {
+                            final UserDataServiceProvider sp = (UserDataServiceProvider) element;
+                            if (!sp.saveHypervisorHostname(profile, network, vm, dest)) {
+                                throw new CloudRuntimeException("Failed to Add hypervisor hostname");
+                            }
                         }
-                    }
                 }
             }
         }
@@ -1746,7 +1661,7 @@
 
     @Override
     public void prepare(final VirtualMachineProfile vmProfile, final DeployDestination dest, final ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException,
-            ResourceUnavailableException {
+    ResourceUnavailableException {
         final List<NicVO> nics = _nicDao.listByVmId(vmProfile.getId());
 
         // we have to implement default nics first - to ensure that default network elements start up first in multiple
@@ -2331,9 +2246,9 @@
 
     @DB
     private Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
-                                       boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
-                                       final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
-                                       final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
+                                      boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
+                                      final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
+                                      final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, Network.PVlanType isolatedPvlanType, String externalId, final Boolean isPrivateNetwork) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
 
         final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
         final DataCenterVO zone = _dcDao.findById(zoneId);
@@ -2449,12 +2364,12 @@
             URI secondaryUri = isNotBlank(isolatedPvlan) ? BroadcastDomainType.fromString(isolatedPvlan) : null;
             //don't allow to specify vlan tag used by physical network for dynamic vlan allocation
             if (!(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) && _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(uri)).size() > 0) {
-                throw new InvalidParameterValueException("The VLAN tag to use for new guest network, " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
+                throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone "
                         + zone.getName());
             }
             if (secondaryUri != null && !(bypassVlanOverlapCheck && ntwkOff.getGuestType() == GuestType.Shared) &&
                     _dcDao.findVnet(zoneId, pNtwk.getId(), BroadcastDomainType.getValue(secondaryUri)).size() > 0) {
-                throw new InvalidParameterValueException("The VLAN tag for isolated PVLAN " + isolatedPvlan + " is already being used for dynamic vlan allocation for the guest network in zone "
+                throw new InvalidParameterValueException("The VLAN tag " + isolatedPvlan + " is already being used for dynamic vlan allocation for the guest network in zone "
                         + zone.getName());
             }
             if (! UuidUtils.validateUUID(vlanId)){
@@ -2690,7 +2605,7 @@
     return bypassVlanOverlapCheck && (ntwkOff.getGuestType() != GuestType.Isolated || isPrivateNetwork);
   }
 
-    /**
+  /**
      * Checks for L2 network offering services. Only 2 cases allowed:
      * - No services
      * - User Data service only, provided by ConfigDrive
@@ -3118,7 +3033,7 @@
 
     @Override
     public boolean startNetwork(final long networkId, final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException,
-            InsufficientCapacityException {
+    InsufficientCapacityException {
 
         // Check if network exists
         final NetworkVO network = _networksDao.findById(networkId);
@@ -3141,7 +3056,7 @@
 
     @Override
     public boolean restartNetwork(final Long networkId, final Account callerAccount, final User callerUser, final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException,
-            InsufficientCapacityException {
+    InsufficientCapacityException {
         boolean status = true;
         boolean restartRequired = false;
         final NetworkVO network = _networksDao.findById(networkId);
@@ -3393,10 +3308,10 @@
         final NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
         if (networkOffering.getGuestType() == Network.GuestType.Shared
                 && (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.SourceNat)
-                || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
-                || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
-                || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
-                networkOfferingId, Service.Lb))) {
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.StaticNat)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Firewall)
+                        || _networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.PortForwarding) || _networkModel.areServicesSupportedByNetworkOffering(
+                                networkOfferingId, Service.Lb))) {
             return true;
         }
         return false;
@@ -4268,4 +4183,4 @@
                 GuestDomainSuffix, NetworkThrottlingRate, MinVRVersion,
                 PromiscuousMode, MacAddressChanges, ForgedTransmits, RollingRestartEnabled};
     }
-}
\ No newline at end of file
+}
diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index 05732e5..3e68d3a 100644
--- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -19,7 +19,6 @@
 package org.apache.cloudstack.engine.orchestration;
 
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -27,18 +26,10 @@
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ExecutionException;
-import java.util.stream.Collectors;
 
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.agent.api.to.DatadiskTO;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.dao.VMTemplateDetailsDao;
-import com.cloud.utils.StringUtils;
-import com.cloud.vm.UserVmDetailVO;
-import com.cloud.vm.VmDetailConstants;
-import com.cloud.vm.dao.UserVmDetailsDao;
 import org.apache.cloudstack.api.command.admin.vm.MigrateVMCmd;
 import org.apache.cloudstack.api.command.admin.volume.MigrateVolumeCmdByAdmin;
 import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
@@ -60,7 +51,6 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.StorageStrategyFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@@ -78,7 +68,6 @@
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.to.DataTO;
@@ -152,8 +141,6 @@
 import com.cloud.vm.dao.UserVmDao;
 import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
 
-import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
-
 public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrationService, Configurable {
 
     public enum UserVmCloneType {
@@ -210,12 +197,6 @@
     protected UserVmCloneSettingDao _vmCloneSettingDao;
     @Inject
     StorageStrategyFactory _storageStrategyFactory;
-    @Inject
-    VMTemplateDetailsDao templateDetailsDao;
-    @Inject
-    TemplateService templateService;
-    @Inject
-    UserVmDetailsDao userVmDetailsDao;
 
     private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
     protected List<StoragePoolAllocator> _storagePoolAllocators;
@@ -315,34 +296,6 @@
         return null;
     }
 
-    @Override
-    public StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId) {
-        Long podId = null;
-        if (pod != null) {
-            podId = pod.getId();
-        } else if (clusterId != null) {
-            Cluster cluster = _entityMgr.findById(Cluster.class, clusterId);
-            if (cluster != null) {
-                podId = cluster.getPodId();
-            }
-        }
-        List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(datastoreClusterId);
-        List<StoragePool> suitablePools = new ArrayList<StoragePool>();
-
-        for (StoragePoolVO childDatastore: childDatastores)
-            suitablePools.add((StoragePool)dataStoreMgr.getDataStore(childDatastore.getId(), DataStoreRole.Primary));
-
-        VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
-        for (StoragePoolAllocator allocator : _storagePoolAllocators) {
-            DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null);
-            final List<StoragePool> poolList = allocator.reorderPools(suitablePools, profile, plan);
-
-            if (poolList != null && !poolList.isEmpty()) {
-                return (StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
-            }
-        }
-        return null;
-    }
     public Pair<Pod, Long> findPod(VirtualMachineTemplate template, ServiceOffering offering, DataCenter dc, long accountId, Set<Long> avoids) {
         for (PodAllocator allocator : _podAllocators) {
             final Pair<Pod, Long> pod = allocator.allocateTo(template, offering, dc, accountId, avoids);
@@ -531,7 +484,7 @@
 
     @DB
     public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering,
-                                                 DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
+            DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) throws NoTransitionException {
 
         final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(avoids);
         DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, diskOffering);
@@ -564,7 +517,7 @@
 
     @DB
     public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering,
-                                   List<StoragePool> avoids, long size, HypervisorType hyperType) {
+            List<StoragePool> avoids, long size, HypervisorType hyperType) {
         // update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
         volume = volService.updateHypervisorSnapshotReserveForVolume(diskOffering, volume.getId(), hyperType);
 
@@ -610,7 +563,7 @@
             try {
                 VolumeApiResult result = future.get();
                 if (result.isFailed()) {
-                    if (result.getResult().contains(REQUEST_TEMPLATE_RELOAD) && (i == 0)) {
+                    if (result.getResult().contains("request template reload") && (i == 0)) {
                         s_logger.debug("Retry template re-deploy for vmware");
                         continue;
                     } else {
@@ -706,7 +659,7 @@
 
     @Override
     public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offering, Long size, Long minIops, Long maxIops, VirtualMachine vm, VirtualMachineTemplate template, Account owner,
-                                         Long deviceId) {
+            Long deviceId) {
         if (size == null) {
             size = offering.getDiskSize();
         } else {
@@ -753,23 +706,19 @@
         return toDiskProfile(vol, offering);
     }
 
-    private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
-                                                Account owner, long deviceId, String configurationId) {
+    @Override
+    public DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
+            Account owner) {
         assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
 
         Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
         if (rootDisksize != null) {
-            if (template.isDeployAsIs()) {
-                // Volume size specified from template deploy-as-is
+            rootDisksize = rootDisksize * 1024 * 1024 * 1024;
+            if (rootDisksize > size) {
+                s_logger.debug("Using root disk size of " + toHumanReadableSize(rootDisksize) + " Bytes for volume " + name);
                 size = rootDisksize;
             } else {
-                rootDisksize = rootDisksize * 1024 * 1024 * 1024;
-                if (rootDisksize > size) {
-                    s_logger.debug("Using root disk size of " + toHumanReadableSize(rootDisksize) + " Bytes for volume " + name);
-                    size = rootDisksize;
-                } else {
-                    s_logger.debug("Using root disk size of " + toHumanReadableSize(rootDisksize) + " Bytes for volume " + name + "since specified root disk size of " + rootDisksize + " Bytes is smaller than template");
-                }
+                s_logger.debug("Using root disk size of " + toHumanReadableSize(size) + " Bytes for volume " + name + "since specified root disk size of " + toHumanReadableSize(rootDisksize) + " Bytes is smaller than template");
             }
         }
 
@@ -783,9 +732,13 @@
         }
         vol.setTemplateId(template.getId());
 
-        vol.setDeviceId(deviceId);
-        if (type.equals(Type.ROOT) && !vm.getType().equals(VirtualMachine.Type.User)) {
-            vol.setRecreatable(true);
+        if (type.equals(Type.ROOT)) {
+            vol.setDeviceId(0l);
+            if (!vm.getType().equals(VirtualMachine.Type.User)) {
+                vol.setRecreatable(true);
+            }
+        } else {
+            vol.setDeviceId(1l);
         }
 
         if (vm.getType() == VirtualMachine.Type.User) {
@@ -795,11 +748,6 @@
 
         vol = _volsDao.persist(vol);
 
-        if (StringUtils.isNotBlank(configurationId)) {
-            VolumeDetailVO deployConfigurationDetail = new VolumeDetailVO(vol.getId(), VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION, configurationId, false);
-            _volDetailDao.persist(deployConfigurationDetail);
-        }
-
         // Create event and update resource count for volumes if vm is a user vm
         if (vm.getType() == VirtualMachine.Type.User) {
 
@@ -818,70 +766,6 @@
         return toDiskProfile(vol, offering);
     }
 
-    @Override
-    public List<DiskProfile> allocateTemplatedVolumes(Type type, String name, DiskOffering offering, Long rootDisksize, Long minIops, Long maxIops, VirtualMachineTemplate template, VirtualMachine vm,
-                                                      Account owner) {
-        int volumesNumber = 1;
-        List<DatadiskTO> templateAsIsDisks = null;
-        String configurationId = null;
-        if (template.isDeployAsIs()) {
-            UserVmDetailVO configurationDetail = userVmDetailsDao.findDetail(vm.getId(), VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION);
-            if (configurationDetail != null) {
-                configurationId = configurationDetail.getValue();
-            }
-            templateAsIsDisks = _tmpltMgr.getTemplateDisksOnImageStore(template.getId(), DataStoreRole.Image, configurationId);
-            if (CollectionUtils.isNotEmpty(templateAsIsDisks)) {
-                templateAsIsDisks = templateAsIsDisks.stream()
-                        .filter(x -> !x.isIso())
-                        .sorted(Comparator.comparing(DatadiskTO::getDiskNumber))
-                        .collect(Collectors.toList());
-            }
-            volumesNumber = templateAsIsDisks.size();
-        }
-
-        if (volumesNumber < 1) {
-            throw new CloudRuntimeException("Unable to create any volume from template " + template.getName());
-        }
-
-        List<DiskProfile> profiles = new ArrayList<>();
-
-        for (int number = 0; number < volumesNumber; number++) {
-            String volumeName = name;
-            Long volumeSize = rootDisksize;
-            long deviceId = type.equals(Type.ROOT) ? 0L : 1L;
-            if (template.isDeployAsIs()) {
-                int volumeNameSuffix = templateAsIsDisks.get(number).getDiskNumber();
-                volumeName = String.format("%s-%d", volumeName, volumeNameSuffix);
-                volumeSize = templateAsIsDisks.get(number).getVirtualSize();
-                deviceId = templateAsIsDisks.get(number).getDiskNumber();
-            }
-            s_logger.info(String.format("adding disk object %s to %s", volumeName, vm.getInstanceName()));
-            DiskProfile diskProfile = allocateTemplatedVolume(type, volumeName, offering, volumeSize, minIops, maxIops,
-                    template, vm, owner, deviceId, configurationId);
-            profiles.add(diskProfile);
-        }
-
-        handleRootDiskControllerTpeForDeployAsIs(templateAsIsDisks, vm);
-        return profiles;
-    }
-
-    private void handleRootDiskControllerTpeForDeployAsIs(List<DatadiskTO> disksAsIs, VirtualMachine vm) {
-        if (CollectionUtils.isNotEmpty(disksAsIs)) {
-            String diskControllerSubType = disksAsIs.get(0).getDiskControllerSubType();
-            if (StringUtils.isNotBlank(diskControllerSubType)) {
-                long vmId = vm.getId();
-                UserVmDetailVO detail = userVmDetailsDao.findDetail(vmId, VmDetailConstants.ROOT_DISK_CONTROLLER);
-                if (detail != null) {
-                    detail.setValue(diskControllerSubType);
-                    userVmDetailsDao.update(detail.getId(), detail);
-                } else {
-                    detail = new UserVmDetailVO(vmId, VmDetailConstants.ROOT_DISK_CONTROLLER, diskControllerSubType, false);
-                    userVmDetailsDao.persist(detail);
-                }
-            }
-        }
-    }
-
     private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) {
         if (hyperType == HypervisorType.XenServer) {
             return ImageFormat.VHD;
@@ -912,7 +796,7 @@
     }
 
     private VolumeInfo copyVolume(StoragePool rootDiskPool, VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate rootDiskTmplt, DataCenter dcVO, Pod pod, DiskOffering diskVO,
-                                  ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
+            ServiceOffering svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
 
         if (!isSupportedImageFormatForCluster(volume, rootDiskHyperType)) {
             throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " + volume.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type");
@@ -1257,14 +1141,8 @@
         details.put(DiskTO.MOUNT_POINT, volumeInfo.get_iScsiName());
 
         VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
-        details.put(DiskTO.PROTOCOL_TYPE, (volume.getPoolType() != null) ? volume.getPoolType().toString() : null);
 
-         if (volume.getPoolId() != null) {
-            StoragePoolVO poolVO = _storagePoolDao.findById(volume.getPoolId());
-            if (poolVO.getParent() != 0L) {
-                details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
-            }
-        }
+        details.put(DiskTO.PROTOCOL_TYPE, (volume.getPoolType() != null) ? volume.getPoolType().toString() : null);
 
         ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
 
@@ -1450,7 +1328,7 @@
             try {
                 result = future.get();
                 if (result.isFailed()) {
-                    if (result.getResult().contains(REQUEST_TEMPLATE_RELOAD) && (i == 0)) {
+                    if (result.getResult().contains("request template reload") && (i == 0)) {
                         s_logger.debug("Retry template re-deploy for vmware");
                         continue;
                     } else {
@@ -1729,7 +1607,7 @@
     }
 
     @Override
-    public void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID) {
+    public void updateVolumeDiskChain(long volumeId, String path, String chainInfo) {
         VolumeVO vol = _volsDao.findById(volumeId);
         boolean needUpdate = false;
         // Volume path is not getting updated in the DB, need to find reason and fix the issue.
@@ -1744,20 +1622,10 @@
             needUpdate = true;
         }
 
-        if (updatedDataStoreUUID != null) {
-            needUpdate = true;
-        }
-
         if (needUpdate) {
             s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
             vol.setPath(path);
             vol.setChainInfo(chainInfo);
-            if (updatedDataStoreUUID != null) {
-                StoragePoolVO pool = _storagePoolDao.findByUuid(updatedDataStoreUUID);
-                if (pool != null) {
-                    vol.setPoolId(pool.getId());
-                }
-            }
             _volsDao.update(volumeId, vol);
         }
     }
@@ -1836,4 +1704,4 @@
             }
         });
     }
-}
\ No newline at end of file
+}
diff --git a/engine/schema/src/main/java/com/cloud/dc/VsphereStoragePolicyVO.java b/engine/schema/src/main/java/com/cloud/dc/VsphereStoragePolicyVO.java
deleted file mode 100644
index 5324de6..0000000
--- a/engine/schema/src/main/java/com/cloud/dc/VsphereStoragePolicyVO.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dc;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.db.GenericDao;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-import java.util.Date;
-import java.util.UUID;
-
-@Entity
-@Table(name = "vsphere_storage_policy")
-public class VsphereStoragePolicyVO implements VsphereStoragePolicy {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "uuid")
-    private String uuid;
-
-    @Column(name = "zone_id")
-    private long zoneId;
-
-    @Column(name = "policy_id")
-    private String policyId;
-
-    @Column(name = "name")
-    private String name;
-
-    @Column(name = "description")
-    private String description;
-
-    @Column(name = "update_time", updatable = true)
-    @Temporal(value = TemporalType.TIMESTAMP)
-    private Date updateTime;
-
-    @Column(name = GenericDao.REMOVED_COLUMN)
-    private Date removed;
-
-    public VsphereStoragePolicyVO(long zoneId, String policyId, String name, String description) {
-        this.uuid = UUID.randomUUID().toString();
-        this.zoneId = zoneId;
-        this.policyId = policyId;
-        this.name = name;
-        this.description = description;
-        this.updateTime = DateUtil.currentGMTTime();
-    }
-
-    public VsphereStoragePolicyVO() {
-        uuid = UUID.randomUUID().toString();
-    }
-    public VsphereStoragePolicyVO(long id) {
-        this.id = id;
-        uuid = UUID.randomUUID().toString();
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    @Override
-    public String getUuid() {
-        return uuid;
-    }
-
-    @Override
-    public long getZoneId() {
-        return zoneId;
-    }
-
-    @Override
-    public String getPolicyId() {
-        return policyId;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public Date getUpdateTime() {
-        return updateTime;
-    }
-
-    public Date getRemoved() {
-        return removed;
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDaoImpl.java b/engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDaoImpl.java
deleted file mode 100644
index 0cdb6ad..0000000
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDaoImpl.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.dc.dao;
-
-import com.cloud.dc.VsphereStoragePolicyVO;
-import com.cloud.utils.db.GenericDaoBase;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-@Component
-public class VsphereStoragePolicyDaoImpl extends GenericDaoBase<VsphereStoragePolicyVO, Long> implements VsphereStoragePolicyDao {
-
-    protected static final Logger LOGGER = Logger.getLogger(VsphereStoragePolicyDaoImpl.class);
-
-    private final SearchBuilder<VsphereStoragePolicyVO> zoneSearch;
-    private final SearchBuilder<VsphereStoragePolicyVO> policySearch;
-
-    public VsphereStoragePolicyDaoImpl() {
-        super();
-
-        zoneSearch = createSearchBuilder();
-        zoneSearch.and("zoneId", zoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
-        zoneSearch.done();
-
-        policySearch = createSearchBuilder();
-        policySearch.and("zoneId", policySearch.entity().getZoneId(), SearchCriteria.Op.EQ);
-        policySearch.and("policyId", policySearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
-        policySearch.done();
-    }
-
-    @Override
-    public VsphereStoragePolicyVO findByPolicyId(Long zoneId, String policyId) {
-        SearchCriteria<VsphereStoragePolicyVO> sc = policySearch.create();
-        sc.setParameters("zoneId", zoneId);
-        sc.setParameters("policyId", policyId);
-        return findOneBy(sc);
-    }
-
-    @Override
-    public List<VsphereStoragePolicyVO> findByZoneId(Long zoneId) {
-        SearchCriteria<VsphereStoragePolicyVO> sc = zoneSearch.create();
-        sc.setParameters("zoneId", zoneId);
-
-        return listBy(sc);
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java b/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java
deleted file mode 100644
index 047d985..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.api.ResourceDetail;
-
-@Entity
-@Table(name = "template_deploy_as_is_details")
-public class TemplateDeployAsIsDetailVO implements ResourceDetail {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "template_id")
-    private long resourceId;
-
-    @Column(name = "name")
-    private String name;
-
-    @Lob
-    @Column(name = "value", length = 65535)
-    private String value;
-
-    public TemplateDeployAsIsDetailVO() {
-    }
-
-    public TemplateDeployAsIsDetailVO(long templateId, String name, String value) {
-        this.resourceId = templateId;
-        this.name = name;
-        this.value = value;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public long getResourceId() {
-        return resourceId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        return true;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public void setResourceId(long resourceId) {
-        this.resourceId = resourceId;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java b/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java
deleted file mode 100644
index b56b4a4..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.Table;
-
-import org.apache.cloudstack.api.ResourceDetail;
-
-@Entity
-@Table(name = "user_vm_deploy_as_is_details")
-public class UserVmDeployAsIsDetailVO implements ResourceDetail {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private long id;
-
-    @Column(name = "vm_id")
-    private long resourceId;
-
-    @Column(name = "name")
-    private String name;
-
-    @Lob
-    @Column(name = "value", length = 65535)
-    private String value;
-
-    public UserVmDeployAsIsDetailVO() {
-    }
-
-    public UserVmDeployAsIsDetailVO(long vmId, String name, String value) {
-        this.resourceId = vmId;
-        this.name = name;
-        this.value = value;
-    }
-
-    @Override
-    public long getId() {
-        return id;
-    }
-
-    public long getResourceId() {
-        return resourceId;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    @Override
-    public boolean isDisplay() {
-        return true;
-    }
-
-    public void setId(long id) {
-        this.id = id;
-    }
-
-    public void setResourceId(long resourceId) {
-        this.resourceId = resourceId;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java
deleted file mode 100644
index ebbc1ea..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis.dao;
-
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
-import com.cloud.utils.db.GenericDao;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
-
-import java.util.List;
-
-public interface TemplateDeployAsIsDetailsDao extends GenericDao<TemplateDeployAsIsDetailVO, Long>, ResourceDetailsDao<TemplateDeployAsIsDetailVO> {
-
-    OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key);
-    List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix);
-    List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId);
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java
deleted file mode 100644
index 198ef6d..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis.dao;
-
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.deployasis.DeployAsIsConstants;
-import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
-import com.cloud.utils.db.SearchCriteria;
-import com.google.gson.Gson;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
-import org.springframework.stereotype.Component;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-
-@Component
-public class TemplateDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase<TemplateDeployAsIsDetailVO> implements TemplateDeployAsIsDetailsDao {
-
-    private Gson gson = new Gson();
-
-    public TemplateDeployAsIsDetailsDaoImpl() {
-    }
-
-    @Override
-    public void addDetail(long resourceId, String key, String value, boolean display) {
-        super.addDetail(new TemplateDeployAsIsDetailVO(resourceId, key, value));
-    }
-
-    @Override
-    public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) {
-        SearchCriteria<TemplateDeployAsIsDetailVO> sc = createSearchCriteria();
-        sc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId);
-        sc.addAnd("name", SearchCriteria.Op.EQ, key.startsWith(DeployAsIsConstants.PROPERTY_PREFIX) ? key : DeployAsIsConstants.PROPERTY_PREFIX + key);
-        OVFPropertyTO property = null;
-        TemplateDeployAsIsDetailVO detail = findOneBy(sc);
-        if (detail != null) {
-            property = gson.fromJson(detail.getValue(), OVFPropertyTO.class);
-        }
-        return property;
-    }
-
-    @Override
-    public List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) {
-        SearchCriteria<TemplateDeployAsIsDetailVO> ssc = createSearchCriteria();
-        ssc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId);
-        ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%");
-
-        return search(ssc, null);
-    }
-
-    @Override
-    public List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId) {
-        List<TemplateDeployAsIsDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.NETWORK_PREFIX);
-        List<OVFNetworkTO> networkPrereqs = new ArrayList<>();
-        for (TemplateDeployAsIsDetailVO property : networkDetails) {
-            OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class);
-            networkPrereqs.add(ovfPropertyTO);
-        }
-        networkPrereqs.sort(new Comparator<OVFNetworkTO>() {
-            @Override
-            public int compare(OVFNetworkTO o1, OVFNetworkTO o2) {
-                return o1.getInstanceID() - o2.getInstanceID();
-            }
-        });
-        return networkPrereqs;
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java
deleted file mode 100644
index 4366e46..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis.dao;
-
-import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
-import com.cloud.utils.db.GenericDao;
-import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
-
-public interface UserVmDeployAsIsDetailsDao extends GenericDao<UserVmDeployAsIsDetailVO, Long>, ResourceDetailsDao<UserVmDeployAsIsDetailVO> {
-}
diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java
deleted file mode 100644
index 8dc5f4a..0000000
--- a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.deployasis.dao;
-
-import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
-import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
-import org.springframework.stereotype.Component;
-
-@Component
-public class UserVmDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase<UserVmDeployAsIsDetailVO> implements UserVmDeployAsIsDetailsDao {
-
-    @Override
-    public void addDetail(long resourceId, String key, String value, boolean display) {
-        super.addDetail(new UserVmDeployAsIsDetailVO(resourceId, key, value));
-    }
-}
diff --git a/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java
index 10ba8d5..f905ab9 100644
--- a/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java
+++ b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDao.java
@@ -26,5 +26,4 @@
 public interface ServiceOfferingDetailsDao extends GenericDao<ServiceOfferingDetailsVO, Long>, ResourceDetailsDao<ServiceOfferingDetailsVO> {
     List<Long> findDomainIds(final long resourceId);
     List<Long> findZoneIds(final long resourceId);
-    String getDetail(Long diskOfferingId, String key);
 }
\ No newline at end of file
diff --git a/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
index 0080174..7684026 100644
--- a/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/service/dao/ServiceOfferingDetailsDaoImpl.java
@@ -58,13 +58,4 @@
         return zoneIds;
     }
 
-    @Override
-    public String getDetail(Long serviceOfferingId, String key) {
-        String detailValue = null;
-        ServiceOfferingDetailsVO serviceOfferingDetail = findDetail(serviceOfferingId, key);
-        if (serviceOfferingDetail != null) {
-            detailValue = serviceOfferingDetail.getValue();
-        }
-        return detailValue;
-    }
 }
diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java b/engine/schema/src/main/java/com/cloud/storage/TemplateOVFPropertyVO.java
similarity index 60%
copy from api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java
copy to engine/schema/src/main/java/com/cloud/storage/TemplateOVFPropertyVO.java
index 32c6255..425b1f2 100644
--- a/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java
+++ b/engine/schema/src/main/java/com/cloud/storage/TemplateOVFPropertyVO.java
@@ -1,4 +1,3 @@
-//
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -15,40 +14,60 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-//
 
-package com.cloud.agent.api.to.deployasis;
+package com.cloud.storage;
 
-import com.cloud.agent.api.LogLevel;
+import com.cloud.agent.api.storage.OVFProperty;
 
-/**
- * Used to represent travel objects like:
- * <Property ovf:key="RouteDefault" ovf:type="string" ovf:qualifiers="ValueMap{&quot;Default Route&quot;,&quot;Remote HTTP and SSH Client Routes&quot;}" ovf:value="Default Route" ovf:userConfigurable="true">
- *         <Label>Select Route Type</Label>
- *         <Description>Select the route/gateway type.
- * Choose "Default Route" to route all traffic through the Management gateway. Use this option when enabling Smart Licensing registration at initial deployment.
- * Choose "Remote HTTP and SSH Client Routes" to route only traffic destined for the management client(s), when they are on remote networks.</Description>
- *       </Property>
- */
-public class OVFPropertyTO implements TemplateDeployAsIsInformationTO {
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
 
+@Entity
+@Table(name = "template_ovf_properties")
+public class TemplateOVFPropertyVO implements OVFProperty {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    private long id;
+
+    @Column(name = "template_id")
+    private Long templateId;
+
+    @Column(name = "key")
     private String key;
-    private String type;
-    @LogLevel(LogLevel.Log4jLevel.Off)
-    private String value;
-    private String qualifiers;
-    private Boolean userConfigurable;
-    private String label;
-    private String description;
-    private Boolean password;
-    private int index;
-    private String category;
 
-    public OVFPropertyTO() {
+    @Column(name = "type")
+    private String type;
+
+    @Column(name = "value")
+    private String value;
+
+    @Column(name = "qualifiers")
+    private String qualifiers;
+
+    @Column(name = "password")
+    private Boolean password;
+
+    @Column(name = "user_configurable")
+    private Boolean userConfigurable;
+
+    @Column(name = "label")
+    private String label;
+
+    @Column(name = "description")
+    private String description;
+
+    public TemplateOVFPropertyVO() {
     }
 
-    public OVFPropertyTO(String key, String type, String value, String qualifiers, boolean userConfigurable,
-                       String label, String description, boolean password, int index, String category) {
+    public TemplateOVFPropertyVO(Long templateId, String key, String type, String value, String qualifiers,
+                                 Boolean userConfigurable, String label, String description, Boolean password) {
+        this.templateId = templateId;
         this.key = key;
         this.type = type;
         this.value = value;
@@ -57,12 +76,22 @@
         this.label = label;
         this.description = description;
         this.password = password;
-        this.index = index;
-        this.category = category;
+    }
+
+    public long getId() {
+        return id;
+    }
+
+    public void setId(long id) {
+        this.id = id;
     }
 
     public Long getTemplateId() {
-        return null;
+        return templateId;
+    }
+
+    public void setTemplateId(Long templateId) {
+        this.templateId = templateId;
     }
 
     public String getKey() {
@@ -97,6 +126,7 @@
         this.qualifiers = qualifiers;
     }
 
+    @Override
     public Boolean isUserConfigurable() {
         return userConfigurable;
     }
@@ -129,11 +159,9 @@
         this.password = password;
     }
 
-    public String getCategory() {
-        return category;
-    }
-
-    public int getIndex() {
-        return index;
+    @Override
+    public String toString() {
+        return String.format("PROP - templateId=%s> key=%s value=%s type=%s qual=%s conf=%s label=%s desc=%s password=%s",
+                templateId, key, value, type, qualifiers, userConfigurable, label, description, password);
     }
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java
index 69c9c85..6dfe6eb 100644
--- a/engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java
+++ b/engine/schema/src/main/java/com/cloud/storage/VMTemplateStoragePoolVO.java
@@ -95,9 +95,6 @@
     @Enumerated(EnumType.STRING)
     ObjectInDataStoreStateMachine.State state;
 
-    @Column(name = "deployment_option")
-    private String deploymentOption;
-
     @Override
     public String getInstallPath() {
         return installPath;
@@ -171,18 +168,17 @@
         return downloadState;
     }
 
-    public VMTemplateStoragePoolVO(long poolId, long templateId, String configuration) {
+    public VMTemplateStoragePoolVO(long poolId, long templateId) {
         super();
         this.poolId = poolId;
         this.templateId = templateId;
         this.downloadState = Status.NOT_DOWNLOADED;
         this.state = ObjectInDataStoreStateMachine.State.Allocated;
         this.markedForGC = false;
-        this.deploymentOption = configuration;
     }
 
     public VMTemplateStoragePoolVO(long poolId, long templateId, Date lastUpdated, int downloadPercent, Status downloadState, String localDownloadPath,
-            String errorString, String jobId, String installPath, long templateSize, String configuration) {
+            String errorString, String jobId, String installPath, long templateSize) {
         super();
         this.poolId = poolId;
         this.templateId = templateId;
@@ -194,7 +190,6 @@
         this.jobId = jobId;
         this.installPath = installPath;
         this.templateSize = templateSize;
-        this.deploymentOption = configuration;
     }
 
     protected VMTemplateStoragePoolVO() {
@@ -305,11 +300,4 @@
         return this.state;
     }
 
-    public String getDeploymentOption() {
-        return deploymentOption;
-    }
-
-    public void setDeploymentOption(String deploymentOption) {
-        this.deploymentOption = deploymentOption;
-    }
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java
index 61df40e..af04099 100644
--- a/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java
+++ b/engine/schema/src/main/java/com/cloud/storage/VMTemplateVO.java
@@ -152,9 +152,6 @@
     @Column(name = "parent_template_id")
     private Long parentTemplateId;
 
-    @Column(name = "deploy_as_is")
-    private boolean deployAsIs;
-
     @Override
     public String getUniqueName() {
         return uniqueName;
@@ -195,9 +192,9 @@
         uuid = UUID.randomUUID().toString();
     }
 
-    public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url, boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
-                        HypervisorType hyperType, String templateTag, Map<String, String> details, boolean sshKeyEnabled, boolean isDynamicallyScalable, boolean directDownload,
-                        boolean deployAsIs) {
+    public VMTemplateVO(long id, String name, ImageFormat format, boolean isPublic, boolean featured, boolean isExtractable, TemplateType type, String url,
+            boolean requiresHvm, int bits, long accountId, String cksum, String displayText, boolean enablePassword, long guestOSId, boolean bootable,
+            HypervisorType hyperType, String templateTag, Map<String, String> details, boolean sshKeyEnabled, boolean isDynamicallyScalable, boolean directDownload) {
         this(id,
             name,
             format,
@@ -222,7 +219,6 @@
         dynamicallyScalable = isDynamicallyScalable;
         state = State.Active;
         this.directDownload = directDownload;
-        this.deployAsIs = deployAsIs;
     }
 
     public static VMTemplateVO createPreHostIso(Long id, String uniqueName, String name, ImageFormat format, boolean isPublic, boolean featured, TemplateType type,
@@ -641,11 +637,4 @@
         this.parentTemplateId = parentTemplateId;
     }
 
-    @Override public boolean isDeployAsIs() {
-        return deployAsIs;
-    }
-
-    public void setDeployAsIs(boolean deployAsIs) {
-        this.deployAsIs = deployAsIs;
-    }
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/VolumeVO.java b/engine/schema/src/main/java/com/cloud/storage/VolumeVO.java
index b766483..d8323e9 100644
--- a/engine/schema/src/main/java/com/cloud/storage/VolumeVO.java
+++ b/engine/schema/src/main/java/com/cloud/storage/VolumeVO.java
@@ -166,9 +166,6 @@
     @Column(name = "hv_ss_reserve")
     private Integer hypervisorSnapshotReserve;
 
-    @Transient
-    private boolean deployAsIs;
-
     // Real Constructor
     public VolumeVO(Type type, String name, long dcId, long domainId,
             long accountId, long diskOfferingId, Storage.ProvisioningType provisioningType, long size,
@@ -264,7 +261,6 @@
         format = that.getFormat();
         provisioningType = that.getProvisioningType();
         uuid = UUID.randomUUID().toString();
-        deployAsIs = that.isDeployAsIs();
     }
 
     @Override
@@ -576,11 +572,6 @@
         return displayVolume;
     }
 
-    @Override
-    public boolean isDeployAsIs() {
-        return deployAsIs;
-    }
-
     public void setDisplay(boolean display){
         this.displayVolume = display;
     }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java
index d98ef23..61fec36 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDao.java
@@ -21,5 +21,4 @@
 
 public interface GuestOSCategoryDao extends GenericDao<GuestOSCategoryVO, Long> {
 
-    GuestOSCategoryVO findByCategoryName(String categoryName);
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
index 6fad6c5..8ffb54a 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java
@@ -16,8 +16,7 @@
 // under the License.
 package com.cloud.storage.dao;
 
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria;
+
 import org.springframework.stereotype.Component;
 
 import com.cloud.storage.GuestOSCategoryVO;
@@ -30,10 +29,4 @@
 
     }
 
-    @Override
-    public GuestOSCategoryVO findByCategoryName(String categoryName) {
-        final QueryBuilder<GuestOSCategoryVO> sc = QueryBuilder.create(GuestOSCategoryVO.class);
-        sc.and(sc.entity().getName(), SearchCriteria.Op.EQ, categoryName);
-        return sc.find();
-    }
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
index 41b9571..cd00703 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDao.java
@@ -20,8 +20,6 @@
 import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.utils.db.GenericDao;
 
-import java.util.List;
-
 public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Long> {
 
     HypervisorType findHypervisorTypeByGuestOsId(long guestOsId);
@@ -33,9 +31,4 @@
     GuestOSHypervisorVO findByOsIdAndHypervisorAndUserDefined(long guestOsId, String hypervisorType, String hypervisorVersion, boolean isUserDefined);
 
     GuestOSHypervisorVO findByOsNameAndHypervisor(String guestOsName, String hypervisorType, String hypervisorVersion);
-
-    List<GuestOSHypervisorVO> listByOsNameAndHypervisorMinimumVersion(String guestOsName, String hypervisorType,
-                                                                      String minHypervisorVersion);
-
-    List<String> listHypervisorSupportedVersionsFromMinimumVersion(String hypervisorType, String hypervisorVersion);
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
index add4bfc..699ce0b 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
@@ -16,11 +16,9 @@
 // under the License.
 package com.cloud.storage.dao;
 
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-import com.cloud.utils.db.QueryBuilder;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.stereotype.Component;
 
@@ -38,7 +36,6 @@
     protected final SearchBuilder<GuestOSHypervisorVO> mappingSearch;
     protected final SearchBuilder<GuestOSHypervisorVO> userDefinedMappingSearch;
     protected final SearchBuilder<GuestOSHypervisorVO> guestOsNameSearch;
-    protected final SearchBuilder<GuestOSHypervisorVO> availableHypervisorVersionSearch;
 
     protected GuestOSHypervisorDaoImpl() {
         guestOsSearch = createSearchBuilder();
@@ -63,15 +60,6 @@
         guestOsNameSearch.and("hypervisor_type", guestOsNameSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
         guestOsNameSearch.and("hypervisor_version", guestOsNameSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
         guestOsNameSearch.done();
-
-        availableHypervisorVersionSearch = createSearchBuilder();
-        availableHypervisorVersionSearch.and("hypervisor_type",
-                availableHypervisorVersionSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
-        availableHypervisorVersionSearch.and("hypervisor_version",
-                availableHypervisorVersionSearch.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ);
-        availableHypervisorVersionSearch.select(null, SearchCriteria.Func.DISTINCT,
-                availableHypervisorVersionSearch.entity().getHypervisorVersion());
-        availableHypervisorVersionSearch.done();
     }
 
     @Override
@@ -133,29 +121,4 @@
         return CollectionUtils.isNotEmpty(results) ? results.get(0) : null;
     }
 
-    @Override
-    public List<GuestOSHypervisorVO> listByOsNameAndHypervisorMinimumVersion(String guestOsName, String hypervisorType,
-                                                                             String minHypervisorVersion) {
-        final QueryBuilder<GuestOSHypervisorVO> sc = QueryBuilder.create(GuestOSHypervisorVO.class);
-        sc.and(sc.entity().getGuestOsName(), SearchCriteria.Op.EQ, guestOsName);
-        sc.and(sc.entity().getHypervisorType(), SearchCriteria.Op.EQ, hypervisorType);
-        sc.and(sc.entity().getHypervisorVersion(), SearchCriteria.Op.GTEQ, minHypervisorVersion);
-        sc.and(sc.entity().getHypervisorVersion(), SearchCriteria.Op.NEQ, "default");
-        return sc.list();
-    }
-
-    @Override
-    public List<String> listHypervisorSupportedVersionsFromMinimumVersion(String hypervisorType, String hypervisorVersion) {
-        List<String> versions = new ArrayList<>();
-        SearchCriteria<GuestOSHypervisorVO> sc = availableHypervisorVersionSearch.create();
-        sc.setParameters("hypervisor_type", hypervisorType);
-        sc.setParameters("hypervisor_version", hypervisorVersion);
-        Filter filter = new Filter(GuestOSHypervisorVO.class, "hypervisorVersion", true, null, null);
-        List<GuestOSHypervisorVO> mappings = listBy(sc, filter);
-        for (GuestOSHypervisorVO mapping : mappings) {
-            versions.add(mapping.getHypervisorVersion());
-        }
-        return versions;
-    }
-
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
index 0c39a8c..1e74d25 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java
@@ -21,19 +21,11 @@
 import org.apache.cloudstack.framework.config.ConfigKey.Scope;
 import org.apache.cloudstack.framework.config.ScopedConfigStorage;
 import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import javax.inject.Inject;
-import java.util.List;
 
 public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoolDetailVO> implements StoragePoolDetailsDao, ScopedConfigStorage {
 
-    @Inject
-    PrimaryDataStoreDao _storagePoolDao;
-
     public StoragePoolDetailsDaoImpl() {
     }
 
@@ -50,10 +42,6 @@
 
     @Override
     public void addDetail(long resourceId, String key, String value, boolean display) {
-        List<StoragePoolVO> ChildPools = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(resourceId);
-        for(StoragePoolVO childPool : ChildPools) {
-            super.addDetail(new StoragePoolDetailVO(childPool.getId(), key, value, display));
-        }
         super.addDetail(new StoragePoolDetailVO(resourceId, key, value, display));
     }
 }
diff --git a/engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDao.java
similarity index 67%
rename from engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDao.java
rename to engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDao.java
index 6e79b5e..eb78f20 100644
--- a/engine/schema/src/main/java/com/cloud/dc/dao/VsphereStoragePolicyDao.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDao.java
@@ -14,17 +14,18 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
-package com.cloud.dc.dao;
 
-import com.cloud.dc.VsphereStoragePolicyVO;
+package com.cloud.storage.dao;
+
+import com.cloud.storage.TemplateOVFPropertyVO;
 import com.cloud.utils.db.GenericDao;
 
 import java.util.List;
 
-public interface VsphereStoragePolicyDao extends GenericDao<VsphereStoragePolicyVO, Long> {
+public interface TemplateOVFPropertiesDao extends GenericDao<TemplateOVFPropertyVO, Long> {
 
-    public VsphereStoragePolicyVO findByPolicyId(Long zoneId, String policyId);
-
-    public List<VsphereStoragePolicyVO> findByZoneId(Long zoneId);
-
+    boolean existsOption(long templateId, String key);
+    TemplateOVFPropertyVO findByTemplateAndKey(long templateId, String key);
+    void saveOptions(List<TemplateOVFPropertyVO> opts);
+    List<TemplateOVFPropertyVO> listByTemplateId(long templateId);
 }
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDaoImpl.java
new file mode 100644
index 0000000..cf6a280
--- /dev/null
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/TemplateOVFPropertiesDaoImpl.java
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.storage.dao;
+
+import com.cloud.storage.TemplateOVFPropertyVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.TransactionLegacy;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class TemplateOVFPropertiesDaoImpl extends GenericDaoBase<TemplateOVFPropertyVO, Long> implements TemplateOVFPropertiesDao {
+
+    private final static Logger s_logger = Logger.getLogger(TemplateOVFPropertiesDaoImpl.class);
+
+    SearchBuilder<TemplateOVFPropertyVO> OptionsSearchBuilder;
+
+    public TemplateOVFPropertiesDaoImpl() {
+        super();
+        OptionsSearchBuilder = createSearchBuilder();
+        OptionsSearchBuilder.and("templateid", OptionsSearchBuilder.entity().getTemplateId(), SearchCriteria.Op.EQ);
+        OptionsSearchBuilder.and("key", OptionsSearchBuilder.entity().getKey(), SearchCriteria.Op.EQ);
+        OptionsSearchBuilder.done();
+    }
+
+    @Override
+    public boolean existsOption(long templateId, String key) {
+        return findByTemplateAndKey(templateId, key) != null;
+    }
+
+    @Override
+    public TemplateOVFPropertyVO findByTemplateAndKey(long templateId, String key) {
+        SearchCriteria<TemplateOVFPropertyVO> sc = OptionsSearchBuilder.create();
+        sc.setParameters("templateid", templateId);
+        sc.setParameters("key", key);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public void saveOptions(List<TemplateOVFPropertyVO> opts) {
+        if (CollectionUtils.isEmpty(opts)) {
+            return;
+        }
+        TransactionLegacy txn = TransactionLegacy.currentTxn();
+        txn.start();
+        for (TemplateOVFPropertyVO opt : opts) {
+            persist(opt);
+        }
+        txn.commit();
+    }
+
+    @Override
+    public List<TemplateOVFPropertyVO> listByTemplateId(long templateId) {
+        SearchCriteria<TemplateOVFPropertyVO> sc = OptionsSearchBuilder.create();
+        sc.setParameters("templateid", templateId);
+        return listBy(sc);
+    }
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
index 60e583b..3e7072f 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java
@@ -30,4 +30,4 @@
     public void addDetail(long resourceId, String key, String value, boolean display) {
         super.addDetail(new VMTemplateDetailVO(resourceId, key, value, display));
     }
-}
\ No newline at end of file
+}
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java
index d00eece..05afad6 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDao.java
@@ -27,27 +27,27 @@
 
 public interface VMTemplatePoolDao extends GenericDao<VMTemplateStoragePoolVO, Long>,
         StateDao<ObjectInDataStoreStateMachine.State, ObjectInDataStoreStateMachine.Event, DataObjectInStore> {
-    List<VMTemplateStoragePoolVO> listByPoolId(long id);
+    public List<VMTemplateStoragePoolVO> listByPoolId(long id);
 
-    List<VMTemplateStoragePoolVO> listByTemplateId(long templateId);
+    public List<VMTemplateStoragePoolVO> listByTemplateId(long templateId);
 
-    VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId, String configuration);
+    public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId);
 
-    List<VMTemplateStoragePoolVO> listByPoolIdAndState(long poolId, ObjectInDataStoreStateMachine.State state);
+    public List<VMTemplateStoragePoolVO> listByPoolIdAndState(long poolId, ObjectInDataStoreStateMachine.State state);
 
-    List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState);
+    public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState);
 
-    List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId);
+    public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId);
 
-    List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState);
+    public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState);
 
-    List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState);
+    public List<VMTemplateStoragePoolVO> listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState);
 
-    List<VMTemplateStoragePoolVO> listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states);
+    public List<VMTemplateStoragePoolVO> listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states);
 
     boolean templateAvailable(long templateId, long poolId);
 
-    VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId, String configuration);
+    public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId);
 
     VMTemplateStoragePoolVO findByPoolPath(Long poolId, String path);
 
diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
index 998df5e..3287470 100644
--- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java
@@ -28,7 +28,6 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -74,7 +73,7 @@
 
     protected static final String HOST_TEMPLATE_SEARCH =
         "SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.id=? "
-            + " and tp.template_id=? and tp.deployment_option ";
+            + " and tp.template_id=? ";
 
     public VMTemplatePoolDaoImpl() {
         PoolSearch = createSearchBuilder();
@@ -88,7 +87,6 @@
         PoolTemplateSearch = createSearchBuilder();
         PoolTemplateSearch.and("pool_id", PoolTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
         PoolTemplateSearch.and("template_id", PoolTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
-        PoolTemplateSearch.and("configuration", PoolTemplateSearch.entity().getDeploymentOption(), SearchCriteria.Op.EQ);
         PoolTemplateSearch.done();
 
         TemplateStatusSearch = createSearchBuilder();
@@ -140,13 +138,10 @@
     }
 
     @Override
-    public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId, String configuration) {
+    public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId) {
         SearchCriteria<VMTemplateStoragePoolVO> sc = PoolTemplateSearch.create();
         sc.setParameters("pool_id", poolId);
         sc.setParameters("template_id", templateId);
-        if (StringUtils.isNotBlank(configuration)) {
-            sc.setParameters("configuration", configuration);
-        }
         return findOneIncludingRemovedBy(sc);
     }
 
@@ -224,17 +219,13 @@
 
     }
 
-    public List<VMTemplateStoragePoolVO> listByHostTemplate(long hostId, long templateId, String configuration) {
+    public List<VMTemplateStoragePoolVO> listByHostTemplate(long hostId, long templateId) {
         TransactionLegacy txn = TransactionLegacy.currentTxn();
         List<VMTemplateStoragePoolVO> result = new ArrayList<VMTemplateStoragePoolVO>();
         String sql = HOST_TEMPLATE_SEARCH;
-        sql += StringUtils.isBlank(configuration) ? "IS NULL" : "= ?";
         try(PreparedStatement pstmt = txn.prepareStatement(sql);) {
             pstmt.setLong(1, hostId);
             pstmt.setLong(2, templateId);
-            if (StringUtils.isNotBlank(configuration)) {
-                pstmt.setString(3, configuration);
-            }
             try(ResultSet rs = pstmt.executeQuery();) {
                 while (rs.next()) {
                     // result.add(toEntityBean(rs, false)); TODO: this is buggy in
@@ -254,7 +245,7 @@
 
     @Override
     public boolean templateAvailable(long templateId, long hostId) {
-        VMTemplateStorageResourceAssoc tmpltPool = findByPoolTemplate(hostId, templateId, null);
+        VMTemplateStorageResourceAssoc tmpltPool = findByPoolTemplate(hostId, templateId);
         if (tmpltPool == null)
             return false;
 
@@ -271,9 +262,9 @@
     }
 
     @Override
-    public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId, String configuration) {
-        List<VMTemplateStoragePoolVO> result = listByHostTemplate(hostId, templateId, configuration);
-        return (result.size() == 0) ? null : result.get(0);
+    public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId) {
+        List<VMTemplateStoragePoolVO> result = listByHostTemplate(hostId, templateId);
+        return (result.size() == 0) ? null : result.get(1);
     }
 
     @Override
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
index 815f169..e201ae2 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDao.java
@@ -26,5 +26,4 @@
 public interface DiskOfferingDetailsDao extends GenericDao<DiskOfferingDetailVO, Long>, ResourceDetailsDao<DiskOfferingDetailVO> {
     List<Long> findDomainIds(final long resourceId);
     List<Long> findZoneIds(final long resourceId);
-    String getDetail(Long diskOfferingId, String key);
 }
\ No newline at end of file
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
index 5408f2d..da0ec5b 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/dao/DiskOfferingDetailsDaoImpl.java
@@ -56,14 +56,4 @@
         }
         return zoneIds;
     }
-
-    @Override
-    public String getDetail(Long diskOfferingId, String key) {
-        String detailValue = null;
-        DiskOfferingDetailVO diskOfferingDetail = findDetail(diskOfferingId, key);
-        if (diskOfferingDetail != null) {
-            detailValue = diskOfferingDetail.getValue();
-        }
-        return detailValue;
-    }
 }
\ No newline at end of file
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
index 59fe3f1..2398e91 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -123,9 +123,4 @@
     List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String path);
 
     void deletePoolTags(long poolId);
-
-    List<StoragePoolVO> listChildStoragePoolsInDatastoreCluster(long poolId);
-
-    Integer countAll();
-
 }
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
index 7830df5..fee9dc2 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -132,7 +132,6 @@
         DcLocalStorageSearch.and("path", DcLocalStorageSearch.entity().getPath(), SearchCriteria.Op.EQ);
         DcLocalStorageSearch.and("scope", DcLocalStorageSearch.entity().getScope(), SearchCriteria.Op.EQ);
         DcLocalStorageSearch.done();
-
     }
 
     @Override
@@ -553,19 +552,4 @@
     public void deletePoolTags(long poolId) {
         _tagsDao.deleteTags(poolId);
     }
-
-    @Override
-    public List<StoragePoolVO> listChildStoragePoolsInDatastoreCluster(long poolId) {
-        QueryBuilder<StoragePoolVO> sc = QueryBuilder.create(StoragePoolVO.class);
-        sc.and(sc.entity().getParent(), Op.EQ, poolId);
-        return sc.list();
-    }
-
-    @Override
-    public Integer countAll() {
-        SearchCriteria<StoragePoolVO> sc = createSearchCriteria();
-        sc.addAnd("parent", SearchCriteria.Op.EQ, 0);
-        sc.addAnd("removed", SearchCriteria.Op.NULL);
-        return getCount(sc);
-    }
 }
diff --git a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
index 926b8a5..b30b33d 100644
--- a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
+++ b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java
@@ -119,9 +119,6 @@
     @Enumerated(value = EnumType.STRING)
     private HypervisorType hypervisor;
 
-    @Column(name = "parent")
-    private Long parent = 0L;
-
     @Override
     public long getId() {
         return id;
@@ -380,14 +377,6 @@
         return !isShared();
     }
 
-    public Long getParent() {
-        return parent;
-    }
-
-    public void setParent(Long parent) {
-        this.parent = parent;
-    }
-
     @Override
     public boolean isInMaintenance() {
         return status == StoragePoolStatus.PrepareForMaintenance || status == StoragePoolStatus.Maintenance || status == StoragePoolStatus.ErrorInMaintenance ||
diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index 67b4010..9ab5774 100644
--- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -293,8 +293,6 @@
   <bean id="backupDaoImpl" class="org.apache.cloudstack.backup.dao.BackupDaoImpl" />
   <bean id="directDownloadCertificateDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateDaoImpl" />
   <bean id="directDownloadCertificateHostMapDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMapDaoImpl" />
+  <bean id="templateOVFPropertiesDaoImpl" class="com.cloud.storage.dao.TemplateOVFPropertiesDaoImpl" />
   <bean id="routerHealthCheckResultsDaoImpl" class="com.cloud.network.dao.RouterHealthCheckResultDaoImpl" />
-  <bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" />
-  <bean id="TemplateDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDaoImpl" />
-  <bean id="UserVmDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDaoImpl" />
 </beans>
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql
index bd4d1ca..20ed35c 100644
--- a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql
@@ -190,371 +190,10 @@
 UPDATE `cloud`.`guest_os_hypervisor` SET guest_os_name='CentOS 7' where guest_os_id=(SELECT guest_os_id from `cloud`.`vm_template` WHERE unique_name='centos56-x86_64-xen') AND hypervisor_type='Xenserver' AND hypervisor_version='8.0.0';
 
 -- Add XenServer 8.1 hypervisor capabilities
-INSERT INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported) values (UUID(), 'XenServer', '8.1.0', 1000, 253, 64, 1);
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hypervisor_version, max_guests_limit, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported) values (UUID(), 'XenServer', '8.1.0', 1000, 253, 64, 1);
 
 -- Copy XenServer 8.0 hypervisor guest OS mappings to XenServer8.1
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '8.1.0', guest_os_name, guest_os_id, now(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='8.0.0';
-
-CREATE TABLE IF NOT EXISTS `cloud`.`vsphere_storage_policy` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `uuid` varchar(255) UNIQUE,
-  `zone_id` bigint(20) unsigned NOT NULL COMMENT 'id of the zone',
-  `policy_id` varchar(255) NOT NULL COMMENT 'the identifier of the Storage Policy in vSphere DataCenter',
-  `name` varchar(255) NOT NULL COMMENT 'name of the storage policy',
-  `description` text COMMENT 'description of the storage policy',
-  `update_time` datetime COMMENT 'last updated when policy imported',
-  `removed` datetime COMMENT 'date removed',
-  PRIMARY KEY (`id`),
-  KEY `fk_vsphere_storage_policy__zone_id` (`zone_id`),
-  UNIQUE KEY (`zone_id`, `policy_id`),
-  CONSTRAINT `fk_vsphere_storage_policy__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-ALTER TABLE `cloud`.`storage_pool` ADD COLUMN `parent` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'ID of the Datastore cluster (storage pool) if this is a child in that Datastore cluster';
-
--- Added parent column to support datastore clusters in vmware vsphere
-DROP VIEW IF EXISTS `cloud`.`storage_pool_view`;
-CREATE VIEW `cloud`.`storage_pool_view` AS
-    SELECT
-        `storage_pool`.`id` AS `id`,
-        `storage_pool`.`uuid` AS `uuid`,
-        `storage_pool`.`name` AS `name`,
-        `storage_pool`.`status` AS `status`,
-        `storage_pool`.`path` AS `path`,
-        `storage_pool`.`pool_type` AS `pool_type`,
-        `storage_pool`.`host_address` AS `host_address`,
-        `storage_pool`.`created` AS `created`,
-        `storage_pool`.`removed` AS `removed`,
-        `storage_pool`.`capacity_bytes` AS `capacity_bytes`,
-        `storage_pool`.`capacity_iops` AS `capacity_iops`,
-        `storage_pool`.`scope` AS `scope`,
-        `storage_pool`.`hypervisor` AS `hypervisor`,
-        `storage_pool`.`storage_provider_name` AS `storage_provider_name`,
-        `storage_pool`.`parent` AS `parent`,
-        `cluster`.`id` AS `cluster_id`,
-        `cluster`.`uuid` AS `cluster_uuid`,
-        `cluster`.`name` AS `cluster_name`,
-        `cluster`.`cluster_type` AS `cluster_type`,
-        `data_center`.`id` AS `data_center_id`,
-        `data_center`.`uuid` AS `data_center_uuid`,
-        `data_center`.`name` AS `data_center_name`,
-        `data_center`.`networktype` AS `data_center_type`,
-        `host_pod_ref`.`id` AS `pod_id`,
-        `host_pod_ref`.`uuid` AS `pod_uuid`,
-        `host_pod_ref`.`name` AS `pod_name`,
-        `storage_pool_tags`.`tag` AS `tag`,
-        `op_host_capacity`.`used_capacity` AS `disk_used_capacity`,
-        `op_host_capacity`.`reserved_capacity` AS `disk_reserved_capacity`,
-        `async_job`.`id` AS `job_id`,
-        `async_job`.`uuid` AS `job_uuid`,
-        `async_job`.`job_status` AS `job_status`,
-        `async_job`.`account_id` AS `job_account_id`
-    FROM
-        ((((((`storage_pool`
-        LEFT JOIN `cluster` ON ((`storage_pool`.`cluster_id` = `cluster`.`id`)))
-        LEFT JOIN `data_center` ON ((`storage_pool`.`data_center_id` = `data_center`.`id`)))
-        LEFT JOIN `host_pod_ref` ON ((`storage_pool`.`pod_id` = `host_pod_ref`.`id`)))
-        LEFT JOIN `storage_pool_tags` ON (((`storage_pool_tags`.`pool_id` = `storage_pool`.`id`))))
-        LEFT JOIN `op_host_capacity` ON (((`storage_pool`.`id` = `op_host_capacity`.`host_id`)
-            AND (`op_host_capacity`.`capacity_type` IN (3 , 9)))))
-        LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `storage_pool`.`id`)
-            AND (`async_job`.`instance_type` = 'StoragePool')
-            AND (`async_job`.`job_status` = 0))));
-
--- Add passthrough instruction for appliance deployments
-ALTER TABLE `cloud`.`vm_template` ADD COLUMN `deploy_as_is` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the template should be deployed with disks and networks as defined by OVF';
-
--- Changes to template_view for both deploying multidisk OVA/vApp as is
-DROP VIEW IF EXISTS `cloud`.`template_view`;
-CREATE VIEW `cloud`.`template_view` AS
-     SELECT
-         `vm_template`.`id` AS `id`,
-         `vm_template`.`uuid` AS `uuid`,
-         `vm_template`.`unique_name` AS `unique_name`,
-         `vm_template`.`name` AS `name`,
-         `vm_template`.`public` AS `public`,
-         `vm_template`.`featured` AS `featured`,
-         `vm_template`.`type` AS `type`,
-         `vm_template`.`hvm` AS `hvm`,
-         `vm_template`.`bits` AS `bits`,
-         `vm_template`.`url` AS `url`,
-         `vm_template`.`format` AS `format`,
-         `vm_template`.`created` AS `created`,
-         `vm_template`.`checksum` AS `checksum`,
-         `vm_template`.`display_text` AS `display_text`,
-         `vm_template`.`enable_password` AS `enable_password`,
-         `vm_template`.`dynamically_scalable` AS `dynamically_scalable`,
-         `vm_template`.`state` AS `template_state`,
-         `vm_template`.`guest_os_id` AS `guest_os_id`,
-         `guest_os`.`uuid` AS `guest_os_uuid`,
-         `guest_os`.`display_name` AS `guest_os_name`,
-         `vm_template`.`bootable` AS `bootable`,
-         `vm_template`.`prepopulate` AS `prepopulate`,
-         `vm_template`.`cross_zones` AS `cross_zones`,
-         `vm_template`.`hypervisor_type` AS `hypervisor_type`,
-         `vm_template`.`extractable` AS `extractable`,
-         `vm_template`.`template_tag` AS `template_tag`,
-         `vm_template`.`sort_key` AS `sort_key`,
-         `vm_template`.`removed` AS `removed`,
-         `vm_template`.`enable_sshkey` AS `enable_sshkey`,
-         `parent_template`.`id` AS `parent_template_id`,
-         `parent_template`.`uuid` AS `parent_template_uuid`,
-         `source_template`.`id` AS `source_template_id`,
-         `source_template`.`uuid` AS `source_template_uuid`,
-         `account`.`id` AS `account_id`,
-         `account`.`uuid` AS `account_uuid`,
-         `account`.`account_name` AS `account_name`,
-         `account`.`type` AS `account_type`,
-         `domain`.`id` AS `domain_id`,
-         `domain`.`uuid` AS `domain_uuid`,
-         `domain`.`name` AS `domain_name`,
-         `domain`.`path` AS `domain_path`,
-         `projects`.`id` AS `project_id`,
-         `projects`.`uuid` AS `project_uuid`,
-         `projects`.`name` AS `project_name`,
-         `data_center`.`id` AS `data_center_id`,
-         `data_center`.`uuid` AS `data_center_uuid`,
-         `data_center`.`name` AS `data_center_name`,
-         `launch_permission`.`account_id` AS `lp_account_id`,
-         `template_store_ref`.`store_id` AS `store_id`,
-         `image_store`.`scope` AS `store_scope`,
-         `template_store_ref`.`state` AS `state`,
-         `template_store_ref`.`download_state` AS `download_state`,
-         `template_store_ref`.`download_pct` AS `download_pct`,
-         `template_store_ref`.`error_str` AS `error_str`,
-         `template_store_ref`.`size` AS `size`,
-         `template_store_ref`.physical_size AS `physical_size`,
-         `template_store_ref`.`destroyed` AS `destroyed`,
-         `template_store_ref`.`created` AS `created_on_store`,
-         `vm_template_details`.`name` AS `detail_name`,
-         `vm_template_details`.`value` AS `detail_value`,
-         `resource_tags`.`id` AS `tag_id`,
-         `resource_tags`.`uuid` AS `tag_uuid`,
-         `resource_tags`.`key` AS `tag_key`,
-         `resource_tags`.`value` AS `tag_value`,
-         `resource_tags`.`domain_id` AS `tag_domain_id`,
-         `domain`.`uuid` AS `tag_domain_uuid`,
-         `domain`.`name` AS `tag_domain_name`,
-         `resource_tags`.`account_id` AS `tag_account_id`,
-         `account`.`account_name` AS `tag_account_name`,
-         `resource_tags`.`resource_id` AS `tag_resource_id`,
-         `resource_tags`.`resource_uuid` AS `tag_resource_uuid`,
-         `resource_tags`.`resource_type` AS `tag_resource_type`,
-         `resource_tags`.`customer` AS `tag_customer`,
-          CONCAT(`vm_template`.`id`,
-                 '_',
-                 IFNULL(`data_center`.`id`, 0)) AS `temp_zone_pair`,
-          `vm_template`.`direct_download` AS `direct_download`,
-          `vm_template`.`deploy_as_is` AS `deploy_as_is`
-     FROM
-         (((((((((((((`vm_template`
-         JOIN `guest_os` ON ((`guest_os`.`id` = `vm_template`.`guest_os_id`)))
-         JOIN `account` ON ((`account`.`id` = `vm_template`.`account_id`)))
-         JOIN `domain` ON ((`domain`.`id` = `account`.`domain_id`)))
-         LEFT JOIN `projects` ON ((`projects`.`project_account_id` = `account`.`id`)))
-         LEFT JOIN `vm_template_details` ON ((`vm_template_details`.`template_id` = `vm_template`.`id`)))
-         LEFT JOIN `vm_template` `source_template` ON ((`source_template`.`id` = `vm_template`.`source_template_id`)))
-         LEFT JOIN `template_store_ref` ON (((`template_store_ref`.`template_id` = `vm_template`.`id`)
-             AND (`template_store_ref`.`store_role` = 'Image')
-             AND (`template_store_ref`.`destroyed` = 0))))
-         LEFT JOIN `vm_template` `parent_template` ON ((`parent_template`.`id` = `vm_template`.`parent_template_id`)))
-         LEFT JOIN `image_store` ON ((ISNULL(`image_store`.`removed`)
-             AND (`template_store_ref`.`store_id` IS NOT NULL)
-             AND (`image_store`.`id` = `template_store_ref`.`store_id`))))
-         LEFT JOIN `template_zone_ref` ON (((`template_zone_ref`.`template_id` = `vm_template`.`id`)
-             AND ISNULL(`template_store_ref`.`store_id`)
-             AND ISNULL(`template_zone_ref`.`removed`))))
-         LEFT JOIN `data_center` ON (((`image_store`.`data_center_id` = `data_center`.`id`)
-             OR (`template_zone_ref`.`zone_id` = `data_center`.`id`))))
-         LEFT JOIN `launch_permission` ON ((`launch_permission`.`template_id` = `vm_template`.`id`)))
-         LEFT JOIN `resource_tags` ON (((`resource_tags`.`resource_id` = `vm_template`.`id`)
-             AND ((`resource_tags`.`resource_type` = 'Template')
-             OR (`resource_tags`.`resource_type` = 'ISO')))));
-
--- Add mincpu, maxcpu, minmemory and maxmemory to the view supporting constrained offerings
-DROP VIEW IF EXISTS `cloud`.`service_offering_view`;
-CREATE VIEW `cloud`.`service_offering_view` AS
-    SELECT
-        `service_offering`.`id` AS `id`,
-        `disk_offering`.`uuid` AS `uuid`,
-        `disk_offering`.`name` AS `name`,
-        `disk_offering`.`display_text` AS `display_text`,
-        `disk_offering`.`provisioning_type` AS `provisioning_type`,
-        `disk_offering`.`created` AS `created`,
-        `disk_offering`.`tags` AS `tags`,
-        `disk_offering`.`removed` AS `removed`,
-        `disk_offering`.`use_local_storage` AS `use_local_storage`,
-        `disk_offering`.`system_use` AS `system_use`,
-        `disk_offering`.`customized_iops` AS `customized_iops`,
-        `disk_offering`.`min_iops` AS `min_iops`,
-        `disk_offering`.`max_iops` AS `max_iops`,
-        `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
-        `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
-        `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
-        `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
-        `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
-        `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
-        `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
-        `disk_offering`.`iops_read_rate` AS `iops_read_rate`,
-        `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
-        `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
-        `disk_offering`.`iops_write_rate` AS `iops_write_rate`,
-        `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
-        `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
-        `disk_offering`.`cache_mode` AS `cache_mode`,
-        `service_offering`.`cpu` AS `cpu`,
-        `service_offering`.`speed` AS `speed`,
-        `service_offering`.`ram_size` AS `ram_size`,
-        `service_offering`.`nw_rate` AS `nw_rate`,
-        `service_offering`.`mc_rate` AS `mc_rate`,
-        `service_offering`.`ha_enabled` AS `ha_enabled`,
-        `service_offering`.`limit_cpu_use` AS `limit_cpu_use`,
-        `service_offering`.`host_tag` AS `host_tag`,
-        `service_offering`.`default_use` AS `default_use`,
-        `service_offering`.`vm_type` AS `vm_type`,
-        `service_offering`.`sort_key` AS `sort_key`,
-        `service_offering`.`is_volatile` AS `is_volatile`,
-        `service_offering`.`deployment_planner` AS `deployment_planner`,
-        `vsphere_storage_policy`.`value` AS `vsphere_storage_policy`,
-        GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
-        GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
-        GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
-        GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
-        GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
-        GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
-        GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name,
-        IFNULL(`min_compute_details`.`value`, `cpu`) AS min_cpu,
-        IFNULL(`max_compute_details`.`value`, `cpu`) AS max_cpu,
-        IFNULL(`min_memory_details`.`value`, `ram_size`) AS min_memory,
-        IFNULL(`max_memory_details`.`value`, `ram_size`) AS max_memory
-    FROM
-        `cloud`.`service_offering`
-            INNER JOIN
-        `cloud`.`disk_offering_view` AS `disk_offering` ON service_offering.id = disk_offering.id
-            LEFT JOIN
-        `cloud`.`service_offering_details` AS `domain_details` ON `domain_details`.`service_offering_id` = `disk_offering`.`id` AND `domain_details`.`name`='domainid'
-            LEFT JOIN
-        `cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
-            LEFT JOIN
-        `cloud`.`service_offering_details` AS `zone_details` ON `zone_details`.`service_offering_id` = `disk_offering`.`id` AND `zone_details`.`name`='zoneid'
-            LEFT JOIN
-        `cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
-			LEFT JOIN
-		`cloud`.`service_offering_details` AS `min_compute_details` ON `min_compute_details`.`service_offering_id` = `disk_offering`.`id`
-				AND `min_compute_details`.`name` = 'mincpunumber'
-			LEFT JOIN
-		`cloud`.`service_offering_details` AS `max_compute_details` ON `max_compute_details`.`service_offering_id` = `disk_offering`.`id`
-				AND `max_compute_details`.`name` = 'maxcpunumber'
-			LEFT JOIN
-		`cloud`.`service_offering_details` AS `min_memory_details` ON `min_memory_details`.`service_offering_id` = `disk_offering`.`id`
-				AND `min_memory_details`.`name` = 'minmemory'
-			LEFT JOIN
-		`cloud`.`service_offering_details` AS `max_memory_details` ON `max_memory_details`.`service_offering_id` = `disk_offering`.`id`
-				AND `max_memory_details`.`name` = 'maxmemory'
-			LEFT JOIN
-		`cloud`.`service_offering_details` AS `vsphere_storage_policy` ON `vsphere_storage_policy`.`service_offering_id` = `disk_offering`.`id`
-				AND `vsphere_storage_policy`.`name` = 'storagepolicy'
-    WHERE
-        `disk_offering`.`state`='Active'
-    GROUP BY
-        `service_offering`.`id`;
-
-DROP VIEW IF EXISTS `cloud`.`disk_offering_view`;
-CREATE VIEW `cloud`.`disk_offering_view` AS
-    SELECT
-        `disk_offering`.`id` AS `id`,
-        `disk_offering`.`uuid` AS `uuid`,
-        `disk_offering`.`name` AS `name`,
-        `disk_offering`.`display_text` AS `display_text`,
-        `disk_offering`.`provisioning_type` AS `provisioning_type`,
-        `disk_offering`.`disk_size` AS `disk_size`,
-        `disk_offering`.`min_iops` AS `min_iops`,
-        `disk_offering`.`max_iops` AS `max_iops`,
-        `disk_offering`.`created` AS `created`,
-        `disk_offering`.`tags` AS `tags`,
-        `disk_offering`.`customized` AS `customized`,
-        `disk_offering`.`customized_iops` AS `customized_iops`,
-        `disk_offering`.`removed` AS `removed`,
-        `disk_offering`.`use_local_storage` AS `use_local_storage`,
-        `disk_offering`.`system_use` AS `system_use`,
-        `disk_offering`.`hv_ss_reserve` AS `hv_ss_reserve`,
-        `disk_offering`.`bytes_read_rate` AS `bytes_read_rate`,
-        `disk_offering`.`bytes_read_rate_max` AS `bytes_read_rate_max`,
-        `disk_offering`.`bytes_read_rate_max_length` AS `bytes_read_rate_max_length`,
-        `disk_offering`.`bytes_write_rate` AS `bytes_write_rate`,
-        `disk_offering`.`bytes_write_rate_max` AS `bytes_write_rate_max`,
-        `disk_offering`.`bytes_write_rate_max_length` AS `bytes_write_rate_max_length`,
-        `disk_offering`.`iops_read_rate` AS `iops_read_rate`,
-        `disk_offering`.`iops_read_rate_max` AS `iops_read_rate_max`,
-        `disk_offering`.`iops_read_rate_max_length` AS `iops_read_rate_max_length`,
-        `disk_offering`.`iops_write_rate` AS `iops_write_rate`,
-        `disk_offering`.`iops_write_rate_max` AS `iops_write_rate_max`,
-        `disk_offering`.`iops_write_rate_max_length` AS `iops_write_rate_max_length`,
-        `disk_offering`.`cache_mode` AS `cache_mode`,
-        `disk_offering`.`sort_key` AS `sort_key`,
-        `disk_offering`.`type` AS `type`,
-        `disk_offering`.`display_offering` AS `display_offering`,
-        `disk_offering`.`state` AS `state`,
-        `vsphere_storage_policy`.`value` AS `vsphere_storage_policy`,
-        GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id,
-        GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid,
-        GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name,
-        GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path,
-        GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id,
-        GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid,
-        GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name
-    FROM
-        `cloud`.`disk_offering`
-            LEFT JOIN
-        `cloud`.`disk_offering_details` AS `domain_details` ON `domain_details`.`offering_id` = `disk_offering`.`id` AND `domain_details`.`name`='domainid'
-            LEFT JOIN
-        `cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`)
-            LEFT JOIN
-        `cloud`.`disk_offering_details` AS `zone_details` ON `zone_details`.`offering_id` = `disk_offering`.`id` AND `zone_details`.`name`='zoneid'
-            LEFT JOIN
-        `cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`)
-			LEFT JOIN
-		`cloud`.`disk_offering_details` AS `vsphere_storage_policy` ON `vsphere_storage_policy`.`offering_id` = `disk_offering`.`id`
-				AND `vsphere_storage_policy`.`name` = 'storagepolicy'
-
-    WHERE
-        `disk_offering`.`state`='Active'
-    GROUP BY
-        `disk_offering`.`id`;
-
-ALTER TABLE `cloud`.`template_spool_ref`
-DROP FOREIGN KEY `fk_template_spool_ref__template_id`;
-
-ALTER TABLE `cloud`.`template_spool_ref`
-ADD COLUMN `deployment_option` VARCHAR(255) NULL DEFAULT NULL AFTER `updated`,
-ADD INDEX `fk_template_spool_ref__template_id_idx` (`template_id` ASC),
-ADD UNIQUE INDEX `index_template_spool_configuration` (`pool_id` ASC, `template_id` ASC, `deployment_option` ASC),
-DROP INDEX `i_template_spool_ref__template_id__pool_id` ;
-
-ALTER TABLE `cloud`.`template_spool_ref`
-ADD CONSTRAINT `fk_template_spool_ref__template_id`
-  FOREIGN KEY (`template_id`)
-  REFERENCES `cloud`.`vm_template` (`id`)
-  ON DELETE NO ACTION
-  ON UPDATE NO ACTION;
-
-CREATE TABLE `cloud`.`template_deploy_as_is_details` (
-  `id` bigint unsigned NOT NULL auto_increment,
-  `template_id` bigint unsigned NOT NULL COMMENT 'template id',
-  `name` varchar(255) NOT NULL,
-  `value` TEXT,
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_template_deploy_as_is_details__template_id` FOREIGN KEY `fk_template_deploy_as_is_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
-CREATE TABLE `cloud`.`user_vm_deploy_as_is_details` (
-  `id` bigint unsigned NOT NULL auto_increment,
-  `vm_id` bigint unsigned NOT NULL COMMENT 'virtual machine id',
-  `name` varchar(255) NOT NULL,
-  `value` TEXT,
-  PRIMARY KEY (`id`),
-  CONSTRAINT `fk_user_vm_deploy_as_is_details__vm_id` FOREIGN KEY `fk_user_vm_deploy_as_is_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'Xenserver', '8.1.0', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='Xenserver' AND hypervisor_version='8.0.0';
 
 ALTER TABLE `cloud`.`image_store` ADD COLUMN `readonly` boolean DEFAULT false COMMENT 'defines status of image store';
 
@@ -581,247 +220,3 @@
         `cloud`.`data_center` ON image_store.data_center_id = data_center.id
             left join
         `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id;
-
--- OVF configured OS while registering deploy-as-is templates Linux 3.x Kernel OS
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (305, UUID(), 11, 'OVF Configured OS', now());
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (306, UUID(), 2, 'Linux 3.x Kernel (64 bit)', now());
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (307, UUID(), 2, 'Linux 3.x Kernel (32 bit)', now());
-
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.0', 'other3xLinux64Guest', 306, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.5', 'other3xLinux64Guest', 306, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7', 'other3xLinux64Guest', 306, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.1', 'other3xLinux64Guest', 306, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.2', 'other3xLinux64Guest', 306, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.3', 'other3xLinux64Guest', 306, now(), 0);
-
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.0', 'other3xLinuxGuest', 307, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.5', 'other3xLinuxGuest', 307, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7', 'other3xLinuxGuest', 307, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.1', 'other3xLinuxGuest', 307, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.2', 'other3xLinuxGuest', 307, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '6.7.3', 'other3xLinuxGuest', 307, now(), 0);
-
-
--- Add amazonlinux as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (308, UUID(), 7, 'Amazon Linux 2 (64 bit)', now());
--- Amazonlinux VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'amazonlinux2_64Guest', 308, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'amazonlinux2_64Guest', 308, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'amazonlinux2_64Guest', 308, now(), 0);
-
-
--- Add asianux4 32 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (309, UUID(), 7, 'Asianux Server 4 (32 bit)', now());
--- asianux4 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'asianux4Guest', 309, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux4Guest', 309, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux4Guest', 309, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux4Guest', 309, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux4Guest', 309, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux4Guest', 309, now(), 0);
-
-
--- Add asianux4 64 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (310, UUID(), 7, 'Asianux Server 4 (64 bit)', now());
--- asianux4 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'asianux4_64Guest', 310, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux4_64Guest', 310, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux4_64Guest', 310, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux4_64Guest', 310, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux4_64Guest', 310, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux4_64Guest', 310, now(), 0);
-
-
--- Add asianux5 32 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (311, UUID(), 7, 'Asianux Server 5 (32 bit)', now());
--- asianux5 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'asianux5Guest', 311, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux5Guest', 311, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux5Guest', 311, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux5Guest', 311, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux5Guest', 311, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux5Guest', 311, now(), 0);
-
-
--- Add asianux5 64 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (312, UUID(), 7, 'Asianux Server 5 (64 bit)', now());
--- asianux5 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'asianux5_64Guest', 312, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux5_64Guest', 312, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux5_64Guest', 312, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux5_64Guest', 312, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux5_64Guest', 312, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux5_64Guest', 312, now(), 0);
-
-
--- Add asianux7 32 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (313, UUID(), 7, 'Asianux Server 7 (32 bit)', now());
--- asianux7 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux7Guest', 313, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux7Guest', 313, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux7Guest', 313, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux7Guest', 313, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux7Guest', 313, now(), 0);
-
-
--- Add asianux7 64 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (314, UUID(), 7, 'Asianux Server 7 (64 bit)', now());
--- asianux7 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'asianux7_64Guest', 314, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux7_64Guest', 314, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux7_64Guest', 314, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux7_64Guest', 314, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux7_64Guest', 314, now(), 0);
-
-
--- Add asianux8 as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (315, UUID(), 7, 'Asianux Server 8 (64 bit)', now());
--- asianux8 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'asianux8_64Guest', 315, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'asianux8_64Guest', 315, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'asianux8_64Guest', 315, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'asianux8_64Guest', 315, now(), 0);
-
-
--- Add eComStation 2.0   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (316, UUID(), 7, 'eComStation 2.0', now());
--- eComStation 2.0 VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'eComStation2Guest', 316, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'eComStation2Guest', 316, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'eComStation2Guest', 316, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'eComStation2Guest', 316, now(), 0);
-
--- Add macOS 10.13 (64 bit)  as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (317, UUID(), 7, 'macOS 10.13 (64 bit)', now());
--- macOS 10.13 (64 bit)  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'darwin17_64Guest', 317, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'darwin17_64Guest', 317, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'darwin17_64Guest', 317, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'darwin17_64Guest', 317, now(), 0);
-
--- Add macOS 10.14 (64 bit)  as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (318, UUID(), 7, 'macOS 10.14 (64 bit)', now());
--- macOS 10.14 (64 bit) VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'darwin18_64Guest', 318, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'darwin18_64Guest', 318, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'darwin18_64Guest', 318, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'darwin18_64Guest', 318, now(), 0);
-
-
--- Add Fedora Linux (64 bit)   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (319, UUID(), 7, 'Fedora Linux (64 bit)', now());
--- Fedora Linux (64 bit)  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'fedora64Guest', 319, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'fedora64Guest', 319, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'fedora64Guest', 319, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'fedora64Guest', 319, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'fedora64Guest', 319, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'fedora64Guest', 319, now(), 0);
-
-
--- Add Fedora Linux   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (320, UUID(), 7, 'Fedora Linux', now());
--- Fedora Linux  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'fedoraGuest', 320, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'fedoraGuest', 320, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'fedoraGuest', 320, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'fedoraGuest', 320, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'fedoraGuest', 320, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'fedoraGuest', 320, now(), 0);
-
--- Add Mandrake Linux   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (321, UUID(), 7, 'Mandrake Linux', now());
--- Mandrake Linux  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'mandrakeGuest', 321, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'mandrakeGuest', 321, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'mandrakeGuest', 321, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'mandrakeGuest', 321, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'mandrakeGuest', 321, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'mandrakeGuest', 321, now(), 0);
-
--- Add Mandriva Linux (64 bit)  as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (322, UUID(), 7, 'Mandriva Linux (64 bit)', now());
--- Mandriva Linux (64 bit)  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'mandriva64Guest', 322, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'mandriva64Guest', 322, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'mandriva64Guest', 322, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'mandriva64Guest', 322, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'mandriva64Guest', 322, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'mandriva64Guest', 322, now(), 0);
-
-
--- Add Mandriva Linux  as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (323, UUID(), 7, 'Mandriva Linux', now());
--- Mandriva Linux  VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'mandrivaGuest', 323, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'mandrivaGuest', 323, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'mandrivaGuest', 323, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'mandrivaGuest', 323, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'mandrivaGuest', 323, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'mandrivaGuest', 323, now(), 0);
-
-
--- Add SCO OpenServer 5   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (324, UUID(), 7, 'SCO OpenServer 5', now());
--- SCO OpenServer 5   VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'openServer5Guest', 324, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'openServer5Guest', 324, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'openServer5Guest', 324, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'openServer5Guest', 324, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'openServer5Guest', 324, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'openServer5Guest', 324, now(), 0);
-
-
--- Add SCO OpenServer 6   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (325, UUID(), 7, 'SCO OpenServer 6', now());
--- SCO OpenServer 6   VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'openServer6Guest', 325, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'openServer6Guest', 325, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'openServer6Guest', 325, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'openServer6Guest', 325, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'openServer6Guest', 325, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'openServer6Guest', 325, now(), 0);
-
-
-
--- Add OpenSUSE Linux (64 bit)    as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (326, UUID(), 7, 'OpenSUSE Linux (64 bit)', now());
--- OpenSUSE Linux (64 bit)   VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'opensuse64Guest', 326, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'opensuse64Guest', 326, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'opensuse64Guest', 326, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'opensuse64Guest', 326, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'opensuse64Guest', 326, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'opensuse64Guest', 326, now(), 0);
-
-
--- Add SCO OpenServer 6   as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (327, UUID(), 7, 'SCO OpenServer 6', now());
--- SCO OpenServer 6   VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'opensuseGuest', 327, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'opensuseGuest', 327, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'opensuseGuest', 327, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'opensuseGuest', 327, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'opensuseGuest', 327, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'opensuseGuest', 327, now(), 0);
-
-
--- Add Solaris 11 (64 bit)    as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (328, UUID(), 7, 'Solaris 11 (64 bit)', now());
--- Solaris 11 (64 bit)    VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.0', 'solaris11_64Guest', 328, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'solaris11_64Guest', 328, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'solaris11_64Guest', 328, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'solaris11_64Guest', 328, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'solaris11_64Guest', 328, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'solaris11_64Guest', 328, now(), 0);
-
-
--- Add  VMware Photon (64 bit)     as support guest os
-INSERT INTO `cloud`.`guest_os` (id, uuid, category_id, display_name, created) VALUES (329, UUID(), 7, 'VMware Photon (64 bit)', now());
--- VMware Photon (64 bit)    VMWare guest os mapping
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.5', 'vmwarePhoton64Guest', 329, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7', 'vmwarePhoton64Guest', 329, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.1', 'vmwarePhoton64Guest', 329, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.2', 'vmwarePhoton64Guest', 329, now(), 0);
-INSERT INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '6.7.3', 'vmwarePhoton64Guest', 329, now(), 0);
diff --git a/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
index 40eeafe..278c80d 100644
--- a/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
+++ b/engine/storage/cache/src/main/java/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java
@@ -291,7 +291,7 @@
 
                 if (st == ObjectInDataStoreStateMachine.State.Ready) {
                     s_logger.debug("there is already one in the cache store");
-                    DataObject dataObj = objectInStoreMgr.get(data, store, null);
+                    DataObject dataObj = objectInStoreMgr.get(data, store);
                     dataObj.incRefCount();
                     existingDataObj = dataObj;
                 }
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index c49ffba..7c930fb 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -356,47 +356,37 @@
             DataObject objOnImageStore = imageStore.create(srcData);
             objOnImageStore.processEvent(Event.CreateOnlyRequested);
 
-            Answer answer = null;
-            try {
-                answer = copyObject(srcData, objOnImageStore);
-
-                if (answer == null || !answer.getResult()) {
-                    if (answer != null) {
-                        s_logger.debug("copy to image store failed: " + answer.getDetails());
-                    }
-                    objOnImageStore.processEvent(Event.OperationFailed);
-                    imageStore.delete(objOnImageStore);
-                    return answer;
+            Answer answer = copyObject(srcData, objOnImageStore);
+            if (answer == null || !answer.getResult()) {
+                if (answer != null) {
+                    s_logger.debug("copy to image store failed: " + answer.getDetails());
                 }
+                objOnImageStore.processEvent(Event.OperationFailed);
+                imageStore.delete(objOnImageStore);
+                return answer;
+            }
 
-                objOnImageStore.processEvent(Event.OperationSuccessed, answer);
+            objOnImageStore.processEvent(Event.OperationSuccessed, answer);
 
-                objOnImageStore.processEvent(Event.CopyingRequested);
+            objOnImageStore.processEvent(Event.CopyingRequested);
 
-                CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
-                EndPoint ep = selector.select(objOnImageStore, destData);
-                if (ep == null) {
-                    String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                    s_logger.error(errMsg);
-                    answer = new Answer(cmd, false, errMsg);
-                } else {
-                    answer = ep.sendMessage(cmd);
+            CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), addFullCloneFlagOnVMwareDest(destData.getTO()), _copyvolumewait, VirtualMachineManager.ExecuteInSequence.value());
+            EndPoint ep = selector.select(objOnImageStore, destData);
+            if (ep == null) {
+                String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
+                s_logger.error(errMsg);
+                answer = new Answer(cmd, false, errMsg);
+            } else {
+                answer = ep.sendMessage(cmd);
+            }
+
+            if (answer == null || !answer.getResult()) {
+                if (answer != null) {
+                    s_logger.debug("copy to primary store failed: " + answer.getDetails());
                 }
-
-                if (answer == null || !answer.getResult()) {
-                    if (answer != null) {
-                        s_logger.debug("copy to primary store failed: " + answer.getDetails());
-                    }
-                    objOnImageStore.processEvent(Event.OperationFailed);
-                    imageStore.delete(objOnImageStore);
-                    return answer;
-                }
-            } catch (Exception e) {
-                if (imageStore.exists(objOnImageStore)) {
-                    objOnImageStore.processEvent(Event.OperationFailed);
-                    imageStore.delete(objOnImageStore);
-                }
-                throw e;
+                objOnImageStore.processEvent(Event.OperationFailed);
+                imageStore.delete(objOnImageStore);
+                return answer;
             }
 
             objOnImageStore.processEvent(Event.OperationSuccessed);
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
index 9718596..e6b5c85 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageDataMotionStrategy.java
@@ -195,7 +195,7 @@
     @Override
     protected void copyTemplateToTargetFilesystemStorageIfNeeded(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, DataStore destDataStore, StoragePool destStoragePool,
             Host destHost) {
-        VMTemplateStoragePoolVO sourceVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(destStoragePool.getId(), srcVolumeInfo.getTemplateId(), null);
+        VMTemplateStoragePoolVO sourceVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(destStoragePool.getId(), srcVolumeInfo.getTemplateId());
         if (sourceVolumeTemplateStoragePoolVO == null && destStoragePool.getPoolType() == StoragePoolType.Filesystem) {
             DataStore sourceTemplateDataStore = dataStoreManagerImpl.getRandomImageStore(srcVolumeInfo.getDataCenterId());
             if (sourceTemplateDataStore != null) {
@@ -220,8 +220,8 @@
      *  Update the template reference on table "template_spool_ref" (VMTemplateStoragePoolVO).
      */
     protected void updateTemplateReferenceIfSuccessfulCopy(VolumeInfo srcVolumeInfo, StoragePool srcStoragePool, TemplateInfo destTemplateInfo, DataStore destDataStore) {
-        VMTemplateStoragePoolVO srcVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(srcStoragePool.getId(), srcVolumeInfo.getTemplateId(), null);
-        VMTemplateStoragePoolVO destVolumeTemplateStoragePoolVO = new VMTemplateStoragePoolVO(destDataStore.getId(), srcVolumeInfo.getTemplateId(), null);
+        VMTemplateStoragePoolVO srcVolumeTemplateStoragePoolVO = vmTemplatePoolDao.findByPoolTemplate(srcStoragePool.getId(), srcVolumeInfo.getTemplateId());
+        VMTemplateStoragePoolVO destVolumeTemplateStoragePoolVO = new VMTemplateStoragePoolVO(destDataStore.getId(), srcVolumeInfo.getTemplateId());
         destVolumeTemplateStoragePoolVO.setDownloadPercent(100);
         destVolumeTemplateStoragePoolVO.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
         destVolumeTemplateStoragePoolVO.setState(ObjectInDataStoreStateMachine.State.Ready);
diff --git a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
index 936f062..4d3ec18 100644
--- a/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
+++ b/engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java
@@ -1710,7 +1710,7 @@
      * Return expected MigrationOptions for a linked clone volume live storage migration
      */
     protected MigrationOptions createLinkedCloneMigrationOptions(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo, String srcVolumeBackingFile, String srcPoolUuid, Storage.StoragePoolType srcPoolType) {
-        VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(destVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId(), null);
+        VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(destVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId());
         boolean updateBackingFileReference = ref == null;
         String backingFile = ref != null ? ref.getInstallPath() : srcVolumeBackingFile;
         return new MigrationOptions(srcPoolUuid, srcPoolType, backingFile, updateBackingFileReference);
@@ -1983,7 +1983,7 @@
                 srcVolumeInfo.getTemplateId() != null && srcVolumeInfo.getPoolId() != null) {
             VMTemplateVO template = _vmTemplateDao.findById(srcVolumeInfo.getTemplateId());
             if (template.getFormat() != null && template.getFormat() != Storage.ImageFormat.ISO) {
-                VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(srcVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId(), null);
+                VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(srcVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId());
                 return ref != null ? ref.getInstallPath() : null;
             }
         }
@@ -2157,8 +2157,8 @@
      * Update reference on template_spool_ref table of copied template to destination storage
      */
     protected void updateCopiedTemplateReference(VolumeInfo srcVolumeInfo, VolumeInfo destVolumeInfo) {
-        VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(srcVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId(), null);
-        VMTemplateStoragePoolVO newRef = new VMTemplateStoragePoolVO(destVolumeInfo.getPoolId(), ref.getTemplateId(), null);
+        VMTemplateStoragePoolVO ref = templatePoolDao.findByPoolTemplate(srcVolumeInfo.getPoolId(), srcVolumeInfo.getTemplateId());
+        VMTemplateStoragePoolVO newRef = new VMTemplateStoragePoolVO(destVolumeInfo.getPoolId(), ref.getTemplateId());
         newRef.setDownloadPercent(100);
         newRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
         newRef.setState(ObjectInDataStoreStateMachine.State.Ready);
diff --git a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java
index ba7fb74..6971444 100644
--- a/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java
+++ b/engine/storage/datamotion/src/test/java/org/apache/cloudstack/storage/motion/KvmNonManagedStorageSystemDataMotionTest.java
@@ -19,7 +19,6 @@
 package org.apache.cloudstack.storage.motion;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.when;
 
@@ -302,7 +301,7 @@
     public void copyTemplateToTargetStorageIfNeededTestTemplateAlreadyOnTargetHost() throws AgentUnavailableException, OperationTimedoutException {
         Answer copyCommandAnswer = Mockito.mock(Answer.class);
         Mockito.lenient().when(copyCommandAnswer.getResult()).thenReturn(true);
-        configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l, null), StoragePoolType.Filesystem, 0);
+        configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), StoragePoolType.Filesystem, 0);
     }
 
     @Test
@@ -317,7 +316,7 @@
             if (storagePoolTypeArray[i] == StoragePoolType.Filesystem) {
                 continue;
             }
-            configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l, null), storagePoolTypeArray[i], 0);
+            configureAndTestcopyTemplateToTargetStorageIfNeeded(new VMTemplateStoragePoolVO(0l, 0l), storagePoolTypeArray[i], 0);
         }
     }
 
@@ -354,7 +353,7 @@
         Mockito.when(sourceTemplateInfo.getSize()).thenReturn(0l);
         Mockito.when(sourceTemplateInfo.getHypervisorType()).thenReturn(HypervisorType.KVM);
 
-        Mockito.when(vmTemplatePoolDao.findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong(), nullable(String.class))).thenReturn(vmTemplateStoragePoolVO);
+        Mockito.when(vmTemplatePoolDao.findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong())).thenReturn(vmTemplateStoragePoolVO);
         Mockito.when(dataStoreManagerImpl.getRandomImageStore(Mockito.anyLong())).thenReturn(sourceTemplateDataStore);
         Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore))).thenReturn(sourceTemplateInfo);
         Mockito.when(templateDataFactory.getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore))).thenReturn(sourceTemplateInfo);
@@ -363,7 +362,7 @@
                 Mockito.any(TemplateInfo.class), Mockito.any(DataStore.class));
 
         InOrder verifyInOrder = Mockito.inOrder(vmTemplatePoolDao, dataStoreManagerImpl, templateDataFactory, kvmNonManagedStorageDataMotionStrategy);
-        verifyInOrder.verify(vmTemplatePoolDao, Mockito.times(1)).findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong(), nullable(String.class));
+        verifyInOrder.verify(vmTemplatePoolDao, Mockito.times(1)).findByPoolTemplate(Mockito.anyLong(), Mockito.anyLong());
         verifyInOrder.verify(dataStoreManagerImpl, Mockito.times(times)).getRandomImageStore(Mockito.anyLong());
         verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(sourceTemplateDataStore));
         verifyInOrder.verify(templateDataFactory, Mockito.times(times)).getTemplate(Mockito.anyLong(), Mockito.eq(destDataStore));
diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
index 1590fe0..043af9a 100644
--- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java
@@ -23,9 +23,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.utils.StringUtils;
-import com.cloud.utils.exception.CloudRuntimeException;
 import org.apache.cloudstack.direct.download.DirectDownloadManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
@@ -42,11 +39,13 @@
 
 import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.VMTemplateStoragePoolVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 @Component
 public class TemplateDataFactoryImpl implements TemplateDataFactory {
@@ -67,29 +66,16 @@
     PrimaryDataStoreDao primaryDataStoreDao;
 
     @Override
-    public TemplateInfo getTemplateOnPrimaryStorage(long templateId, DataStore store, String configuration) {
-        VMTemplateVO templ = imageDataDao.findById(templateId);
-        if (store.getRole() == DataStoreRole.Primary) {
-            VMTemplateStoragePoolVO templatePoolVO = templatePoolDao.findByPoolTemplate(store.getId(), templateId, configuration);
-            if (templatePoolVO != null) {
-                String deployAsIsConfiguration = templatePoolVO.getDeploymentOption();
-                return TemplateObject.getTemplate(templ, store, deployAsIsConfiguration);
-            }
-        }
-        return null;
-    }
-
-    @Override
     public TemplateInfo getTemplate(long templateId, DataStore store) {
         VMTemplateVO templ = imageDataDao.findById(templateId);
         if (store == null && !templ.isDirectDownload()) {
-            TemplateObject tmpl = TemplateObject.getTemplate(templ, null, null);
+            TemplateObject tmpl = TemplateObject.getTemplate(templ, null);
             return tmpl;
         }
         // verify if the given input parameters are consistent with our db data.
         boolean found = false;
         if (store.getRole() == DataStoreRole.Primary) {
-            VMTemplateStoragePoolVO templatePoolVO = templatePoolDao.findByPoolTemplate(store.getId(), templateId, null);
+            VMTemplateStoragePoolVO templatePoolVO = templatePoolDao.findByPoolTemplate(store.getId(), templateId);
             if (templatePoolVO != null) {
                 found = true;
             }
@@ -108,7 +94,7 @@
             }
         }
 
-        TemplateObject tmpl = TemplateObject.getTemplate(templ, store, null);
+        TemplateObject tmpl = TemplateObject.getTemplate(templ, store);
         return tmpl;
     }
 
@@ -144,13 +130,8 @@
     }
 
     @Override
-    public TemplateInfo getTemplate(DataObject obj, DataStore store, String configuration) {
-        TemplateObject tmpObj;
-        if (StringUtils.isNotBlank(configuration)) {
-            tmpObj = (TemplateObject)this.getTemplateOnPrimaryStorage(obj.getId(), store, configuration);
-        } else {
-            tmpObj = (TemplateObject)this.getTemplate(obj.getId(), store);
-        }
+    public TemplateInfo getTemplate(DataObject obj, DataStore store) {
+        TemplateObject tmpObj = (TemplateObject)this.getTemplate(obj.getId(), store);
         // carry over url set in passed in data object, for copyTemplate case
         // where url is generated on demand and not persisted in DB.
         // need to think of a more generic way to pass these runtime information
@@ -236,7 +217,7 @@
         if (pool == null) {
             throw new CloudRuntimeException("No storage pool found where to download template: " + templateId);
         }
-        VMTemplateStoragePoolVO spoolRef = templatePoolDao.findByPoolTemplate(pool, templateId, null);
+        VMTemplateStoragePoolVO spoolRef = templatePoolDao.findByPoolTemplate(pool, templateId);
         if (spoolRef == null) {
             directDownloadManager.downloadTemplate(templateId, pool, hostId);
         }
diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
index ed9359d..00bc7e4 100644
--- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -204,7 +204,7 @@
             // clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
             TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId());
             if (templateStoreVO != null) {
-                TemplateInfo tmplObj = _templateFactory.getTemplate(template, store, null);
+                TemplateInfo tmplObj = _templateFactory.getTemplate(template, store);
                 tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
             }
             TemplateApiResult result = new TemplateApiResult(template);
@@ -412,7 +412,7 @@
                                         VirtualMachineTemplate.Event event = VirtualMachineTemplate.Event.OperationSucceeded;
                                         // For multi-disk OVA, check and create data disk templates
                                         if (tmplt.getFormat().equals(ImageFormat.OVA)) {
-                                            if (!createOvaDataDiskTemplates(_templateFactory.getTemplate(tmlpt.getId(), store), tmplt.isDeployAsIs())) {
+                                            if (!createOvaDataDiskTemplates(_templateFactory.getTemplate(tmlpt.getId(), store))) {
                                                 event = VirtualMachineTemplate.Event.OperationFailed;
                                             }
                                         }
@@ -710,7 +710,7 @@
 
         // For multi-disk OVA, check and create data disk templates
         if (template.getFormat().equals(ImageFormat.OVA)) {
-            if (!createOvaDataDiskTemplates(template, template.isDeployAsIs())) {
+            if (!createOvaDataDiskTemplates(template)) {
                 template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
                 result.setResult(callbackResult.getResult());
                 if (parentCallback != null) {
@@ -737,18 +737,12 @@
     }
 
     @Override
-    public List<DatadiskTO> getTemplateDatadisksOnImageStore(TemplateInfo templateInfo, String configurationId) {
-        ImageStoreEntity tmpltStore = (ImageStoreEntity)templateInfo.getDataStore();
-        return tmpltStore.getDataDiskTemplates(templateInfo, configurationId);
-    }
-
-    @Override
-    public boolean createOvaDataDiskTemplates(TemplateInfo parentTemplate, boolean deployAsIs) {
+    public boolean createOvaDataDiskTemplates(TemplateInfo parentTemplate) {
         try {
             // Get Datadisk template (if any) for OVA
             List<DatadiskTO> dataDiskTemplates = new ArrayList<DatadiskTO>();
             ImageStoreEntity tmpltStore = (ImageStoreEntity)parentTemplate.getDataStore();
-            dataDiskTemplates = tmpltStore.getDataDiskTemplates(parentTemplate, null);
+            dataDiskTemplates = tmpltStore.getDataDiskTemplates(parentTemplate);
             int diskCount = 0;
             VMTemplateVO templateVO = _templateDao.findById(parentTemplate.getId());
             _templateDao.loadDetails(templateVO);
@@ -760,27 +754,23 @@
                     details = new HashMap<>();
                 }
             }
-
             for (DatadiskTO diskTemplate : dataDiskTemplates) {
-                if (!deployAsIs) {
-                    if (!diskTemplate.isBootable()) {
-                        createChildDataDiskTemplate(diskTemplate, templateVO, parentTemplate, imageStore, diskCount++);
-                        if (!diskTemplate.isIso() && Strings.isNullOrEmpty(details.get(VmDetailConstants.DATA_DISK_CONTROLLER))){
-                            details.put(VmDetailConstants.DATA_DISK_CONTROLLER, getOvaDiskControllerDetails(diskTemplate, false));
-                            details.put(VmDetailConstants.DATA_DISK_CONTROLLER + diskTemplate.getDiskId(), getOvaDiskControllerDetails(diskTemplate, false));
-                        }
-                    } else {
-                        finalizeParentTemplate(diskTemplate, templateVO, parentTemplate, imageStore, diskCount++);
-                        if (Strings.isNullOrEmpty(VmDetailConstants.ROOT_DISK_CONTROLLER)) {
-                            final String rootDiskController = getOvaDiskControllerDetails(diskTemplate, true);
-                            if (!Strings.isNullOrEmpty(rootDiskController)) {
-                                details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskController);
-                            }
+                if (!diskTemplate.isBootable()) {
+                    createChildDataDiskTemplate(diskTemplate, templateVO, parentTemplate, imageStore, diskCount++);
+                    if (!diskTemplate.isIso() && Strings.isNullOrEmpty(details.get(VmDetailConstants.DATA_DISK_CONTROLLER))){
+                        details.put(VmDetailConstants.DATA_DISK_CONTROLLER, getOvaDiskControllerDetails(diskTemplate, false));
+                        details.put(VmDetailConstants.DATA_DISK_CONTROLLER + diskTemplate.getDiskId(), getOvaDiskControllerDetails(diskTemplate, false));
+                    }
+                } else {
+                    finalizeParentTemplate(diskTemplate, templateVO, parentTemplate, imageStore, diskCount++);
+                    if (Strings.isNullOrEmpty(VmDetailConstants.ROOT_DISK_CONTROLLER)) {
+                        final String rootDiskController = getOvaDiskControllerDetails(diskTemplate, true);
+                        if (!Strings.isNullOrEmpty(rootDiskController)) {
+                            details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskController);
                         }
                     }
                 }
             }
-
             templateVO.setDetails(details);
             _templateDao.saveDetails(templateVO);
             return true;
@@ -799,7 +789,7 @@
         String templateName = dataDiskTemplate.isIso() ? dataDiskTemplate.getPath().substring(dataDiskTemplate.getPath().lastIndexOf(File.separator) + 1) : template.getName() + suffix + diskCount;
         VMTemplateVO templateVO = new VMTemplateVO(templateId, templateName, format, false, false, false, ttype, template.getUrl(),
                 template.requiresHvm(), template.getBits(), template.getAccountId(), null, templateName, false, guestOsId, false, template.getHypervisorType(), null,
-                null, false, false, false, false);
+                null, false, false, false);
         if (dataDiskTemplate.isIso()){
             templateVO.setUniqueName(templateName);
         }
@@ -962,7 +952,7 @@
         AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
         // no need to create entry on template_store_ref here, since entries are already created when prepareSecondaryStorageForMigration is invoked.
         // But we need to set default install path so that sync can be done in the right s3 path
-        TemplateInfo templateOnStore = _templateFactory.getTemplate(template, store, null);
+        TemplateInfo templateOnStore = _templateFactory.getTemplate(template, store);
         String installPath =
                 TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + template.getAccountId() + "/" + template.getId() + "/" +
                         template.getUniqueName();
@@ -1049,7 +1039,7 @@
             throw new CloudRuntimeException("No secondary VM in running state in source template zone ");
         }
 
-        TemplateObject tmplForCopy = (TemplateObject)_templateFactory.getTemplate(srcTemplate, destStore, null);
+        TemplateObject tmplForCopy = (TemplateObject)_templateFactory.getTemplate(srcTemplate, destStore);
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Setting source template url to " + url);
         }
@@ -1078,7 +1068,7 @@
             // clean up already persisted template_store_ref entry in case of createTemplateCallback is never called
             TemplateDataStoreVO templateStoreVO = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId());
             if (templateStoreVO != null) {
-                TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore, null);
+                TemplateInfo tmplObj = _templateFactory.getTemplate(srcTemplate, destStore);
                 tmplObj.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
             }
             TemplateApiResult res = new TemplateApiResult((TemplateObject)templateOnStore);
@@ -1140,7 +1130,7 @@
 
     @Override
     public AsyncCallFuture<TemplateApiResult> deleteTemplateOnPrimary(TemplateInfo template, StoragePool pool) {
-        TemplateObject templateObject = (TemplateObject)_templateFactory.getTemplateOnPrimaryStorage(template.getId(), (DataStore)pool, template.getDeployAsIsConfiguration());
+        TemplateObject templateObject = (TemplateObject)_templateFactory.getTemplate(template.getId(), (DataStore)pool);
 
         templateObject.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
 
@@ -1251,7 +1241,7 @@
             dataDiskTemplateOnStore = (TemplateObject)store.create(dataDiskTemplate);
             dataDiskTemplateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
         } else {
-            dataDiskTemplateOnStore = (TemplateObject) imageFactory.getTemplate(parentTemplate, store, null);
+            dataDiskTemplateOnStore = (TemplateObject) imageFactory.getTemplate(parentTemplate, store);
         }
         try {
             CreateDataDiskTemplateContext<TemplateApiResult> context = new CreateDataDiskTemplateContext<TemplateApiResult>(null, dataDiskTemplateOnStore, future);
@@ -1271,7 +1261,7 @@
     }
 
     protected Void createDatadiskTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback,
-                                                  CreateDataDiskTemplateContext<TemplateApiResult> context) {
+            CreateDataDiskTemplateContext<TemplateApiResult> context) {
         DataObject dataDiskTemplate = context.dataDiskTemplate;
         AsyncCallFuture<TemplateApiResult> future = context.getFuture();
         CreateCmdResult result = callback.getResult();
@@ -1290,4 +1280,4 @@
         future.complete(dataDiskTemplateResult);
         return null;
     }
-}
\ No newline at end of file
+}
diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index d4e2c05..f54673d 100644
--- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -218,8 +218,8 @@
     }
 
     @Override
-    public List<DatadiskTO> getDataDiskTemplates(DataObject obj, String configurationId) {
-        return driver.getDataDiskTemplates(obj, configurationId);
+    public List<DatadiskTO> getDataDiskTemplates(DataObject obj) {
+        return driver.getDataDiskTemplates(obj);
     }
 
     @Override
diff --git a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java
index b7a44cd..86030f2 100644
--- a/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java
+++ b/engine/storage/image/src/main/java/org/apache/cloudstack/storage/image/store/TemplateObject.java
@@ -63,7 +63,6 @@
     private DataStore dataStore;
     private String url;
     private String installPath; // temporarily set installPath before passing to resource for entries with empty installPath for object store migration case
-    private String deployAsIsConfiguration; // Temporarily set
     @Inject
     VMTemplateDao imageDao;
     @Inject
@@ -81,9 +80,8 @@
         this.dataStore = dataStore;
     }
 
-    public static TemplateObject getTemplate(VMTemplateVO vo, DataStore store, String configuration) {
+    public static TemplateObject getTemplate(VMTemplateVO vo, DataStore store) {
         TemplateObject to = ComponentContext.inject(TemplateObject.class);
-        to.deployAsIsConfiguration = configuration;
         to.configure(vo, store);
         return to;
     }
@@ -192,9 +190,7 @@
                 if (answer instanceof CopyCmdAnswer) {
                     CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer;
                     TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData();
-
-                    String deployAsIsConfiguration = newTemplate.getDeployAsIsConfiguration();
-                    VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(getDataStore().getId(), getId(), deployAsIsConfiguration);
+                    VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(getDataStore().getId(), getId());
                     templatePoolRef.setDownloadPercent(100);
 
                     setTemplateSizeIfNeeded(newTemplate, templatePoolRef);
@@ -332,11 +328,6 @@
     }
 
     @Override
-    public String getDeployAsIsConfiguration() {
-        return deployAsIsConfiguration;
-    }
-
-    @Override
     public DataTO getTO() {
         DataTO to = null;
         if (dataStore == null) {
@@ -374,14 +365,6 @@
         return this.imageVO.isDirectDownload();
     }
 
-    @Override
-    public boolean isDeployAsIs() {
-        if (this.imageVO == null) {
-            return false;
-        }
-        return this.imageVO.isDeployAsIs();
-    }
-
     public void setInstallPath(String installPath) {
         this.installPath = installPath;
     }
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
index cfe32c2..727d10a 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
@@ -26,9 +26,6 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.storage.StoragePoolStatus;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -92,7 +89,7 @@
     @Override
     public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
         List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo);
-        return reorderPools(pools, vmProfile, plan);
+        return reOrder(pools, vmProfile, plan);
     }
 
     protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan,
@@ -158,8 +155,7 @@
         return reorderedPools;
     }
 
-    @Override
-    public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) {
+    protected List<StoragePool> reOrder(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) {
         if (pools == null) {
             return null;
         }
@@ -219,29 +215,6 @@
         Volume volume = volumeDao.findById(dskCh.getVolumeId());
         List<Volume> requestVolumes = new ArrayList<>();
         requestVolumes.add(volume);
-        if (dskCh.getHypervisorType() == HypervisorType.VMware) {
-            // Skip the parent datastore cluster, consider only child storage pools in it
-            if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster && storageMgr.isStoragePoolDatastoreClusterParent(pool)) {
-                return false;
-            }
-            // Skip the storage pool whose parent datastore cluster is not in UP state.
-            if (pool.getParent() != 0L) {
-                StoragePoolVO datastoreCluster = storagePoolDao.findById(pool.getParent());
-                if (datastoreCluster == null || (datastoreCluster != null && datastoreCluster.getStatus() != StoragePoolStatus.Up)) {
-                    return false;
-                }
-            }
-
-            try {
-                boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolComplaintWithStoragePolicy(requestVolumes, pool);
-                if (!isStoragePoolStoragepolicyComplaince) {
-                    return false;
-                }
-            } catch (StorageUnavailableException e) {
-                s_logger.warn(String.format("Could not verify storage policy complaince against storage pool %s due to exception %s", pool.getUuid(), e.getMessage()));
-                return false;
-            }
-        }
         return storageMgr.storagePoolHasEnoughIops(requestVolumes, pool) && storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool, plan.getClusterId());
     }
 
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
index 777eb37..2caa3ef 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java
@@ -76,7 +76,7 @@
             s_logger.debug("waiting too long for template downloading, marked it as failed");
             throw new CloudRuntimeException("waiting too long for template downloading, marked it as failed");
         }
-        return objectInDataStoreMgr.get(dataObj, dataStore, null);
+        return objectInDataStoreMgr.get(dataObj, dataStore);
     }
 
     class CreateContext<T> extends AsyncRpcContext<T> {
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
index 48aceca..8f081d3 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java
@@ -33,11 +33,11 @@
 
     boolean deleteIfNotReady(DataObject dataObj);
 
-    DataObject get(DataObject dataObj, DataStore store, String configuration);
+    DataObject get(DataObject dataObj, DataStore store);
 
     boolean update(DataObject vo, Event event) throws NoTransitionException, ConcurrentOperationException;
 
-    DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role, String deployAsIsConfiguration);
+    DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role);
 
     DataObjectInStore findObject(DataObject obj, DataStore store);
 
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
index da97b22..ff8112c 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java
@@ -118,7 +118,7 @@
     public DataObject create(DataObject obj, DataStore dataStore) {
         if (dataStore.getRole() == DataStoreRole.Primary) {
             if (obj.getType() == DataObjectType.TEMPLATE) {
-                VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId(), null);
+                VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId());
                 vo = templatePoolDao.persist(vo);
             } else if (obj.getType() == DataObjectType.SNAPSHOT) {
                 SnapshotInfo snapshotInfo = (SnapshotInfo)obj;
@@ -197,7 +197,7 @@
             }
         }
 
-        return this.get(obj, dataStore, null);
+        return this.get(obj, dataStore);
     }
 
     @Override
@@ -206,7 +206,7 @@
         DataStore dataStore = dataObj.getDataStore();
         if (dataStore.getRole() == DataStoreRole.Primary) {
             if (dataObj.getType() == DataObjectType.TEMPLATE) {
-                VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId, null);
+                VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId);
                 if (destTmpltPool != null) {
                     return templatePoolDao.remove(destTmpltPool.getId());
                 } else {
@@ -254,7 +254,7 @@
         DataStore dataStore = dataObj.getDataStore();
         if (dataStore.getRole() == DataStoreRole.Primary) {
             if (dataObj.getType() == DataObjectType.TEMPLATE) {
-                VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId, null);
+                VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId);
                 if (destTmpltPool != null && destTmpltPool.getState() != ObjectInDataStoreStateMachine.State.Ready) {
                     return templatePoolDao.remove(destTmpltPool.getId());
                 } else {
@@ -333,9 +333,9 @@
     }
 
     @Override
-    public DataObject get(DataObject dataObj, DataStore store, String configuration) {
+    public DataObject get(DataObject dataObj, DataStore store) {
         if (dataObj.getType() == DataObjectType.TEMPLATE) {
-            return imageFactory.getTemplate(dataObj, store, configuration);
+            return imageFactory.getTemplate(dataObj, store);
         } else if (dataObj.getType() == DataObjectType.VOLUME) {
             return volumeFactory.getVolume(dataObj, store);
         } else if (dataObj.getType() == DataObjectType.SNAPSHOT) {
@@ -347,15 +347,11 @@
 
     @Override
     public DataObjectInStore findObject(DataObject obj, DataStore store) {
-        String deployAsIsConfiguration = null;
-        if (obj.getType() == DataObjectType.TEMPLATE) {
-            deployAsIsConfiguration = ((TemplateInfo) obj).getDeployAsIsConfiguration();
-        }
-        return findObject(obj.getId(), obj.getType(), store.getId(), store.getRole(), deployAsIsConfiguration);
+        return findObject(obj.getId(), obj.getType(), store.getId(), store.getRole());
     }
 
     @Override
-    public DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role, String deployAsIsConfiguration) {
+    public DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role) {
         DataObjectInStore vo = null;
         if (role == DataStoreRole.Image || role == DataStoreRole.ImageCache) {
             switch (type) {
@@ -370,7 +366,7 @@
                     break;
             }
         } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) {
-            vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId, deployAsIsConfiguration);
+            vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId);
         } else if (type == DataObjectType.SNAPSHOT && role == DataStoreRole.Primary) {
             vo = snapshotDataStoreDao.findByStoreSnapshot(role, dataStoreId, objId);
         } else {
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
index 37a7985..2341603 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
@@ -32,10 +32,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.storage.Upload;
-import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper;
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
@@ -55,6 +51,8 @@
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.endpoint.DefaultEndPointSelector;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -62,9 +60,11 @@
 import com.cloud.agent.api.storage.DownloadAnswer;
 import com.cloud.agent.api.storage.GetDatadisksAnswer;
 import com.cloud.agent.api.storage.GetDatadisksCommand;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.DatadiskTO;
+import com.cloud.agent.api.to.NfsTO;
 import com.cloud.alert.AlertManager;
 import com.cloud.configuration.Config;
 import com.cloud.exception.AgentUnavailableException;
@@ -72,25 +72,30 @@
 import com.cloud.host.dao.HostDao;
 import com.cloud.secstorage.CommandExecLogDao;
 import com.cloud.secstorage.CommandExecLogVO;
+import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.StorageManager;
+import com.cloud.storage.TemplateOVFPropertyVO;
+import com.cloud.storage.Upload;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.TemplateOVFPropertiesDao;
 import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateDetailsDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.download.DownloadMonitor;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.crypt.DBEncryptionUtil;
 import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.net.Proxy;
 import com.cloud.vm.dao.SecondaryStorageVmDao;
 
 public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
-    private static final Logger LOGGER = Logger.getLogger(BaseImageStoreDriverImpl.class);
-
+    private static final Logger s_logger = Logger.getLogger(BaseImageStoreDriverImpl.class);
     @Inject
     protected VMTemplateDao _templateDao;
     @Inject
@@ -110,13 +115,15 @@
     @Inject
     AlertManager _alertMgr;
     @Inject
+    VMTemplateDetailsDao _templateDetailsDao;
+    @Inject
     DefaultEndPointSelector _defaultEpSelector;
     @Inject
     AccountDao _accountDao;
     @Inject
     ResourceLimitService _resourceLimitMgr;
     @Inject
-    DeployAsIsHelper deployAsIsHelper;
+    TemplateOVFPropertiesDao templateOvfPropertiesDao;
     @Inject
     HostDao hostDao;
     @Inject
@@ -177,45 +184,63 @@
         caller.setContext(context);
         if (data.getType() == DataObjectType.TEMPLATE) {
             caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null));
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("Downloading template to data store " + dataStore.getId());
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Downloading template to data store " + dataStore.getId());
             }
             _downloadMonitor.downloadTemplateToStorage(data, caller);
         } else if (data.getType() == DataObjectType.VOLUME) {
             caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null));
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("Downloading volume to data store " + dataStore.getId());
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Downloading volume to data store " + dataStore.getId());
             }
             _downloadMonitor.downloadVolumeToStorage(data, caller);
         }
     }
 
+    /**
+     * Persist OVF properties as template details for template with id = templateId
+     */
+    private void persistOVFProperties(List<OVFPropertyTO> ovfProperties, long templateId) {
+        List<TemplateOVFPropertyVO> listToPersist = new ArrayList<>();
+        for (OVFPropertyTO property : ovfProperties) {
+            if (!templateOvfPropertiesDao.existsOption(templateId, property.getKey())) {
+                TemplateOVFPropertyVO option = new TemplateOVFPropertyVO(templateId, property.getKey(), property.getType(),
+                        property.getValue(), property.getQualifiers(), property.isUserConfigurable(),
+                        property.getLabel(), property.getDescription(), property.isPassword());
+                if (property.isPassword()) {
+                    String encryptedPassword = DBEncryptionUtil.encrypt(property.getValue());
+                    option.setValue(encryptedPassword);
+                }
+                listToPersist.add(option);
+            }
+        }
+        if (CollectionUtils.isNotEmpty(listToPersist)) {
+            s_logger.debug("Persisting " + listToPersist.size() + " OVF properties for template " + templateId);
+            templateOvfPropertiesDao.saveOptions(listToPersist);
+        }
+    }
+
     protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback,
-                                               CreateContext<CreateCmdResult> context) {
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Performing image store createTemplate async callback");
+        CreateContext<CreateCmdResult> context) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Performing image store createTemplate async callback");
         }
         DownloadAnswer answer = callback.getResult();
         DataObject obj = context.data;
         DataStore store = obj.getDataStore();
+        List<OVFPropertyTO> ovfProperties = answer.getOvfProperties();
 
-        VMTemplateVO template = _templateDao.findById(obj.getId());
         TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId());
         if (tmpltStoreVO != null) {
             if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                if (template.isDeployAsIs()) {
-                    boolean persistDeployAsIs = deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer, tmpltStoreVO);
-                    if (!persistDeployAsIs) {
-                        LOGGER.info("Failed persisting deploy-as-is template details for template " + template.getName());
-                        return null;
-                    }
+                if (CollectionUtils.isNotEmpty(ovfProperties)) {
+                    persistOVFProperties(ovfProperties, obj.getId());
                 }
-                if (LOGGER.isDebugEnabled()) {
-                    LOGGER.debug("Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
                 }
                 return null;
             }
-            LOGGER.info("Updating store ref entry for template " + template.getName());
             TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate();
             updateBuilder.setDownloadPercent(answer.getDownloadPct());
             updateBuilder.setDownloadState(answer.getDownloadStatus());
@@ -236,20 +261,23 @@
         AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
 
         if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR ||
-                answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
+            answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
             CreateCmdResult result = new CreateCmdResult(null, null);
             result.setSuccess(false);
             result.setResult(answer.getErrorString());
             caller.complete(result);
             String msg = "Failed to register template: " + obj.getUuid() + " with error: " + answer.getErrorString();
             _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED, _vmTemplateZoneDao.listByTemplateId(obj.getId()).get(0).getZoneId(), null, msg, msg);
-            LOGGER.error(msg);
+            s_logger.error(msg);
         } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
             if (answer.getCheckSum() != null) {
                 VMTemplateVO templateDaoBuilder = _templateDao.createForUpdate();
                 templateDaoBuilder.setChecksum(answer.getCheckSum());
                 _templateDao.update(obj.getId(), templateDaoBuilder);
             }
+            if (CollectionUtils.isNotEmpty(ovfProperties)) {
+                persistOVFProperties(ovfProperties, obj.getId());
+            }
 
             CreateCmdResult result = new CreateCmdResult(null, null);
             caller.complete(result);
@@ -258,7 +286,7 @@
     }
 
     protected Void
-    createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) {
+        createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) {
         DownloadAnswer answer = callback.getResult();
         DataObject obj = context.data;
         DataStore store = obj.getDataStore();
@@ -266,8 +294,8 @@
         VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId());
         if (volStoreVO != null) {
             if (volStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
-                if (LOGGER.isDebugEnabled()) {
-                    LOGGER.debug("Volume is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Volume is already in DOWNLOADED state, ignore further incoming DownloadAnswer");
                 }
                 return null;
             }
@@ -291,7 +319,7 @@
         AsyncCompletionCallback<CreateCmdResult> caller = context.getParentCallback();
 
         if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR ||
-                answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
+            answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) {
             CreateCmdResult result = new CreateCmdResult(null, null);
             result.setSuccess(false);
             result.setResult(answer.getErrorString());
@@ -299,7 +327,7 @@
             String msg = "Failed to upload volume: " + obj.getUuid() + " with error: " + answer.getErrorString();
             _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPLOAD_FAILED,
                     (volStoreVO == null ? -1L : volStoreVO.getZoneId()), null, msg, msg);
-            LOGGER.error(msg);
+            s_logger.error(msg);
         } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
             CreateCmdResult result = new CreateCmdResult(null, null);
             caller.complete(result);
@@ -316,7 +344,7 @@
             Answer answer = null;
             if (ep == null) {
                 String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                LOGGER.error(errMsg);
+                s_logger.error(errMsg);
                 answer = new Answer(cmd, false, errMsg);
             } else {
                 answer = ep.sendMessage(cmd);
@@ -325,7 +353,7 @@
                 result.setResult(answer.getDetails());
             }
         } catch (Exception ex) {
-            LOGGER.debug("Unable to destoy " + data.getType().toString() + ": " + data.getId(), ex);
+            s_logger.debug("Unable to destoy " + data.getType().toString() + ": " + data.getId(), ex);
             result.setResult(ex.toString());
         }
         callback.complete(result);
@@ -349,7 +377,7 @@
             List<EndPoint> eps = _epSelector.findAllEndpointsForScope(srcdata.getDataStore());
             if (eps == null || eps.isEmpty()) {
                 String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-                LOGGER.error(errMsg);
+                s_logger.error(errMsg);
                 answer = new Answer(cmd, false, errMsg);
             } else {
                 // select endpoint with least number of commands running on them
@@ -386,16 +414,25 @@
             return answer;
         }  catch (AgentUnavailableException e) {
             errMsg = e.toString();
-            LOGGER.debug("Failed to send command, due to Agent:" + endPoint.getId() + ", " + e.toString());
+            s_logger.debug("Failed to send command, due to Agent:" + endPoint.getId() + ", " + e.toString());
         } catch (OperationTimedoutException e) {
             errMsg = e.toString();
-            LOGGER.debug("Failed to send command, due to Agent:" + endPoint.getId() + ", " + e.toString());
+            s_logger.debug("Failed to send command, due to Agent:" + endPoint.getId() + ", " + e.toString());
         }
         throw new CloudRuntimeException("Failed to send command, due to Agent:" + endPoint.getId() + ", " + errMsg);
     }
 
     @Override
     public boolean canCopy(DataObject srcData, DataObject destData) {
+        DataStore srcStore = srcData.getDataStore();
+        DataStore destStore = destData.getDataStore();
+        if ((srcData.getDataStore().getTO() instanceof NfsTO && destData.getDataStore().getTO() instanceof NfsTO) &&
+                (srcStore.getRole() == DataStoreRole.Image && destStore.getRole() == DataStoreRole.Image) &&
+                ((srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.TEMPLATE) ||
+                (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) ||
+                (srcData.getType() == DataObjectType.VOLUME && destData.getType() == DataObjectType.VOLUME))) {
+            return true;
+        }
         return false;
     }
 
@@ -408,18 +445,18 @@
     }
 
     @Override
-    public List<DatadiskTO> getDataDiskTemplates(DataObject obj, String configurationId) {
+    public List<DatadiskTO> getDataDiskTemplates(DataObject obj) {
         List<DatadiskTO> dataDiskDetails = new ArrayList<DatadiskTO>();
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Get the data disks present in the OVA template");
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Get the data disks present in the OVA template");
         }
         DataStore store = obj.getDataStore();
-        GetDatadisksCommand cmd = new GetDatadisksCommand(obj.getTO(), configurationId);
+        GetDatadisksCommand cmd = new GetDatadisksCommand(obj.getTO());
         EndPoint ep = _defaultEpSelector.select(store);
         Answer answer = null;
         if (ep == null) {
             String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            LOGGER.error(errMsg);
+            s_logger.error(errMsg);
             answer = new Answer(cmd, false, errMsg);
         } else {
             answer = ep.sendMessage(cmd);
@@ -438,14 +475,14 @@
     public Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, String diskId, boolean bootable, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback) {
         Answer answer = null;
         String errMsg = null;
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Create Datadisk template: " + dataDiskTemplate.getId());
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Create Datadisk template: " + dataDiskTemplate.getId());
         }
         CreateDatadiskTemplateCommand cmd = new CreateDatadiskTemplateCommand(dataDiskTemplate.getTO(), path, diskId, fileSize, bootable);
         EndPoint ep = _defaultEpSelector.select(dataDiskTemplate.getDataStore());
         if (ep == null) {
             errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
-            LOGGER.error(errMsg);
+            s_logger.error(errMsg);
             answer = new Answer(cmd, false, errMsg);
         } else {
             answer = ep.sendMessage(cmd);
@@ -459,12 +496,8 @@
         return null;
     }
 
-    private Integer getCopyCmdsCountToSpecificSSVM(Long ssvmId) {
-        return _cmdExecLogDao.getCopyCmdCountForSSVM(ssvmId);
-    }
-
     private List<Long> ssvmWithLeastMigrateJobs() {
-        LOGGER.debug("Picking ssvm from the pool with least commands running on it");
+        s_logger.debug("Picking ssvm from the pool with least commands running on it");
         String query = "select host_id, count(*) from cmd_exec_log group by host_id order by 2;";
         TransactionLegacy txn = TransactionLegacy.currentTxn();
 
@@ -477,7 +510,7 @@
                 result.add((long) rs.getInt(1));
             }
         } catch (SQLException e) {
-            LOGGER.debug("SQLException caught", e);
+            s_logger.debug("SQLException caught", e);
         }
         return result;
     }
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java
index 29071d8..70f40f6 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/ImageStoreDriver.java
@@ -37,7 +37,7 @@
 
     void deleteEntityExtractUrl(DataStore store, String installPath, String url, Upload.Type entityType);
 
-    List<DatadiskTO> getDataDiskTemplates(DataObject obj, String configurationId);
+    List<DatadiskTO> getDataDiskTemplates(DataObject obj);
 
     Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, String diskId, boolean bootable, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback);
 }
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
new file mode 100644
index 0000000..b027c42
--- /dev/null
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cloudstack.storage.image;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
+import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.TemplateType;
+import com.cloud.template.VirtualMachineTemplate;
+
+public class TemplateEntityImpl implements TemplateEntity {
+    protected TemplateInfo templateInfo;
+
+    @Override
+    public State getState() {
+        return templateInfo.getState();
+    }
+
+    public TemplateEntityImpl(TemplateInfo templateInfo) {
+        this.templateInfo = templateInfo;
+    }
+
+    public ImageStoreInfo getImageDataStore() {
+        return (ImageStoreInfo)templateInfo.getDataStore();
+    }
+
+    public long getImageDataStoreId() {
+        return getImageDataStore().getImageStoreId();
+    }
+
+    public TemplateInfo getTemplateInfo() {
+        return templateInfo;
+    }
+
+    @Override
+    public String getUuid() {
+        return templateInfo.getUuid();
+    }
+
+    @Override
+    public long getId() {
+        return templateInfo.getId();
+    }
+
+    public String getExternalId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getCurrentState() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getDesiredState() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getCreatedTime() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Date getLastUpdatedTime() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getOwner() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<String, String> getDetails() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isDynamicallyScalable() {
+        return false;
+    }
+
+    @Override
+    public void addDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void delDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void updateDetail(String name, String value) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public List<Method> getApplicableActions() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isFeatured() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isPublicTemplate() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isExtractable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ImageFormat getFormat() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isRequiresHvm() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public String getDisplayText() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isEnablePassword() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isEnableSshKey() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isCrossZones() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Date getCreated() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long getGuestOSId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public boolean isBootable() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public TemplateType getTemplateType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public int getBits() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getUniqueName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getUrl() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getChecksum() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Long getSourceTemplateId() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public String getTemplateTag() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public long getAccountId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getDomainId() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getPhysicalSize() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public long getVirtualSize() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public Class<?> getEntityType() {
+        return VirtualMachineTemplate.class;
+    }
+
+    @Override
+    public long getUpdatedCount() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public void incrUpdatedCount() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public Date getUpdated() {
+        return null;
+    }
+
+    @Override
+    public Long getParentTemplateId() {
+        return null;
+    }
+}
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java
deleted file mode 100644
index 4f7277e..0000000
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.storage.image.deployasis;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.vm.VirtualMachineProfile;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-
-import java.util.Map;
-
-public interface DeployAsIsHelper {
-
-    boolean persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer, TemplateDataStoreVO tmpltStoreVO);
-    Map<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vmId);
-
-    String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool);
-    String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm);
-
-    Map<Integer, String> getAllocatedVirtualMachineNicsAdapterMapping(VirtualMachineProfile vm, NicTO[] nics);
-}
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java
deleted file mode 100644
index 0d52f57..0000000
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.cloudstack.storage.image.deployasis;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.OVFInformationTO;
-import com.cloud.agent.api.to.deployasis.OVFConfigurationTO;
-import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO;
-import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO;
-import com.cloud.agent.api.to.deployasis.TemplateDeployAsIsInformationTO;
-import com.cloud.deployasis.DeployAsIsConstants;
-import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
-import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
-import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
-import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.storage.GuestOSCategoryVO;
-import com.cloud.storage.GuestOSHypervisorVO;
-import com.cloud.storage.GuestOSVO;
-import com.cloud.storage.VMTemplateStoragePoolVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.Volume;
-import com.cloud.storage.dao.GuestOSCategoryDao;
-import com.cloud.storage.dao.GuestOSDao;
-import com.cloud.storage.dao.GuestOSHypervisorDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.utils.Pair;
-import com.cloud.utils.compression.CompressionUtil;
-import com.cloud.utils.crypt.DBEncryptionUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.VirtualMachineProfile;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import javax.inject.Inject;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State.Failed;
-
-@Component
-public class DeployAsIsHelperImpl implements DeployAsIsHelper {
-
-    private static final Logger LOGGER = Logger.getLogger(DeployAsIsHelperImpl.class);
-    private static Gson gson;
-
-    @Inject
-    private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
-    @Inject
-    private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
-    @Inject
-    private PrimaryDataStoreDao storagePoolDao;
-    @Inject
-    private VMTemplatePoolDao templateStoragePoolDao;
-    @Inject
-    private VMTemplateDao templateDao;
-    @Inject
-    private GuestOSDao guestOSDao;
-    @Inject
-    private GuestOSHypervisorDao guestOSHypervisorDao;
-    @Inject
-    private GuestOSCategoryDao guestOSCategoryDao;
-    @Inject
-    private TemplateDataStoreDao templateDataStoreDao;
-
-    static {
-        GsonBuilder builder = new GsonBuilder();
-        builder.disableHtmlEscaping();
-        gson = builder.create();
-    }
-
-    public boolean persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer, TemplateDataStoreVO tmpltStoreVO) {
-        try {
-            OVFInformationTO ovfInformationTO = answer.getOvfInformationTO();
-            if (ovfInformationTO != null) {
-                List<OVFPropertyTO> ovfProperties = ovfInformationTO.getProperties();
-                List<OVFNetworkTO> networkRequirements = ovfInformationTO.getNetworks();
-                OVFVirtualHardwareSectionTO ovfHardwareSection = ovfInformationTO.getHardwareSection();
-                List<OVFEulaSectionTO> eulaSections = ovfInformationTO.getEulaSections();
-                Pair<String, String> guestOsInfo = ovfInformationTO.getGuestOsInfo();
-
-                if (CollectionUtils.isNotEmpty(ovfProperties)) {
-                    persistTemplateDeployAsIsInformationTOList(templateId, ovfProperties);
-                }
-                if (CollectionUtils.isNotEmpty(networkRequirements)) {
-                    persistTemplateDeployAsIsInformationTOList(templateId, networkRequirements);
-                }
-                if (CollectionUtils.isNotEmpty(eulaSections)) {
-                    persistTemplateDeployAsIsInformationTOList(templateId, eulaSections);
-                }
-                String minimumHardwareVersion = null;
-                if (ovfHardwareSection != null) {
-                    if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) {
-                        persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getConfigurations());
-                    }
-                    if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) {
-                        persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getCommonHardwareItems());
-                    }
-                    minimumHardwareVersion = ovfHardwareSection.getMinimiumHardwareVersion();
-                }
-                if (guestOsInfo != null) {
-                    String osType = guestOsInfo.first();
-                    String osDescription = guestOsInfo.second();
-                    LOGGER.info("Guest OS information retrieved from the template: " + osType + " - " + osDescription);
-                    handleGuestOsFromOVFDescriptor(templateId, osType, osDescription, minimumHardwareVersion);
-                }
-            }
-        } catch (Exception e) {
-            LOGGER.error("Error persisting deploy-as-is details for template " + templateId, e);
-            tmpltStoreVO.setErrorString(e.getMessage());
-            tmpltStoreVO.setState(Failed);
-            tmpltStoreVO.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-            templateDataStoreDao.update(tmpltStoreVO.getId(), tmpltStoreVO);
-            return false;
-        }
-        LOGGER.info("Successfully persisted deploy-as-is details for template " + templateId);
-        return true;
-    }
-
-    /**
-     * Handle the guest OS read from the OVF and try to match it to an existing guest OS in DB.
-     * If the guest OS cannot be mapped to an existing guest OS in DB, then create it and create support for hypervisor versions.
-     * Roll back actions in case of unexpected erros
-     */
-    private void handleGuestOsFromOVFDescriptor(long templateId, String guestOsType, String guestOsDescription,
-                                                String minimumHardwareVersion) {
-        VMTemplateVO template = templateDao.findById(templateId);
-        Hypervisor.HypervisorType hypervisor = template.getHypervisorType();
-        if (hypervisor != Hypervisor.HypervisorType.VMware) {
-            return;
-        }
-        String minimumHypervisorVersion = getMinimumSupportedHypervisorVersionForHardwareVersion(minimumHardwareVersion);
-        LOGGER.info("Minimum hardware version " + minimumHardwareVersion + " matched to hypervisor version " + minimumHypervisorVersion + ". " +
-                "Checking guest OS supporting this version");
-
-        List<GuestOSHypervisorVO> guestOsMappings = guestOSHypervisorDao.listByOsNameAndHypervisorMinimumVersion(guestOsType,
-                hypervisor.toString(), minimumHypervisorVersion);
-
-        if (CollectionUtils.isNotEmpty(guestOsMappings)) {
-            GuestOSHypervisorVO mapping = guestOsMappings.get(0);
-            long guestOsId = mapping.getGuestOsId();
-            LOGGER.info("Updating deploy-as-is template guest OS to " + guestOsType);
-            updateTemplateGuestOsId(template, guestOsId);
-        } else {
-            throw new CloudRuntimeException("Did not find a guest OS with type " + guestOsType);
-        }
-    }
-
-    /**
-     * Updates the deploy-as-is template guest OS doing:
-     * - Create a new guest OS with the guest OS description parsed from the OVF
-     * - Create mappings for the new guest OS and supported hypervisor versions
-     * - Update the template guest OS ID to the new guest OS ID
-     */
-    private void updateDeployAsIsTemplateToNewGuestOs(VMTemplateVO template, String guestOsType, String guestOsDescription,
-                                                      Hypervisor.HypervisorType hypervisor, Collection<String> hypervisorVersions) {
-        GuestOSVO newGuestOs = createGuestOsEntry(guestOsDescription);
-        for (String hypervisorVersion : hypervisorVersions) {
-            LOGGER.info(String.format("Adding a new guest OS mapping for hypervisor: %s version: %s and " +
-                    "guest OS: %s", hypervisor.toString(), hypervisorVersion, guestOsType));
-            createGuestOsHypervisorMapping(newGuestOs.getId(), guestOsType, hypervisor.toString(), hypervisorVersion);
-        }
-        updateTemplateGuestOsId(template, newGuestOs.getId());
-    }
-
-    private void updateTemplateGuestOsId(VMTemplateVO template, long guestOsId) {
-        template.setGuestOSId(guestOsId);
-        templateDao.update(template.getId(), template);
-    }
-
-    /**
-     * Create a new entry on guest_os_hypervisor
-     */
-    private void createGuestOsHypervisorMapping(long guestOsId, String guestOsType, String hypervisorType, String hypervisorVersion) {
-        GuestOSHypervisorVO mappingVO = new GuestOSHypervisorVO();
-        mappingVO.setGuestOsId(guestOsId);
-        mappingVO.setHypervisorType(hypervisorType);
-        mappingVO.setHypervisorVersion(hypervisorVersion);
-        mappingVO.setGuestOsName(guestOsType);
-        guestOSHypervisorDao.persist(mappingVO);
-    }
-
-    /**
-     * Create new guest OS entry with category 'Other'
-     */
-    private GuestOSVO createGuestOsEntry(String guestOsDescription) {
-        GuestOSCategoryVO categoryVO = guestOSCategoryDao.findByCategoryName("Other");
-        long categoryId = categoryVO != null ? categoryVO.getId() : 7L;
-        GuestOSVO guestOSVO = new GuestOSVO();
-        guestOSVO.setDisplayName(guestOsDescription);
-        guestOSVO.setCategoryId(categoryId);
-        return guestOSDao.persist(guestOSVO);
-    }
-
-    /**
-     * Minimum VMware hosts supported version is 6.0
-     */
-    protected String getMinimumSupportedHypervisorVersionForHardwareVersion(String hardwareVersion) {
-        // From https://kb.vmware.com/s/article/1003746 and https://kb.vmware.com/s/article/2007240
-        String hypervisorVersion = "default";
-        if (StringUtils.isBlank(hardwareVersion)) {
-            return hypervisorVersion;
-        }
-        String hwVersion = hardwareVersion.replace("vmx-", "");
-        try {
-            int hwVersionNumber = Integer.parseInt(hwVersion);
-            if (hwVersionNumber <= 11) {
-                hypervisorVersion = "6.0";
-            } else if (hwVersionNumber == 13) {
-                hypervisorVersion = "6.5";
-            } else if (hwVersionNumber >= 14) {
-                hypervisorVersion = "6.7";
-            }
-        } catch (NumberFormatException e) {
-            LOGGER.error("Cannot parse hardware version " + hwVersion + " to integer. Using default hypervisor version", e);
-        }
-        return hypervisorVersion;
-    }
-
-    @Override
-    public Map<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vm) {
-        Map<String, String> map = new HashMap<>();
-        List<UserVmDeployAsIsDetailVO> details = userVmDeployAsIsDetailsDao.listDetails(vm.getId());
-        if (CollectionUtils.isNotEmpty(details)) {
-            for (UserVmDeployAsIsDetailVO detail : details) {
-                OVFPropertyTO property = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), detail.getName());
-                String value = property.isPassword() ? DBEncryptionUtil.decrypt(detail.getValue()) : detail.getValue();
-                map.put(detail.getName(), value);
-            }
-        }
-        return map;
-    }
-
-    @Override
-    public String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool) {
-        StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(destStoragePool);
-        VMTemplateStoragePoolVO tmplRef = templateStoragePoolDao.findByPoolTemplate(storagePoolVO.getId(),
-                vm.getTemplate().getId(), configuration);
-        if (tmplRef != null) {
-            return tmplRef.getInstallPath();
-        }
-        return null;
-    }
-
-    @Override
-    public String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm) {
-        if (vm != null) {
-            if (CollectionUtils.isNotEmpty(vm.getDisks())) {
-                for (DiskTO disk : vm.getDisks()) {
-                    if (disk.getType() == Volume.Type.ISO) {
-                        continue;
-                    }
-                    DataTO data = disk.getData();
-                    if (data != null) {
-                        DataStoreTO dataStore = data.getDataStore();
-                        if (dataStore != null) {
-                            return dataStore.getUuid();
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public Map<Integer, String> getAllocatedVirtualMachineNicsAdapterMapping(VirtualMachineProfile vm, NicTO[] nics) {
-        Map<Integer, String> map = new HashMap<>();
-        List<OVFNetworkTO> networks = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplateId());
-        if (ArrayUtils.isNotEmpty(nics)) {
-            if (nics.length != networks.size()) {
-                String msg = "Different number of networks provided vs networks defined in deploy-as-is template";
-                LOGGER.error(msg);
-                return map;
-            }
-            for (int i = 0; i < nics.length; i++) {
-                // The nic Adapter is defined on the resource sub type
-                map.put(nics[i].getDeviceId(), networks.get(i).getResourceSubType());
-            }
-        }
-        return map;
-    }
-
-    private void persistTemplateDeployAsIsInformationTOList(long templateId,
-                                                            List<? extends TemplateDeployAsIsInformationTO> informationTOList) {
-        for (TemplateDeployAsIsInformationTO informationTO : informationTOList) {
-            String propKey = getKeyFromInformationTO(informationTO);
-            if (LOGGER.isTraceEnabled()) {
-                LOGGER.trace(String.format("Saving property %s for template %d as detail", propKey, templateId));
-            }
-            String propValue = null;
-            try {
-                 propValue = getValueFromInformationTO(informationTO);
-            } catch (RuntimeException re) {
-                LOGGER.error("gson marshalling of property object fails: " + propKey,re);
-            } catch (IOException e) {
-                LOGGER.error("Could not decompress the license for template " + templateId, e);
-            }
-            saveTemplateDeployAsIsPropertyAttribute(templateId, propKey, propValue);
-        }
-    }
-
-    private String getValueFromInformationTO(TemplateDeployAsIsInformationTO informationTO) throws IOException {
-        if (informationTO instanceof OVFEulaSectionTO) {
-            CompressionUtil compressionUtil = new CompressionUtil();
-            byte[] compressedLicense = ((OVFEulaSectionTO) informationTO).getCompressedLicense();
-            return compressionUtil.decompressByteArary(compressedLicense);
-        }
-        return gson.toJson(informationTO);
-    }
-
-    private String getKeyFromInformationTO(TemplateDeployAsIsInformationTO informationTO) {
-        if (informationTO instanceof OVFPropertyTO) {
-            return DeployAsIsConstants.PROPERTY_PREFIX + ((OVFPropertyTO) informationTO).getKey();
-        } else if (informationTO instanceof OVFNetworkTO) {
-            return DeployAsIsConstants.NETWORK_PREFIX + ((OVFNetworkTO) informationTO).getName();
-        } else if (informationTO instanceof OVFConfigurationTO) {
-            return DeployAsIsConstants.CONFIGURATION_PREFIX +
-                    ((OVFConfigurationTO) informationTO).getIndex() + "-" + ((OVFConfigurationTO) informationTO).getId();
-        } else if (informationTO instanceof OVFVirtualHardwareItemTO) {
-            String key = ((OVFVirtualHardwareItemTO) informationTO).getResourceType().getName().trim().replaceAll("\\s","")
-                    + "-" + ((OVFVirtualHardwareItemTO) informationTO).getInstanceId();
-            return DeployAsIsConstants.HARDWARE_ITEM_PREFIX + key;
-        } else if (informationTO instanceof OVFEulaSectionTO) {
-            return DeployAsIsConstants.EULA_PREFIX + ((OVFEulaSectionTO) informationTO).getIndex() +
-                    "-" + ((OVFEulaSectionTO) informationTO).getInfo();
-        }
-        return null;
-    }
-
-    private void saveTemplateDeployAsIsPropertyAttribute(long templateId, String key, String value) {
-        if (LOGGER.isTraceEnabled()) {
-            LOGGER.trace(String.format("Saving property %s for template %d as detail", key, templateId));
-        }
-        if (templateDeployAsIsDetailsDao.findDetail(templateId,key) != null) {
-            LOGGER.debug(String.format("Detail '%s' existed for template %d, deleting.", key, templateId));
-            templateDeployAsIsDetailsDao.removeDetail(templateId,key);
-        }
-        if (LOGGER.isTraceEnabled()) {
-            LOGGER.trace(String.format("Template detail for template %d to save is '%s': '%s'", templateId, key, value));
-        }
-        TemplateDeployAsIsDetailVO detailVO = new TemplateDeployAsIsDetailVO(templateId, key, value);
-        LOGGER.debug("Persisting template details " + detailVO.getName() + " from OVF properties for template " + templateId);
-        templateDeployAsIsDetailsDao.persist(detailVO);
-    }
-
-}
diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
index ac2c935..31b5708 100644
--- a/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
+++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java
@@ -161,13 +161,6 @@
         pool.setScope(ScopeType.CLUSTER);
         pool.setStatus(StoragePoolStatus.Up);
         this.dataStoreDao.update(pool.getId(), pool);
-        if(pool.getPoolType() == StoragePoolType.DatastoreCluster && pool.getParent() == 0) {
-            List<StoragePoolVO> childDatastores = dataStoreDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-            for (StoragePoolVO child : childDatastores) {
-                child.setScope(ScopeType.CLUSTER);
-                this.dataStoreDao.update(child.getId(), child);
-            }
-        }
         return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
     }
 
@@ -185,13 +178,6 @@
         pool.setHypervisor(hypervisor);
         pool.setStatus(StoragePoolStatus.Up);
         this.dataStoreDao.update(pool.getId(), pool);
-        if(pool.getPoolType() == StoragePoolType.DatastoreCluster && pool.getParent() == 0) {
-            List<StoragePoolVO> childDatastores = dataStoreDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-            for (StoragePoolVO child : childDatastores) {
-                child.setScope(ScopeType.ZONE);
-                this.dataStoreDao.update(child.getId(), child);
-            }
-        }
         return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
     }
 
diff --git a/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
index 5cecb22..33385b5 100644
--- a/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
+++ b/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml
@@ -72,6 +72,4 @@
     
     <bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" />
 
-    <bean id="deployAsIsImageStoreHelper" class="org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelperImpl" />
-
 </beans>
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
index 18a7f3c..8196678 100644
--- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java
@@ -218,12 +218,12 @@
     }
 
     @Override
-    public TemplateInfo getTemplate(long templateId, String configuration) {
-        VMTemplateStoragePoolVO template = templatePoolDao.findByPoolTemplate(getId(), templateId, configuration);
+    public TemplateInfo getTemplate(long templateId) {
+        VMTemplateStoragePoolVO template = templatePoolDao.findByPoolTemplate(getId(), templateId);
         if (template == null || template.getState() != ObjectInDataStoreStateMachine.State.Ready) {
             return null;
         }
-        return imageDataFactory.getTemplateOnPrimaryStorage(templateId, this, configuration);
+        return imageDataFactory.getTemplate(templateId, this);
     }
 
     @Override
@@ -241,11 +241,6 @@
         return pdsv.isManaged();
     }
 
-    @Override
-    public Long getParent() {
-        return pdsv.getParent();
-    }
-
     private boolean canCloneVolume() {
         return Boolean.valueOf(getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString()));
     }
@@ -264,26 +259,18 @@
      */
     @Override
     public DataObject create(DataObject dataObject) {
-        return create(dataObject, true, null);
-    }
-
-    @Override
-    public DataObject create(DataObject dataObject, String configuration) {
-        return create(dataObject, true, configuration);
+        return create(dataObject, true);
     }
 
     /**
      * Please read the comment for the create(DataObject) method if you are planning on passing in "false" for createEntryInTempSpoolRef.
-     *
-     * The parameter configuration allows storing multiple configurations of the
-     * base template appliance in primary storage (VMware supported) - null by default or no configurations
      */
     @Override
-    public DataObject create(DataObject obj, boolean createEntryInTempSpoolRef, String configuration) {
+    public DataObject create(DataObject obj, boolean createEntryInTempSpoolRef) {
         // create template on primary storage
         if (obj.getType() == DataObjectType.TEMPLATE && (!isManaged() || (createEntryInTempSpoolRef && canCloneVolume()))) {
             try {
-                String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + getId() + "conf:" + configuration;
+                String templateIdPoolIdString = "templateId:" + obj.getId() + "poolId:" + getId();
                 VMTemplateStoragePoolVO templateStoragePoolRef;
                 GlobalLock lock = GlobalLock.getInternLock(templateIdPoolIdString);
                 if (!lock.lock(5)) {
@@ -291,20 +278,20 @@
                     return null;
                 }
                 try {
-                    templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId(), configuration);
+                    templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId());
                     if (templateStoragePoolRef == null) {
 
                         if (s_logger.isDebugEnabled()) {
                             s_logger.debug("Not found (" + templateIdPoolIdString + ") in template_spool_ref, persisting it");
                         }
-                        templateStoragePoolRef = new VMTemplateStoragePoolVO(getId(), obj.getId(), configuration);
+                        templateStoragePoolRef = new VMTemplateStoragePoolVO(getId(), obj.getId());
                         templateStoragePoolRef = templatePoolDao.persist(templateStoragePoolRef);
                     }
                 } catch (Throwable t) {
                     if (s_logger.isDebugEnabled()) {
                         s_logger.debug("Failed to insert (" + templateIdPoolIdString + ") to template_spool_ref", t);
                     }
-                    templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId(), configuration);
+                    templateStoragePoolRef = templatePoolDao.findByPoolTemplate(getId(), obj.getId());
                     if (templateStoragePoolRef == null) {
                         throw new CloudRuntimeException("Failed to create template storage pool entry");
                     } else {
@@ -329,7 +316,7 @@
             }
         }
 
-        return objectInStoreMgr.get(obj, this, configuration);
+        return objectInStoreMgr.get(obj, this);
     }
 
     @Override
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
index cb4ff74..64533d5 100644
--- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java
@@ -18,34 +18,28 @@
  */
 package org.apache.cloudstack.storage.datastore.provider;
 
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.ModifyStoragePoolAnswer;
 import com.cloud.agent.api.ModifyStoragePoolCommand;
-import com.cloud.agent.api.StoragePoolInfo;
 import com.cloud.alert.AlertManager;
 import com.cloud.exception.StorageConflictException;
 import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.StoragePoolHostVO;
-import com.cloud.storage.StoragePoolStatus;
 import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolTagsDao;
 import com.cloud.utils.exception.CloudRuntimeException;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 public class DefaultHostListener implements HypervisorHostListener {
     private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class);
@@ -59,10 +53,6 @@
     StoragePoolHostDao storagePoolHostDao;
     @Inject
     PrimaryDataStoreDao primaryStoreDao;
-    @Inject
-    StoragePoolDetailsDao storagePoolDetailsDao;
-    @Inject
-    StoragePoolTagsDao storagePoolTagsDao;
 
     @Override
     public boolean hostAdded(long hostId) {
@@ -100,54 +90,7 @@
                 }
             }
         }
-        StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId);
-        updateStoragePoolHostVOAndDetails(poolVO, hostId, mspAnswer);
 
-        if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-            for (ModifyStoragePoolAnswer childDataStoreAnswer : ((ModifyStoragePoolAnswer) answer).getDatastoreClusterChildren()) {
-                StoragePoolInfo childStoragePoolInfo = childDataStoreAnswer.getPoolInfo();
-                StoragePoolVO dataStoreVO = primaryStoreDao.findPoolByUUID(childStoragePoolInfo.getUuid());
-                if (dataStoreVO != null) {
-                    continue;
-                }
-                dataStoreVO = new StoragePoolVO();
-                dataStoreVO.setStorageProviderName(poolVO.getStorageProviderName());
-                dataStoreVO.setHostAddress(childStoragePoolInfo.getHost());
-                dataStoreVO.setPoolType(Storage.StoragePoolType.PreSetup);
-                dataStoreVO.setPath(childStoragePoolInfo.getHostPath());
-                dataStoreVO.setPort(poolVO.getPort());
-                dataStoreVO.setName(childStoragePoolInfo.getName());
-                dataStoreVO.setUuid(childStoragePoolInfo.getUuid());
-                dataStoreVO.setDataCenterId(poolVO.getDataCenterId());
-                dataStoreVO.setPodId(poolVO.getPodId());
-                dataStoreVO.setClusterId(poolVO.getClusterId());
-                dataStoreVO.setStatus(StoragePoolStatus.Up);
-                dataStoreVO.setUserInfo(poolVO.getUserInfo());
-                dataStoreVO.setManaged(poolVO.isManaged());
-                dataStoreVO.setCapacityIops(poolVO.getCapacityIops());
-                dataStoreVO.setCapacityBytes(childDataStoreAnswer.getPoolInfo().getCapacityBytes());
-                dataStoreVO.setUsedBytes(childDataStoreAnswer.getPoolInfo().getCapacityBytes() - childDataStoreAnswer.getPoolInfo().getAvailableBytes());
-                dataStoreVO.setHypervisor(poolVO.getHypervisor());
-                dataStoreVO.setScope(poolVO.getScope());
-                dataStoreVO.setParent(poolVO.getId());
-
-                Map<String, String> details = new HashMap<>();
-                if(StringUtils.isNotEmpty(childDataStoreAnswer.getPoolType())) {
-                    details.put("pool_type", childDataStoreAnswer.getPoolType());
-                }
-
-                List<String> storageTags = storagePoolTagsDao.getStoragePoolTags(poolId);
-                primaryStoreDao.persist(dataStoreVO, details, storageTags);
-
-                updateStoragePoolHostVOAndDetails(dataStoreVO, hostId, childDataStoreAnswer);
-            }
-        }
-
-        s_logger.info("Connection established between storage pool " + pool + " and host " + hostId);
-        return true;
-    }
-
-    private void updateStoragePoolHostVOAndDetails(StoragePool pool, long hostId, ModifyStoragePoolAnswer mspAnswer) {
         StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(pool.getId(), hostId);
         if (poolHost == null) {
             poolHost = new StoragePoolHostVO(pool.getId(), hostId, mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
@@ -156,17 +99,13 @@
             poolHost.setLocalPath(mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
         }
 
-        StoragePoolVO poolVO = this.primaryStoreDao.findById(pool.getId());
+        StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId);
         poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes());
         poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes());
-        if(StringUtils.isNotEmpty(mspAnswer.getPoolType())) {
-            StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(pool.getId(), "pool_type");
-            if (poolType == null) {
-                StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(pool.getId(), "pool_type", mspAnswer.getPoolType(), false);
-                storagePoolDetailsDao.persist(storagePoolDetailVO);
-            }
-        }
         primaryStoreDao.update(pool.getId(), poolVO);
+
+        s_logger.info("Connection established between storage pool " + pool + " and host " + hostId);
+        return true;
     }
 
     @Override
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java
index da759f8..76e59d8 100644
--- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeObject.java
@@ -20,20 +20,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.dc.VsphereStoragePolicyVO;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.storage.MigrationOptions;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VolumeDetailVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.vm.VmDetailConstants;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
@@ -44,6 +30,7 @@
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.storage.DownloadAnswer;
@@ -53,6 +40,7 @@
 import com.cloud.offering.DiskOffering.DiskCacheMode;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.DiskOfferingVO;
+import com.cloud.storage.MigrationOptions;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.ProvisioningType;
 import com.cloud.storage.Volume;
@@ -83,21 +71,9 @@
     VMInstanceDao vmInstanceDao;
     @Inject
     DiskOfferingDao diskOfferingDao;
-    @Inject
-    VMTemplateDao templateDao;
-    @Inject
-    VolumeDetailsDao volumeDetailsDao;
-    @Inject
-    ServiceOfferingDetailsDao serviceOfferingDetailsDao;
-    @Inject
-    DiskOfferingDetailsDao diskOfferingDetailsDao;
-    @Inject
-    VsphereStoragePolicyDao vsphereStoragePolicyDao;
-
     private Object payload;
     private MigrationOptions migrationOptions;
     private boolean directDownload;
-    private String vSphereStoragePolicyId;
 
     public VolumeObject() {
         _volStateMachine = Volume.State.getStateMachine();
@@ -381,7 +357,7 @@
         if (dataStore == null) {
             throw new CloudRuntimeException("datastore must be set before using this object");
         }
-        DataObjectInStore obj = objectInStoreMgr.findObject(volumeVO.getId(), DataObjectType.VOLUME, dataStore.getId(), dataStore.getRole(), null);
+        DataObjectInStore obj = objectInStoreMgr.findObject(volumeVO.getId(), DataObjectType.VOLUME, dataStore.getId(), dataStore.getRole());
         if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) {
             return dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + EncodingType.SIZE + "=" + volumeVO.getSize() + "&" +
                 EncodingType.NAME + "=" + volumeVO.getName();
@@ -415,7 +391,9 @@
                 if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
                     volEvent = Volume.Event.UploadRequested;
                 } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) {
-                    volEvent = Volume.Event.CopyRequested;
+                    volEvent = Event.CopyRequested;
+                } else if (event == ObjectInDataStoreStateMachine.Event.MigrateDataRequested) {
+                    return;
                 }
             } else {
                 if (event == ObjectInDataStoreStateMachine.Event.CreateRequested || event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) {
@@ -459,18 +437,6 @@
     }
 
     @Override
-    public boolean isDeployAsIs() {
-        VMTemplateVO template = templateDao.findById(getTemplateId());
-        return template != null && template.isDeployAsIs();
-    }
-
-    @Override
-    public String getDeployAsIsConfiguration() {
-        VolumeDetailVO detail = volumeDetailsDao.findDetail(getId(), VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION);
-        return detail != null ? detail.getValue() : null;
-    }
-
-    @Override
     public void processEventOnly(ObjectInDataStoreStateMachine.Event event) {
         try {
             objectInStoreMgr.update(this, event);
@@ -794,28 +760,6 @@
 
     }
 
-    public String getvSphereStoragePolicyId() {
-        if (StringUtils.isEmpty(vSphereStoragePolicyId)) {
-            String storagePolicyVOid = null;
-            if (Volume.Type.ROOT == getVolumeType()) {
-                Long vmId = volumeVO.getInstanceId();
-                if (vmId != null) {
-                    VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(vmId);
-                    storagePolicyVOid = serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(),
-                            ApiConstants.STORAGE_POLICY);
-                }
-            } else {
-                storagePolicyVOid = diskOfferingDetailsDao.getDetail(volumeVO.getDiskOfferingId(),
-                        ApiConstants.STORAGE_POLICY);
-            }
-            if (storagePolicyVOid != null) {
-                VsphereStoragePolicyVO vsphereStoragePolicyVO = vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyVOid));
-                vSphereStoragePolicyId = vsphereStoragePolicyVO.getPolicyId();
-            }
-        }
-        return vSphereStoragePolicyId;
-    }
-
     @Override
     public ImageFormat getFormat() {
         return volumeVO.getFormat();
diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 5e3493a..77413ad 100644
--- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -28,8 +28,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
 import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity;
 import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
@@ -123,8 +121,6 @@
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.VirtualMachine;
 
-import static com.cloud.storage.resource.StorageProcessor.REQUEST_TEMPLATE_RELOAD;
-
 @Component
 public class VolumeServiceImpl implements VolumeService {
     private static final Logger s_logger = Logger.getLogger(VolumeServiceImpl.class);
@@ -170,8 +166,6 @@
     private ClusterDao clusterDao;
     @Inject
     private VolumeDetailsDao _volumeDetailsDao;
-    @Inject
-    private VMTemplateDao templateDao;
 
     private final static String SNAPSHOT_ID = "SNAPSHOT_ID";
 
@@ -355,12 +349,9 @@
                 if (s_logger.isDebugEnabled()) {
                     s_logger.debug("Marking volume that was never created as destroyed: " + vol);
                 }
-                VMTemplateVO template = templateDao.findById(vol.getTemplateId());
-                if (template != null && !template.isDeployAsIs()) {
-                    volDao.remove(vol.getId());
-                    future.complete(result);
-                    return future;
-                }
+                volDao.remove(vol.getId());
+                future.complete(result);
+                return future;
             }
         }
         VolumeObject vo = (VolumeObject)volume;
@@ -467,7 +458,7 @@
         private final AsyncCallFuture<VolumeApiResult> _future;
 
         public ManagedCreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volumeInfo, PrimaryDataStore primaryDatastore, TemplateInfo templateInfo,
-                                             AsyncCallFuture<VolumeApiResult> future) {
+                AsyncCallFuture<VolumeApiResult> future) {
             super(callback);
 
             _volumeInfo = volumeInfo;
@@ -502,7 +493,7 @@
         long templatePoolId;
 
         public CreateBaseImageContext(AsyncCompletionCallback<T> callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture<VolumeApiResult> future,
-                                      DataObject destObj, long templatePoolId) {
+                DataObject destObj, long templatePoolId) {
             super(callback);
             this.volume = volume;
             this.dataStore = datastore;
@@ -539,7 +530,7 @@
         int sleepTime = 120;
         int tries = storagePoolMaxWaitSeconds / sleepTime;
         while (tries > 0) {
-            TemplateInfo tmpl = store.getTemplate(template.getId(), null);
+            TemplateInfo tmpl = store.getTemplate(template.getId());
             if (tmpl != null) {
                 return tmpl;
             }
@@ -555,10 +546,9 @@
 
     @DB
     protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture<VolumeApiResult> future) {
-        String deployAsIsConfiguration = volume.getDeployAsIsConfiguration();
-        DataObject templateOnPrimaryStoreObj = dataStore.create(template, deployAsIsConfiguration);
+        DataObject templateOnPrimaryStoreObj = dataStore.create(template);
 
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId(), deployAsIsConfiguration);
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
         if (templatePoolRef == null) {
             throw new CloudRuntimeException("Failed to find template " + template.getUniqueName() + " in storage pool " + dataStore.getId());
         } else {
@@ -581,7 +571,7 @@
             if (s_logger.isDebugEnabled()) {
                 s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId);
             }
-            templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId(), deployAsIsConfiguration);
+            templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId());
             if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) {
                 s_logger.info(
                         "Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + " is already copied to primary storage, skip copying");
@@ -605,7 +595,7 @@
         } catch (Throwable e) {
             s_logger.debug("failed to create template on storage", e);
             templateOnPrimaryStoreObj.processEvent(Event.OperationFailed);
-            dataStore.create(template, deployAsIsConfiguration);  // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
+            dataStore.create(template);  // make sure that template_spool_ref entry is still present so that the second thread can acquire the lock
             VolumeApiResult result = new VolumeApiResult(volume);
             result.setResult(e.toString());
             future.complete(result);
@@ -715,16 +705,14 @@
         private final AsyncCallFuture<VolumeApiResult> future;
         private final DataObject templateOnStore;
         private final SnapshotInfo snapshot;
-        private final String deployAsIsConfiguration;
 
         public CreateVolumeFromBaseImageContext(AsyncCompletionCallback<T> callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture<VolumeApiResult> future,
-                                                SnapshotInfo snapshot, String configuration) {
+                SnapshotInfo snapshot) {
             super(callback);
             this.vo = vo;
             this.future = future;
             this.templateOnStore = templateOnStore;
             this.snapshot = snapshot;
-            this.deployAsIsConfiguration = configuration;
         }
 
         public AsyncCallFuture<VolumeApiResult> getFuture() {
@@ -734,16 +722,15 @@
 
     @DB
     protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture<VolumeApiResult> future) {
-        DataObject volumeOnPrimaryStorage = pd.create(volume, volume.getDeployAsIsConfiguration());
+        DataObject volumeOnPrimaryStorage = pd.create(volume);
         volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested);
 
-        CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null, volume.getDeployAsIsConfiguration());
+        CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null);
         AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
         caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null));
         caller.setContext(context);
 
         motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller);
-
         return;
     }
 
@@ -753,7 +740,6 @@
         DataObject tmplOnPrimary = context.templateOnStore;
         CopyCommandResult result = callback.getResult();
         VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
-        String deployAsIsConfiguration = context.deployAsIsConfiguration;
 
         if (result.isSuccess()) {
             vo.processEvent(Event.OperationSuccessed, result.getAnswer());
@@ -764,10 +750,10 @@
             // hack for Vmware: host is down, previously download template to the host needs to be re-downloaded, so we need to reset
             // template_spool_ref entry here to NOT_DOWNLOADED and Allocated state
             Answer ans = result.getAnswer();
-            if (ans != null && ans instanceof CopyCmdAnswer && ans.getDetails().contains(REQUEST_TEMPLATE_RELOAD)) {
+            if (ans != null && ans instanceof CopyCmdAnswer && ans.getDetails().contains("request template reload")) {
                 if (tmplOnPrimary != null) {
                     s_logger.info("Reset template_spool_ref entry so that vmware template can be reloaded in next try");
-                    VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(tmplOnPrimary.getDataStore().getId(), tmplOnPrimary.getId(), deployAsIsConfiguration);
+                    VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(tmplOnPrimary.getDataStore().getId(), tmplOnPrimary.getId());
                     if (templatePoolRef != null) {
                         long templatePoolRefId = templatePoolRef.getId();
                         templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, 1200);
@@ -803,9 +789,9 @@
     private TemplateInfo createManagedTemplateVolume(TemplateInfo srcTemplateInfo, PrimaryDataStore destPrimaryDataStore) {
         // create a template volume on primary storage
         AsyncCallFuture<VolumeApiResult> createTemplateFuture = new AsyncCallFuture<>();
-        TemplateInfo templateOnPrimary = (TemplateInfo)destPrimaryDataStore.create(srcTemplateInfo, srcTemplateInfo.getDeployAsIsConfiguration());
+        TemplateInfo templateOnPrimary = (TemplateInfo)destPrimaryDataStore.create(srcTemplateInfo);
 
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId(), srcTemplateInfo.getDeployAsIsConfiguration());
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
 
         if (templatePoolRef == null) {
             throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
@@ -875,7 +861,7 @@
      * @param destHost The host that we will use for the copy
      */
     private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore,
-                                                     Host destHost) {
+            Host destHost) {
         AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
         int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
         long templatePoolRefId = templatePoolRef.getId();
@@ -1000,7 +986,7 @@
      * @param future For async
      */
     private void createManagedVolumeCloneTemplateAsync(VolumeInfo volumeInfo, TemplateInfo templateOnPrimary, PrimaryDataStore destPrimaryDataStore, AsyncCallFuture<VolumeApiResult> future) {
-        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId(), volumeInfo.getDeployAsIsConfiguration());
+        VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
 
         if (templatePoolRef == null) {
             throw new CloudRuntimeException("Failed to find template " + templateOnPrimary.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
@@ -1014,7 +1000,7 @@
         try {
             volumeInfo.processEvent(Event.CreateOnlyRequested);
 
-            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null, volumeInfo.getDeployAsIsConfiguration());
+            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<>(null, volumeInfo, destPrimaryDataStore, templateOnPrimary, future, null);
 
             AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
 
@@ -1035,7 +1021,7 @@
         try {
             // Create a volume on managed storage.
 
-            TemplateInfo destTemplateInfo = (TemplateInfo)primaryDataStore.create(srcTemplateInfo, false, volumeInfo.getDeployAsIsConfiguration());
+            TemplateInfo destTemplateInfo = (TemplateInfo)primaryDataStore.create(srcTemplateInfo, false);
 
             AsyncCallFuture<VolumeApiResult> createVolumeFuture = createVolumeAsync(volumeInfo, primaryDataStore);
             VolumeApiResult createVolumeResult = createVolumeFuture.get();
@@ -1123,7 +1109,7 @@
         if (storageCanCloneVolume && computeSupportsVolumeClone) {
             s_logger.debug("Storage " + destDataStoreId + " can support cloning using a cached template and compute side is OK with volume cloning.");
 
-            TemplateInfo templateOnPrimary = destPrimaryDataStore.getTemplate(srcTemplateInfo.getId(), null);
+            TemplateInfo templateOnPrimary = destPrimaryDataStore.getTemplate(srcTemplateInfo.getId());
 
             if (templateOnPrimary == null) {
                 templateOnPrimary = createManagedTemplateVolume(srcTemplateInfo, destPrimaryDataStore);
@@ -1134,7 +1120,7 @@
             }
 
             // Copy the template to the template volume.
-            VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId(), null);
+            VMTemplateStoragePoolVO templatePoolRef = _tmpltPoolDao.findByPoolTemplate(destPrimaryDataStore.getId(), templateOnPrimary.getId());
 
             if (templatePoolRef == null) {
                 throw new CloudRuntimeException("Failed to find template " + srcTemplateInfo.getUniqueName() + " in storage pool " + destPrimaryDataStore.getId());
@@ -1210,8 +1196,8 @@
     @Override
     public AsyncCallFuture<VolumeApiResult> createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template) {
         PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId);
-        TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId(), volume.getDeployAsIsConfiguration());
-        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<>();
+        TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId());
+        AsyncCallFuture<VolumeApiResult> future = new AsyncCallFuture<VolumeApiResult>();
 
         if (templateOnPrimaryStore == null) {
             createBaseImageAsync(volume, pd, template, future);
@@ -1248,7 +1234,7 @@
             volumeOnStore.processEvent(Event.CreateOnlyRequested);
             _volumeDetailsDao.addDetail(volume.getId(), SNAPSHOT_ID, Long.toString(snapshot.getId()), false);
 
-            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot, null);
+            CreateVolumeFromBaseImageContext<VolumeApiResult> context = new CreateVolumeFromBaseImageContext<VolumeApiResult>(null, volume, store, volumeOnStore, future, snapshot);
             AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
             caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context);
             motionSrv.copyAsync(snapshot, volumeOnStore, caller);
@@ -2139,4 +2125,4 @@
             volDao.remove(vol.getId());
         }
     }
-}
\ No newline at end of file
+}
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index cc47c55..b792ff2 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -46,7 +46,6 @@
 import org.apache.cloudstack.agent.directdownload.NfsDirectDownloadCommand;
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
@@ -1834,10 +1833,4 @@
         }
         return availableBytes >= templateSize;
     }
-
-    @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        s_logger.info("'CheckDataStoreStoragePolicyComplainceCommand' not currently applicable for KVMStorageProcessor");
-        return new Answer(cmd,false,"Not currently applicable for KVMStorageProcessor");
-    }
 }
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
index dd58bb5..7915586 100644
--- a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
@@ -24,7 +24,6 @@
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
@@ -828,12 +827,6 @@
     }
 
     @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        LOGGER.info("'CheckDataStoreStoragePolicyComplainceCommand' not applicable used for Ovm3StorageProcessor");
-        return new Answer(cmd,false,"Not applicable used for Ovm3StorageProcessor");
-    }
-
-    @Override
     public Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd) {
         return null;
     }
diff --git a/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java
index 16579bc..e4ef4df 100644
--- a/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java
+++ b/plugins/hypervisors/simulator/src/main/java/com/cloud/resource/SimulatorStorageProcessor.java
@@ -31,7 +31,6 @@
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
 import org.apache.cloudstack.storage.command.CreateObjectCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.DettachAnswer;
 import org.apache.cloudstack.storage.command.DettachCommand;
@@ -270,9 +269,4 @@
     public Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd) {
         return null;
     }
-
-    @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        return new Answer(cmd, true, null);
-    }
 }
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index c4dbb1d..f548948 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -72,11 +72,5 @@
             <groupId>wsdl4j</groupId>
             <artifactId>wsdl4j</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.cloud.com.vmware</groupId>
-            <artifactId>vmware-pbm</artifactId>
-            <version>${cs.vmware.api.version}</version>
-            <scope>compile</scope>
-        </dependency>
     </dependencies>
 </project>
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
index d48a5d9..740b6684 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -598,7 +598,7 @@
     private VMTemplateVO createVMTemplateRecord(String vmInternalName, long guestOsId, long accountId) {
         Long nextTemplateId = vmTemplateDao.getNextInSequence(Long.class, "id");
         VMTemplateVO templateVO = new VMTemplateVO(nextTemplateId, "Imported-from-" + vmInternalName, Storage.ImageFormat.OVA, false, false, false, Storage.TemplateType.USER, null,
-                false, 64, accountId, null, "Template imported from VM " + vmInternalName, false, guestOsId, false, HypervisorType.VMware, null, null, false, false, false, false);
+                false, 64, accountId, null, "Template imported from VM " + vmInternalName, false, guestOsId, false, HypervisorType.VMware, null, null, false, false, false);
         return vmTemplateDao.persist(templateVO);
     }
 
@@ -619,7 +619,7 @@
         VMTemplateStoragePoolVO templateRef = templateStoragePoolDao.findByPoolPath(poolId, templatePath);
         if (templateRef == null) {
             templateRef = new VMTemplateStoragePoolVO(poolId, templateId, null, 100, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, templatePath, null, null, templatePath,
-                    templateSize, null);
+                    templateSize);
             templateRef.setState(ObjectInDataStoreStateMachine.State.Ready);
             templateStoragePoolDao.persist(templateRef);
         }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java
index b8de0bb..c9f8b0c 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java
@@ -16,7 +16,9 @@
 // under the License.
 package com.cloud.hypervisor.guru;
 
-import com.cloud.agent.api.to.DeployAsIsInfoTO;
+import com.cloud.agent.api.storage.OVFPropertyTO;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.exception.InsufficientAddressCapacityException;
@@ -33,10 +35,16 @@
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.TemplateOVFPropertyVO;
+import com.cloud.storage.VMTemplateStoragePoolVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.Volume;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.GuestOSHypervisorDao;
+import com.cloud.storage.dao.TemplateOVFPropertiesDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.Pair;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.NicProfile;
@@ -45,8 +53,10 @@
 import com.cloud.vm.VmDetailConstants;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.BooleanUtils;
 import org.apache.log4j.Logger;
 
@@ -57,9 +67,10 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 class VmwareVmImplementer {
-    private static final Logger LOGGER = Logger.getLogger(VmwareVmImplementer.class);
+    private static final Logger LOG = Logger.getLogger(VmwareVmImplementer.class);
 
     @Inject
     DomainRouterDao domainRouterDao;
@@ -78,11 +89,11 @@
     @Inject
     PrimaryDataStoreDao storagePoolDao;
     @Inject
+    TemplateOVFPropertiesDao templateOVFPropertiesDao;
+    @Inject
     VMTemplatePoolDao templateStoragePoolDao;
     @Inject
     VmwareManager vmwareMgr;
-    @Inject
-    DeployAsIsHelper deployAsIsHelper;
 
     private Boolean globalNestedVirtualisationEnabled;
     private Boolean globalNestedVPerVMEnabled;
@@ -105,11 +116,10 @@
 
     VirtualMachineTO implement(VirtualMachineProfile vm, VirtualMachineTO to, long clusterId) {
         to.setBootloader(VirtualMachineTemplate.BootloaderType.HVM);
-        boolean deployAsIs = vm.getTemplate().isDeployAsIs();
-        HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
+
         Map<String, String> details = to.getDetails();
         if (details == null)
-            details = new HashMap<>();
+            details = new HashMap<String, String>();
 
         VirtualMachine.Type vmType = vm.getType();
         boolean userVm = !(vmType.equals(VirtualMachine.Type.DomainRouter) || vmType.equals(VirtualMachine.Type.ConsoleProxy) || vmType.equals(VirtualMachine.Type.SecondaryStorageVm));
@@ -123,7 +133,7 @@
                 try {
                     VirtualEthernetCardType.valueOf(nicDeviceType);
                 } catch (Exception e) {
-                    LOGGER.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
+                    LOG.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
                     details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
                 }
             }
@@ -135,7 +145,7 @@
                 try {
                     VirtualEthernetCardType.valueOf(nicDeviceType);
                 } catch (Exception e) {
-                    LOGGER.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
+                    LOG.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000");
                     details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString());
                 }
             }
@@ -162,7 +172,7 @@
         GuestOSVO guestOS = guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
         to.setOs(guestOS.getDisplayName());
         to.setHostName(vm.getHostName());
-
+        HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
         GuestOSHypervisorVO guestOsMapping = null;
         if (host != null) {
             guestOsMapping = guestOsHypervisorDao.findByOsIdAndHypervisor(guestOS.getId(), Hypervisor.HypervisorType.VMware.toString(), host.getHypervisorVersion());
@@ -173,29 +183,19 @@
             to.setPlatformEmulator(guestOsMapping.getGuestOsName());
         }
 
-        if (deployAsIs) {
-            setDeployAsIsInfoTO(vm, to, details);
-        }
+        List<OVFPropertyTO> ovfProperties = getOvfPropertyList(vm, details);
+
+        handleOvfProperties(vm, to, details, ovfProperties);
 
         setDetails(to, details);
 
         return to;
     }
 
-    /**
-     * Set the information relevant for deploy-as-is VMs on the VM TO
-     */
-    private void setDeployAsIsInfoTO(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) {
-        Map<String, String> properties = deployAsIsHelper.getVirtualMachineDeployAsIsProperties(vm);
-        Map<Integer, String> nicsAdapterMapping = deployAsIsHelper.getAllocatedVirtualMachineNicsAdapterMapping(vm, to.getNics());
-        DeployAsIsInfoTO info = new DeployAsIsInfoTO(properties, nicsAdapterMapping);
-        to.setDeployAsIsInfo(info);
-    }
-
     private void setDetails(VirtualMachineTO to, Map<String, String> details) {
-        if (LOGGER.isTraceEnabled()) {
-            for (String key : details.keySet()) {
-                LOGGER.trace(String.format("Detail for VM %s: %s => %s", to.getName(), key, details.get(key)));
+        if (LOG.isTraceEnabled()) {
+            for (String key: details.keySet()) {
+                LOG.trace(String.format("Detail for VM %s: %s => %s",to.getName(), key, details.get(key)));
             }
         }
         to.setDetails(details);
@@ -286,6 +286,56 @@
         }
     }
 
+    private void handleOvfProperties(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<OVFPropertyTO> ovfProperties) {
+        if (CollectionUtils.isNotEmpty(ovfProperties)) {
+            removeOvfPropertiesFromDetails(ovfProperties, details);
+            String templateInstallPath = null;
+            List<DiskTO> rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == Volume.Type.ROOT).collect(Collectors.toList());
+            if (rootDiskList.size() != 1) {
+                throw new CloudRuntimeException("Did not find only one root disk for VM " + vm.getHostName());
+            }
+
+            DiskTO rootDiskTO = rootDiskList.get(0);
+            DataStoreTO dataStore = rootDiskTO.getData().getDataStore();
+            StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(dataStore.getUuid());
+            long dataCenterId = storagePoolVO.getDataCenterId();
+            List<StoragePoolVO> pools = storagePoolDao.listByDataCenterId(dataCenterId);
+            for (StoragePoolVO pool : pools) {
+                VMTemplateStoragePoolVO ref = templateStoragePoolDao.findByPoolTemplate(pool.getId(), vm.getTemplateId());
+                if (ref != null && ref.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
+                    templateInstallPath = ref.getInstallPath();
+                    break;
+                }
+            }
+
+            if (templateInstallPath == null) {
+                throw new CloudRuntimeException("Did not find the template install path for template " + vm.getTemplateId() + " on zone " + dataCenterId);
+            }
+
+            Pair<String, List<OVFPropertyTO>> pair = new Pair<String, List<OVFPropertyTO>>(templateInstallPath, ovfProperties);
+            to.setOvfProperties(pair);
+        }
+    }
+
+    private List<OVFPropertyTO> getOvfPropertyList(VirtualMachineProfile vm, Map<String, String> details) {
+        List<OVFPropertyTO> ovfProperties = new ArrayList<OVFPropertyTO>();
+        for (String detailKey : details.keySet()) {
+            if (detailKey.startsWith(ApiConstants.OVF_PROPERTIES)) {
+                String ovfPropKey = detailKey.replace(ApiConstants.OVF_PROPERTIES + "-", "");
+                TemplateOVFPropertyVO templateOVFPropertyVO = templateOVFPropertiesDao.findByTemplateAndKey(vm.getTemplateId(), ovfPropKey);
+                if (templateOVFPropertyVO == null) {
+                    LOG.warn(String.format("OVF property %s not found on template, discarding", ovfPropKey));
+                    continue;
+                }
+                String ovfValue = details.get(detailKey);
+                boolean isPassword = templateOVFPropertyVO.isPassword();
+                OVFPropertyTO propertyTO = new OVFPropertyTO(ovfPropKey, ovfValue, isPassword);
+                ovfProperties.add(propertyTO);
+            }
+        }
+        return ovfProperties;
+    }
+
     private void addReservationDetails(long clusterId, Map<String, String> details) {
         details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString());
         details.put(VMwareGuru.VmwareReserveMemory.key(), VMwareGuru.VmwareReserveMemory.valueIn(clusterId).toString());
@@ -333,6 +383,16 @@
 //        details.put(VmDetailConstants.BOOT_TYPE, to.getBootType());
     }
 
+    /*
+        Remove OVF properties from details to be sent to hypervisor (avoid duplicate data)
+     */
+    private void removeOvfPropertiesFromDetails(List<OVFPropertyTO> ovfProperties, Map<String, String> details) {
+        for (OVFPropertyTO propertyTO : ovfProperties) {
+            String key = propertyTO.getKey();
+            details.remove(ApiConstants.OVF_PROPERTIES + "-" + key);
+        }
+    }
+
     /**
      * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
      * @param details vm details should not be null
@@ -345,8 +405,8 @@
         Boolean globalNestedVPerVMEnabled = getGlobalNestedVPerVMEnabled();
 
         Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedVirtualisationEnabled, globalNestedVPerVMEnabled, localNestedV);
-        if(LOGGER.isDebugEnabled()) {
-            LOGGER.debug(String.format(
+        if(LOG.isDebugEnabled()) {
+            LOG.debug(String.format(
                     "Due to '%B'(globalNestedVirtualisationEnabled) and '%B'(globalNestedVPerVMEnabled) I'm adding a flag with value %B to the vm configuration for Nested Virtualisation.",
                     globalNestedVirtualisationEnabled,
                     globalNestedVPerVMEnabled,
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
index 431526a..5379253 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
@@ -17,21 +17,17 @@
 
 package com.cloud.hypervisor.vmware;
 
-import com.cloud.dc.VsphereStoragePolicy;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.ResourceInUseException;
-import com.cloud.storage.StoragePool;
-import com.cloud.utils.component.PluggableService;
-import com.cloud.utils.exception.CloudRuntimeException;
+import java.util.List;
+
 import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
 import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
 import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
 import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
 
-import java.util.List;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.ResourceInUseException;
+import com.cloud.utils.component.PluggableService;
+import com.cloud.utils.exception.CloudRuntimeException;
 
 public interface VmwareDatacenterService extends PluggableService {
 
@@ -42,10 +38,4 @@
     boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws IllegalArgumentException, ResourceInUseException;
 
     List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws IllegalArgumentException, CloudRuntimeException;
-
-    List<? extends VsphereStoragePolicy> importVsphereStoragePolicies(ImportVsphereStoragePoliciesCmd cmd);
-
-    List<? extends VsphereStoragePolicy> listVsphereStoragePolicies(ListVsphereStoragePoliciesCmd cmd);
-
-    List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
index ea97a6e..14630b3 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java
@@ -17,7 +17,6 @@
 package com.cloud.hypervisor.vmware.manager;
 
 import com.cloud.agent.api.Command;
-import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
 
@@ -28,5 +27,5 @@
 
     VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd);
 
-    String getWorkerName(VmwareContext context, Command cmd, int workerSequence, DatastoreMO dsMo) throws Exception;
+    String getWorkerName(VmwareContext context, Command cmd, int workerSequence);
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index e1e0d6b..9cbaaf7 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -16,6 +16,43 @@
 // under the License.
 package com.cloud.hypervisor.vmware.manager;
 
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.rmi.RemoteException;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
+import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
+import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
+import org.apache.cloudstack.management.ManagementServerHost;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+
 import com.amazonaws.util.CollectionUtils;
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
@@ -25,7 +62,6 @@
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.agent.api.to.StorageFilerTO;
 import com.cloud.api.query.dao.TemplateJoinDao;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.cluster.dao.ManagementServerHostPeerDao;
@@ -34,19 +70,14 @@
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.ClusterVSMMapVO;
 import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.VsphereStoragePolicy;
-import com.cloud.dc.VsphereStoragePolicyVO;
 import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.ClusterVSMMapDao;
 import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
-import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.DiscoveredWithErrorException;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceInUseException;
 import com.cloud.host.Host;
 import com.cloud.host.Status;
@@ -54,7 +85,6 @@
 import com.cloud.host.dao.HostDetailsDao;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.hypervisor.vmware.LegacyZoneVO;
 import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
@@ -72,7 +102,6 @@
 import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
 import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
-import com.cloud.hypervisor.vmware.mo.PbmProfileManagerMO;
 import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
 import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
 import com.cloud.hypervisor.vmware.mo.VmwareHostType;
@@ -93,8 +122,6 @@
 import com.cloud.storage.JavaStorageLayer;
 import com.cloud.storage.StorageLayer;
 import com.cloud.storage.StorageManager;
-import com.cloud.storage.StoragePool;
-import com.cloud.storage.StoragePoolStatus;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.template.TemplateManager;
 import com.cloud.utils.FileUtil;
@@ -115,51 +142,8 @@
 import com.cloud.vm.dao.UserVmCloneSettingDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.google.common.base.Strings;
-import com.vmware.pbm.PbmProfile;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.ManagedObjectReference;
-import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
-import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
-import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
-import org.apache.cloudstack.api.command.admin.zone.UpdateVmwareDcCmd;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
-import org.apache.cloudstack.management.ManagementServerHost;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.rmi.RemoteException;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
     private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
@@ -224,12 +208,6 @@
     private UserVmCloneSettingDao cloneSettingDao;
     @Inject
     private TemplateManager templateManager;
-    @Inject
-    private VsphereStoragePolicyDao vsphereStoragePolicyDao;
-    @Inject
-    private StorageManager storageManager;
-    @Inject
-    private HypervisorGuruManager hypervisorGuruManager;
 
     private String _mountParent;
     private StorageLayer _storage;
@@ -1068,9 +1046,6 @@
         cmdList.add(UpdateVmwareDcCmd.class);
         cmdList.add(RemoveVmwareDcCmd.class);
         cmdList.add(ListVmwareDcsCmd.class);
-        cmdList.add(ImportVsphereStoragePoliciesCmd.class);
-        cmdList.add(ListVsphereStoragePoliciesCmd.class);
-        cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
         return cmdList;
     }
 
@@ -1198,7 +1173,6 @@
             }
             context = null;
         }
-        importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
         return vmwareDc;
     }
 
@@ -1259,7 +1233,6 @@
                             hostDetailsDao.persist(host.getId(), hostDetails);
                         }
                     }
-                    importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
                     return vmwareDc;
                 }
                 return null;
@@ -1411,112 +1384,6 @@
     }
 
     @Override
-    public List<? extends VsphereStoragePolicy> importVsphereStoragePolicies(ImportVsphereStoragePoliciesCmd cmd) {
-        Long zoneId = cmd.getZoneId();
-        // Validate Id of zone
-        doesZoneExist(zoneId);
-
-        final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
-        // Check if zone is associated with VMware DC
-        if (vmwareDcZoneMap == null) {
-            throw new CloudRuntimeException("Zone " + zoneId + " is not associated with any VMware datacenter.");
-        }
-
-        final long vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
-        return importVsphereStoragePoliciesInternal(zoneId, vmwareDcId);
-    }
-
-    public List<? extends VsphereStoragePolicy> importVsphereStoragePoliciesInternal(Long zoneId, Long vmwareDcId) {
-
-        // Get DC associated with this zone
-        VmwareDatacenterVO vmwareDatacenter = vmwareDcDao.findById(vmwareDcId);
-        String vmwareDcName = vmwareDatacenter.getVmwareDatacenterName();
-        String vCenterHost = vmwareDatacenter.getVcenterHost();
-        String userName = vmwareDatacenter.getUser();
-        String password = vmwareDatacenter.getPassword();
-        List<PbmProfile> storageProfiles = null;
-        try {
-            s_logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
-            VmwareContext context = VmwareContextFactory.getContext(vCenterHost, userName, password);
-            PbmProfileManagerMO profileManagerMO = new PbmProfileManagerMO(context);
-            storageProfiles = profileManagerMO.getStorageProfiles();
-            s_logger.debug(String.format("Import vSphere Storage Policies for the vmware DC %d in zone %d is successful", vmwareDcId, zoneId));
-        } catch (Exception e) {
-            String msg = String.format("Unable to list storage profiles from DC %s due to : %s", vmwareDcName, VmwareHelper.getExceptionMessage(e));
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        }
-
-        for (PbmProfile storageProfile : storageProfiles) {
-            VsphereStoragePolicyVO storagePolicyVO = vsphereStoragePolicyDao.findByPolicyId(zoneId, storageProfile.getProfileId().getUniqueId());
-            if (storagePolicyVO == null) {
-                storagePolicyVO = new VsphereStoragePolicyVO(zoneId, storageProfile.getProfileId().getUniqueId(), storageProfile.getName(), storageProfile.getDescription());
-                vsphereStoragePolicyDao.persist(storagePolicyVO);
-            } else {
-                storagePolicyVO.setDescription(storageProfile.getDescription());
-                storagePolicyVO.setName(storageProfile.getName());
-                vsphereStoragePolicyDao.update(storagePolicyVO.getId(), storagePolicyVO);
-            }
-        }
-
-        List<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
-        List<PbmProfile> finalStorageProfiles = storageProfiles;
-        List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
-                .filter(existingPolicy -> !finalStorageProfiles.stream()
-                    .anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
-                .collect(Collectors.toList());
-
-        for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
-            vsphereStoragePolicyDao.remove(storagePolicy.getId());
-        }
-
-        List<VsphereStoragePolicyVO> storagePolicies = vsphereStoragePolicyDao.listAll();
-        return storagePolicies;
-    }
-
-    @Override
-    public List<? extends VsphereStoragePolicy> listVsphereStoragePolicies(ListVsphereStoragePoliciesCmd cmd) {
-        List<? extends VsphereStoragePolicy> storagePolicies = vsphereStoragePolicyDao.findByZoneId(cmd.getZoneId());
-        if (storagePolicies != null) {
-            return new ArrayList<>(storagePolicies);
-        }
-        return Collections.emptyList();
-    }
-
-    @Override
-    public List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd) {
-        Long policyId = cmd.getPolicyId();
-        VsphereStoragePolicyVO storagePolicy = vsphereStoragePolicyDao.findById(policyId);
-        if (storagePolicy == null) {
-            throw new CloudRuntimeException("Storage policy with ID = " + policyId + " was not found");
-        }
-        long zoneId = storagePolicy.getZoneId();
-        List<StoragePoolVO> poolsInZone = primaryStorageDao.listByStatusInZone(zoneId, StoragePoolStatus.Up);
-        List<StoragePool> compatiblePools = new ArrayList<>();
-        for (StoragePoolVO pool : poolsInZone) {
-            StorageFilerTO storageFilerTO = new StorageFilerTO(pool);
-            List<Long> hostIds = storageManager.getUpHostsInPool(pool.getId());
-            if (CollectionUtils.isNullOrEmpty(hostIds)) {
-                s_logger.debug("Did not find a suitable host to verify compatibility of the pool " + pool.getName());
-                continue;
-            }
-            Collections.shuffle(hostIds);
-            CheckDataStoreStoragePolicyComplainceCommand command = new CheckDataStoreStoragePolicyComplainceCommand(storagePolicy.getPolicyId(), storageFilerTO);
-            long targetHostId = hypervisorGuruManager.getGuruProcessedCommandTargetHost(hostIds.get(0), command);
-            try {
-                Answer answer = _agentMgr.send(targetHostId, command);
-                boolean result = answer != null && answer.getResult();
-                if (result) {
-                    compatiblePools.add(pool);
-                }
-            } catch (AgentUnavailableException | OperationTimedoutException e) {
-                s_logger.error("Could not verify if storage policy " + storagePolicy.getName() + " is compatible with storage pool " + pool.getName());
-            }
-        }
-        return compatiblePools;
-    }
-
-    @Override
     public boolean hasNexusVSM(Long clusterId) {
         ClusterVSMMapVO vsmMapVo = null;
 
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 3e2b5a0..d59fcfb 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -343,7 +343,7 @@
                     if (vmMo == null) {
                         dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
 
-                        workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
+                        workerVMName = hostService.getWorkerName(context, cmd, 0);
                         vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
 
                         if (vmMo == null) {
@@ -362,7 +362,7 @@
                 }
 
                 snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid,
-                        prevBackupUuid, hostService.getWorkerName(context, cmd, 1, dsMo), cmd.getNfsVersion());
+                        prevBackupUuid, hostService.getWorkerName(context, cmd, 1), cmd.getNfsVersion());
 
                 success = (snapshotBackupUuid != null);
                 if (success) {
@@ -428,7 +428,7 @@
             }
 
             Ternary<String, Long, Long> result = createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath,
-                    hostService.getWorkerName(context, cmd, 0, null), cmd.getNfsVersion());
+                    hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
 
             return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), cmd.getUniqueName(), ImageFormat.OVA);
 
@@ -486,13 +486,13 @@
             Pair<String, String> result;
             if (cmd.toSecondaryStorage()) {
                 result = copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL,
-                        hostService.getWorkerName(context, cmd, 0, null), cmd.getNfsVersion());
+                        hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion());
             } else {
                 StorageFilerTO poolTO = cmd.getPool();
 
                 ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolTO.getUuid());
                 if (morDatastore == null) {
-                    morDatastore = hyperHost.mountDatastore(false, poolTO.getHost(), 0, poolTO.getPath(), poolTO.getUuid().replace("-", ""), true);
+                    morDatastore = hyperHost.mountDatastore(false, poolTO.getHost(), 0, poolTO.getPath(), poolTO.getUuid().replace("-", ""));
 
                     if (morDatastore == null) {
                         throw new Exception("Unable to mount storage pool on host. storeUrl: " + poolTO.getHost() + ":/" + poolTO.getPath());
@@ -591,7 +591,7 @@
         }
 
         String vmName = templateUuid;
-        hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin", null);
+        hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin");
 
         VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
         if (vmMo == null) {
@@ -912,7 +912,7 @@
 
         VirtualMachineMO clonedVm = null;
         try {
-            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin", null);
+            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin");
             clonedVm = hyperHost.findVmOnHyperHost(newVolumeName);
             if (clonedVm == null) {
                 throw new Exception("Unable to create container VM for volume creation");
@@ -1025,7 +1025,7 @@
                 vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
             }
 
-            exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1, null),
+            exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1),
                     nfsVersion, clonedWorkerVMNeeded);
             return new Pair<String, String>(volumeFolder, exportName);
 
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index a3da897..711020a 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -40,22 +40,21 @@
 import java.util.Set;
 import java.util.TimeZone;
 import java.util.UUID;
-import java.util.stream.Collectors;
 
 import javax.naming.ConfigurationException;
 import javax.xml.datatype.XMLGregorianCalendar;
 
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DeployAsIsInfoTO;
-import com.cloud.agent.api.ValidateVcenterDetailsCommand;
 import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.cloudstack.storage.configdrive.ConfigDrive;
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
 import org.apache.cloudstack.vm.UnmanagedInstanceTO;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.apache.log4j.Logger;
@@ -178,7 +177,7 @@
 import com.cloud.agent.api.storage.DestroyCommand;
 import com.cloud.agent.api.storage.MigrateVolumeAnswer;
 import com.cloud.agent.api.storage.MigrateVolumeCommand;
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
 import com.cloud.agent.api.storage.ResizeVolumeAnswer;
@@ -218,9 +217,7 @@
 import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
 import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
 import com.cloud.hypervisor.vmware.mo.NetworkDetails;
-import com.cloud.hypervisor.vmware.mo.PbmProfileManagerMO;
 import com.cloud.hypervisor.vmware.mo.TaskMO;
-import com.cloud.hypervisor.vmware.mo.StoragepodMO;
 import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
 import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
 import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
@@ -252,6 +249,7 @@
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
+import com.cloud.utils.crypt.DBEncryptionUtil;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.exception.ExceptionUtil;
@@ -289,7 +287,6 @@
 import com.vmware.vim25.HostPortGroupSpec;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.NasDatastoreInfo;
-import com.vmware.vim25.VirtualMachineDefinedProfileSpec;
 import com.vmware.vim25.ObjectContent;
 import com.vmware.vim25.OptionValue;
 import com.vmware.vim25.PerfCounterInfo;
@@ -300,7 +297,6 @@
 import com.vmware.vim25.PerfMetricSeries;
 import com.vmware.vim25.PerfQuerySpec;
 import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.StoragePodSummary;
 import com.vmware.vim25.ToolsUnavailableFaultMsg;
 import com.vmware.vim25.VAppOvfSectionInfo;
 import com.vmware.vim25.VAppOvfSectionSpec;
@@ -341,12 +337,9 @@
 import com.vmware.vim25.VirtualVmxnet3;
 import com.vmware.vim25.VmConfigInfo;
 import com.vmware.vim25.VmConfigSpec;
+import com.vmware.vim25.VmfsDatastoreInfo;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
 import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
-import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 
 import static com.cloud.utils.HumanReadableJson.getHumanReadableBytesJson;
 import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
@@ -575,8 +568,6 @@
                 answer = execute((GetUnmanagedInstancesCommand) cmd);
             } else if (clz == PrepareUnmanageVMInstanceCommand.class) {
                 answer = execute((PrepareUnmanageVMInstanceCommand) cmd);
-            } else if (clz == ValidateVcenterDetailsCommand.class) {
-                answer = execute((ValidateVcenterDetailsCommand) cmd);
             } else {
                 answer = Answer.createUnsupportedCommandAnswer(cmd);
             }
@@ -754,30 +745,13 @@
             } else if (newSize == oldSize) {
                 return new ResizeVolumeAnswer(cmd, true, "success", newSize * ResourceType.bytesToKiB);
             }
-            /*
-            // FR41 this is yet to fix
-            ManagedObjectReference morDS1 = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid());
-            DatastoreMO dsMo1 = new DatastoreMO(hyperHost.getContext(), morDS1);
-            vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo1, path + VMDK_EXTENSION);
-            DatastoreFile dsFile1 = new DatastoreFile(vmdkDataStorePath);
-
-            s_logger.debug("vDiskid does not exist for volume " + vmdkDataStorePath + " registering the disk now");
-            VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(getServiceContext());
-            try {
-                VStorageObject vStorageObject = vStorageObjectManagerMO.registerVirtualDisk(dsFile1, null, dsMo1.getOwnerDatacenter().second());
-                VStorageObjectConfigInfo diskConfigInfo = vStorageObject.getConfig();
-                ID vdiskId = diskConfigInfo.getId();
-            } catch (Throwable e) {
-                if (e instanceof AlreadyExistsFaultMsg) {
-
-                }
-            }*/
 
             if (vmName.equalsIgnoreCase("none")) {
                 // OfflineVmwareMigration: we need to refactor the worker vm creation out for use in migration methods as well as here
                 // OfflineVmwareMigration: this method is 100 lines and needs refactorring anyway
                 // we need to spawn a worker VM to attach the volume to and resize the volume.
                 useWorkerVm = true;
+                vmName = getWorkerName(getServiceContext(), cmd, 0);
 
                 String poolId = cmd.getPoolUuid();
 
@@ -785,7 +759,6 @@
                 // OfflineVmwareMigration: 1. find data(store)
                 ManagedObjectReference morDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolId);
                 DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDS);
-                vmName = getWorkerName(getServiceContext(), cmd, 0, dsMo);
 
                 s_logger.info("Create worker VM " + vmName);
 
@@ -1750,21 +1723,39 @@
         VirtualMachineFileInfo existingVmFileInfo = null;
         VirtualMachineFileLayoutEx existingVmFileLayout = null;
         List<DatastoreMO> existingDatastores = new ArrayList<DatastoreMO>();
-        String diskStoragePolicyId = null;
-        String vmStoragePolicyId = null;
-        VirtualMachineDefinedProfileSpec diskProfileSpec = null;
-        VirtualMachineDefinedProfileSpec vmProfileSpec = null;
-
-
-        DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo();
-        boolean deployAsIs = deployAsIsInfo != null;
 
         Pair<String, String> names = composeVmNames(vmSpec);
         String vmInternalCSName = names.first();
         String vmNameOnVcenter = names.second();
+        String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
+        String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
         DiskTO rootDiskTO = null;
-        String bootMode = getBootModeFromVmSpec(vmSpec, deployAsIs);
-        Pair<String, String> controllerInfo = getControllerInfoFromVmSpec(vmSpec);
+        String bootMode = null;
+        if (vmSpec.getDetails().containsKey(VmDetailConstants.BOOT_MODE)) {
+            bootMode = vmSpec.getDetails().get(VmDetailConstants.BOOT_MODE);
+        }
+        if (null == bootMode) {
+            bootMode = ApiConstants.BootType.BIOS.toString();
+        }
+
+        // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
+        // This helps avoid mix of different scsi subtype controllers in instance.
+        if (DiskControllerType.osdefault == DiskControllerType.getType(dataDiskController) && DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
+            dataDiskController = DiskControllerType.scsi.toString();
+        }
+
+        // Validate the controller types
+        dataDiskController = DiskControllerType.getType(dataDiskController).toString();
+        rootDiskController = DiskControllerType.getType(rootDiskController).toString();
+
+        if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
+            throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
+        }
+        if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
+            throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
+        }
+
+        Pair<String, String> controllerInfo = new Pair<String, String>(rootDiskController, dataDiskController);
 
         Boolean systemVm = vmSpec.getType().isUsedBySystem();
         // Thus, vmInternalCSName always holds i-x-y, the cloudstack generated internal VM name.
@@ -1784,9 +1775,7 @@
                 s_logger.error(msg);
                 throw new Exception(msg);
             }
-
-            DiskTO[] specDisks = vmSpec.getDisks();
-            String guestOsId = getGuestOsIdFromVmSpec(vmSpec, deployAsIs);
+            String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
             DiskTO[] disks = validateDisks(vmSpec.getDisks());
             assert (disks.length > 0);
             NicTO[] nics = vmSpec.getNics();
@@ -1798,29 +1787,36 @@
                 throw new Exception(msg);
             }
 
+            DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
+            if (dsRootVolumeIsOn == null) {
+                String msg = "Unable to locate datastore details of root volume";
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
             VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
-            VirtualDevice[] nicDevices = null;
             VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
             DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
             int firstScsiControllerBusNum = 0;
             int numScsiControllerForSystemVm = 1;
             boolean hasSnapshot = false;
-
-            List<Pair<Integer, ManagedObjectReference>> diskDatastores = null;
             if (vmMo != null) {
                 s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
                 if (getVmPowerState(vmMo) != PowerState.PowerOff)
                     vmMo.safePowerOff(_shutdownWaitMs);
 
                 // retrieve disk information before we tear down
-                diskDatastores = vmMo.getAllDiskDatastores();
                 diskInfoBuilder = vmMo.getDiskInfoBuilder();
                 hasSnapshot = vmMo.hasSnapshot();
-                nicDevices = vmMo.getNicDevices();
-
-                tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
-                ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
-                        numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
+                if (!hasSnapshot)
+                    vmMo.tearDownDevices(new Class<?>[]{VirtualDisk.class, VirtualEthernetCard.class});
+                else
+                    vmMo.tearDownDevices(new Class<?>[]{VirtualEthernetCard.class});
+                if (systemVm) {
+                    ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
+                } else {
+                    ensureDiskControllers(vmMo, controllerInfo);
+                }
             } else {
                 ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
                 assert (morDc != null);
@@ -1838,11 +1834,17 @@
 
                     diskInfoBuilder = vmMo.getDiskInfoBuilder();
                     hasSnapshot = vmMo.hasSnapshot();
-                    diskDatastores = vmMo.getAllDiskDatastores();
+                    if (!hasSnapshot)
+                        vmMo.tearDownDevices(new Class<?>[]{VirtualDisk.class, VirtualEthernetCard.class});
+                    else
+                        vmMo.tearDownDevices(new Class<?>[]{VirtualEthernetCard.class});
 
-                    tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
-                    ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
-                            numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
+                    if (systemVm) {
+                        // System volumes doesn't require more than 1 SCSI controller as there is no requirement for data volumes.
+                        ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
+                    } else {
+                        ensureDiskControllers(vmMo, controllerInfo);
+                    }
                 } else {
                     // If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
                     VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
@@ -1854,55 +1856,45 @@
                         existingDatastores = existingVmInDc.getAllDatastores();
                         existingVmInDc.unregisterVm();
                     }
+                    Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
+                    for (DiskTO vol : disks) {
+                        if (vol.getType() == Volume.Type.ROOT) {
+                            Map<String, String> details = vol.getDetails();
+                            boolean managed = false;
 
-                    if (deployAsIs) {
+                            if (details != null) {
+                                managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                            }
+
+                            if (managed) {
+                                String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
+
+                                rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
+                            } else {
+                                DataStoreTO primaryStore = vol.getData().getDataStore();
+
+                                rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
+                            }
+                        }
+                    }
+
+                    assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
+
+                    boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
+                    String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
+                    if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present.
+                        registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
                         vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
-                        if (vmMo == null) {
-                            s_logger.info("Cloned deploy-as-is VM " + vmInternalCSName + " is not in this host, relocating it");
-                            vmMo = takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
-                        }
-                    } else {
-                        DiskTO rootDisk = null;
-                        for (DiskTO vol : disks) {
-                            if (vol.getType() == Volume.Type.ROOT) {
-                                rootDisk = vol;
+                        if (vmMo != null) {
+                            if (s_logger.isDebugEnabled()) {
+                                s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
                             }
                         }
-                        Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = getDatastoreThatDiskIsOn(dataStoresDetails, rootDisk);
-                        assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
-                        DatastoreMO dsRootVolumeIsOn = rootDiskDataStoreDetails.second();
-                        if (dsRootVolumeIsOn == null) {
-                                String msg = "Unable to locate datastore details of root volume";
-                                s_logger.error(msg);
-                                throw new Exception(msg);
-                            }
-                        if (rootDisk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && rootDisk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
-                            if (diskInfoBuilder != null) {
-                                DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, rootDisk, diskDatastores);
-                                if (diskDatastoreMofromVM != null) {
-                                    String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                                    if (!actualPoolUuid.equalsIgnoreCase(rootDisk.getData().getDataStore().getUuid())) {
-                                        dsRootVolumeIsOn = diskDatastoreMofromVM;
-                                    }
-                                }
-                            }
-                        }
-
-                        boolean vmFolderExists = dsRootVolumeIsOn.folderExists(String.format("[%s]", dsRootVolumeIsOn.getName()), vmNameOnVcenter);                        String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                        if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present.
-                            registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
-                            vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
-                            if (vmMo != null) {
-                                if (s_logger.isDebugEnabled()) {
-                                    s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
-                                }
-                            }
-                            tearDownVm(vmMo);
-                        } else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec),
-                                vmSpec.getLimitCpuUse(), (int) (vmSpec.getMaxRam() / ResourceType.bytesToMiB), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false,
-                                controllerInfo, systemVm)) {
-                            throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
-                        }
+                        tearDownVm(vmMo);
+                    } else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec),
+                            vmSpec.getLimitCpuUse(), (int) (vmSpec.getMaxRam() / ResourceType.bytesToMiB), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false,
+                            controllerInfo, systemVm)) {
+                        throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
                     }
                 }
 
@@ -1911,16 +1903,8 @@
                     throw new Exception("Failed to find the newly create or relocated VM. vmName: " + vmInternalCSName);
                 }
             }
-            if (deployAsIs) {
-                s_logger.info("Mapping VM disks to spec disks and tearing down datadisks (if any)");
-                mapSpecDisksToClonedDisksAndTearDownDatadisks(vmMo, vmInternalCSName, specDisks);
-            }
 
-            int disksChanges = getDisksChangesNumberFromDisksSpec(disks, deployAsIs);
-            int totalChangeDevices = disksChanges + nics.length;
-            if (deployAsIsInfo != null && deployAsIsInfo.getProperties() != null) {
-                totalChangeDevices++;
-            }
+            int totalChangeDevices = disks.length + nics.length;
 
             DiskTO volIso = null;
             if (vmSpec.getType() != VirtualMachine.Type.User) {
@@ -1928,23 +1912,14 @@
                 totalChangeDevices++;
             } else {
                 volIso = getIsoDiskTO(disks);
-                if (volIso == null && !deployAsIs) {
+                if (volIso == null)
                     totalChangeDevices++;
-                }
             }
 
             VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
 
-            int i = 0;
-            int ideUnitNumber = !deployAsIs ? 0 : vmMo.getNextIDEDeviceNumber();
-            int scsiUnitNumber = !deployAsIs ? 0 : vmMo.getNextScsiDiskDeviceNumber();
-            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
-            int scsiControllerKey = vmMo.getScsiDeviceControllerKeyNoException();
-            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
-            DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
-
             VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int) (vmSpec.getMaxRam() / (1024 * 1024)),
-                    getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse(), deployAsIs);
+                    getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse());
 
             // Check for multi-cores per socket settings
             int numCoresPerSocket = 1;
@@ -1972,6 +1947,14 @@
 
             configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
 
+            VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
+            int i = 0;
+            int ideUnitNumber = 0;
+            int scsiUnitNumber = 0;
+            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
+            int scsiControllerKey = vmMo.getScsiDeviceControllerKeyNoException();
+            int controllerKey;
+
             //
             // Setup ISO device
             //
@@ -2009,7 +1992,7 @@
                     deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
                 }
                 i++;
-            } else if (!deployAsIs) {
+            } else {
                 // Note: we will always plug a CDROM device
                 if (volIso != null) {
                     for (DiskTO vol : disks) {
@@ -2065,19 +2048,18 @@
                 }
             }
 
-            int controllerKey;
 
             //
             // Setup ROOT/DATA disk devices
             //
+            DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
             for (DiskTO vol : sortedDisks) {
-                if (vol.getType() == Volume.Type.ISO || deployAsIs && vol.getType() == Volume.Type.ROOT) {
+                if (vol.getType() == Volume.Type.ISO)
                     continue;
-                }
 
                 VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
                 controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey);
-                String diskController = getDiskController(vmMo, matchingExistingDisk, vol, controllerInfo);
+                String diskController = getDiskController(vmMo, matchingExistingDisk, vol, new Pair<String, String>(rootDiskController, dataDiskController));
 
                 if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
                     diskController = vmMo.getRecommendedDiskController(null);
@@ -2120,41 +2102,13 @@
                         iScsiName = details.get(DiskTO.IQN);
                     }
 
-                    String primaryStoreUuid = primaryStore.getUuid();
                     // if the storage is managed, iScsiName should not be null
-                    String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid;
+                    String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
                     Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
 
                     assert (volumeDsDetails != null);
-                    if (volumeDsDetails == null) {
-                        throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
-                    }
 
-                    if (vol.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
-                        if (diskInfoBuilder != null && matchingExistingDisk != null) {
-                            String[] diskChain = matchingExistingDisk.getDiskChain();
-                            if (diskChain != null && diskChain.length > 0) {
-                                DatastoreFile file = new DatastoreFile(diskChain[0]);
-                                if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) {
-                                    if (s_logger.isInfoEnabled())
-                                        s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName());
-                                    volumeTO.setPath(file.getFileBaseName());
-                                }
-                            }
-                            DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores);
-                            if (diskDatastoreMofromVM != null) {
-                                String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                                if (actualPoolUuid != null && !actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
-                                    volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM);
-                                    if (s_logger.isInfoEnabled())
-                                        s_logger.info("Detected datastore uuid change on volume: " + volumeTO.getId() + " " + primaryStore.getUuid() + " -> " + actualPoolUuid);
-                                    ((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid);
-                                }
-                            }
-                        }
-                    }
-
-                    String[] diskChain = syncDiskChain(dcMo, vmMo, vol, matchingExistingDisk, volumeDsDetails.second());
+                    String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
 
                     int deviceNumber = -1;
                     if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) {
@@ -2167,20 +2121,8 @@
 
                     VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1);
 
-                    diskStoragePolicyId = volumeTO.getvSphereStoragePolicyId();
-                    if (!StringUtils.isEmpty(diskStoragePolicyId)) {
-                        PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(context);
-                        diskProfileSpec = profMgrMo.getProfileSpec(diskStoragePolicyId);
-                        deviceConfigSpecArray[i].getProfile().add(diskProfileSpec);
-                        if (s_logger.isDebugEnabled()) {
-                            s_logger.debug(String.format("Adding vSphere storage profile: %s to virtual disk [%s]", diskStoragePolicyId, _gson.toJson(device)));
-                        }
-                    }
-                    if (vol.getType() == Volume.Type.ROOT) {
+                    if (vol.getType() == Volume.Type.ROOT)
                         rootDiskTO = vol;
-                        vmStoragePolicyId = diskStoragePolicyId;
-                        vmProfileSpec = diskProfileSpec;
-                    }
                     deviceConfigSpecArray[i].setDevice(device);
                     deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
 
@@ -2199,7 +2141,7 @@
             //
             // Setup USB devices
             //
-            if (StringUtils.isNotBlank(guestOsId) && guestOsId.startsWith("darwin")) { //Mac OS
+            if (guestOsId.startsWith("darwin")) { //Mac OS
                 VirtualDevice[] devices = vmMo.getMatchedDevices(new Class<?>[]{VirtualUSBController.class});
                 if (devices.length == 0) {
                     s_logger.debug("No USB Controller device on VM Start. Add USB Controller device for Mac OS VM " + vmInternalCSName);
@@ -2259,7 +2201,9 @@
                 }
             }
 
-            VirtualEthernetCardType nicDeviceType;
+            VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
+            if (s_logger.isDebugEnabled())
+                s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType);
 
             NiciraNvpApiVersion.logNiciraApiVersion();
 
@@ -2267,14 +2211,6 @@
             for (NicTO nicTo : sortNicsByDeviceId(nics)) {
                 s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
 
-                String adapterTypeStr = deployAsIs ?
-                        mapAdapterType(deployAsIsInfo.getNicAdapterMap().get(nicTo.getDeviceId())) :
-                        vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER);
-                nicDeviceType = VirtualEthernetCardType.valueOf(adapterTypeStr);
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType + " on NIC device " + nicTo.getDeviceId());
-                }
                 boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
                 VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
                 Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
@@ -2328,11 +2264,6 @@
             // pass boot arguments through machine.id & perform customized options to VMX
             ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
             configBasicExtraOption(extraOptions, vmSpec);
-
-            if (deployAsIs) {
-                setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec);
-            }
-
             configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
             configCustomExtraOption(extraOptions, vmSpec);
 
@@ -2346,19 +2277,35 @@
                 extraOptions.add(option);
             }
 
-            configureVNC(vmSpec, extraOptions, vmConfigSpec, hyperHost, vmInternalCSName);
+            // config VNC
+            String keyboardLayout = null;
+            if (vmSpec.getDetails() != null)
+                keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
+            vmConfigSpec.getExtraConfig()
+                    .addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
 
             // config video card
             configureVideoCard(vmMo, vmSpec, vmConfigSpec);
 
-            setBootOptions(vmSpec, bootMode, vmConfigSpec);
-
-            if (!StringUtils.isEmpty(vmStoragePolicyId)) {
-                vmConfigSpec.getVmProfile().add(vmProfileSpec);
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace(String.format("Configuring the VM %s with storage policy: %s", vmInternalCSName, vmStoragePolicyId));
+            // Set OVF properties (if available)
+            Pair<String, List<OVFPropertyTO>> ovfPropsMap = vmSpec.getOvfProperties();
+            VmConfigInfo templateVappConfig = null;
+            List<OVFPropertyTO> ovfProperties = null;
+            if (ovfPropsMap != null) {
+                String vmTemplate = ovfPropsMap.first();
+                s_logger.info("Find VM template " + vmTemplate);
+                VirtualMachineMO vmTemplateMO = dcMo.findVm(vmTemplate);
+                templateVappConfig = vmTemplateMO.getConfigInfo().getVAppConfig();
+                ovfProperties = ovfPropsMap.second();
+                // Set OVF properties (if available)
+                if (CollectionUtils.isNotEmpty(ovfProperties)) {
+                    s_logger.info("Copying OVF properties from template and setting them to the values the user provided");
+                    copyVAppConfigsFromTemplate(templateVappConfig, ovfProperties, vmConfigSpec);
                 }
             }
+
+            setBootOptions(vmSpec, bootMode, vmConfigSpec);
+
             //
             // Configure VM
             //
@@ -2372,7 +2319,7 @@
 
             // Resizing root disk only when explicit requested by user
             final Map<String, String> vmDetails = cmd.getVirtualMachine().getDetails();
-            if (!deployAsIs && rootDiskTO != null && !hasSnapshot && (vmDetails != null && vmDetails.containsKey(ApiConstants.ROOT_DISK_SIZE))) {
+            if (rootDiskTO != null && !hasSnapshot && (vmDetails != null && vmDetails.containsKey(ApiConstants.ROOT_DISK_SIZE))) {
                 resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context);
             }
 
@@ -2446,186 +2393,6 @@
         }
     }
 
-    private String mapAdapterType(String adapterStringFromOVF) {
-        if (StringUtils.isBlank(adapterStringFromOVF) || adapterStringFromOVF.equalsIgnoreCase(VirtualEthernetCardType.E1000.toString())) {
-            return VirtualEthernetCardType.E1000.toString();
-        } else if (adapterStringFromOVF.equalsIgnoreCase(VirtualEthernetCardType.PCNet32.toString())) {
-            return VirtualEthernetCardType.PCNet32.toString();
-        } else if (adapterStringFromOVF.equalsIgnoreCase(VirtualEthernetCardType.Vmxnet2.toString())) {
-            return VirtualEthernetCardType.Vmxnet2.toString();
-        } else if (adapterStringFromOVF.equalsIgnoreCase(VirtualEthernetCardType.Vmxnet3.toString())) {
-            return VirtualEthernetCardType.Vmxnet3.toString();
-        }
-        return VirtualEthernetCardType.E1000.toString();
-    }
-
-    private int getDisksChangesNumberFromDisksSpec(DiskTO[] disks, boolean deployAsIs) {
-        if (!deployAsIs) {
-            return disks.length;
-        } else {
-            int datadisksNumber = 0;
-            if (ArrayUtils.isNotEmpty(disks)) {
-                List<DiskTO> datadisks = Arrays.stream(disks).filter(x -> x.getType() == Volume.Type.DATADISK).collect(Collectors.toList());
-                if (CollectionUtils.isNotEmpty(datadisks)) {
-                    datadisksNumber = datadisks.size();
-                }
-            }
-            return datadisksNumber;
-        }
-    }
-
-    /**
-     * Configure VNC
-     */
-    private void configureVNC(VirtualMachineTO vmSpec, ArrayList<OptionValue> extraOptions, VirtualMachineConfigSpec vmConfigSpec, VmwareHypervisorHost hyperHost, String vmInternalCSName) throws Exception {
-        String keyboardLayout = null;
-        if (vmSpec.getDetails() != null)
-            keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
-        vmConfigSpec.getExtraConfig()
-                .addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
-
-    }
-
-    private void ensureDiskControllersInternal(VirtualMachineMO vmMo, Boolean systemVm,
-                                               Pair<String, String> controllerInfo,
-                                               DiskControllerType systemVmScsiControllerType,
-                                               int numScsiControllerForSystemVm,
-                                               int firstScsiControllerBusNum, boolean deployAsIs) throws Exception {
-        if (systemVm) {
-            ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
-        } else if (!deployAsIs) {
-            ensureDiskControllers(vmMo, controllerInfo);
-        }
-    }
-
-    private void tearDownVmDevices(VirtualMachineMO vmMo, boolean hasSnapshot, boolean deployAsIs) throws Exception {
-        if (deployAsIs) {
-            vmMo.tearDownDevices(new Class<?>[]{VirtualEthernetCard.class});
-        } else if (!hasSnapshot) {
-            vmMo.tearDownDevices(new Class<?>[]{VirtualDisk.class, VirtualEthernetCard.class});
-        } else {
-            vmMo.tearDownDevices(new Class<?>[]{VirtualEthernetCard.class});
-        }
-    }
-
-    private void tearDownVMDisks(VirtualMachineMO vmMo, List<VirtualDisk> disks) throws Exception {
-        for (VirtualDisk disk : disks) {
-            vmMo.tearDownDevice(disk);
-        }
-    }
-
-    private String getGuestOsIdFromVmSpec(VirtualMachineTO vmSpec, boolean deployAsIs) {
-        return translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
-    }
-
-    private Pair<String, String> getControllerInfoFromVmSpec(VirtualMachineTO vmSpec) throws CloudRuntimeException {
-        String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
-        String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
-
-        // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
-        // This helps avoid mix of different scsi subtype controllers in instance.
-        if (DiskControllerType.osdefault == DiskControllerType.getType(dataDiskController) && DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
-            dataDiskController = DiskControllerType.scsi.toString();
-        }
-
-        // Validate the controller types
-        dataDiskController = DiskControllerType.getType(dataDiskController).toString();
-        rootDiskController = DiskControllerType.getType(rootDiskController).toString();
-
-        if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
-            throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
-        }
-        if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
-            throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
-        }
-
-        return new Pair<>(rootDiskController, dataDiskController);
-    }
-
-    private String getBootModeFromVmSpec(VirtualMachineTO vmSpec, boolean deployAsIs) {
-        String bootMode = null;
-        if (vmSpec.getDetails().containsKey(VmDetailConstants.BOOT_MODE)) {
-            bootMode = vmSpec.getDetails().get(VmDetailConstants.BOOT_MODE);
-        }
-        if (bootMode == null) {
-            bootMode = ApiConstants.BootType.BIOS.toString();
-        }
-        return bootMode;
-    }
-
-    /**
-     * Set OVF properties (if available)
-     */
-    private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo,
-                                         VirtualMachineConfigSpec vmConfigSpec) throws Exception {
-        if (deployAsIsInfo != null) {
-            Map<String, String> properties = deployAsIsInfo.getProperties();
-            VmConfigInfo vAppConfig = vmMo.getConfigInfo().getVAppConfig();
-            s_logger.info("Copying OVF properties to the values the user provided");
-            setVAppPropertiesToConfigSpec(vAppConfig, properties, vmConfigSpec);
-        }
-    }
-
-    /**
-     * Modify the specDisks information to match the cloned VM's disks (from vmMo VM)
-     */
-    private void mapSpecDisksToClonedDisksAndTearDownDatadisks(VirtualMachineMO vmMo, String vmInternalCSName, DiskTO[] specDisks) {
-        try {
-            s_logger.debug("Mapping spec disks information to cloned VM disks for VM " + vmInternalCSName);
-            if (vmMo != null && ArrayUtils.isNotEmpty(specDisks)) {
-                List<VirtualDisk> vmDisks = vmMo.getVirtualDisks();
-                List<VirtualDisk> rootDisks = new ArrayList<>();
-                List<DiskTO> sortedRootDisksFromSpec = Arrays.asList(sortVolumesByDeviceId(specDisks))
-                        .stream()
-                        .filter(x -> x.getType() == Volume.Type.ROOT)
-                        .collect(Collectors.toList());
-                for (int i = 0; i < sortedRootDisksFromSpec.size(); i++) {
-                    DiskTO specDisk = sortedRootDisksFromSpec.get(i);
-                    VirtualDisk vmDisk = vmDisks.get(i);
-                    DataTO dataVolume = specDisk.getData();
-                    if (dataVolume instanceof VolumeObjectTO) {
-                        VolumeObjectTO volumeObjectTO = (VolumeObjectTO) dataVolume;
-                        if (!volumeObjectTO.getSize().equals(vmDisk.getCapacityInBytes())) {
-                            s_logger.info("Mapped disk size is not the same as the cloned VM disk size: " +
-                                    volumeObjectTO.getSize() + " - " + vmDisk.getCapacityInBytes());
-                        }
-                        VirtualDeviceBackingInfo backingInfo = vmDisk.getBacking();
-                        if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
-                            VirtualDiskFlatVer2BackingInfo backing = (VirtualDiskFlatVer2BackingInfo) backingInfo;
-                            String fileName = backing.getFileName();
-                            if (StringUtils.isNotBlank(fileName)) {
-                                String[] fileNameParts = fileName.split(" ");
-                                String datastoreUuid = fileNameParts[0].replace("[", "").replace("]", "");
-                                String relativePath = fileNameParts[1].split("/")[1].replace(".vmdk", "");
-                                String vmSpecDatastoreUuid = volumeObjectTO.getDataStore().getUuid().replaceAll("-", "");
-                                if (!datastoreUuid.equals(vmSpecDatastoreUuid)) {
-                                    s_logger.info("Mapped disk datastore UUID is not the same as the cloned VM datastore UUID: " +
-                                            datastoreUuid + " - " + vmSpecDatastoreUuid);
-                                }
-                                volumeObjectTO.setPath(relativePath);
-                                specDisk.setPath(relativePath);
-                                rootDisks.add(vmDisk);
-                            } else {
-                                s_logger.error("Empty backing filename for volume " + volumeObjectTO.getName());
-                            }
-                        } else {
-                            s_logger.error("Could not get volume backing info for volume " + volumeObjectTO.getName());
-                        }
-                    }
-                }
-                vmDisks.removeAll(rootDisks);
-                if (CollectionUtils.isNotEmpty(vmDisks)) {
-                    s_logger.info("Tearing down datadisks for deploy-as-is VM");
-                    tearDownVMDisks(vmMo, vmDisks);
-                }
-            }
-        } catch (Exception e) {
-            String msg = "Error mapping deploy-as-is VM disks from cloned VM " + vmInternalCSName;
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(e);
-        }
-    }
-
     private void setBootOptions(VirtualMachineTO vmSpec, String bootMode, VirtualMachineConfigSpec vmConfigSpec) {
         VirtualMachineBootOptions bootOptions = null;
         if (StringUtils.isNotBlank(bootMode) && !bootMode.equalsIgnoreCase("bios")) {
@@ -2669,33 +2436,26 @@
     private Map<String, Pair<String, Boolean>> getOVFMap(List<OVFPropertyTO> props) {
         Map<String, Pair<String, Boolean>> map = new HashMap<>();
         for (OVFPropertyTO prop : props) {
-            String value = getPropertyValue(prop);
-            Pair<String, Boolean> pair = new Pair<>(value, prop.isPassword());
+            Pair<String, Boolean> pair = new Pair<>(prop.getValue(), prop.isPassword());
             map.put(prop.getKey(), pair);
         }
         return map;
     }
 
-    private String getPropertyValue(OVFPropertyTO prop) {
-        String type = prop.getType();
-        String value = prop.getValue();
-        if ("boolean".equalsIgnoreCase(type)) {
-            value = Boolean.parseBoolean(value) ? "True" : "False";
-        }
-        return value;
-    }
-
     /**
      * Set the properties section from existing vApp configuration and values set on ovfProperties
      */
-    protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map<String, String> ovfProperties) {
+    protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, List<OVFPropertyTO> ovfProperties) {
         List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty();
         List<VAppPropertySpec> specs = new ArrayList<>();
+        Map<String, Pair<String, Boolean>> ovfMap = getOVFMap(ovfProperties);
         for (VAppPropertyInfo info : productFromOvf) {
             VAppPropertySpec spec = new VAppPropertySpec();
-            if (ovfProperties.containsKey(info.getId())) {
-                String value = ovfProperties.get(info.getId());
-                info.setValue(value);
+            if (ovfMap.containsKey(info.getId())) {
+                Pair<String, Boolean> pair = ovfMap.get(info.getId());
+                String value = pair.first();
+                boolean isPassword = pair.second();
+                info.setValue(isPassword ? DBEncryptionUtil.decrypt(value) : value);
             }
             spec.setInfo(info);
             spec.setOperation(ArrayUpdateOperation.ADD);
@@ -2723,9 +2483,9 @@
      * Set the vApp configuration to vmConfig spec, copying existing configuration from vAppConfig
      * and seting properties values from ovfProperties
      */
-    protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig,
-                                                 Map<String, String> ovfProperties,
-                                                 VirtualMachineConfigSpec vmConfig) throws Exception {
+    protected void copyVAppConfigsFromTemplate(VmConfigInfo vAppConfig,
+                                               List<OVFPropertyTO> ovfProperties,
+                                               VirtualMachineConfigSpec vmConfig) throws Exception {
         VmConfigSpec vmConfigSpec = new VmConfigSpec();
         vmConfigSpec.getEula().addAll(vAppConfig.getEula());
         vmConfigSpec.setInstallBootStopDelay(vAppConfig.getInstallBootStopDelay());
@@ -2919,61 +2679,66 @@
     }
 
     // return the finalized disk chain for startup, from top to bottom
-    private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, DiskTO vol, VirtualMachineDiskInfo diskInfo,
-                                   DatastoreMO dsMo) throws Exception {
+    private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO vol, VirtualMachineDiskInfo diskInfo,
+                                   HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
 
         VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
+        DataStoreTO primaryStore = volumeTO.getDataStore();
         Map<String, String> details = vol.getDetails();
         boolean isManaged = false;
+        String iScsiName = null;
 
         if (details != null) {
             isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+            iScsiName = details.get(DiskTO.IQN);
         }
 
-        String datastoreDiskPath;
-        if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-            datastoreDiskPath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
-            if (!dsMo.fileExists(datastoreDiskPath)) {
-                datastoreDiskPath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmMo.getName(), volumeTO.getPath() + ".vmdk");
+        // if the storage is managed, iScsiName should not be null
+        String datastoreName = isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
+        Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
+
+        if (volumeDsDetails == null) {
+            throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
+        }
+
+        DatastoreMO dsMo = volumeDsDetails.second();
+
+        // we will honor vCenter's meta if it exists
+        if (diskInfo != null) {
+            // to deal with run-time upgrade to maintain the new datastore folder structure
+            String disks[] = diskInfo.getDiskChain();
+            for (int i = 0; i < disks.length; i++) {
+                DatastoreFile file = new DatastoreFile(disks[i]);
+                if (!isManaged && file.getDir() != null && file.getDir().isEmpty()) {
+                    s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder");
+                    disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, file.getFileBaseName(), VmwareManager.s_vmwareSearchExcludeFolder.value());
+                }
             }
-            if (!dsMo.fileExists(datastoreDiskPath)) {
-                datastoreDiskPath = dsMo.searchFileInSubFolders(volumeTO.getPath() + ".vmdk", true, null);
+            return disks;
+        }
+
+        final String datastoreDiskPath;
+
+        if (isManaged) {
+            String vmdkPath = new DatastoreFile(volumeTO.getPath()).getFileBaseName();
+
+            if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
+                if (vmdkPath == null) {
+                    vmdkPath = volumeTO.getName();
+                }
+
+                datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, vmdkPath);
+            } else {
+                if (vmdkPath == null) {
+                    vmdkPath = dsMo.getName();
+                }
+
+                datastoreDiskPath = dsMo.getDatastorePath(vmdkPath + VMDK_EXTENSION);
             }
         } else {
-            // we will honor vCenter's meta if it exists
-            if (diskInfo != null) {
-                // to deal with run-time upgrade to maintain the new datastore folder structure
-                String disks[] = diskInfo.getDiskChain();
-                for (int i = 0; i < disks.length; i++) {
-                    DatastoreFile file = new DatastoreFile(disks[i]);
-                    if (!isManaged && file.getDir() != null && file.getDir().isEmpty()) {
-                        s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder");
-                        disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, file.getFileBaseName(), VmwareManager.s_vmwareSearchExcludeFolder.value());
-                    }
-                }
-                return disks;
-            }
-
-            if (isManaged) {
-                String vmdkPath = new DatastoreFile(volumeTO.getPath()).getFileBaseName();
-
-                if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
-                    if (vmdkPath == null) {
-                        vmdkPath = volumeTO.getName();
-                    }
-
-                    datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, vmdkPath);
-                } else {
-                    if (vmdkPath == null) {
-                        vmdkPath = dsMo.getName();
-                    }
-
-                    datastoreDiskPath = dsMo.getDatastorePath(vmdkPath + VMDK_EXTENSION);
-                }
-            } else {
-                datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
-            }
+            datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
         }
+
         if (!dsMo.fileExists(datastoreDiskPath)) {
             s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath);
         }
@@ -3361,9 +3126,6 @@
                     volInSpec.setPath(datastoreVolumePath);
                 } else {
                     volInSpec.setPath(file.getFileBaseName());
-                    if (vol.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
-                        volInSpec.setUpdatedDataStoreUUID(volumeTO.getDataStore().getUuid());
-                    }
                 }
                 volInSpec.setChainInfo(_gson.toJson(diskInfo));
             }
@@ -3499,41 +3261,6 @@
         return path.substring(0, endIndex).trim();
     }
 
-    private DatastoreMO getDataStoreWhereDiskExists(VmwareHypervisorHost hyperHost, VmwareContext context,
-                                               VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO disk, List<Pair<Integer, ManagedObjectReference>> diskDatastores) throws Exception {
-        VolumeObjectTO volume = (VolumeObjectTO) disk.getData();
-        String diskBackingFileBaseName = volume.getPath();
-        for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
-            DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), diskDatastore.second());
-            String dsName = dsMo.getName();
-
-            VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
-            if (diskInfo != null) {
-                s_logger.info("Found existing disk info from volume path: " + volume.getPath());
-                return dsMo;
-            } else {
-                String chainInfo = volume.getChainInfo();
-                if (chainInfo != null) {
-                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
-                    if (infoInChain != null) {
-                        String[] disks = infoInChain.getDiskChain();
-                        if (disks.length > 0) {
-                            for (String diskPath : disks) {
-                                DatastoreFile file = new DatastoreFile(diskPath);
-                                diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
-                                if (diskInfo != null) {
-                                    s_logger.info("Found existing disk from chain info: " + diskPath);
-                                    return dsMo;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
     private HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context,
                                                                                                          DiskTO[] disks, Command cmd) throws Exception {
         HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> mapIdToMors = new HashMap<>();
@@ -3606,25 +3333,39 @@
         return mapIdToMors;
     }
 
-    private Pair<ManagedObjectReference, DatastoreMO> getDatastoreThatDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO vol) {
+    private DatastoreMO getDatastoreThatRootDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO disks[]) {
         Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
 
-        Map<String, String> details = vol.getDetails();
-        boolean managed = false;
+        for (DiskTO vol : disks) {
+            if (vol.getType() == Volume.Type.ROOT) {
+                Map<String, String> details = vol.getDetails();
+                boolean managed = false;
 
-        if (details != null) {
-            managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                if (details != null) {
+                    managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
+                }
+
+                if (managed) {
+                    String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
+
+                    rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
+
+                    break;
+                } else {
+                    DataStoreTO primaryStore = vol.getData().getDataStore();
+
+                    rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
+
+                    break;
+                }
+            }
         }
 
-        if (managed) {
-            String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
-            rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
-        } else {
-            DataStoreTO primaryStore = vol.getData().getDataStore();
-            rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
+        if (rootDiskDataStoreDetails != null) {
+            return rootDiskDataStoreDetails.second();
         }
 
-        return rootDiskDataStoreDetails;
+        return null;
     }
 
     private String getPvlanInfo(NicTO nicTo) {
@@ -4643,8 +4384,7 @@
 
                 s_logger.debug("Preparing spec for volume : " + volume.getName());
                 morDsAtTarget = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, filerTo.getUuid());
-                morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, volume.getPoolUuid());
-
+                morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, filerTo.getUuid());
                 if (morDsAtTarget == null) {
                     String msg = "Unable to find the target datastore: " + filerTo.getUuid() + " on target host: " + tgtHyperHost.getHyperHostName()
                             + " to execute MigrateWithStorageCommand";
@@ -4664,7 +4404,7 @@
                     // If datastore is NFS and target datastore is not already mounted on source host then mount the datastore.
                     if (filerTo.getType().equals(StoragePoolType.NetworkFilesystem)) {
                         if (morDsAtSource == null) {
-                            morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName, true);
+                            morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName);
                             if (morDsAtSource == null) {
                                 throw new Exception("Unable to mount NFS datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
                             }
@@ -4672,8 +4412,9 @@
                             s_logger.debug("Mounted datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
                         }
                     }
+
                     // If datastore is VMFS and target datastore is not mounted or accessible to source host then fail migration.
-                    if (filerTo.getType().equals(StoragePoolType.VMFS) || filerTo.getType().equals(StoragePoolType.PreSetup)) {
+                    if (filerTo.getType().equals(StoragePoolType.VMFS)) {
                         if (morDsAtSource == null) {
                             s_logger.warn(
                                     "If host version is below 5.1, then target VMFS datastore(s) need to manually mounted on source host for a successful live storage migration.");
@@ -4692,7 +4433,6 @@
                 if (volume.getType() == Volume.Type.ROOT) {
                     relocateSpec.setDatastore(morTgtDatastore);
                 }
-
                 diskLocator = new VirtualMachineRelocateSpecDiskLocator();
                 diskLocator.setDatastore(morDsAtSource);
                 Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, appendFileType(volume.getPath(), VMDK_EXTENSION));
@@ -4717,9 +4457,8 @@
                     diskLocators.add(diskLocator);
                 }
             }
-            if (srcHyperHost.getHyperHostCluster().equals(tgtHyperHost.getHyperHostCluster())) {
-                relocateSpec.getDisk().addAll(diskLocators);
-            }
+
+            relocateSpec.getDisk().addAll(diskLocators);
 
             // Prepare network at target before migration
             NicTO[] nics = vmTo.getNics();
@@ -4837,33 +4576,23 @@
         VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
         VirtualMachineMO vmMo = null;
         DatastoreMO dsMo = null;
-        DatastoreMO destinationDsMo = null;
         ManagedObjectReference morSourceDS = null;
-        ManagedObjectReference morDestintionDS = null;
         String vmdkDataStorePath = null;
-        boolean isvVolsInvolved = false;
 
         String vmName = null;
         try {
             // OfflineVmwareMigration: we need to refactor the worker vm creation out for use in migration methods as well as here
             // OfflineVmwareMigration: this method is 100 lines and needs refactorring anyway
             // we need to spawn a worker VM to attach the volume to and move it
-            morSourceDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getSourcePool().getUuid());
-            dsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS);
-            morDestintionDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getTargetPool().getUuid());
-            destinationDsMo = new DatastoreMO(hyperHost.getContext(), morDestintionDS);
-
-            vmName = getWorkerName(getServiceContext(), cmd, 0, dsMo);
-            if (destinationDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                isvVolsInvolved = true;
-                vmName = getWorkerName(getServiceContext(), cmd, 0, destinationDsMo);
-            }
+            vmName = getWorkerName(getServiceContext(), cmd, 0);
 
             // OfflineVmwareMigration: refactor for re-use
             // OfflineVmwareMigration: 1. find data(store)
             // OfflineVmwareMigration: more robust would be to find the store given the volume as it might have been moved out of band or due to error
 // example:            DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
 
+            morSourceDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getSourcePool().getUuid());
+            dsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS);
             s_logger.info("Create worker VM " + vmName);
             // OfflineVmwareMigration: 2. create the worker with access to the data(store)
             vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, vmName, null);
@@ -4882,16 +4611,12 @@
                     }
                     vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, path, vmdkFileName);
                 }
-                if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), path) || !dsMo.fileExists(vmdkDataStorePath)) {
+                if (!dsMo.fileExists(vmdkDataStorePath)) {
                     if (s_logger.isDebugEnabled()) {
                         s_logger.debug(String.format("path not found (%s), trying under '%s'", vmdkFileName, vmName));
                     }
                     vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkFileName);
                 }
-                if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmName) || !dsMo.fileExists(vmdkDataStorePath)) {
-                    vmdkDataStorePath = dsMo.searchFileInSubFolders(vmdkFileName, true, null);
-                }
-
                 if (s_logger.isDebugEnabled()) {
                     s_logger.debug(String.format("attaching %s to %s for migration", vmdkDataStorePath, vmMo.getVmName()));
                 }
@@ -4958,23 +4683,21 @@
             }
         }
         if (answer instanceof MigrateVolumeAnswer) {
-            if (!isvVolsInvolved) {
-                String newPath = ((MigrateVolumeAnswer) answer).getVolumePath();
-                String vmdkFileName = newPath + VMDK_EXTENSION;
-                try {
-                    VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, newPath, vmName);
-                    vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
+            String newPath = ((MigrateVolumeAnswer) answer).getVolumePath();
+            String vmdkFileName = newPath + VMDK_EXTENSION;
+            try {
+                VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, newPath, vmName);
+                vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
 
-                    if (!dsMo.fileExists(vmdkDataStorePath)) {
-                        String msg = String.format("Migration of volume '%s' failed; file (%s) not found as path '%s'", cmd.getVolumePath(), vmdkFileName, vmdkDataStorePath);
-                        s_logger.error(msg);
-                        answer = new Answer(cmd, false, msg);
-                    }
-                } catch (Exception e) {
-                    String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
-                    s_logger.error(msg, e);
+                if (!dsMo.fileExists(vmdkDataStorePath)) {
+                    String msg = String.format("Migration of volume '%s' failed; file (%s) not found as path '%s'", cmd.getVolumePath(), vmdkFileName, vmdkDataStorePath);
+                    s_logger.error(msg);
                     answer = new Answer(cmd, false, msg);
                 }
+            } catch (Exception e) {
+                String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
+                s_logger.error(msg, e);
+                answer = new Answer(cmd, false, msg);
             }
         }
         return answer;
@@ -5178,71 +4901,27 @@
             VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
             StorageFilerTO pool = cmd.getPool();
 
-            if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS && pool.getType() != StoragePoolType.PreSetup && pool.getType() != StoragePoolType.DatastoreCluster) {
+            if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS) {
                 throw new Exception("Unsupported storage pool type " + pool.getType());
             }
 
             ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, pool.getUuid());
 
             if (morDatastore == null) {
-                morDatastore = hyperHost.mountDatastore((pool.getType() == StoragePoolType.VMFS || pool.getType() == StoragePoolType.PreSetup || pool.getType() == StoragePoolType.DatastoreCluster), pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", ""), true);
+                morDatastore = hyperHost.mountDatastore(pool.getType() == StoragePoolType.VMFS, pool.getHost(), pool.getPort(), pool.getPath(), pool.getUuid().replace("-", ""));
             }
 
             assert (morDatastore != null);
 
-            DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDatastore);
-            HypervisorHostHelper.createBaseFolder(dsMo, hyperHost, pool.getType());
+            DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary();
 
-            long capacity = 0;
-            long available = 0;
-            List<ModifyStoragePoolAnswer> childDatastoresModifyStoragePoolAnswers = new ArrayList<>();
-            if (pool.getType() == StoragePoolType.DatastoreCluster) {
-                StoragepodMO datastoreClusterMo = new StoragepodMO(getServiceContext(), morDatastore);
-                StoragePodSummary dsClusterSummary = datastoreClusterMo.getDatastoreClusterSummary();
-                capacity = dsClusterSummary.getCapacity();
-                available = dsClusterSummary.getFreeSpace();
-
-                List<ManagedObjectReference> childDatastoreMors = datastoreClusterMo.getDatastoresInDatastoreCluster();
-                for (ManagedObjectReference childDsMor : childDatastoreMors) {
-                    DatastoreMO childDsMo = new DatastoreMO(getServiceContext(), childDsMor);
-
-                    Map<String, TemplateProp> tInfo = new HashMap<>();
-                    DatastoreSummary summary = childDsMo.getDatastoreSummary();;
-                    ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, summary.getCapacity(), summary.getFreeSpace(), tInfo);
-                    StoragePoolInfo poolInfo = answer.getPoolInfo();
-                    poolInfo.setName(summary.getName());
-                    String datastoreClusterPath = pool.getPath();
-                    int pathstartPosition = datastoreClusterPath.lastIndexOf('/');
-                    String datacenterName = datastoreClusterPath.substring(0, pathstartPosition+1);
-                    String childPath = datacenterName + summary.getName();
-                    poolInfo.setHostPath(childPath);
-                    String uuid = UUID.nameUUIDFromBytes(((pool.getHost() + childPath)).getBytes()).toString();
-                    poolInfo.setUuid(uuid);
-                    poolInfo.setLocalPath(cmd.LOCAL_PATH_PREFIX + File.separator + uuid);
-
-                    answer.setPoolInfo(poolInfo);
-                    answer.setPoolType(summary.getType());
-                    answer.setLocalDatastoreName(morDatastore.getValue());
-
-                    childDsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, uuid);
-                    HypervisorHostHelper.createBaseFolderInDatastore(childDsMo, hyperHost);
-
-                    childDatastoresModifyStoragePoolAnswers.add(answer);
-                }
-            } else {
-                HypervisorHostHelper.createBaseFolderInDatastore(dsMo, hyperHost);
-
-                DatastoreSummary summary = dsMo.getDatastoreSummary();
-                capacity = summary.getCapacity();
-                available = summary.getFreeSpace();
-            }
+            long capacity = summary.getCapacity();
+            long available = summary.getFreeSpace();
 
             Map<String, TemplateProp> tInfo = new HashMap<>();
             ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
-            answer.setDatastoreClusterChildren(childDatastoresModifyStoragePoolAnswers);
 
-            if (cmd.getAdd() && (pool.getType() == StoragePoolType.VMFS || pool.getType() == StoragePoolType.PreSetup) && pool.getType() != StoragePoolType.DatastoreCluster) {
-                answer.setPoolType(dsMo.getDatastoreType());
+            if (cmd.getAdd() && pool.getType() == StoragePoolType.VMFS) {
                 answer.setLocalDatastoreName(morDatastore.getValue());
             }
 
@@ -5405,7 +5084,7 @@
         URI uri = new URI(storeUrl);
 
         VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""), false);
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
 
         if (morDatastore == null)
             throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
@@ -5417,7 +5096,7 @@
         String storeName = getSecondaryDatastoreUUID(storeUrl);
         URI uri = new URI(storeUrl);
 
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""), false);
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
 
         if (morDatastore == null)
             throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
@@ -5622,20 +5301,12 @@
             ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId());
 
             if (morDs != null) {
-                long capacity = 0;
-                long free = 0;
-                if (cmd.getPooltype() == StoragePoolType.DatastoreCluster) {
-                    StoragepodMO datastoreClusterMo = new StoragepodMO(getServiceContext(), morDs);
-                    StoragePodSummary summary = datastoreClusterMo.getDatastoreClusterSummary();
-                    capacity = summary.getCapacity();
-                    free = summary.getFreeSpace();
-                } else {
-                    DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
-                    DatastoreSummary summary = datastoreMo.getDatastoreSummary();
-                    capacity = summary.getCapacity();
-                    free = summary.getFreeSpace();
-                }
+                DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
+                DatastoreSummary summary = datastoreMo.getSummary();
+                assert (summary != null);
 
+                long capacity = summary.getCapacity();
+                long free = summary.getFreeSpace();
                 long used = capacity - free;
 
                 if (s_logger.isDebugEnabled()) {
@@ -5643,7 +5314,7 @@
                             + ", capacity: " + toHumanReadableSize(capacity) + ", free: " + toHumanReadableSize(free) + ", used: " + toHumanReadableSize(used));
                 }
 
-                if (capacity <= 0) {
+                if (summary.getCapacity() <= 0) {
                     s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help");
                 }
 
@@ -6165,7 +5836,7 @@
                         dsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, poolUuid);
                     }
 
-                    DatastoreSummary dsSummary = dsMo.getDatastoreSummary();
+                    DatastoreSummary dsSummary = dsMo.getSummary();
                     String address = hostMo.getHostName();
                     StoragePoolInfo pInfo = new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.VMFS, dsSummary.getCapacity(),
                             dsSummary.getFreeSpace());
@@ -6881,8 +6552,6 @@
 
             CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
             cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
-            cfmMo.ensureCustomFieldDef("StoragePod", CustomFieldConstants.CLOUD_UUID);
-
             if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch
                     || _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
                 cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
@@ -7060,12 +6729,9 @@
 
     @Override
     @DB
-    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence, DatastoreMO dsMo) throws Exception {
+    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
         VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
         String vmName = mgr.composeWorkerName();
-        if (dsMo!= null && dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-            vmName = CustomFieldConstants.CLOUD_UUID + "-" + vmName;
-        }
 
         assert (cmd != null);
         context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
@@ -7115,13 +6781,11 @@
 
             VirtualMachineMO vmMo = findVmOnDatacenter(context, hyperHost, vol);
 
-            if (vmMo != null) {
+            if (vmMo != null && vmMo.isTemplate()) {
                 if (s_logger.isInfoEnabled()) {
                     s_logger.info("Destroy template volume " + vol.getPath());
                 }
-                if (vmMo.isTemplate()) {
-                    vmMo.markAsVirtualMachine(hyperHost.getHyperHostOwnerResourcePool(), hyperHost.getMor());
-                }
+                vmMo.markAsVirtualMachine(hyperHost.getHyperHostOwnerResourcePool(), hyperHost.getMor());
                 vmMo.destroy();
             } else {
                 if (s_logger.isInfoEnabled()) {
@@ -7258,8 +6922,14 @@
                                     instanceDisk.setDatastorePath(dsInfo.getNas().getRemotePath());
                                     instanceDisk.setDatastoreType(dsInfo.getNas().getType());
                                 }
+                            } else if (info instanceof VmfsDatastoreInfo) {
+                                VmfsDatastoreInfo dsInfo = (VmfsDatastoreInfo) info;
+                                instanceDisk.setDatastoreName(dsInfo.getVmfs().getName());
+                                instanceDisk.setDatastoreType(dsInfo.getVmfs().getType());
                             } else {
-                                instanceDisk.setDatastoreName(info.getName());
+                                String msg = String.format("Unmanaged instance disk: %s is on unsupported datastore %s", instanceDisk.getDiskId(), info.getClass().getSimpleName());
+                                s_logger.error(msg);
+                                throw new Exception(msg);
                             }
                         }
                         s_logger.info(vmMo.getName() + " " + disk.getDeviceInfo().getLabel() + " " + disk.getDeviceInfo().getSummary() + " " + disk.getDiskObjectId() + " " + disk.getCapacityInKB() + " " + instanceDisk.getController());
@@ -7516,18 +7186,4 @@
 
         return new PrepareUnmanageVMInstanceAnswer(cmd, true, "OK");
     }
-
-    private Answer execute(ValidateVcenterDetailsCommand cmd) {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Executing resource ValidateVcenterDetailsCommand " + _gson.toJson(cmd));
-        }
-        String vCenterServerAddress = cmd.getvCenterServerAddress();
-        VmwareContext context = getServiceContext();
-
-        if (vCenterServerAddress.equals(context.getServerAddress())) {
-            return new Answer(cmd, true, "success");
-        } else {
-            return new Answer(cmd, false, "Provided vCenter server address is invalid");
-        }
-    }
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index 936ca15..b58253d 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -41,7 +41,6 @@
 import com.cloud.hypervisor.vmware.manager.VmwareStorageManagerImpl;
 import com.cloud.hypervisor.vmware.manager.VmwareStorageMount;
 import com.cloud.hypervisor.vmware.mo.ClusterMO;
-import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.cloud.hypervisor.vmware.mo.VmwareHostType;
 import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
@@ -298,7 +297,7 @@
     }
 
     @Override
-    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence, DatastoreMO dsMo) {
+    public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
         assert (cmd.getContextParam("worker") != null);
         assert (workerSequence < 2);
 
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
index 6c66183..9b2acbc 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageLayoutHelper.java
@@ -16,19 +16,13 @@
 // under the License.
 package com.cloud.storage.resource;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
 import org.apache.log4j.Logger;
 
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
 import com.cloud.hypervisor.vmware.mo.DatastoreFile;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
-import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
-
 import com.cloud.utils.Pair;
 
 /**
@@ -36,93 +30,32 @@
  * To provide helper methods to handle storage layout in one place
  *
  */
-public class VmwareStorageLayoutHelper implements Configurable {
+public class VmwareStorageLayoutHelper {
     private static final Logger s_logger = Logger.getLogger(VmwareStorageLayoutHelper.class);
 
-    static final ConfigKey<String> VsphereLinkedCloneExtensions = new ConfigKey<String>("Hidden", String.class,
-            "vsphere.linked.clone.extensions", "delta.vmdk,sesparse.vmdk",
-            "Comma separated list of linked clone disk formats allowed to handle storage in VMware", true);
-
-
     public static String[] getVmdkFilePairDatastorePath(DatastoreMO dsMo, String vmName, String vmdkName, VmwareStorageLayoutType layoutType, boolean linkedVmdk)
         throws Exception {
 
-        int i = 0;
-        String[] vSphereLinkedCloneExtensions = VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*");
-        String[] fileNames;
-        if (linkedVmdk)
-            fileNames = new String[vSphereLinkedCloneExtensions.length + 1];
-        else
-            fileNames = new String[2];
-
+        String[] filePair = new String[2];
         switch (layoutType) {
             case VMWARE:
                 assert (vmName != null && !vmName.isEmpty());
-                fileNames[i] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + ".vmdk");
+                filePair[0] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + ".vmdk");
 
-                if (linkedVmdk) {
-                    for (int j=0 ; j < vSphereLinkedCloneExtensions.length; j++) {
-                        fileNames[++i] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, String.format("%s-%s",vmdkName, vSphereLinkedCloneExtensions[j]));
-                    }
-                }
+                if (linkedVmdk)
+                    filePair[1] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + "-delta.vmdk");
                 else
-                    fileNames[i+1] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + "-flat.vmdk");
-                return fileNames;
+                    filePair[1] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + "-flat.vmdk");
+                return filePair;
 
             case CLOUDSTACK_LEGACY:
-                fileNames[i] = getDatastorePathBaseFolderFromVmdkFileName(dsMo, vmdkName + ".vmdk");
+                filePair[0] = getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkName + ".vmdk");
 
-                if (linkedVmdk) {
-                    for (int j=0 ; j < vSphereLinkedCloneExtensions.length; j++) {
-                        fileNames[++i] = getDatastorePathBaseFolderFromVmdkFileName(dsMo, String.format("%s-%s",vmdkName, vSphereLinkedCloneExtensions[j]));
-                    }
-                } else
-                    fileNames[i+1] = getDatastorePathBaseFolderFromVmdkFileName(dsMo, vmdkName + "-flat.vmdk");
-                return fileNames;
-
-            default:
-                assert (false);
-                break;
-        }
-
-        assert (false);
-        return null;
-    }
-
-    public static String[] getVmdkFilePairManagedDatastorePath(DatastoreMO dsMo, String vmName, String vmdkName, VmwareStorageLayoutType layoutType, boolean linkedVmdk)
-            throws Exception {
-
-        int i = 0;
-        String[] vSphereLinkedCloneExtensions = VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*");
-        String[] fileNames;
-        if (linkedVmdk)
-            fileNames = new String[vSphereLinkedCloneExtensions.length + 1];
-        else
-            fileNames = new String[2];
-
-        switch (layoutType) {
-            case VMWARE:
-                assert (vmName != null && !vmName.isEmpty());
-                fileNames[i] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + ".vmdk");
-
-                if (linkedVmdk) {
-                    for (int j=0 ; j < vSphereLinkedCloneExtensions.length; j++) {
-                        fileNames[++i] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, String.format("%s-%s",vmdkName, vSphereLinkedCloneExtensions[j]));
-                    }
-                } else
-                    fileNames[i+1] = getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, vmdkName + "-flat.vmdk");
-                return fileNames;
-
-            case CLOUDSTACK_LEGACY:
-                fileNames[i] = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, vmdkName + ".vmdk");
-
-                if (linkedVmdk) {
-                    for (int j=0 ; j < vSphereLinkedCloneExtensions.length; j++) {
-                        fileNames[++i] = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, String.format("%s-%s",vmdkName, vSphereLinkedCloneExtensions[j]));
-                    }
-                } else
-                    fileNames[i+1] = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, vmdkName + "-flat.vmdk");
-                return fileNames;
+                if (linkedVmdk)
+                    filePair[1] = getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkName + "-delta.vmdk");
+                else
+                    filePair[1] = getLegacyDatastorePathFromVmdkFileName(dsMo, vmdkName + "-flat.vmdk");
+                return filePair;
 
             default:
                 assert (false);
@@ -188,20 +121,16 @@
             syncVolumeToRootFolder(dcMo, ds, vmdkName, vmName, excludeFolders);
         }
 
-        for (int i=1; i<vmdkFullCloneModeLegacyPair.length; i++) {
-            if (ds.fileExists(vmdkFullCloneModeLegacyPair[i])) {
-                s_logger.info("sync " + vmdkFullCloneModeLegacyPair[i] + "->" + vmdkFullCloneModePair[i]);
+        if (ds.fileExists(vmdkFullCloneModeLegacyPair[1])) {
+            s_logger.info("sync " + vmdkFullCloneModeLegacyPair[1] + "->" + vmdkFullCloneModePair[1]);
 
-                ds.moveDatastoreFile(vmdkFullCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[i], dcMo.getMor(), true);
-            }
+            ds.moveDatastoreFile(vmdkFullCloneModeLegacyPair[1], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[1], dcMo.getMor(), true);
         }
 
-        for (int i=1; i<vmdkLinkedCloneModeLegacyPair.length; i++) {
-            if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[i])) {
-                s_logger.info("sync " + vmdkLinkedCloneModeLegacyPair[i] + "->" + vmdkLinkedCloneModePair[i]);
+        if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[1])) {
+            s_logger.info("sync " + vmdkLinkedCloneModeLegacyPair[1] + "->" + vmdkLinkedCloneModePair[1]);
 
-                ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[i], dcMo.getMor(), true);
-            }
+            ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[1], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[1], dcMo.getMor(), true);
         }
 
         if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[0])) {
@@ -228,22 +157,24 @@
         }
 
         DatastoreFile srcDsFile = new DatastoreFile(fileDsFullPath);
+        String companionFilePath = srcDsFile.getCompanionPath(vmdkName + "-flat.vmdk");
+        if (ds.fileExists(companionFilePath)) {
+            String targetPath = getLegacyDatastorePathFromVmdkFileName(ds, vmdkName + "-flat.vmdk");
 
-        List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
-        // add flat file format to the above list
-        vSphereFileExtensions.add("flat.vmdk");
-        for (String linkedCloneExtension :  vSphereFileExtensions) {
-            String companionFilePath = srcDsFile.getCompanionPath(String.format("%s-%s",vmdkName, linkedCloneExtension));
-            if (ds.fileExists(companionFilePath)) {
-                String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, String.format("%s-%s",vmdkName, linkedCloneExtension));
+            s_logger.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
+            ds.moveDatastoreFile(companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
+        }
 
-                s_logger.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
-                ds.moveDatastoreFile(companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
-            }
+        companionFilePath = srcDsFile.getCompanionPath(vmdkName + "-delta.vmdk");
+        if (ds.fileExists(companionFilePath)) {
+            String targetPath = getLegacyDatastorePathFromVmdkFileName(ds, vmdkName + "-delta.vmdk");
+
+            s_logger.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
+            ds.moveDatastoreFile(companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
         }
 
         // move the identity VMDK file the last
-        String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, vmdkName + ".vmdk");
+        String targetPath = getLegacyDatastorePathFromVmdkFileName(ds, vmdkName + ".vmdk");
         s_logger.info("Fixup folder-synchronization. move " + fileDsFullPath + " -> " + targetPath);
         ds.moveDatastoreFile(fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
 
@@ -262,22 +193,24 @@
 
                 s_logger.info("Check if we need to move " + fileFullDsPath + " to its root location");
                 DatastoreMO dsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(file.getDatastoreName()));
-                if (dsMo.getMor() != null && !dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                    DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, file.getFileName());
+                if (dsMo.getMor() != null) {
+                    DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), file.getFileName());
                     if (!targetFile.getPath().equalsIgnoreCase(file.getPath())) {
                         s_logger.info("Move " + file.getPath() + " -> " + targetFile.getPath());
                         dsMo.moveDatastoreFile(file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
 
-                        List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
-                        // add flat file format to the above list
-                        vSphereFileExtensions.add("flat.vmdk");
-                        for (String linkedCloneExtension :  vSphereFileExtensions) {
-                            String pairSrcFilePath = file.getCompanionPath(String.format("%s-%s", file.getFileBaseName(), linkedCloneExtension));
-                            String pairTargetFilePath = targetFile.getCompanionPath(String.format("%s-%s", file.getFileBaseName(), linkedCloneExtension));
-                            if (dsMo.fileExists(pairSrcFilePath)) {
-                                s_logger.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
-                                dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
-                            }
+                        String pairSrcFilePath = file.getCompanionPath(file.getFileBaseName() + "-flat.vmdk");
+                        String pairTargetFilePath = targetFile.getCompanionPath(file.getFileBaseName() + "-flat.vmdk");
+                        if (dsMo.fileExists(pairSrcFilePath)) {
+                            s_logger.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
+                            dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
+                        }
+
+                        pairSrcFilePath = file.getCompanionPath(file.getFileBaseName() + "-delta.vmdk");
+                        pairTargetFilePath = targetFile.getCompanionPath(file.getFileBaseName() + "-delta.vmdk");
+                        if (dsMo.fileExists(pairSrcFilePath)) {
+                            s_logger.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
+                            dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
                         }
                     }
                 } else {
@@ -354,49 +287,32 @@
             s_logger.warn("Unable to locate VMDK file: " + fileName);
         }
 
-        List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
-        vSphereFileExtensions.add("flat.vmdk");
-        for (String linkedCloneExtension :  vSphereFileExtensions) {
-            fileFullPath = getLegacyDatastorePathFromVmdkFileName(dsMo, String.format("%s-%s", volumeName, linkedCloneExtension));
-            if (!dsMo.fileExists(fileFullPath))
-                fileFullPath = dsMo.searchFileInSubFolders(String.format("%s-%s", volumeName, linkedCloneExtension), false, excludeFolders);
-            if (fileFullPath != null) {
-                dsMo.deleteFile(fileFullPath, dcMo.getMor(), true, excludeFolders);
-            } else {
-                s_logger.warn("Unable to locate VMDK file: " + String.format("%s-%s", volumeName, linkedCloneExtension));
-            }
+        fileName = volumeName + "-flat.vmdk";
+        fileFullPath = getLegacyDatastorePathFromVmdkFileName(dsMo, fileName);
+        if (!dsMo.fileExists(fileFullPath))
+            fileFullPath = dsMo.searchFileInSubFolders(fileName, false, excludeFolders);
+        if (fileFullPath != null) {
+            dsMo.deleteFile(fileFullPath, dcMo.getMor(), true, excludeFolders);
+        } else {
+            s_logger.warn("Unable to locate VMDK file: " + fileName);
+        }
+
+        fileName = volumeName + "-delta.vmdk";
+        fileFullPath = getLegacyDatastorePathFromVmdkFileName(dsMo, fileName);
+        if (!dsMo.fileExists(fileFullPath))
+            fileFullPath = dsMo.searchFileInSubFolders(fileName, false, excludeFolders);
+        if (fileFullPath != null) {
+            dsMo.deleteFile(fileFullPath, dcMo.getMor(), true, excludeFolders);
+        } else {
+            s_logger.warn("Unable to locate VMDK file: " + fileName);
         }
     }
 
-    //This method call is for the volumes which actually exists
     public static String getLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception {
-        String vmdkDatastorePath = String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName);
-        if (!dsMo.fileExists(vmdkDatastorePath)) {
-            vmdkDatastorePath = getDeprecatedLegacyDatastorePathFromVmdkFileName(dsMo, vmdkFileName);
-        }
-        return vmdkDatastorePath;
-    }
-
-    //This method call is for the volumes to be created or can also be for volumes already exists
-    public static String getDatastorePathBaseFolderFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception {
-        return String.format("[%s] %s/%s", dsMo.getName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, vmdkFileName);
-    }
-
-    public static String getDeprecatedLegacyDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmdkFileName) throws Exception {
         return String.format("[%s] %s", dsMo.getName(), vmdkFileName);
     }
 
     public static String getVmwareDatastorePathFromVmdkFileName(DatastoreMO dsMo, String vmName, String vmdkFileName) throws Exception {
         return String.format("[%s] %s/%s", dsMo.getName(), vmName, vmdkFileName);
     }
-
-    @Override
-    public String getConfigComponentName() {
-        return VmwareStorageLayoutHelper.class.getSimpleName();
-    }
-
-    @Override
-    public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {VsphereLinkedCloneExtensions};
-    }
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
index 85aacd3..5c9c917 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -34,15 +34,9 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
-import com.cloud.hypervisor.vmware.mo.VirtualStorageObjectManagerMO;
-import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
-import com.vmware.vim25.BaseConfigInfoDiskFileBackingInfo;
-import com.vmware.vim25.VStorageObject;
-import com.vmware.vim25.VirtualDiskType;
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
@@ -400,7 +394,7 @@
 
         // If vmName is not null, then move all VMDK files out of this folder to the root folder and then delete the folder named vmName.
         if (vmName != null) {
-            String workerVmName = hostService.getWorkerName(context, cmd, 0, dsMo);
+            String workerVmName = hostService.getWorkerName(context, cmd, 0);
 
             VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVmName, null);
 
@@ -485,9 +479,9 @@
 
     private Pair<VirtualMachineMO, Long> copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
                                                                             String templatePathAtSecondaryStorage, String templateName, String templateUuid,
-                                                                            boolean createSnapshot, String nfsVersion, String configuration) throws Exception {
+                                                                            boolean createSnapshot, String nfsVersion) throws Exception {
         s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " +
-                templatePathAtSecondaryStorage + ", templateName: " + templateName + ", configuration: " + configuration);
+                templatePathAtSecondaryStorage + ", templateName: " + templateName);
 
         String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion);
         s_logger.info("Secondary storage mount point: " + secondaryMountPoint);
@@ -518,16 +512,11 @@
             throw new Exception(msg);
         }
 
-        if (datastoreMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-            templateUuid = CustomFieldConstants.CLOUD_UUID + "-" + templateUuid;
-        }
+        String vmName = templateUuid;
+        hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin");
 
+        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
         VmConfigInfo vAppConfig;
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug(String.format("Deploying OVF template %s with configuration %s", templateName, configuration));
-        }
-        hyperHost.importVmFromOVF(srcFileName, templateUuid, datastoreMo, "thin", configuration);
-        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(templateUuid);
         if (vmMo == null) {
             String msg =
                     "Failed to import OVA template. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage +
@@ -583,7 +572,6 @@
         DataTO destData = cmd.getDestTO();
         DataStoreTO destStore = destData.getDataStore();
         DataStoreTO primaryStore = destStore;
-        String configurationId = ((TemplateObjectTO) destData).getDeployAsIsConfiguration();
 
         String secondaryStorageUrl = nfsImageStore.getUrl();
 
@@ -641,56 +629,51 @@
 
         try {
             String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
-
-            // Generate a new template uuid if the template is marked as deploy-as-is,
-            // as it supports multiple configurations
-            String templateUuidName = template.isDeployAsIs() ?
-                    UUID.randomUUID().toString() :
-                    deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
-
+            String templateUuidName = deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
             DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
             VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
             Pair<VirtualMachineMO, Long> vmInfo = null;
 
-            final ManagedObjectReference morDs;
-            if (managed) {
-                morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort,
-                        chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
-            }
-            else {
-                morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
-            }
-            assert (morDs != null);
-            dsMo = new DatastoreMO(context, morDs);
-
             if (templateMo == null) {
                 if (s_logger.isInfoEnabled()) {
                     s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
                 }
 
+                final ManagedObjectReference morDs;
+
+                if (managed) {
+                    morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort,
+                                chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
+                }
+                else {
+                    morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
+                }
+
+                assert (morDs != null);
+
+                dsMo = new DatastoreMO(context, morDs);
+
                 if (managed) {
                     vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
-                            managedStoragePoolRootVolumeName, false, _nfsVersion, configurationId);
+                            managedStoragePoolRootVolumeName, false, _nfsVersion);
 
                     VirtualMachineMO vmMo = vmInfo.first();
                     vmMo.unregisterVm();
 
-                    String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, managedStoragePoolRootVolumeName,
+                    String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName,
                             managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false);
-                    String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, null,
+                    String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null,
                             managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
 
                     dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
-                    for (int i=1; i<vmwareLayoutFilePair.length; i++) {
-                        dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
-                    }
+                    dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
 
                     String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
                     dsMo.deleteFolder(folderToDelete, dcMo.getMor());
                 }
                 else {
                     vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
-                            templateUuidName, true, _nfsVersion, configurationId);
+                            templateUuidName, true, _nfsVersion);
                 }
             } else {
                 s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
@@ -706,14 +689,9 @@
                 }
             }
             else {
-                if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                    newTemplate.setPath(CustomFieldConstants.CLOUD_UUID + "-" + templateUuidName);
-                } else {
-                    newTemplate.setPath(templateUuidName);
-                }
+                newTemplate.setPath(templateUuidName);
             }
 
-            newTemplate.setDeployAsIsConfiguration(configurationId);
             newTemplate.setSize((vmInfo != null)? vmInfo.second() : new Long(0));
 
             return new CopyCmdAnswer(newTemplate);
@@ -810,82 +788,94 @@
             DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
 
             String vmdkName = volume.getName();
-            String vmName = volume.getVmName();
-            String vmdkFileBaseName = null;
-            if (template.isDeployAsIs() && volume.getVolumeType() == Volume.Type.ROOT) {
-                VirtualMachineMO existingVm = dcMo.findVm(vmName);
-                if (volume.getDeviceId().equals(0L)) {
-                    if (existingVm != null) {
-                        s_logger.info("Found existing VM " + vmName + " before cloning from template, destroying it");
-                        existingVm.detachAllDisks();
-                        existingVm.destroy();
+            String vmdkFileBaseName;
+            if (srcStore == null) {
+                // create a root volume for blank VM (created from ISO)
+                String dummyVmName = hostService.getWorkerName(context, cmd, 0);
+
+                try {
+                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
+                    if (vmMo == null) {
+                        throw new Exception("Unable to create a dummy VM for volume creation");
                     }
-                    s_logger.info("ROOT Volume from deploy-as-is template, cloning template");
-                    cloneVMFromTemplate(hyperHost, template.getPath(), vmName, primaryStore.getUuid());
-                } else {
-                    s_logger.info("ROOT Volume from deploy-as-is template, volume already created at this point");
+
+                    vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
+                    // we only use the first file in the pair, linked or not will not matter
+                    String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
+                    String volumeDatastorePath = vmdkFilePair[0];
+                    synchronized (this) {
+                        s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
+                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo, searchExcludedFolders);
+                        vmMo.createDisk(volumeDatastorePath, (long)(volume.getSize() / (1024L * 1024L)), morDatastore, -1);
+                        vmMo.detachDisk(volumeDatastorePath, false);
+                    }
+                } finally {
+                    s_logger.info("Destroy dummy VM after volume creation");
+                    if (vmMo != null) {
+                        s_logger.warn("Unable to destroy a null VM ManagedObjectReference");
+                        vmMo.detachAllDisks();
+                        vmMo.destroy();
+                    }
                 }
             } else {
-                if (srcStore == null) {
-                    // create a root volume for blank VM (created from ISO)
-                    String dummyVmName = hostService.getWorkerName(context, cmd, 0, dsMo);
-
-                    try {
-                        vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
-                        if (vmMo == null) {
-                            throw new Exception("Unable to create a dummy VM for volume creation");
-                        }
-
-                        vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
-                        // we only use the first file in the pair, linked or not will not matter
-                        String vmdkFilePair[] = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
-                        String volumeDatastorePath = vmdkFilePair[0];
-                        synchronized (this) {
-                            s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
-                            VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo, searchExcludedFolders);
-                            vmMo.createDisk(volumeDatastorePath, (long)(volume.getSize() / (1024L * 1024L)), morDatastore, -1, null);
-                            vmMo.detachDisk(volumeDatastorePath, false);
-                        }
-                    } finally {
-                        s_logger.info("Destroy dummy VM after volume creation");
-                        if (vmMo != null) {
-                            s_logger.warn("Unable to destroy a null VM ManagedObjectReference");
-                            vmMo.detachAllDisks();
-                            vmMo.destroy();
-                        }
-                    }
-                } else {
-                    String templatePath = template.getPath();
-                    VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true);
-                    if (vmTemplate == null) {
-                        s_logger.warn("Template host in vSphere is not in connected state, request template reload");
-                        return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload");
-                    }
-                    if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                        vmdkFileBaseName = cloneVMforVvols(context, hyperHost, template, vmTemplate, volume, dcMo, dsMo);
-                    } else {
-                        vmdkFileBaseName = createVMFolderWithVMName(context, hyperHost, template, vmTemplate, volume, dcMo, dsMo, searchExcludedFolders);
-                    }
+                String templatePath = template.getPath();
+                VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true);
+                if (vmTemplate == null) {
+                    s_logger.warn("Template host in vSphere is not in connected state, request template reload");
+                    return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload");
                 }
-                // restoreVM - move the new ROOT disk into corresponding VM folder
-                VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
-                if (restoreVmMo != null) {
-                    if (!dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                        String vmNameInVcenter = restoreVmMo.getName(); // VM folder name in datastore will be VM's name in vCenter.
-                        if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
-                            VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName, searchExcludedFolders);
-                        }
-                    }
+
+                ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
+                ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
+                if (template.getSize() != null){
+                    _fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
+                }
+                if (!_fullCloneFlag) {
+                    createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool);
+                } else {
+                    createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
+                }
+
+                vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName);
+                assert (vmMo != null);
+
+                vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
+                s_logger.info("Move volume out of volume-wrapper VM " + vmdkFileBaseName);
+                String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag);
+                String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
+
+                dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
+                dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
+
+                s_logger.info("detach disks from volume-wrapper VM " + vmdkName);
+                vmMo.detachAllDisks();
+
+                s_logger.info("destroy volume-wrapper VM " + vmdkName);
+                vmMo.destroy();
+
+                String srcFile = dsMo.getDatastorePath(vmdkName, true);
+
+                dsMo.deleteFile(srcFile, dcMo.getMor(), true, searchExcludedFolders);
+
+                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) {
+                    dsMo.deleteFolder(srcFile, dcMo.getMor());
+                }
+            }
+            // restoreVM - move the new ROOT disk into corresponding VM folder
+            VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
+            if (restoreVmMo != null) {
+                String vmNameInVcenter = restoreVmMo.getName(); // VM folder name in datastore will be VM's name in vCenter.
+                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
+                    VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName, searchExcludedFolders);
                 }
             }
 
             VolumeObjectTO newVol = new VolumeObjectTO();
             newVol.setPath(vmdkFileBaseName);
-            if (template.isDeployAsIs()) {
-                newVol.setSize(volume.getSize());
-            } else if (template.getSize() != null) {
+            if (template.getSize() != null){
                 newVol.setSize(template.getSize());
-            } else {
+            }
+            else {
                 newVol.setSize(volume.getSize());
             }
             return new CopyCmdAnswer(newVol);
@@ -901,108 +891,6 @@
         }
     }
 
-    private String cloneVMforVvols(VmwareContext context, VmwareHypervisorHost hyperHost, TemplateObjectTO template,
-                                   VirtualMachineMO vmTemplate, VolumeObjectTO volume, DatacenterMO dcMo, DatastoreMO dsMo) throws Exception {
-        ManagedObjectReference morDatastore = dsMo.getMor();
-        ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-        ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-        if (template.getSize() != null) {
-            _fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
-        }
-        String vmName = volume.getVmName();
-        if (volume.getVolumeType() == Volume.Type.DATADISK)
-            vmName = volume.getName();
-        if (!_fullCloneFlag) {
-            createVMLinkedClone(vmTemplate, dcMo, vmName, morDatastore, morPool);
-        } else {
-            createVMFullClone(vmTemplate, dcMo, dsMo, vmName, morDatastore, morPool);
-        }
-
-        VirtualMachineMO vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmName);
-        assert (vmMo != null);
-        String vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
-        if (volume.getVolumeType() == Volume.Type.DATADISK) {
-            s_logger.info("detach disks from volume-wrapper VM " + vmName);
-            vmMo.detachAllDisks();
-            vmMo.destroy();
-        }
-        return vmdkFileBaseName;
-    }
-
-    private String createVMFolderWithVMName(VmwareContext context, VmwareHypervisorHost hyperHost, TemplateObjectTO template,
-                                            VirtualMachineMO vmTemplate, VolumeObjectTO volume, DatacenterMO dcMo, DatastoreMO dsMo,
-                                            String searchExcludedFolders) throws Exception {
-        String vmdkName = volume.getName();
-        try {
-            ManagedObjectReference morDatastore = dsMo.getMor();
-            ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
-            if (template.getSize() != null){
-                _fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
-            }
-            if (!_fullCloneFlag) {
-                createVMLinkedClone(vmTemplate, dcMo, vmdkName, morDatastore, morPool);
-            } else {
-                createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
-            }
-
-            VirtualMachineMO vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName);
-            assert (vmMo != null);
-
-            String vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
-            s_logger.info("Move volume out of volume-wrapper VM " + vmdkFileBaseName);
-            String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag);
-            String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
-
-            for (int i=0; i<vmwareLayoutFilePair.length; i++) {
-                dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
-            }
-
-            s_logger.info("detach disks from volume-wrapper VM " + vmdkName);
-            vmMo.detachAllDisks();
-
-            s_logger.info("destroy volume-wrapper VM " + vmdkName);
-            vmMo.destroy();
-
-            String srcFile = dsMo.getDatastorePath(vmdkName, true);
-
-            dsMo.deleteFile(srcFile, dcMo.getMor(), true, searchExcludedFolders);
-
-            if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) {
-                dsMo.deleteFolder(srcFile, dcMo.getMor());
-            }
-
-            // restoreVM - move the new ROOT disk into corresponding VM folder
-            VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
-            if (restoreVmMo != null) {
-                String vmNameInVcenter = restoreVmMo.getName(); // VM folder name in datastore will be VM's name in vCenter.
-                if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
-                    VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName, searchExcludedFolders);
-                }
-            }
-
-            return vmdkFileBaseName;
-        } finally {
-            // check if volume wrapper VM is cleaned, if not cleanup
-            VirtualMachineMO vmdknamedVM = dcMo.findVm(vmdkName);
-            if (vmdknamedVM != null) {
-                vmdknamedVM.destroy();
-            }
-        }
-    }
-
-    private void createLinkedOrFullClone(TemplateObjectTO template, VolumeObjectTO volume, DatacenterMO dcMo, VirtualMachineMO vmMo, ManagedObjectReference morDatastore,
-                                         DatastoreMO dsMo, String cloneName, ManagedObjectReference morPool) throws Exception {
-        if (template.getSize() != null) {
-            _fullCloneFlag = volume.getSize() > template.getSize() || _fullCloneFlag;
-        }
-        if (!_fullCloneFlag) {
-            createVMLinkedClone(vmMo, dcMo, cloneName, morDatastore, morPool);
-        } else {
-            createVMFullClone(vmMo, dcMo, dsMo, cloneName, morDatastore, morPool);
-        }
-    }
-
     private Pair<String, String> copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl,
                                                           long wait, String nfsVersion) throws Exception {
         String volumeFolder;
@@ -1017,7 +905,7 @@
             volumeName = srcVolumePath.substring(index + 1);
         }
 
-        String newVolume = VmwareHelper.getVCenterSafeUuid(dsMo);
+        String newVolume = VmwareHelper.getVCenterSafeUuid();
         restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion);
 
         return new Pair<>(volumeFolder, newVolume);
@@ -1056,7 +944,7 @@
             if (morDatastore == null) {
                 URI uri = new URI(destStore.getUrl());
 
-                morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), destStore.getUuid().replace("-", ""), true);
+                morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), destStore.getUuid().replace("-", ""));
 
                 if (morDatastore == null) {
                     throw new Exception("Unable to mount storage pool on host. storeUrl: " + uri.getHost() + ":/" + uri.getPath());
@@ -1120,9 +1008,11 @@
                 workerVm.attachDisk(new String[] {datastoreVolumePath}, morDs);
                 vmMo = workerVm;
                 clonedWorkerVMNeeded = false;
+            } else {
+                vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
             }
 
-            exportVolumeToSecondaryStorage(hyperHost.getContext(), vmMo, hyperHost, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1, null), _nfsVersion, clonedWorkerVMNeeded);
+            exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion, clonedWorkerVMNeeded);
             return new Pair<>(destVolumePath, exportName);
 
         } finally {
@@ -1153,7 +1043,7 @@
 
             result =
                     copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, primaryStorage.getUuid(), srcVolume.getPath(), destVolume.getPath(), destStore.getUrl(),
-                            hostService.getWorkerName(context, cmd, 0, null));
+                            hostService.getWorkerName(context, cmd, 0));
             VolumeObjectTO newVolume = new VolumeObjectTO();
             newVolume.setPath(result.first() + File.separator + result.second());
             return new CopyCmdAnswer(newVolume);
@@ -1207,7 +1097,7 @@
         }
     }
 
-    private Ternary<String, Long, Long> createTemplateFromVolume(VmwareContext context, VirtualMachineMO vmMo, VmwareHypervisorHost hyperHost, String installPath, long templateId, String templateUniqueName,
+    private Ternary<String, Long, Long> createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName,
                                                                  String secStorageUrl, String volumePath, String workerVmName, String nfsVersion) throws Exception {
 
         String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
@@ -1234,12 +1124,6 @@
                 throw new Exception(msg);
             }
 
-            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-            ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-            vmMo.createFullCloneWithSpecificDisk(templateUniqueName, dcMo.getVmFolder(), morPool, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), volumeDeviceInfo);
-            clonedVm = dcMo.findVm(templateUniqueName);
-
-            /* FR41 THIS IS OLD way of creating template using snapshot
             if (!vmMo.createSnapshot(templateUniqueName, "Temporary snapshot for template creation", false, false)) {
                 String msg = "Unable to take snapshot for creating template from volume. volume path: " + volumePath;
                 s_logger.error(msg);
@@ -1252,7 +1136,7 @@
             Pair<VirtualMachineMO, String[]> cloneResult =
                     vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), hardwareVersion);
             clonedVm = cloneResult.first();
-            * */
+
             clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, false, false);
 
             // Get VMDK filename
@@ -1285,6 +1169,8 @@
                 clonedVm.detachAllDisks();
                 clonedVm.destroy();
             }
+
+            vmMo.removeSnapshot(templateUniqueName, false);
         }
     }
 
@@ -1343,8 +1229,9 @@
             }
 
             Ternary<String, Long, Long> result =
-                    createTemplateFromVolume(context, vmMo, hyperHost, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
-                            hostService.getWorkerName(context, cmd, 0, null), _nfsVersion);
+                    createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath,
+                            hostService.getWorkerName(context, cmd, 0), _nfsVersion);
+
             TemplateObjectTO newTemplate = new TemplateObjectTO();
             newTemplate.setPath(result.first());
             newTemplate.setFormat(ImageFormat.OVA);
@@ -1661,9 +1548,10 @@
         VmwareContext context = hostService.getServiceContext(cmd);
         VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
 
+        String workerVMName = hostService.getWorkerName(context, cmd, 0);
+
         ManagedObjectReference dsMor = hyperHost.findDatastoreByName(dsFile.getDatastoreName());
         DatastoreMO dsMo = new DatastoreMO(context, dsMor);
-        String workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
 
         VirtualMachineMO workerVM = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
 
@@ -1803,7 +1691,7 @@
     }
 
     // return Pair<String(divice bus name), String[](disk chain)>
-    private Pair<String, String[]> exportVolumeToSecondaryStorage(VmwareContext context, VirtualMachineMO vmMo, VmwareHypervisorHost hyperHost, String volumePath, String secStorageUrl, String secStorageDir,
+    private Pair<String, String[]> exportVolumeToSecondaryStorage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
                                                                   String exportName, String workerVmName, String nfsVersion, boolean clonedWorkerVMNeeded) throws Exception {
 
         String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
@@ -1836,19 +1724,13 @@
             String disks[] = vmMo.getCurrentSnapshotDiskChainDatastorePaths(diskDevice);
             if (clonedWorkerVMNeeded) {
                 // 4 MB is the minimum requirement for VM memory in VMware
-                DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-                ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-                vmMo.createFullCloneWithSpecificDisk(exportName, dcMo.getVmFolder(), morPool, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), volumeDeviceInfo);
-                clonedVm = dcMo.findVm(exportName);
-                if (clonedVm == null) {
-                    String msg = "Failed to clone VM. volume path: " + volumePath;
-                    s_logger.error(msg);
-                    throw new Exception(msg);
-                }
-                vmMo = clonedVm;
+                Pair<VirtualMachineMO, String[]> cloneResult =
+                        vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, diskDevice, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()), virtualHardwareVersion);
+                clonedVm = cloneResult.first();
+                clonedVm.exportVm(exportPath, exportName, false, false);
+            } else {
+                vmMo.exportVm(exportPath, exportName, false, false);
             }
-            vmMo.exportVm(exportPath, exportName, false, false);
-
             return new Pair<>(diskDevice, disks);
         } finally {
             if (clonedVm != null) {
@@ -1859,12 +1741,12 @@
     }
 
     // Ternary<String(backup uuid in secondary storage), String(device bus name), String[](original disk chain in the snapshot)>
-    private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VmwareContext context, VirtualMachineMO vmMo, VmwareHypervisorHost hypervisorHost, String installPath, String volumePath, String snapshotUuid,
+    private Ternary<String, String, String[]> backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid,
                                                                                String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName,
                                                                                String nfsVersion) throws Exception {
 
         String backupUuid = UUID.randomUUID().toString();
-        Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStorage(context, vmMo, hypervisorHost, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion, true);
+        Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion, true);
         return new Ternary<>(backupUuid, snapshotInfo.first(), snapshotInfo.second());
     }
 
@@ -1919,23 +1801,27 @@
                 }
                 if(vmMo == null) {
                     dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
-                    workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
+                    workerVMName = hostService.getWorkerName(context, cmd, 0);
                     vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
                     if (vmMo == null) {
                         throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
                     }
                     workerVm = vmMo;
                     // attach volume to worker VM
-                    String datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumePath + ".vmdk");
+                    String datastoreVolumePath = dsMo.getDatastorePath(volumePath + ".vmdk");
                     vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
                 } else {
                     s_logger.info("Using owner VM " + vmName + " for snapshot operation");
                     hasOwnerVm = true;
                 }
 
+                if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) {
+                    throw new Exception("Failed to take snapshot " + srcSnapshot.getName() + " on vm: " + vmName);
+                }
+
                 backupResult =
-                        backupSnapshotToSecondaryStorage(context, vmMo, hyperHost, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
-                                prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1, null), _nfsVersion);
+                        backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl,
+                                prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
                 snapshotBackupUuid = backupResult.first();
 
                 success = (snapshotBackupUuid != null);
@@ -2015,7 +1901,7 @@
                             }
                         }
                     } else {
-                        s_logger.info("No snapshots created to be deleted!");
+                        s_logger.error("Can not find the snapshot we just used ?!");
                     }
                 }
 
@@ -2063,10 +1949,8 @@
                                 String storageHost, int storagePort, Map<String, String> controllerInfo) {
         VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData();
         DataStoreTO primaryStore = volumeTO.getDataStore();
-        String volumePath = volumeTO.getPath();
-        String storagePolicyId = volumeTO.getvSphereStoragePolicyId();
 
-        String vmdkPath = isManaged ? resource.getVmdkPath(volumePath) : null;
+        String vmdkPath = isManaged ? resource.getVmdkPath(volumeTO.getPath()) : null;
 
         try {
             VmwareContext context = hostService.getServiceContext(null);
@@ -2114,79 +1998,21 @@
 
             DatastoreMO dsMo = new DatastoreMO(context, morDs);
             String datastoreVolumePath;
-            boolean datastoreChangeObserved = false;
-            boolean volumePathChangeObserved = false;
-            String chainInfo = null;
 
             if (isAttach) {
                 if (isManaged) {
                     datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
                 } else {
-                    if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                        datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumePath + ".vmdk");
-                        if (!dsMo.fileExists(datastoreVolumePath)) {
-                            datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumePath + ".vmdk");
-                        }
-                        if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmName) || !dsMo.fileExists(datastoreVolumePath)) {
-                            datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, volumePath, volumePath + ".vmdk");
-                        }
-                        if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), volumePath) || !dsMo.fileExists(datastoreVolumePath)) {
-                            datastoreVolumePath = dsMo.searchFileInSubFolders(volumePath + ".vmdk", true, null);
-                        }
-
-                    } else {
-                        datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName, dsMo, volumePath, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                    }
+                    datastoreVolumePath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dsMo.getOwnerDatacenter().first(), vmName, dsMo, volumeTO.getPath(), VmwareManager.s_vmwareSearchExcludeFolder.value());
                 }
             } else {
                 if (isManaged) {
                     datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
                 } else {
-                    String datastoreUUID = primaryStore.getUuid();
-                    if (disk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && disk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
-                        VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(hyperHost, context, vmMo, disk);
-                        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                        if (diskInfoBuilder != null && matchingExistingDisk != null) {
-                            String[] diskChain = matchingExistingDisk.getDiskChain();
-                            assert (diskChain.length > 0);
-                            DatastoreFile file = new DatastoreFile(diskChain[0]);
-                            if (!file.getFileBaseName().equalsIgnoreCase(volumePath)) {
-                                if (s_logger.isInfoEnabled())
-                                    s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumePath + " -> " + file.getFileBaseName());
-                                volumePathChangeObserved = true;
-                                volumePath = file.getFileBaseName();
-                                volumeTO.setPath(volumePath);
-                                chainInfo = _gson.toJson(matchingExistingDisk);
-                            }
+                    datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
 
-                            DatastoreMO diskDatastoreMofromVM = getDiskDatastoreMofromVM(hyperHost, context, vmMo, disk, diskInfoBuilder);
-                            if (diskDatastoreMofromVM != null) {
-                                String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
-                                if (!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
-                                    s_logger.warn(String.format("Volume %s found to be in a different storage pool %s", volumePath, actualPoolUuid));
-                                    datastoreChangeObserved = true;
-                                    datastoreUUID = actualPoolUuid;
-                                    chainInfo = _gson.toJson(matchingExistingDisk);
-                                }
-                            }
-                        }
-                    }
-                    if (storagePort == DEFAULT_NFS_PORT) {
-                        morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(diskUuid) : datastoreUUID);
-                    } else {
-                        morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : datastoreUUID);
-                    }
-                    dsMo = new DatastoreMO(context, morDs);
-
-                    datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumePath + ".vmdk");
                     if (!dsMo.fileExists(datastoreVolumePath)) {
-                        datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumePath + ".vmdk");
-                    }
-                    if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmName) || !dsMo.fileExists(datastoreVolumePath)) {
-                        datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, volumePath, volumePath + ".vmdk");
-                    }
-                    if (!dsMo.folderExists(String.format("[%s]", dsMo.getName()), volumePath) || !dsMo.fileExists(datastoreVolumePath)) {
-                        datastoreVolumePath = dsMo.searchFileInSubFolders(volumePath + ".vmdk", true, null);
+                        datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
                     }
                 }
             }
@@ -2206,10 +2032,7 @@
                     diskController = vmMo.getRecommendedDiskController(null);
                 }
 
-                vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController, storagePolicyId);
-                VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-                VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volumePath, dsMo.getName());
-                chainInfo = _gson.toJson(diskInfo);
+                vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs, diskController);
 
                 if (isManaged) {
                     expandVirtualDisk(vmMo, datastoreVolumePath, volumeTO.getSize());
@@ -2221,22 +2044,10 @@
                 if (isManaged) {
                     handleDatastoreAndVmdkDetachManaged(cmd, diskUuid, iScsiName, storageHost, storagePort);
                 } else {
-                    if (!dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                        VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumePath, vmName, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                    }
-                }
-                if (datastoreChangeObserved) {
-                    answer.setContextParam("datastoreName", dsMo.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID));
-                }
-
-                if (volumePathChangeObserved) {
-                    answer.setContextParam("volumePath", volumePath);
+                    VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath(), vmName, VmwareManager.s_vmwareSearchExcludeFolder.value());
                 }
             }
 
-            if (chainInfo != null && !chainInfo.isEmpty())
-                answer.setContextParam("chainInfo", chainInfo);
-
             return answer;
         } catch (Throwable e) {
             if (e instanceof RemoteException) {
@@ -2260,91 +2071,6 @@
         }
     }
 
-    private VirtualMachineDiskInfo getMatchingExistingDisk(VmwareHypervisorHost hyperHost, VmwareContext context, VirtualMachineMO vmMo, DiskTO vol)
-            throws Exception {
-        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
-        if (diskInfoBuilder != null) {
-            VolumeObjectTO volume = (VolumeObjectTO) vol.getData();
-
-            ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid());
-            DatastoreMO dsMo = new DatastoreMO(context, morDs);
-
-            String dsName = dsMo.getName();
-
-            String diskBackingFileBaseName = volume.getPath();
-
-            VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
-            if (diskInfo != null) {
-                s_logger.info("Found existing disk info from volume path: " + volume.getPath());
-                return diskInfo;
-            } else {
-                String chainInfo = volume.getChainInfo();
-                if (chainInfo != null) {
-                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
-                    if (infoInChain != null) {
-                        String[] disks = infoInChain.getDiskChain();
-                        if (disks.length > 0) {
-                            for (String diskPath : disks) {
-                                DatastoreFile file = new DatastoreFile(diskPath);
-                                diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
-                                if (diskInfo != null) {
-                                    s_logger.info("Found existing disk from chain info: " + diskPath);
-                                    return diskInfo;
-                                }
-                            }
-                        }
-
-                        if (diskInfo == null) {
-                            diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(infoInChain.getDiskDeviceBusName());
-                            if (diskInfo != null) {
-                                s_logger.info("Found existing disk from from chain device bus information: " + infoInChain.getDiskDeviceBusName());
-                                return diskInfo;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    private DatastoreMO getDiskDatastoreMofromVM(VmwareHypervisorHost hyperHost, VmwareContext context,
-                                                 VirtualMachineMO vmMo, DiskTO disk, VirtualMachineDiskInfoBuilder diskInfoBuilder) throws Exception {
-        assert (hyperHost != null) && (context != null);
-        List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
-        VolumeObjectTO volume = (VolumeObjectTO) disk.getData();
-        String diskBackingFileBaseName = volume.getPath();
-        for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
-            DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), diskDatastore.second());
-            String dsName = dsMo.getName();
-
-            VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
-            if (diskInfo != null) {
-                s_logger.info("Found existing disk info from volume path: " + volume.getPath());
-                return dsMo;
-            } else {
-                String chainInfo = volume.getChainInfo();
-                if (chainInfo != null) {
-                    VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
-                    if (infoInChain != null) {
-                        String[] disks = infoInChain.getDiskChain();
-                        if (disks.length > 0) {
-                            for (String diskPath : disks) {
-                                DatastoreFile file = new DatastoreFile(diskPath);
-                                diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
-                                if (diskInfo != null) {
-                                    s_logger.info("Found existing disk from chain info: " + diskPath);
-                                    return dsMo;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
     private boolean expandVirtualDisk(VirtualMachineMO vmMo, String datastoreVolumePath, long currentSizeInBytes) throws Exception {
         long currentSizeInKB = currentSizeInBytes / 1024;
 
@@ -2401,7 +2127,7 @@
         URI uri = new URI(storeUrl);
 
         VmwareHypervisorHost hyperHost = hostService.getHyperHost(hostService.getServiceContext(null), null);
-        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""), false);
+        ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", ""));
 
         if (morDatastore == null) {
             throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl);
@@ -2509,7 +2235,6 @@
 
         VolumeObjectTO volume = (VolumeObjectTO)cmd.getData();
         DataStoreTO primaryStore = volume.getDataStore();
-        String vSphereStoragePolicyId = volume.getvSphereStoragePolicyId();
 
         try {
             VmwareContext context = hostService.getServiceContext(null);
@@ -2526,50 +2251,38 @@
             VirtualMachineMO vmMo = null;
             String volumeUuid = UUID.randomUUID().toString().replace("-", "");
 
-            String volumeDatastorePath = VmwareStorageLayoutHelper.getDatastorePathBaseFolderFromVmdkFileName(dsMo, volumeUuid + ".vmdk");
-            VolumeObjectTO newVol = new VolumeObjectTO();
-
+            String volumeDatastorePath = dsMo.getDatastorePath(volumeUuid + ".vmdk");
+            String dummyVmName = hostService.getWorkerName(context, cmd, 0);
             try {
-                VirtualStorageObjectManagerMO vStorageObjectManagerMO = new VirtualStorageObjectManagerMO(context);
-                VStorageObject virtualDisk = vStorageObjectManagerMO.createDisk(morDatastore, VirtualDiskType.THIN, volume.getSize(), volumeDatastorePath, volumeUuid);
-                DatastoreFile file = new DatastoreFile(((BaseConfigInfoDiskFileBackingInfo)virtualDisk.getConfig().getBacking()).getFilePath());
-                newVol.setPath(file.getFileBaseName());
-                newVol.setSize(volume.getSize());
-            } catch (Exception e) {
-                s_logger.debug("Create disk using vStorageObject manager failed due to exception " + e.getMessage() + ", retying using worker VM");
-                String dummyVmName = hostService.getWorkerName(context, cmd, 0, dsMo);
-                try {
-                    s_logger.info("Create worker VM " + dummyVmName);
-                    vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
-                    if (vmMo == null) {
-                        throw new Exception("Unable to create a dummy VM for volume creation");
-                    }
+                s_logger.info("Create worker VM " + dummyVmName);
+                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
+                if (vmMo == null) {
+                    throw new Exception("Unable to create a dummy VM for volume creation");
+                }
 
-                    synchronized (this) {
-                        try {
-                            vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey(), vSphereStoragePolicyId);
-                            vmMo.detachDisk(volumeDatastorePath, false);
-                        }
-                        catch (Exception e1) {
-                            s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e1.getMessage());
-                            VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
-                            throw new CloudRuntimeException("Unable to create volume due to: " + e1.getMessage());
-                        }
+                synchronized (this) {
+                    try {
+                        vmMo.createDisk(volumeDatastorePath, (int)(volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey());
+                        vmMo.detachDisk(volumeDatastorePath, false);
                     }
-
-                    newVol = new VolumeObjectTO();
-                    newVol.setPath(volumeUuid);
-                    newVol.setSize(volume.getSize());
-                    return new CreateObjectAnswer(newVol);
-                } finally {
-                    s_logger.info("Destroy dummy VM after volume creation");
-                    if (vmMo != null) {
-                        vmMo.detachAllDisks();
-                        vmMo.destroy();
+                    catch (Exception e) {
+                        s_logger.error("Deleting file " + volumeDatastorePath + " due to error: " + e.getMessage());
+                        VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid, dcMo, VmwareManager.s_vmwareSearchExcludeFolder.value());
+                        throw new CloudRuntimeException("Unable to create volume due to: " + e.getMessage());
                     }
                 }
+
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(volumeUuid);
+                newVol.setSize(volume.getSize());
+                return new CreateObjectAnswer(newVol);
+            } finally {
+                s_logger.info("Destroy dummy VM after volume creation");
+                if (vmMo != null) {
+                    vmMo.detachAllDisks();
+                    vmMo.destroy();
+                }
             }
-            return new CreateObjectAnswer(newVol);
         } catch (Throwable e) {
             if (e instanceof RemoteException) {
                 s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
@@ -2652,14 +2365,9 @@
 
                     List<Map<String, String>> dynamicTargetsToRemove = null;
 
-                    boolean deployAsIs = vol.isDeployAsIs();
                     if (vmMo != null) {
                         if (s_logger.isInfoEnabled()) {
-                            if (deployAsIs) {
-                                s_logger.info("Destroying root volume " + vol.getPath() + " of deploy-as-is VM " + vmName);
-                            } else {
-                                s_logger.info("Destroy root volume and VM itself. vmName " + vmName);
-                            }
+                            s_logger.info("Destroy root volume and VM itself. vmName " + vmName);
                         }
 
                         VirtualMachineDiskInfo diskInfo = null;
@@ -2682,12 +2390,13 @@
                         List<VirtualDisk> virtualDisks = vmMo.getVirtualDisks();
                         List<String> managedDatastoreNames = getManagedDatastoreNamesFromVirtualDisks(virtualDisks);
 
+                        List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
+                        VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
+
                         // let vmMo.destroy to delete volume for us
                         // vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
 
                         if (isManaged) {
-                            List<String> detachedDisks = vmMo.detachAllDisksExcept(vol.getPath(), diskInfo != null ? diskInfo.getDiskDeviceBusName() : null);
-                            VmwareStorageLayoutHelper.moveVolumeToRootFolder(new DatacenterMO(context, morDc), detachedDisks);
                             vmMo.unregisterVm();
                         }
                         else {
@@ -2706,24 +2415,6 @@
                                 }
                             }
                         }
-                    } else if (deployAsIs) {
-                        if (s_logger.isInfoEnabled()) {
-                            s_logger.info("Destroying root volume " + vol.getPath() + " of already removed deploy-as-is VM " + vmName);
-                        }
-                        // The disks of the deploy-as-is VM have been detached from the VM and moved to root folder
-                        String deployAsIsRootDiskPath = dsMo.searchFileInSubFolders(vol.getPath() + VmwareResource.VMDK_EXTENSION,
-                                true, null);
-                        if (StringUtils.isNotBlank(deployAsIsRootDiskPath)) {
-                            if (s_logger.isInfoEnabled()) {
-                                s_logger.info("Removing disk " + deployAsIsRootDiskPath);
-                            }
-                            dsMo.deleteFile(deployAsIsRootDiskPath, morDc, true);
-                            String deltaFilePath = dsMo.searchFileInSubFolders(vol.getPath() + "-delta" + VmwareResource.VMDK_EXTENSION,
-                                    true, null);
-                            if (StringUtils.isNotBlank(deltaFilePath)) {
-                                dsMo.deleteFile(deltaFilePath, morDc, true);
-                            }
-                        }
                     }
 
                     /*
@@ -3245,7 +2936,7 @@
         VmwareContext context = hostService.getServiceContext(null);
         VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
 
-        String dummyVmName = hostService.getWorkerName(context, cmd, 0, dsMo);
+        String dummyVmName = hostService.getWorkerName(context, cmd, 0);
 
         VirtualMachineMO vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName, null);
 
@@ -3253,9 +2944,9 @@
             throw new Exception("Unable to create a dummy VM for volume creation");
         }
 
-        Long volumeSizeToUse = volumeSize < dsMo.getDatastoreSummary().getFreeSpace() ? volumeSize : dsMo.getDatastoreSummary().getFreeSpace();
+        Long volumeSizeToUse = volumeSize < dsMo.getSummary().getFreeSpace() ? volumeSize : dsMo.getSummary().getFreeSpace();
 
-        vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey(), null);
+        vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey());
         vmMo.detachDisk(vmdkDatastorePath, false);
         vmMo.destroy();
     }
@@ -3763,15 +3454,13 @@
 
         VirtualMachineMO clonedVm = null;
         try {
-            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin", null);
+            hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin");
             clonedVm = hyperHost.findVmOnHyperHost(newVolumeName);
             if (clonedVm == null) {
                 throw new Exception("Unable to create container VM for volume creation");
             }
 
-            if(!primaryDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-                clonedVm.moveAllVmDiskFiles(primaryDsMo, HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, false);
-            }
+            clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false);
             clonedVm.detachAllDisks();
             return _storage.getSize(srcOVFFileName);
         } finally {
@@ -3803,6 +3492,7 @@
         String backupPath = backedUpSnapshotUuid.substring(0, index);
         backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 1);
         String details;
+        String newVolumeName = VmwareHelper.getVCenterSafeUuid();
 
         VmwareContext context = hostService.getServiceContext(cmd);
         try {
@@ -3814,14 +3504,13 @@
                 throw new Exception(msg);
             }
 
-            DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
-            String newVolumeName = VmwareHelper.getVCenterSafeUuid(primaryDsMo);
             // strip off the extension since restoreVolumeFromSecStorage internally will append suffix there.
             if (backedUpSnapshotUuid.endsWith(".ova")){
                 backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ova", "");
             } else if (backedUpSnapshotUuid.endsWith(".ovf")){
                 backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
             }
+            DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
             restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion);
 
             VolumeObjectTO newVol = new VolumeObjectTO();
@@ -3892,74 +3581,7 @@
     }
 
     @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        String primaryStorageNameLabel = cmd.getStoragePool().getUuid();
-        String storagePolicyId = cmd.getStoragePolicyId();
-        VmwareContext context = hostService.getServiceContext(cmd);
-        try {
-            VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
-            ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStorageNameLabel);
-            if (morPrimaryDs == null) {
-                String msg = "Unable to find datastore: " + primaryStorageNameLabel;
-                s_logger.error(msg);
-                throw new Exception(msg);
-            }
-
-            DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
-            boolean isDatastoreStoragePolicyComplaint = primaryDsMo.isDatastoreStoragePolicyComplaint(storagePolicyId);
-
-            String failedMessage = String.format("DataStore %s is not complaince with storage policy id %s", primaryStorageNameLabel, storagePolicyId);
-            if (!isDatastoreStoragePolicyComplaint)
-                return new Answer(cmd, isDatastoreStoragePolicyComplaint, failedMessage);
-            else
-                return new Answer(cmd, isDatastoreStoragePolicyComplaint, null);
-        } catch (Throwable e) {
-            if (e instanceof RemoteException) {
-                hostService.invalidateServiceContext(context);
-            }
-            String details = String.format("Exception while checking if datastore %s is storage policy %s complaince : %s", primaryStorageNameLabel, storagePolicyId,  VmwareHelper.getExceptionMessage(e));
-            s_logger.error(details, e);
-            return new Answer(cmd, false, details);
-        }
-    }
-
-    @Override
     public Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd) {
         return null;
     }
-
-    /**
-     * Return the cloned VM from the template
-     */
-    public VirtualMachineMO cloneVMFromTemplate(VmwareHypervisorHost hyperHost, String templateName, String cloneName, String templatePrimaryStoreUuid) {
-        try {
-            VmwareContext context = hyperHost.getContext();
-            DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
-            VirtualMachineMO templateMo = dcMo.findVm(templateName);
-            if (templateMo == null) {
-                throw new CloudRuntimeException(String.format("Unable to find template %s in vSphere", templateName));
-            }
-            ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, templatePrimaryStoreUuid);
-            DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
-            ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
-            if (morDatastore == null) {
-                throw new CloudRuntimeException("Unable to find datastore in vSphere");
-            }
-            s_logger.info("Cloning VM " + cloneName + " from template " + templateName + " into datastore " + templatePrimaryStoreUuid);
-            if (!_fullCloneFlag) {
-                createVMLinkedClone(templateMo, dcMo, cloneName, morDatastore, morPool);
-            } else {
-                createVMFullClone(templateMo, dcMo, dsMo, cloneName, morDatastore, morPool);
-            }
-            VirtualMachineMO vm = dcMo.findVm(cloneName);
-            if (vm == null) {
-                throw new CloudRuntimeException("Unable to get the cloned VM " + cloneName);
-            }
-            return vm;
-        } catch (Throwable e) {
-            String msg = "Error cloning VM from template in primary storage: %s" + e.getMessage();
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg, e);
-        }
-    }
 }
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java
deleted file mode 100644
index ea5bacf..0000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.api.command.admin.zone;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.VsphereStoragePolicy;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.vmware.VmwareDatacenterService;
-
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-
-@APICommand(name = ImportVsphereStoragePoliciesCmd.APINAME, description = "Import vSphere storage policies",
-        responseObject = VsphereStoragePoliciesResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
-        authorized = {RoleType.Admin})
-public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
-
-    public static final Logger LOGGER = Logger.getLogger(ImportVsphereStoragePoliciesCmd.class.getName());
-
-    public static final String APINAME = "importVsphereStoragePolicies";
-
-    @Inject
-    public VmwareDatacenterService _vmwareDatacenterService;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
-            description = "ID of the zone")
-    private Long zoneId;
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
-        final DataCenter dataCenter = _resourceService.getZone(getZoneId());
-        if (dataCenter == null) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find zone by ID: " + getZoneId());
-        }
-
-        List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
-        final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
-        final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
-        for (VsphereStoragePolicy storagePolicy : storagePolicies) {
-            final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
-            storagePoliciesResponse.setZoneId(dataCenter.getUuid());
-            storagePoliciesResponse.setId(storagePolicy.getUuid());
-            storagePoliciesResponse.setName(storagePolicy.getName());
-            storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
-            storagePoliciesResponse.setDescription(storagePolicy.getDescription());
-            storagePoliciesResponse.setObjectName("StoragePolicy");
-
-            storagePoliciesResponseList.add(storagePoliciesResponse);
-        }
-        responseList.setResponses(storagePoliciesResponseList);
-        responseList.setResponseName(getCommandName());
-        setResponseObject(responseList);
-    }
-
-    @Override
-    public String getCommandName() {
-        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccountId();
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-}
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java
deleted file mode 100644
index 90e8e88..0000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.cloudstack.api.command.admin.zone;
-
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.VsphereStoragePolicy;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.NetworkRuleConflictException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.hypervisor.vmware.VmwareDatacenterService;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-
-@APICommand(name = ListVsphereStoragePoliciesCmd.APINAME, description = "List vSphere storage policies",
-        responseObject = VsphereStoragePoliciesResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
-        authorized = {RoleType.Admin})
-public class ListVsphereStoragePoliciesCmd extends BaseCmd {
-
-    public static final Logger LOGGER = Logger.getLogger(ListVsphereStoragePoliciesCmd.class.getName());
-
-    public static final String APINAME = "listVsphereStoragePolicies";
-
-    @Inject
-    public VmwareDatacenterService _vmwareDatacenterService;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
-            description = "ID of the zone")
-    private Long zoneId;
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
-        final DataCenter dataCenter = _resourceService.getZone(getZoneId());
-        if (dataCenter == null) {
-            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Unable to find zone by ID: " + getZoneId());
-        }
-
-        List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
-        final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
-        final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
-        for (VsphereStoragePolicy storagePolicy : storagePolicies) {
-            final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
-            storagePoliciesResponse.setZoneId(dataCenter.getUuid());
-            storagePoliciesResponse.setId(storagePolicy.getUuid());
-            storagePoliciesResponse.setName(storagePolicy.getName());
-            storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
-            storagePoliciesResponse.setDescription(storagePolicy.getDescription());
-            storagePoliciesResponse.setObjectName("StoragePolicy");
-
-            storagePoliciesResponseList.add(storagePoliciesResponse);
-        }
-        responseList.setResponses(storagePoliciesResponseList);
-        responseList.setResponseName(getCommandName());
-        setResponseObject(responseList);
-    }
-
-    @Override
-    public String getCommandName() {
-        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccountId();
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java
deleted file mode 100644
index ee7146a..0000000
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package org.apache.cloudstack.api.command.admin.zone;
-
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.hypervisor.vmware.VmwareDatacenterService;
-import com.cloud.storage.StoragePool;
-import org.apache.cloudstack.acl.RoleType;
-import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.BaseListCmd;
-import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-
-import javax.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-
-@APICommand(name = ListVsphereStoragePolicyCompatiblePoolsCmd.APINAME, description = "List storage pools compatible with a vSphere storage policy",
-        responseObject = StoragePoolResponse.class,
-        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
-        authorized = {RoleType.Admin})
-public class ListVsphereStoragePolicyCompatiblePoolsCmd extends BaseListCmd {
-    public static final String APINAME = "listVsphereStoragePolicyCompatiblePools";
-
-    @Inject
-    public VmwareDatacenterService vmwareDatacenterService;
-
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
-
-    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
-            description = "ID of the zone")
-    private Long zoneId;
-
-    @Parameter(name = ApiConstants.POLICY_ID, type = BaseCmd.CommandType.UUID, entityType = VsphereStoragePoliciesResponse.class,
-            description = "ID of the storage policy")
-    private Long policyId;
-
-    /////////////////////////////////////////////////////
-    /////////////// API Implementation///////////////////
-    /////////////////////////////////////////////////////
-
-    @Override
-    public void execute() throws ServerApiException, ConcurrentOperationException {
-        List<StoragePool> pools = vmwareDatacenterService.listVsphereStoragePolicyCompatibleStoragePools(this);
-        ListResponse<StoragePoolResponse> response = new ListResponse<>();
-        List<StoragePoolResponse> poolResponses = new ArrayList<>();
-        for (StoragePool pool : pools) {
-            StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
-            poolResponse.setObjectName("storagepool");
-            poolResponses.add(poolResponse);
-        }
-        response.setResponses(poolResponses);
-        response.setResponseName(getCommandName());
-        this.setResponseObject(response);
-    }
-
-    @Override
-    public String getCommandName() {
-        return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
-    }
-
-    @Override
-    public long getEntityOwnerId() {
-        return CallContext.current().getCallingAccountId();
-    }
-
-    public Long getZoneId() {
-        return zoneId;
-    }
-
-    public Long getPolicyId() {
-        return policyId;
-    }
-}
diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
index 5a7b4c4..2463e75 100644
--- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
+++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
@@ -132,10 +132,7 @@
         StoragePool srcPool = storagePoolDao.findById(srcStore.getId());
         DataStore destStore = destData.getDataStore();
         StoragePool destPool = storagePoolDao.findById(destStore.getId());
-        if (srcPool.getClusterId() != null && destPool.getClusterId() != null) {
-            return srcPool.getClusterId().equals(destPool.getClusterId());
-        }
-        return false;
+        return srcPool.getClusterId().equals(destPool.getClusterId());
     }
 
     /**
diff --git a/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
index a2d8314..3af2d1a 100644
--- a/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
+++ b/plugins/hypervisors/vmware/src/main/resources/META-INF/cloudstack/core/spring-vmware-core-context.xml
@@ -37,6 +37,7 @@
         class="com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDaoImpl" />
     <bean id="LegacyZoneDaoImpl" class="com.cloud.hypervisor.vmware.dao.LegacyZoneDaoImpl" />
 
+
     <bean id="ciscoNexusVSMDeviceDaoImpl" class="com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl" />
 
 </beans>
\ No newline at end of file
diff --git a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
index 95387db..eb04139 100644
--- a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -31,7 +31,6 @@
 import com.cloud.dc.dao.ClusterVSMMapDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.dc.dao.HostPodDao;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
 import com.cloud.event.dao.EventDao;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
@@ -39,7 +38,6 @@
 import com.cloud.host.dao.HostDao;
 import com.cloud.host.dao.HostDetailsDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.hypervisor.vmware.dao.LegacyZoneDao;
 import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
@@ -52,7 +50,6 @@
 import com.cloud.secstorage.CommandExecLogDao;
 import com.cloud.server.ConfigurationServer;
 import com.cloud.storage.ImageStoreDetailsUtil;
-import com.cloud.storage.StorageManager;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
@@ -489,21 +486,6 @@
             return Mockito.mock(TemplateManager.class);
         }
 
-        @Bean
-        public VsphereStoragePolicyDao vsphereStoragePolicyDao() {
-            return Mockito.mock(VsphereStoragePolicyDao.class);
-        }
-
-        @Bean
-        public StorageManager storageManager() {
-            return Mockito.mock(StorageManager.class);
-        }
-
-        @Bean
-        public HypervisorGuruManager hypervisorGuruManager() {
-            return Mockito.mock(HypervisorGuruManager.class);
-        }
-
         public static class Library implements TypeFilter {
 
             @Override
diff --git a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java
index 80677e9..8aa92f7 100644
--- a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java
+++ b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImplTest.java
@@ -105,7 +105,6 @@
         Mockito.lenient().doReturn(hostDetails).when(hostDetailsDao).findDetails(Mockito.anyLong());
         Mockito.doReturn("some-old-guid").when(hostDetails).get("guid");
         Mockito.doReturn(hostDetails).when(hostDetailsDao).findDetails(Mockito.anyLong());
-        Mockito.doReturn(null).when(vmwareManager).importVsphereStoragePoliciesInternal(Mockito.anyLong(), Mockito.anyLong());
 
         final VmwareDatacenter vmwareDatacenter = vmwareManager.updateVmwareDatacenter(updateVmwareDcCmd);
 
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
index d530969..d987f28 100644
--- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
@@ -35,7 +35,6 @@
 import org.apache.cloudstack.agent.directdownload.DirectDownloadCommand;
 import org.apache.cloudstack.storage.command.AttachAnswer;
 import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.CreateObjectAnswer;
@@ -217,12 +216,6 @@
     }
 
     @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        s_logger.info("'CheckDataStoreStoragePolicyComplainceCommand' not applicable used for XenServerStorageProcessor");
-        return new Answer(cmd,false,"Not applicable used for XenServerStorageProcessor");
-    }
-
-    @Override
     public AttachAnswer attachIso(final AttachCommand cmd) {
         final DiskTO disk = cmd.getDisk();
         final DataTO data = disk.getData();
diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
index 9b54e0b..184013e 100644
--- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
+++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java
@@ -27,7 +27,6 @@
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.CopyCmdAnswer;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
@@ -914,12 +913,6 @@
     }
 
     @Override
-    public Answer CheckDataStoreStoragePolicyComplaince(CheckDataStoreStoragePolicyComplainceCommand cmd) {
-        s_logger.info("'CheckDataStoreStoragePolicyComplainceCommand' not applicable used for XenServerStorageProcessor");
-        return new Answer(cmd,false,"Not applicable used for XenServerStorageProcessor");
-    }
-
-    @Override
     public Answer copyVolumeFromPrimaryToSecondary(final CopyCommand cmd) {
         final Connection conn = hypervisorResource.getConnection();
         final VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO();
diff --git a/plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/driver/DateraPrimaryDataStoreDriver.java b/plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/driver/DateraPrimaryDataStoreDriver.java
index fa1f3d4..497960d 100644
--- a/plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/driver/DateraPrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/datera/src/main/java/org/apache/cloudstack/storage/datastore/driver/DateraPrimaryDataStoreDriver.java
@@ -955,7 +955,7 @@
         } else if (dataType == DataObjectType.TEMPLATE) {
             s_logger.debug("Clone volume from a template");
 
-            VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, dataObjectId, null);
+            VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
 
             if (templatePoolRef != null) {
                 baseAppInstanceName = templatePoolRef.getLocalDownloadPath();
@@ -1114,7 +1114,7 @@
             iqn = appInstance.getIqn();
 
             VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId,
-                    templateInfo.getId(), null);
+                    templateInfo.getId());
 
             templatePoolRef.setInstallPath(DateraUtil.generateIqnPath(iqn));
             templatePoolRef.setLocalDownloadPath(appInstance.getName());
@@ -1505,7 +1505,7 @@
             DateraUtil.deleteAppInstance(conn, appInstanceName);
 
             VMTemplateStoragePoolVO templatePoolRef = tmpltPoolDao.findByPoolTemplate(storagePoolId,
-                    templateInfo.getId(), null);
+                    templateInfo.getId());
 
             tmpltPoolDao.remove(templatePoolRef.getId());
 
diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
index 068b26f..bdaeddc 100644
--- a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
+++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java
@@ -18,12 +18,36 @@
  */
 package org.apache.cloudstack.storage.datastore.lifecycle;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
+import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
+
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CreateStoragePoolCommand;
 import com.cloud.agent.api.DeleteStoragePoolCommand;
 import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.api.ValidateVcenterDetailsCommand;
 import com.cloud.alert.AlertManager;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.StorageConflictException;
@@ -53,29 +77,6 @@
 import com.cloud.vm.dao.SecondaryStorageVmDao;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
-import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import javax.inject.Inject;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
 
 public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
     private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreLifeCycleImpl.class);
@@ -132,7 +133,6 @@
         Long zoneId = (Long)dsInfos.get("zoneId");
         String url = (String)dsInfos.get("url");
         String providerName = (String)dsInfos.get("providerName");
-        String hypervisorType = (String)dsInfos.get("hypervisorType");
         if (clusterId != null && podId == null) {
             throw new InvalidParameterValueException("Cluster id requires pod id");
         }
@@ -250,21 +250,10 @@
             parameters.setPath(hostPath.replaceFirst("/", ""));
             parameters.setUserInfo(userInfo);
         } else if (scheme.equalsIgnoreCase("PreSetup")) {
-            if (StringUtils.isNotBlank(hypervisorType) && HypervisorType.getType(hypervisorType).equals(HypervisorType.VMware)) {
-                validateVcenterDetails(zoneId, podId, clusterId,storageHost);
-            }
             parameters.setType(StoragePoolType.PreSetup);
             parameters.setHost(storageHost);
             parameters.setPort(0);
             parameters.setPath(hostPath);
-        } else if (scheme.equalsIgnoreCase("DatastoreCluster")) {
-            if (StringUtils.isNotBlank(hypervisorType) && HypervisorType.getType(hypervisorType).equals(HypervisorType.VMware)) {
-                validateVcenterDetails(zoneId, podId, clusterId,storageHost);
-            }
-            parameters.setType(StoragePoolType.DatastoreCluster);
-            parameters.setHost(storageHost);
-            parameters.setPort(0);
-            parameters.setPath(hostPath);
         } else if (scheme.equalsIgnoreCase("iscsi")) {
             String[] tokens = hostPath.split("/");
             int lun = NumbersUtil.parseInt(tokens[tokens.length - 1], -1);
@@ -338,7 +327,7 @@
             uuid = (String)existingUuid;
         } else if (scheme.equalsIgnoreCase("sharedmountpoint") || scheme.equalsIgnoreCase("clvm")) {
             uuid = UUID.randomUUID().toString();
-        } else if (scheme.equalsIgnoreCase("PreSetup") && !(StringUtils.isNotBlank(hypervisorType) && HypervisorType.getType(hypervisorType).equals(HypervisorType.VMware))) {
+        } else if (scheme.equalsIgnoreCase("PreSetup")) {
             uuid = hostPath.replace("/", "");
         } else {
             uuid = UUID.nameUUIDFromBytes((storageHost + hostPath).getBytes()).toString();
@@ -364,39 +353,12 @@
         return dataStoreHelper.createPrimaryDataStore(parameters);
     }
 
-    private void validateVcenterDetails(Long zoneId, Long podId, Long clusterId, String storageHost) {
-
-        List<HostVO> allHosts =
-                _resourceMgr.listAllUpHosts(Host.Type.Routing, clusterId, podId, zoneId);
-        if (allHosts.isEmpty()) {
-            throw new CloudRuntimeException("No host up to associate a storage pool with in zone: " + zoneId + " pod: " + podId + " cluster: " + clusterId);
-        }
-
-        boolean success = false;
-        for (HostVO h : allHosts) {
-            ValidateVcenterDetailsCommand cmd = new ValidateVcenterDetailsCommand(storageHost);
-            final Answer answer = agentMgr.easySend(h.getId(), cmd);
-            if (answer != null && answer.getResult()) {
-                s_logger.info("Successfully validated vCenter details provided");
-                return;
-            } else {
-                if (answer != null) {
-                    throw new InvalidParameterValueException("Provided vCenter server details does not match with the existing vCenter in zone id: " + zoneId);
-                } else {
-                    String msg = "Can not validate vCenter through host " + h.getId() + " due to ValidateVcenterDetailsCommand returns null";
-                    s_logger.warn(msg);
-                }
-            }
-        }
-        throw new CloudRuntimeException("Could not validate vCenter details through any of the hosts with in zone: " + zoneId + ", pod: " + podId + ", cluster: " + clusterId);
-    }
-
     protected boolean createStoragePool(long hostId, StoragePool pool) {
         s_logger.debug("creating pool " + pool.getName() + " on  host " + hostId);
 
         if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem &&
                 pool.getPoolType() != StoragePoolType.IscsiLUN && pool.getPoolType() != StoragePoolType.Iscsi && pool.getPoolType() != StoragePoolType.VMFS &&
-                pool.getPoolType() != StoragePoolType.SharedMountPoint && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.DatastoreCluster && pool.getPoolType() != StoragePoolType.OCFS2 &&
+                pool.getPoolType() != StoragePoolType.SharedMountPoint && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 &&
                 pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM && pool.getPoolType() != StoragePoolType.SMB &&
                 pool.getPoolType() != StoragePoolType.Gluster) {
             s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType());
diff --git a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
index 0651f2e..22e4e95 100644
--- a/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/main/java/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java
@@ -709,7 +709,7 @@
             sfVolumeId = Long.parseLong(snapshotDetails.getValue());
         } else if (dataObjectType == DataObjectType.TEMPLATE) {
             // get the cached template on this storage
-            VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, dataObjectId, null);
+            VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, dataObjectId);
 
             if (templatePoolRef != null) {
                 sfVolumeId = Long.parseLong(templatePoolRef.getLocalDownloadPath());
@@ -1135,7 +1135,7 @@
 
         String iqn = sfVolume.getIqn();
 
-        VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId(), null);
+        VMTemplateStoragePoolVO templatePoolRef = vmTemplatePoolDao.findByPoolTemplate(storagePoolId, templateInfo.getId());
 
         templatePoolRef.setInstallPath(iqn);
         templatePoolRef.setLocalDownloadPath(Long.toString(sfVolume.getId()));
diff --git a/server/src/main/java/com/cloud/api/ApiDBUtils.java b/server/src/main/java/com/cloud/api/ApiDBUtils.java
index a2433ab..e6b3077 100644
--- a/server/src/main/java/com/cloud/api/ApiDBUtils.java
+++ b/server/src/main/java/com/cloud/api/ApiDBUtils.java
@@ -2004,16 +2004,16 @@
         return s_templateJoinDao.newUpdateResponse(vr);
     }
 
-    public static TemplateResponse newTemplateResponse(EnumSet<DomainDetails> detailsView, ResponseView view, TemplateJoinVO vr) {
-        return s_templateJoinDao.newTemplateResponse(detailsView, view, vr);
+    public static TemplateResponse newTemplateResponse(ResponseView view, TemplateJoinVO vr) {
+        return s_templateJoinDao.newTemplateResponse(view, vr);
     }
 
     public static TemplateResponse newIsoResponse(TemplateJoinVO vr) {
         return s_templateJoinDao.newIsoResponse(vr);
     }
 
-    public static TemplateResponse fillTemplateDetails(EnumSet<DomainDetails> detailsView, ResponseView view, TemplateResponse vrData, TemplateJoinVO vr) {
-        return s_templateJoinDao.setTemplateResponse(detailsView, view, vrData, vr);
+    public static TemplateResponse fillTemplateDetails(ResponseView view, TemplateResponse vrData, TemplateJoinVO vr) {
+        return s_templateJoinDao.setTemplateResponse(view, vrData, vr);
     }
 
     public static List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate vr) {
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index 51a5436..2957a59 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -1564,7 +1564,7 @@
             tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly);
 
         }
-        return ViewResponseHelper.createTemplateResponse(EnumSet.of(DomainDetails.all), view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
     }
 
     @Override
@@ -1581,7 +1581,7 @@
                     tvo.addAll(ApiDBUtils.newTemplateView(result, zoneId, readyOnly));
             }
         }
-        return ViewResponseHelper.createTemplateResponse(EnumSet.of(DomainDetails.all), view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
+        return ViewResponseHelper.createTemplateResponse(view, tvo.toArray(new TemplateJoinVO[tvo.size()]));
     }
 
     @Override
diff --git a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
index e8161bc..28f6bfc 100644
--- a/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
@@ -31,7 +31,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.storage.dao.VMTemplateDetailsDao;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -72,6 +71,7 @@
 import org.apache.cloudstack.api.command.user.resource.ListDetailOptionsCmd;
 import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
 import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplateOVFProperties;
 import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
 import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
@@ -101,6 +101,7 @@
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.cloudstack.api.response.StoragePoolResponse;
 import org.apache.cloudstack.api.response.StorageTagResponse;
+import org.apache.cloudstack.api.response.TemplateOVFPropertyResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.api.response.UserVmResponse;
@@ -117,13 +118,12 @@
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.query.QueryService;
 import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import com.cloud.agent.api.storage.OVFProperty;
 import com.cloud.api.query.dao.AccountJoinDao;
 import com.cloud.api.query.dao.AffinityGroupJoinDao;
 import com.cloud.api.query.dao.AsyncJobJoinDao;
@@ -212,9 +212,11 @@
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
 import com.cloud.storage.StoragePoolTagVO;
+import com.cloud.storage.TemplateOVFPropertyVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Volume;
 import com.cloud.storage.dao.StoragePoolTagsDao;
+import com.cloud.storage.dao.TemplateOVFPropertiesDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.tags.ResourceTagVO;
 import com.cloud.tags.dao.ResourceTagDao;
@@ -401,7 +403,7 @@
     ManagementServerHostDao managementServerHostDao;
 
     @Inject
-    VMTemplateDetailsDao vmTemplateDetailsDao;
+    TemplateOVFPropertiesDao templateOVFPropertiesDao;
 
     @Inject
     public VpcVirtualNetworkApplianceService routerService;
@@ -416,9 +418,6 @@
     private TemplateDataStoreDao templateDataStoreDao;
 
     @Inject
-    private PrimaryDataStoreDao _storagePoolDao;
-
-    @Inject
     private ProjectInvitationDao projectInvitationDao;
 
     @Inject
@@ -974,12 +973,7 @@
         }
 
         if (storageId != null) {
-            StoragePoolVO poolVO = _storagePoolDao.findById((Long) storageId);
-            if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.IN);
-            } else {
-                sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.EQ);
-            }
+            sb.and("poolId", sb.entity().getPoolId(), SearchCriteria.Op.EQ);
         }
 
         if (affinityGroupId != null) {
@@ -1117,14 +1111,7 @@
             }
 
             if (storageId != null) {
-                StoragePoolVO poolVO = _storagePoolDao.findById((Long) storageId);
-                if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                    List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster((Long) storageId);
-                    List<Long> childDatastoreIds = childDatastores.stream().map(mo -> mo.getId()).collect(Collectors.toList());
-                    sc.setParameters("poolId", childDatastoreIds.toArray());
-                } else {
-                    sc.setParameters("poolId", storageId);
-                }
+                sc.setParameters("poolId", storageId);
             }
         }
 
@@ -1517,15 +1504,19 @@
         }
 
         if (accountId != null) {
-            sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+            if (userId == null) {
+                sb.and().op("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+                sb.and("userIdNull", sb.entity().getUserId(), Op.NULL);
+                sb.cp();
+            } else {
+                sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
+            }
         }
 
         if (userId != null) {
             sb.and().op("userId", sb.entity().getUserId(), Op.EQ);
             sb.or("userIdNull", sb.entity().getUserId(), Op.NULL);
             sb.cp();
-        } else {
-            sb.and("userIdNull", sb.entity().getUserId(), Op.NULL);
         }
 
         SearchCriteria<ProjectJoinVO> sc = sb.create();
@@ -1951,14 +1942,7 @@
         sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ);
         sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
         sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ);
-        if (storageId != null) {
-            StoragePoolVO poolVO = _storagePoolDao.findByUuid(storageId);
-            if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.IN);
-            } else {
-                sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.EQ);
-            }
-        }
+        sb.and("storageId", sb.entity().getPoolUuid(), SearchCriteria.Op.EQ);
         sb.and("diskOfferingId", sb.entity().getDiskOfferingId(), SearchCriteria.Op.EQ);
         sb.and("display", sb.entity().isDisplayVolume(), SearchCriteria.Op.EQ);
         sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
@@ -2027,14 +2011,7 @@
         }
 
         if (storageId != null) {
-            StoragePoolVO poolVO = _storagePoolDao.findByUuid(storageId);
-            if (poolVO.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(poolVO.getId());
-                List<String> childDatastoreIds = childDatastores.stream().map(mo -> mo.getUuid()).collect(Collectors.toList());
-                sc.setParameters("storageId", childDatastoreIds.toArray());
-            } else {
-                sc.setParameters("storageId", storageId);
-            }
+            sc.setParameters("storageId", storageId);
         }
 
         if (clusterId != null) {
@@ -2425,7 +2402,6 @@
         sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
         sb.and("hostAddress", sb.entity().getHostAddress(), SearchCriteria.Op.EQ);
         sb.and("scope", sb.entity().getScope(), SearchCriteria.Op.EQ);
-        sb.and("parent", sb.entity().getParent(), Op.EQ);
 
         SearchCriteria<StoragePoolJoinVO> sc = sb.create();
 
@@ -2463,7 +2439,6 @@
         if (scopeType != null) {
             sc.setParameters("scope", scopeType.toString());
         }
-        sc.setParameters("parent", 0);
 
         // search Pool details by ids
         Pair<List<StoragePoolJoinVO>, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter);
@@ -2585,6 +2560,7 @@
         Object keyword = cmd.getKeyword();
         Long startIndex = cmd.getStartIndex();
         Long pageSize = cmd.getPageSizeVal();
+        Boolean readonly = cmd.getReadonly();
 
         Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize);
 
@@ -2597,6 +2573,7 @@
         sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ);
         sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ);
         sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ);
+        sb.and("readonly", sb.entity().isReadonly(), Op.EQ);
 
         SearchCriteria<ImageStoreJoinVO> sc = sb.create();
         sc.setParameters("role", DataStoreRole.Image);
@@ -2625,7 +2602,9 @@
         if (protocol != null) {
             sc.setParameters("protocol", protocol);
         }
-
+        if (readonly != null) {
+            sc.setParameters("readonly", readonly);
+        }
         // search Store details by ids
         Pair<List<ImageStoreJoinVO>, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter);
         Integer count = uniqueStorePair.second();
@@ -2915,9 +2894,6 @@
         ServiceOfferingVO currentVmOffering = null;
         Boolean isRecursive = cmd.isRecursive();
         Long zoneId = cmd.getZoneId();
-        Integer cpuNumber = cmd.getCpuNumber();
-        Integer memory = cmd.getMemory();
-        Integer cpuSpeed = cmd.getCpuSpeed();
 
         SearchCriteria<ServiceOfferingJoinVO> sc = _srvOfferingJoinDao.createSearchCriteria();
         if (!_accountMgr.isRootAdmin(caller.getId()) && isSystem) {
@@ -2969,7 +2945,35 @@
                 if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
                     throw new InvalidParameterValueException("Only ROOT admins and Domain admins can list service offerings with isrecursive=true");
                 }
-            }
+            }/* else { // domain + all ancestors
+                // find all domain Id up to root domain for this account
+                List<Long> domainIds = new ArrayList<Long>();
+                DomainVO domainRecord;
+                if (vmId != null) {
+                    UserVmVO vmInstance = _userVmDao.findById(vmId);
+                    domainRecord = _domainDao.findById(vmInstance.getDomainId());
+                    if (domainRecord == null) {
+                        s_logger.error("Could not find the domainId for vmId:" + vmId);
+                        throw new CloudAuthenticationException("Could not find the domainId for vmId:" + vmId);
+                    }
+                } else {
+                    domainRecord = _domainDao.findById(caller.getDomainId());
+                    if (domainRecord == null) {
+                        s_logger.error("Could not find the domainId for account:" + caller.getAccountName());
+                        throw new CloudAuthenticationException("Could not find the domainId for account:" + caller.getAccountName());
+                    }
+                }
+                domainIds.add(domainRecord.getId());
+                while (domainRecord.getParent() != null) {
+                    domainRecord = _domainDao.findById(domainRecord.getParent());
+                    domainIds.add(domainRecord.getId());
+                }
+
+                SearchCriteria<ServiceOfferingJoinVO> spc = _srvOfferingJoinDao.createSearchCriteria();
+                spc.addOr("domainId", SearchCriteria.Op.IN, domainIds.toArray());
+                spc.addOr("domainId", SearchCriteria.Op.NULL); // include public offering as well
+                sc.addAnd("domainId", SearchCriteria.Op.SC, spc);
+            }*/
         } else {
             // for root users
             if (caller.getDomainId() != 1 && isSystem) { // NON ROOT admin
@@ -3016,37 +3020,6 @@
             sc.addAnd("zoneId", SearchCriteria.Op.SC, zoneSC);
         }
 
-        if (cpuNumber != null) {
-            SearchCriteria<ServiceOfferingJoinVO> cpuConstraintSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
-            cpuConstraintSearchCriteria.addAnd("minCpu", Op.LTEQ, cpuNumber);
-            cpuConstraintSearchCriteria.addAnd("maxCpu", Op.GTEQ, cpuNumber);
-
-            SearchCriteria<ServiceOfferingJoinVO> cpuSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
-            cpuSearchCriteria.addOr("minCpu", Op.NULL);
-            cpuSearchCriteria.addOr("constraints", Op.SC, cpuConstraintSearchCriteria);
-
-            sc.addAnd("cpuConstraints", SearchCriteria.Op.SC, cpuSearchCriteria);
-        }
-
-        if (memory != null) {
-            SearchCriteria<ServiceOfferingJoinVO> memoryConstraintSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
-            memoryConstraintSearchCriteria.addAnd("minMemory", Op.LTEQ, memory);
-            memoryConstraintSearchCriteria.addAnd("maxMemory", Op.GTEQ, memory);
-
-            SearchCriteria<ServiceOfferingJoinVO> memSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
-            memSearchCriteria.addOr("minMemory", Op.NULL);
-            memSearchCriteria.addOr("memconstraints", Op.SC, memoryConstraintSearchCriteria);
-
-            sc.addAnd("memoryConstraints", SearchCriteria.Op.SC, memSearchCriteria);
-        }
-
-        if (cpuSpeed != null) {
-            SearchCriteria<ServiceOfferingJoinVO> cpuSpeedSearchCriteria = _srvOfferingJoinDao.createSearchCriteria();
-            cpuSpeedSearchCriteria.addOr("speed", Op.NULL);
-            cpuSpeedSearchCriteria.addOr("speed", Op.EQ, cpuSpeed);
-            sc.addAnd("cpuspeedconstraints", SearchCriteria.Op.SC, cpuSpeedSearchCriteria);
-        }
-
         Pair<List<ServiceOfferingJoinVO>, Integer> result = _srvOfferingJoinDao.searchAndCount(sc, searchFilter);
 
         //Couldn't figure out a smart way to filter offerings based on tags in sql so doing it in Java.
@@ -3327,7 +3300,7 @@
             respView = ResponseView.Full;
         }
 
-        List<TemplateResponse> templateResponses = ViewResponseHelper.createTemplateResponse(cmd.getDetails(), respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
+        List<TemplateResponse> templateResponses = ViewResponseHelper.createTemplateResponse(respView, result.first().toArray(new TemplateJoinVO[result.first().size()]));
         response.setResponses(templateResponses, result.second());
         return response;
     }
@@ -4098,6 +4071,29 @@
     }
 
     @Override
+    public ListResponse<TemplateOVFPropertyResponse> listTemplateOVFProperties(ListTemplateOVFProperties cmd) {
+        ListResponse<TemplateOVFPropertyResponse> response = new ListResponse<>();
+        List<TemplateOVFPropertyResponse> result = new ArrayList<>();
+        Long templateId = cmd.getTemplateId();
+        List<TemplateOVFPropertyVO> ovfProperties = templateOVFPropertiesDao.listByTemplateId(templateId);
+        for (OVFProperty property : ovfProperties) {
+            TemplateOVFPropertyResponse propertyResponse = new TemplateOVFPropertyResponse();
+            propertyResponse.setKey(property.getKey());
+            propertyResponse.setType(property.getType());
+            propertyResponse.setValue(property.getValue());
+            propertyResponse.setQualifiers(property.getQualifiers());
+            propertyResponse.setUserConfigurable(property.isUserConfigurable());
+            propertyResponse.setLabel(property.getLabel());
+            propertyResponse.setDescription(property.getDescription());
+            propertyResponse.setPassword(property.isPassword());
+            propertyResponse.setObjectName("ovfproperty");
+            result.add(propertyResponse);
+        }
+        response.setResponses(result);
+        return response;
+    }
+
+    @Override
     public List<RouterHealthCheckResultResponse> listRouterHealthChecks(GetRouterHealthCheckResultsCmd cmd) {
         s_logger.info("Executing health check command " + cmd);
         long routerId = cmd.getRouterId();
diff --git a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
index d91fa7b..88a7639 100644
--- a/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/query/ViewResponseHelper.java
@@ -26,7 +26,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
 import org.apache.cloudstack.api.ApiConstants.DomainDetails;
 import org.apache.cloudstack.api.ApiConstants.HostDetails;
@@ -584,17 +583,17 @@
         return respList;
     }
 
-    public static List<TemplateResponse> createTemplateResponse(EnumSet<ApiConstants.DomainDetails> detailsView, ResponseView view, TemplateJoinVO... templates) {
+    public static List<TemplateResponse> createTemplateResponse(ResponseView view, TemplateJoinVO... templates) {
         LinkedHashMap<String, TemplateResponse> vrDataList = new LinkedHashMap<String, TemplateResponse>();
         for (TemplateJoinVO vr : templates) {
             TemplateResponse vrData = vrDataList.get(vr.getTempZonePair());
             if (vrData == null) {
                 // first time encountering this volume
-                vrData = ApiDBUtils.newTemplateResponse(detailsView, view, vr);
+                vrData = ApiDBUtils.newTemplateResponse(view, vr);
             }
             else{
                 // update tags
-                vrData = ApiDBUtils.fillTemplateDetails(detailsView, view, vrData, vr);
+                vrData = ApiDBUtils.fillTemplateDetails(view, vrData, vr);
             }
             vrDataList.put(vr.getTempZonePair(), vrData);
         }
@@ -610,7 +609,7 @@
                 vrData = ApiDBUtils.newTemplateUpdateResponse(vr);
             } else {
                 // update tags
-                vrData = ApiDBUtils.fillTemplateDetails(EnumSet.of(DomainDetails.all), view, vrData, vr);
+                vrData = ApiDBUtils.fillTemplateDetails(view, vrData, vr);
             }
             vrDataList.put(vr.getId(), vrData);
         }
@@ -626,7 +625,7 @@
                 vrData = ApiDBUtils.newIsoResponse(vr);
             } else {
                 // update tags
-                vrData = ApiDBUtils.fillTemplateDetails(EnumSet.of(DomainDetails.all), view, vrData, vr);
+                vrData = ApiDBUtils.fillTemplateDetails(view, vrData, vr);
             }
             vrDataList.put(vr.getTempZonePair(), vrData);
         }
diff --git a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
index a62fbcd..9220974 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
@@ -17,13 +17,7 @@
 package com.cloud.api.query.dao;
 
 import java.util.List;
-import java.util.Map;
 
-import com.cloud.api.ApiDBUtils;
-import com.cloud.dc.VsphereStoragePolicyVO;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
-import com.cloud.server.ResourceTag;
-import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.response.DiskOfferingResponse;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
@@ -36,15 +30,10 @@
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 
-import javax.inject.Inject;
-
 @Component
 public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO, Long> implements DiskOfferingJoinDao {
     public static final Logger s_logger = Logger.getLogger(DiskOfferingJoinDaoImpl.class);
 
-    @Inject
-    VsphereStoragePolicyDao _vsphereStoragePolicyDao;
-
     private final SearchBuilder<DiskOfferingJoinVO> dofIdSearch;
     private final Attribute _typeAttr;
 
@@ -119,15 +108,6 @@
         diskOfferingResponse.setIopsWriteRateMaxLength(offering.getIopsWriteRateMaxLength());
         diskOfferingResponse.setCacheMode(offering.getCacheMode());
         diskOfferingResponse.setObjectName("diskoffering");
-        Map<String, String> offeringDetails = ApiDBUtils.getResourceDetails(offering.getId(), ResourceTag.ResourceObjectType.DiskOffering);
-        if (offeringDetails != null && !offeringDetails.isEmpty()) {
-            String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY);
-            if (vsphereStoragePolicyId != null) {
-                VsphereStoragePolicyVO vsphereStoragePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(vsphereStoragePolicyId));
-                if (vsphereStoragePolicyVO != null)
-                    diskOfferingResponse.setVsphereStoragePolicy(vsphereStoragePolicyVO.getName());
-            }
-        }
 
         return diskOfferingResponse;
     }
diff --git a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
index 4c025b9..add6415 100644
--- a/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
@@ -17,11 +17,7 @@
 package com.cloud.api.query.dao;
 
 import java.util.List;
-import java.util.Map;
 
-import com.cloud.dc.VsphereStoragePolicyVO;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
-import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
@@ -34,15 +30,10 @@
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 
-import javax.inject.Inject;
-
 @Component
 public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJoinVO, Long> implements ServiceOfferingJoinDao {
     public static final Logger s_logger = Logger.getLogger(ServiceOfferingJoinDaoImpl.class);
 
-    @Inject
-    VsphereStoragePolicyDao _vsphereStoragePolicyDao;
-
     private SearchBuilder<ServiceOfferingJoinVO> sofIdSearch;
 
     protected ServiceOfferingJoinDaoImpl() {
@@ -108,19 +99,11 @@
         offeringResponse.setIopsWriteRate(offering.getIopsWriteRate());
         offeringResponse.setIopsWriteRateMax(offering.getIopsWriteRateMax());
         offeringResponse.setIopsWriteRateMaxLength(offering.getIopsWriteRateMaxLength());
-        Map<String, String> offeringDetails = ApiDBUtils.getResourceDetails(offering.getId(), ResourceObjectType.ServiceOffering);
-        offeringResponse.setDetails(offeringDetails);
+        offeringResponse.setDetails(ApiDBUtils.getResourceDetails(offering.getId(), ResourceObjectType.ServiceOffering));
         offeringResponse.setObjectName("serviceoffering");
         offeringResponse.setIscutomized(offering.isDynamic());
         offeringResponse.setCacheMode(offering.getCacheMode());
-        if (offeringDetails != null && !offeringDetails.isEmpty()) {
-            String vsphereStoragePolicyId = offeringDetails.get(ApiConstants.STORAGE_POLICY);
-            if (vsphereStoragePolicyId != null) {
-                VsphereStoragePolicyVO vsphereStoragePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(vsphereStoragePolicyId));
-                if (vsphereStoragePolicyVO != null)
-                    offeringResponse.setVsphereStoragePolicy(vsphereStoragePolicyVO.getName());
-            }
-        }
+
         return offeringResponse;
     }
 
diff --git a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
index d2fe6a5..b8b312b 100644
--- a/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/StoragePoolJoinDaoImpl.java
@@ -20,7 +20,6 @@
 import com.cloud.api.query.vo.StoragePoolJoinVO;
 import com.cloud.capacity.CapacityManager;
 import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.StorageStats;
 import com.cloud.utils.StringUtils;
@@ -33,9 +32,6 @@
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -56,9 +52,6 @@
     @Inject
     protected PrimaryDataStoreDao storagePoolDao;
 
-    @Inject
-    private StoragePoolDetailsDao storagePoolDetailsDao;
-
     private final SearchBuilder<StoragePoolJoinVO> spSearch;
 
     private final SearchBuilder<StoragePoolJoinVO> spIdSearch;
@@ -101,20 +94,7 @@
             poolResponse.setHypervisor(pool.getHypervisor().toString());
         }
 
-        StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(pool.getId(), "pool_type");
-        if (poolType != null) {
-            poolResponse.setType(poolType.getValue());
-        }
         long allocatedSize = pool.getUsedCapacity() + pool.getReservedCapacity();
-        if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-            List<StoragePoolVO> childDatastores = storagePoolDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-            if (childDatastores != null) {
-                for (StoragePoolVO childDatastore: childDatastores) {
-                    StoragePoolJoinVO childDSJoinVO = findById(childDatastore.getId());
-                    allocatedSize += (childDSJoinVO.getUsedCapacity() + childDSJoinVO.getReservedCapacity());
-                }
-            }
-        }
         poolResponse.setDiskSizeTotal(pool.getCapacityBytes());
         poolResponse.setDiskSizeAllocated(allocatedSize);
         poolResponse.setCapacityIops(pool.getCapacityIops());
diff --git a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java
index 58cb886..c9d7eba 100644
--- a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java
+++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDao.java
@@ -16,10 +16,8 @@
 // under the License.
 package com.cloud.api.query.dao;
 
-import java.util.EnumSet;
 import java.util.List;
 
-import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.response.TemplateResponse;
 
@@ -32,13 +30,13 @@
 
 public interface TemplateJoinDao extends GenericDao<TemplateJoinVO, Long> {
 
-    TemplateResponse newTemplateResponse(EnumSet<ApiConstants.DomainDetails> detailsView, ResponseView view, TemplateJoinVO tmpl);
+    TemplateResponse newTemplateResponse(ResponseView view, TemplateJoinVO tmpl);
 
     TemplateResponse newIsoResponse(TemplateJoinVO tmpl);
 
     TemplateResponse newUpdateResponse(TemplateJoinVO tmpl);
 
-    TemplateResponse setTemplateResponse(EnumSet<ApiConstants.DomainDetails> detailsView, ResponseView view, TemplateResponse tmplData, TemplateJoinVO tmpl);
+    TemplateResponse setTemplateResponse(ResponseView view, TemplateResponse tmplData, TemplateJoinVO tmpl);
 
     List<TemplateJoinVO> newTemplateView(VirtualMachineTemplate tmpl);
 
diff --git a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
index 92072c7..6b700a2 100644
--- a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java
@@ -17,7 +17,6 @@
 package com.cloud.api.query.dao;
 
 import java.util.ArrayList;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -26,14 +25,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.deployasis.DeployAsIsConstants;
-import com.cloud.deployasis.TemplateDeployAsIsDetailVO;
-import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
-import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.utils.security.DigestHelper;
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.response.ChildTemplateResponse;
 import org.apache.cloudstack.api.response.TemplateResponse;
@@ -44,6 +35,9 @@
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
+import org.apache.cloudstack.utils.security.DigestHelper;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
 
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.ApiResponseHelper;
@@ -83,8 +77,6 @@
     private ImageStoreDao dataStoreDao;
     @Inject
     private VMTemplateDetailsDao _templateDetailsDao;
-    @Inject
-    private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
 
     private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch;
 
@@ -155,7 +147,7 @@
     }
 
     @Override
-    public TemplateResponse newTemplateResponse(EnumSet<ApiConstants.DomainDetails> detailsView, ResponseView view, TemplateJoinVO template) {
+    public TemplateResponse newTemplateResponse(ResponseView view, TemplateJoinVO template) {
         List<TemplateDataStoreVO> templatesInStore = _templateStoreDao.listByTemplateNotBypassed(template.getId());
         List<Map<String, String>> downloadProgressDetails = new ArrayList();
         HashMap<String, String> downloadDetailInImageStores = null;
@@ -166,7 +158,6 @@
             downloadDetailInImageStores.put("downloadState", (templateInStore.getDownloadState() != null ? templateInStore.getDownloadState().toString() : ""));
             downloadProgressDetails.add(downloadDetailInImageStores);
         }
-
         TemplateResponse templateResponse = new TemplateResponse();
         templateResponse.setDownloadProgress(downloadProgressDetails);
         templateResponse.setId(template.getUuid());
@@ -239,12 +230,8 @@
         }
 
         // set details map
-        if (detailsView.contains(ApiConstants.DomainDetails.all)) {
-            Map<String, String> details = _templateDetailsDao.listDetailsKeyPairs(template.getId());
-            templateResponse.setDetails(details);
-
-            setDeployAsIsDetails(template, templateResponse);
-        }
+        Map<String, String> details = _templateDetailsDao.listDetailsKeyPairs(template.getId());
+        templateResponse.setDetails(details);
 
         // update tag information
         long tag_id = template.getTagId();
@@ -253,7 +240,6 @@
         }
 
         templateResponse.setDirectDownload(template.isDirectDownload());
-        templateResponse.setDeployAsIs(template.isDeployAsIs());
         templateResponse.setRequiresHvm(template.isRequiresHvm());
 
         //set template children disks
@@ -276,19 +262,6 @@
         return templateResponse;
     }
 
-    private void setDeployAsIsDetails(TemplateJoinVO template, TemplateResponse templateResponse) {
-        if (template.isDeployAsIs()) {
-            List<TemplateDeployAsIsDetailVO> deployAsIsDetails = templateDeployAsIsDetailsDao.listDetails(template.getId());
-            for (TemplateDeployAsIsDetailVO deployAsIsDetailVO : deployAsIsDetails) {
-                if (deployAsIsDetailVO.getName().startsWith(DeployAsIsConstants.HARDWARE_ITEM_PREFIX)) {
-                    //Do not list hardware items
-                    continue;
-                }
-                templateResponse.addDeployAsIsDetail(deployAsIsDetailVO.getName(), deployAsIsDetailVO.getValue());
-            }
-        }
-    }
-
     //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse
     // compared to listTemplates and listIsos.
     @Override
@@ -334,13 +307,16 @@
     }
 
     @Override
-    public TemplateResponse setTemplateResponse(EnumSet<ApiConstants.DomainDetails> detailsView, ResponseView view, TemplateResponse templateResponse, TemplateJoinVO template) {
-        if (detailsView.contains(ApiConstants.DomainDetails.all)) {
-            // update details map
-            String key = template.getDetailName();
-            if (key != null) {
-                templateResponse.addDetail(key, template.getDetailValue());
+    public TemplateResponse setTemplateResponse(ResponseView view, TemplateResponse templateResponse, TemplateJoinVO template) {
+
+        // update details map
+        if (template.getDetailName() != null) {
+            Map<String, String> details = templateResponse.getDetails();
+            if (details == null) {
+                details = new HashMap<>();
             }
+            details.put(template.getDetailName(), template.getDetailValue());
+            templateResponse.setDetails(details);
         }
 
         // update tag information
@@ -520,6 +496,7 @@
         sc.setParameters("store_id", storeId);
         sc.setParameters("type", TemplateType.USER);
         sc.setParameters("templateState", VirtualMachineTemplate.State.Active);
+        sc.setParameters("public", Boolean.FALSE);
         return searchIncludingRemoved(sc, null, null, false);
     }
 
diff --git a/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
index 8e489f8..80c433a 100644
--- a/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/UserVmJoinDaoImpl.java
@@ -322,8 +322,8 @@
         if (vmDetails != null) {
             Map<String, String> resourceDetails = new HashMap<String, String>();
             for (UserVmDetailVO userVmDetailVO : vmDetails) {
-                if (!userVmDetailVO.getName().startsWith(ApiConstants.PROPERTIES) ||
-                        (UserVmManager.DisplayVMOVFProperties.value() && userVmDetailVO.getName().startsWith(ApiConstants.PROPERTIES))) {
+                if (!userVmDetailVO.getName().startsWith(ApiConstants.OVF_PROPERTIES) ||
+                        (UserVmManager.DisplayVMOVFProperties.value() && userVmDetailVO.getName().startsWith(ApiConstants.OVF_PROPERTIES))) {
                     resourceDetails.put(userVmDetailVO.getName(), userVmDetailVO.getValue());
                 }
                 if ((ApiConstants.BootType.UEFI.toString()).equalsIgnoreCase(userVmDetailVO.getName())) {
diff --git a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
index 2ee0ca1..c797735 100644
--- a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
@@ -24,8 +24,6 @@
 import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.response.VolumeResponse;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -53,8 +51,6 @@
     public AccountManager _accountMgr;
     @Inject
     private VmDiskStatisticsDao vmDiskStatsDao;
-    @Inject
-    private PrimaryDataStoreDao primaryDataStoreDao;
 
     private final SearchBuilder<VolumeJoinVO> volSearch;
 
@@ -224,14 +220,6 @@
             String poolName = (poolId == null) ? "none" : volume.getPoolName();
             volResponse.setStoragePoolName(poolName);
             volResponse.setStoragePoolId(volume.getPoolUuid());
-            if (poolId != null) {
-                StoragePoolVO poolVO = primaryDataStoreDao.findById(poolId);
-                if (poolVO != null && poolVO.getParent() != 0L) {
-                    StoragePoolVO datastoreClusterVO = primaryDataStoreDao.findById(poolVO.getParent());
-                    volResponse.setStoragePoolName(datastoreClusterVO.getName());
-                    volResponse.setStoragePoolId(datastoreClusterVO.getUuid());
-                }
-            }
         }
 
         volResponse.setAttached(volume.getAttached());
diff --git a/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java
index 707c2a3..50559c7 100644
--- a/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/DiskOfferingJoinVO.java
@@ -159,9 +159,6 @@
     @Column(name = "state")
     DiskOffering.State state;
 
-    @Column(name = "vsphere_storage_policy")
-    String vsphereStoragePolicy;
-
     public DiskOfferingJoinVO() {
     }
 
@@ -346,8 +343,4 @@
     public void setState(DiskOffering.State state) {
         this.state = state;
     }
-
-    public String getVsphereStoragePolicy() {
-        return vsphereStoragePolicy;
-    }
 }
diff --git a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
index e025da5..4f8932a 100644
--- a/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
@@ -175,21 +175,6 @@
     @Column(name = "cache_mode")
     String cacheMode;
 
-    @Column(name = "min_cpu")
-    Integer minCpu;
-
-    @Column(name = "max_cpu")
-    Integer maxCpu;
-
-    @Column(name = "min_memory")
-    Integer minMemory;
-
-    @Column(name = "max_memory")
-    Integer maxMemory;
-
-    @Column(name = "vsphere_storage_policy")
-    String vsphereStoragePolicy;
-
     public ServiceOfferingJoinVO() {
     }
 
@@ -371,25 +356,4 @@
     public String getCacheMode() {
         return cacheMode;
     }
-
-    public Integer getMinCpu() {
-        return minCpu;
-    }
-
-    public Integer getMaxCpu() {
-        return maxCpu;
-    }
-
-    public Integer getMinMemory() {
-        return minMemory;
-    }
-
-    public Integer getMaxMemory() {
-        return maxMemory;
-    }
-
-    public String getVsphereStoragePolicy() {
-        return vsphereStoragePolicy;
-    }
-
 }
diff --git a/server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java
index 1831aaa..565e290 100644
--- a/server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/StoragePoolJoinVO.java
@@ -139,9 +139,6 @@
     @Column(name = "storage_provider_name")
     private String storageProviderName;
 
-    @Column(name = "parent")
-    private Long parent;
-
     /**
      * @return the scope
      */
@@ -266,8 +263,4 @@
     public String getStorageProviderName() {
         return storageProviderName;
     }
-
-    public Long getParent() {
-        return parent;
-    }
 }
diff --git a/server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java
index 91bb763..25e3b0b 100644
--- a/server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/TemplateJoinVO.java
@@ -231,9 +231,6 @@
     @Column(name = "direct_download")
     private boolean directDownload;
 
-    @Column(name = "deploy_as_is")
-    private boolean deployAsIs;
-
     public TemplateJoinVO() {
     }
 
@@ -493,10 +490,6 @@
         return directDownload;
     }
 
-    public boolean isDeployAsIs() {
-        return deployAsIs;
-    }
-
     public Object getParentTemplateId() {
         return parentTemplateId;
     }
diff --git a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
index 9d1cffc..cc24a45 100755
--- a/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -39,8 +39,7 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
-import com.cloud.storage.Storage;
+import com.cloud.utils.StringUtils;
 import org.apache.cloudstack.acl.SecurityChecker;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -224,7 +223,6 @@
 import com.cloud.user.dao.UserDao;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
-import com.cloud.utils.StringUtils;
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
@@ -389,9 +387,6 @@
     IndirectAgentLB _indirectAgentLB;
     @Inject
     private VMTemplateZoneDao templateZoneDao;
-    @Inject
-    VsphereStoragePolicyDao vsphereStoragePolicyDao;
-
 
     // FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
     @Inject
@@ -603,12 +598,6 @@
                 }
 
                 _storagePoolDetailsDao.addDetail(resourceId, name, value, true);
-                if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                    List<StoragePoolVO> childDataStores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(resourceId);
-                    for (StoragePoolVO childDataStore: childDataStores) {
-                        _storagePoolDetailsDao.addDetail(childDataStore.getId(), name, value, true);
-                    }
-                }
 
                 break;
 
@@ -2462,13 +2451,6 @@
             }
         }
 
-        final Long storagePolicyId = cmd.getStoragePolicy();
-        if (storagePolicyId != null) {
-            if (vsphereStoragePolicyDao.findById(storagePolicyId) == null) {
-                throw new InvalidParameterValueException("Please specify a valid vSphere storage policy id");
-            }
-        }
-
         return createServiceOffering(userId, cmd.isSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber, memory, cpuSpeed, cmd.getDisplayText(),
                 cmd.getProvisioningType(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainIds(), cmd.getZoneIds(), cmd.getHostTag(),
                 cmd.getNetworkRate(), cmd.getDeploymentPlanner(), details, isCustomizedIops, cmd.getMinIops(), cmd.getMaxIops(),
@@ -2476,7 +2458,7 @@
                 cmd.getBytesWriteRate(), cmd.getBytesWriteRateMax(), cmd.getBytesWriteRateMaxLength(),
                 cmd.getIopsReadRate(), cmd.getIopsReadRateMax(), cmd.getIopsReadRateMaxLength(),
                 cmd.getIopsWriteRate(), cmd.getIopsWriteRateMax(), cmd.getIopsWriteRateMaxLength(),
-                cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode(), storagePolicyId);
+                cmd.getHypervisorSnapshotReserve(), cmd.getCacheMode());
     }
 
     protected ServiceOfferingVO createServiceOffering(final long userId, final boolean isSystem, final VirtualMachine.Type vmType,
@@ -2487,7 +2469,7 @@
             Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
             Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
             Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
-            final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID) {
+            final Integer hypervisorSnapshotReserve, String cacheMode) {
         // Filter child domains when both parent and child domains are present
         List<Long> filteredDomainIds = filterChildSubDomains(domainIds);
 
@@ -2594,10 +2576,6 @@
             }
         }
 
-        if (storagePolicyID != null) {
-            detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), ApiConstants.STORAGE_POLICY, String.valueOf(storagePolicyID), false));
-        }
-
         if ((offering = _serviceOfferingDao.persist(offering)) != null) {
             for (Long domainId : filteredDomainIds) {
                 detailsVO.add(new ServiceOfferingDetailsVO(offering.getId(), ApiConstants.DOMAIN_ID, String.valueOf(domainId), false));
@@ -2858,7 +2836,7 @@
                                                 Long bytesWriteRate, Long bytesWriteRateMax, Long bytesWriteRateMaxLength,
                                                 Long iopsReadRate, Long iopsReadRateMax, Long iopsReadRateMaxLength,
                                                 Long iopsWriteRate, Long iopsWriteRateMax, Long iopsWriteRateMaxLength,
-                                                final Integer hypervisorSnapshotReserve, String cacheMode, final Long storagePolicyID) {
+                                                final Integer hypervisorSnapshotReserve, String cacheMode) {
         long diskSize = 0;// special case for custom disk offerings
         if (numGibibytes != null && numGibibytes <= 0) {
             throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
@@ -2953,9 +2931,6 @@
                     detailsVO.add(new DiskOfferingDetailVO(offering.getId(), ApiConstants.ZONE_ID, String.valueOf(zoneId), false));
                 }
             }
-            if (storagePolicyID != null) {
-                detailsVO.add(new DiskOfferingDetailVO(offering.getId(), ApiConstants.STORAGE_POLICY, String.valueOf(storagePolicyID), false));
-            }
             if (!detailsVO.isEmpty()) {
                 diskOfferingDetailsDao.saveDetails(detailsVO);
             }
@@ -2977,7 +2952,6 @@
         final String tags = cmd.getTags();
         final List<Long> domainIds = cmd.getDomainIds();
         final List<Long> zoneIds = cmd.getZoneIds();
-        final Long storagePolicyId = cmd.getStoragePolicy();
 
         // check if valid domain
         if (CollectionUtils.isNotEmpty(domainIds)) {
@@ -3017,12 +2991,6 @@
             }
         }
 
-        if (storagePolicyId != null) {
-            if (vsphereStoragePolicyDao.findById(storagePolicyId) == null) {
-                throw new InvalidParameterValueException("Please specify a valid vSphere storage policy id");
-            }
-        }
-
         final Boolean isCustomizedIops = cmd.isCustomizedIops();
         final Long minIops = cmd.getMinIops();
         final Long maxIops = cmd.getMaxIops();
@@ -3053,7 +3021,7 @@
                 localStorageRequired, isDisplayOfferingEnabled, isCustomizedIops, minIops,
                 maxIops, bytesReadRate, bytesReadRateMax, bytesReadRateMaxLength, bytesWriteRate, bytesWriteRateMax, bytesWriteRateMaxLength,
                 iopsReadRate, iopsReadRateMax, iopsReadRateMaxLength, iopsWriteRate, iopsWriteRateMax, iopsWriteRateMaxLength,
-                hypervisorSnapshotReserve, cacheMode, storagePolicyId);
+                hypervisorSnapshotReserve, cacheMode);
     }
 
     /**
diff --git a/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java
index 6c00709..2149a56 100644
--- a/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java
+++ b/server/src/main/java/com/cloud/deploy/DeploymentPlanningManagerImpl.java
@@ -30,10 +30,7 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.utils.StringUtils;
-import com.cloud.exception.StorageUnavailableException;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.fsm.StateMachine2;
 
@@ -175,8 +172,6 @@
     protected VMReservationDao _reservationDao;
     @Inject
     HostDetailsDao _hostDetailsDao;
-    @Inject
-    private VMTemplateDao templateDao;
 
     private static final long INITIAL_RESERVATION_RELEASE_CHECKER_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
     protected long _nodeId = -1;
@@ -324,9 +319,8 @@
                     return null;
                 }
 
-                boolean displayStorage = getDisplayStorageFromVmProfile(vmProfile);
                 if (vm.getHypervisorType() == HypervisorType.BareMetal) {
-                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>(), displayStorage);
+                    DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
                     s_logger.debug("Returning Deployment Destination: " + dest);
                     return dest;
                 }
@@ -346,7 +340,7 @@
                     suitableHosts.add(host);
                     Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
                             suitableHosts, suitableVolumeStoragePools, avoids,
-                            getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts(), vm);
+                            getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
                     if (potentialResources != null) {
                         pod = _podDao.findById(host.getPodId());
                         cluster = _clusterDao.findById(host.getClusterId());
@@ -356,7 +350,7 @@
                         for (Volume vol : readyAndReusedVolumes) {
                             storageVolMap.remove(vol);
                         }
-                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap, displayStorage);
+                        DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap);
                         s_logger.debug("Returning Deployment Destination: " + dest);
                         return dest;
                     }
@@ -445,7 +439,6 @@
                                 hostHasCapacity = _capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, false, cpuOvercommitRatio, memoryOvercommitRatio, true);
                         }
 
-                        boolean displayStorage = getDisplayStorageFromVmProfile(vmProfile);
                         if (hostHasCapacity
                                 && hostHasCpuCapability) {
                             s_logger.debug("The last host of this VM is UP and has enough capacity");
@@ -455,7 +448,7 @@
                             Pod pod = _podDao.findById(host.getPodId());
                             Cluster cluster = _clusterDao.findById(host.getClusterId());
                             if (vm.getHypervisorType() == HypervisorType.BareMetal) {
-                                DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>(), displayStorage);
+                                DeployDestination dest = new DeployDestination(dc, pod, cluster, host, new HashMap<Volume, StoragePool>());
                                 s_logger.debug("Returning Deployment Destination: " + dest);
                                 return dest;
                             }
@@ -477,7 +470,7 @@
                                 suitableHosts.add(host);
                                 Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(
                                         suitableHosts, suitableVolumeStoragePools, avoids,
-                                        getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts(), vm);
+                                        getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes, plan.getPreferredHosts());
                                 if (potentialResources != null) {
                                     Map<Volume, StoragePool> storageVolMap = potentialResources.second();
                                     // remove the reused vol<->pool from
@@ -488,7 +481,7 @@
                                         storageVolMap.remove(vol);
                                     }
                                     DeployDestination dest = new DeployDestination(dc, pod, cluster, host,
-                                            storageVolMap, displayStorage);
+                                            storageVolMap);
                                     s_logger.debug("Returning Deployment Destination: " + dest);
                                     return dest;
                                 }
@@ -561,19 +554,6 @@
         return dest;
     }
 
-    private boolean isDeployAsIs(VirtualMachine vm) {
-        long templateId = vm.getTemplateId();
-        VMTemplateVO template = templateDao.findById(templateId);
-        return template != null && template.isDeployAsIs();
-    }
-
-    /**
-     * Display storage in the logs by default if the template is not deploy-as-is.
-     */
-    private boolean getDisplayStorageFromVmProfile(VirtualMachineProfile vmProfile) {
-        return vmProfile == null || vmProfile.getTemplate() == null || !vmProfile.getTemplate().isDeployAsIs();
-    }
-
     @Override
     public DeploymentPlanner getDeploymentPlannerByName(String plannerName) {
         if (plannerName != null) {
@@ -1130,7 +1110,7 @@
                     // choose the potential host and pool for the VM
                     if (!suitableVolumeStoragePools.isEmpty()) {
                         Pair<Host, Map<Volume, StoragePool>> potentialResources = findPotentialDeploymentResources(suitableHosts, suitableVolumeStoragePools, avoid,
-                                resourceUsageRequired, readyAndReusedVolumes, plan.getPreferredHosts(), vmProfile.getVirtualMachine());
+                                resourceUsageRequired, readyAndReusedVolumes, plan.getPreferredHosts());
 
                         if (potentialResources != null) {
                             Host host = _hostDao.findById(potentialResources.first().getId());
@@ -1140,8 +1120,7 @@
                             for (Volume vol : readyAndReusedVolumes) {
                                 storageVolMap.remove(vol);
                             }
-                            boolean displayStorage = getDisplayStorageFromVmProfile(vmProfile);
-                            DeployDestination dest = new DeployDestination(dc, pod, clusterVO, host, storageVolMap, displayStorage);
+                            DeployDestination dest = new DeployDestination(dc, pod, clusterVO, host, storageVolMap);
                             s_logger.debug("Returning Deployment Destination: " + dest);
                             return dest;
                         }
@@ -1271,7 +1250,7 @@
     }
 
     protected Pair<Host, Map<Volume, StoragePool>> findPotentialDeploymentResources(List<Host> suitableHosts, Map<Volume, List<StoragePool>> suitableVolumeStoragePools,
-                                                                                    ExcludeList avoid, PlannerResourceUsage resourceUsageRequired, List<Volume> readyAndReusedVolumes, List<Long> preferredHosts, VirtualMachine vm) {
+            ExcludeList avoid, DeploymentPlanner.PlannerResourceUsage resourceUsageRequired, List<Volume> readyAndReusedVolumes, List<Long> preferredHosts) {
         s_logger.debug("Trying to find a potenial host and associated storage pools from the suitable host/pool lists for this VM");
 
         boolean hostCanAccessPool = false;
@@ -1293,121 +1272,50 @@
         });
         volumesOrderBySizeDesc.addAll(suitableVolumeStoragePools.keySet());
         boolean multipleVolume = volumesOrderBySizeDesc.size() > 1;
-        boolean deployAsIs = isDeployAsIs(vm);
         for (Host potentialHost : suitableHosts) {
             Map<StoragePool, List<Volume>> volumeAllocationMap = new HashMap<StoragePool, List<Volume>>();
-            if (deployAsIs) {
-                storage = new HashMap<>();
-                // Find the common suitable pools
-                s_logger.debug("Trying to allocate all the VM volumes to a single storage pool");
-                Set<StoragePool> suitablePools = new HashSet<>();
-                List<StoragePool> notAllowedPools = new ArrayList<>();
-                for (List<StoragePool> pools : suitableVolumeStoragePools.values()) {
-                    if (CollectionUtils.isEmpty(suitablePools)) {
-                        // All the suitable pools of the first volume
-                        suitablePools.addAll(pools);
-                    } else {
-                        for (StoragePool pool : pools) {
-                            if (!suitablePools.contains(pool)) {
-                                s_logger.debug("Storage pool " + pool.getUuid() + " not allowed for this VM");
-                                notAllowedPools.add(pool);
-                            }
-                        }
-                    }
-                }
-                suitablePools.removeAll(notAllowedPools);
-                if (CollectionUtils.isEmpty(suitablePools)) {
-                    s_logger.debug("Could not find a storage pool to fit all the VM volumes on this host");
-                    continue;
-                }
-
-                List<Volume> allVolumes = new ArrayList<>();
-                allVolumes.addAll(volumesOrderBySizeDesc);
-                for (StoragePool storagePool : suitablePools) {
-                    haveEnoughSpace = false;
-                    hostCanAccessPool = false;
-                    hostAffinityCheck = checkAffinity(potentialHost, preferredHosts);
-                    if (hostCanAccessSPool(potentialHost, storagePool)) {
+            for (Volume vol : volumesOrderBySizeDesc) {
+                haveEnoughSpace = false;
+                s_logger.debug("Checking if host: " + potentialHost.getId() + " can access any suitable storage pool for volume: " + vol.getVolumeType());
+                List<StoragePool> volumePoolList = suitableVolumeStoragePools.get(vol);
+                hostCanAccessPool = false;
+                hostAffinityCheck = checkAffinity(potentialHost, preferredHosts);
+                for (StoragePool potentialSPool : volumePoolList) {
+                    if (hostCanAccessSPool(potentialHost, potentialSPool)) {
                         hostCanAccessPool = true;
-                        if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
-                            try {
-                                boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolComplaintWithStoragePolicy(allVolumes, storagePool);
-                                if (!isStoragePoolStoragepolicyComplaince) {
-                                    continue;
-                                }
-                            } catch (StorageUnavailableException e) {
-                                s_logger.warn(String.format("Could not verify storage policy complaince against storage pool %s due to exception %s", storagePool.getUuid(), e.getMessage()));
+                        if (multipleVolume && !readyAndReusedVolumes.contains(vol)) {
+                            List<Volume> requestVolumes = null;
+                            if (volumeAllocationMap.containsKey(potentialSPool))
+                                requestVolumes = volumeAllocationMap.get(potentialSPool);
+                            else
+                                requestVolumes = new ArrayList<Volume>();
+                            requestVolumes.add(vol);
+
+                            if (!_storageMgr.storagePoolHasEnoughIops(requestVolumes, potentialSPool) ||
+                                !_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool, potentialHost.getClusterId()))
                                 continue;
-                            }
-                            haveEnoughSpace = true;
+                            volumeAllocationMap.put(potentialSPool, requestVolumes);
                         }
-                    }
-                    if (hostCanAccessPool && haveEnoughSpace && hostAffinityCheck) {
-                        for (Volume vol : volumesOrderBySizeDesc) {
-                            s_logger.debug("Found a suitable storage pool for all the VM volumes: " + storagePool.getUuid());
-                            storage.put(vol, storagePool);
-                        }
+                        storage.put(vol, potentialSPool);
+                        haveEnoughSpace = true;
                         break;
                     }
                 }
-            } else {
-                for (Volume vol : volumesOrderBySizeDesc) {
-                    haveEnoughSpace = false;
-                    s_logger.debug("Checking if host: " + potentialHost.getId() + " can access any suitable storage pool for volume: " + vol.getVolumeType());
-                    List<StoragePool> volumePoolList = suitableVolumeStoragePools.get(vol);
-                    hostCanAccessPool = false;
-                    hostAffinityCheck = checkAffinity(potentialHost, preferredHosts);
-                    for (StoragePool potentialSPool : volumePoolList) {
-                        if (hostCanAccessSPool(potentialHost, potentialSPool)) {
-                            hostCanAccessPool = true;
-                            if (multipleVolume && !readyAndReusedVolumes.contains(vol)) {
-                                List<Volume> requestVolumes = null;
-                                if (volumeAllocationMap.containsKey(potentialSPool))
-                                    requestVolumes = volumeAllocationMap.get(potentialSPool);
-                                else
-                                    requestVolumes = new ArrayList<Volume>();
-                                requestVolumes.add(vol);
-
-                                if (potentialHost.getHypervisorType() == HypervisorType.VMware) {
-                                    try {
-                                        boolean isStoragePoolStoragepolicyComplaince = _storageMgr.isStoragePoolComplaintWithStoragePolicy(requestVolumes, potentialSPool);
-                                        if (!isStoragePoolStoragepolicyComplaince) {
-                                            continue;
-                                        }
-                                    } catch (StorageUnavailableException e) {
-                                        s_logger.warn(String.format("Could not verify storage policy complaince against storage pool %s due to exception %s", potentialSPool.getUuid(), e.getMessage()));
-                                        continue;
-                                    }
-                                }
-
-                                if (!_storageMgr.storagePoolHasEnoughIops(requestVolumes, potentialSPool) ||
-                                        !_storageMgr.storagePoolHasEnoughSpace(requestVolumes, potentialSPool, potentialHost.getClusterId()))
-                                    continue;
-                                volumeAllocationMap.put(potentialSPool, requestVolumes);
-                            }
-                            storage.put(vol, potentialSPool);
-                            haveEnoughSpace = true;
-                            break;
-                        }
-                    }
-                    if (!hostCanAccessPool) {
-                        break;
-                    }
-                    if (!haveEnoughSpace) {
-                        s_logger.warn("insufficient capacity to allocate all volumes");
-                        break;
-                    }
-                    if (!hostAffinityCheck) {
-                        s_logger.debug("Host affinity check failed");
-                        break;
-                    }
+                if (!hostCanAccessPool) {
+                    break;
+                }
+                if (!haveEnoughSpace) {
+                    s_logger.warn("insufficient capacity to allocate all volumes");
+                    break;
+                }
+                if (!hostAffinityCheck) {
+                    s_logger.debug("Host affinity check failed");
+                    break;
                 }
             }
-
             if (hostCanAccessPool && haveEnoughSpace && hostAffinityCheck && checkIfHostFitsPlannerUsage(potentialHost.getId(), resourceUsageRequired)) {
                 s_logger.debug("Found a potential host " + "id: " + potentialHost.getId() + " name: " + potentialHost.getName() +
                         " and associated storage pools for this VM");
-                volumeAllocationMap.clear();
                 return new Pair<Host, Map<Volume, StoragePool>>(potentialHost, storage);
             } else {
                 avoid.addHost(potentialHost.getId());
diff --git a/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java
index 848340b..3ed5fcc 100644
--- a/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java
+++ b/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java
@@ -218,7 +218,7 @@
             }
             String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(uservm.getServiceOfferingId()).getDisplayText();
             String zoneName = _dcDao.findById(network.getDataCenterId()).getName();
-            String destHostname = VirtualMachineManager.getHypervisorHostname(dest.getHost() != null ? dest.getHost().getName() : "");
+            String destHostname = VirtualMachineManager.getHypervisorHostname(dest.getHost().getName());
             cmds.addCommand(
                 "vmdata",
                 generateVmDataCommand(nic.getIPv4Address(), userData, serviceOffering, zoneName, nic.getIPv4Address(), uservm.getHostName(), uservm.getInstanceName(),
diff --git a/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
index 7482eca..4daeda6 100644
--- a/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
+++ b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
@@ -369,7 +369,7 @@
             if (userVm != null) {
                 final boolean isWindows = isWindows(userVm.getGuestOSId());
                 List<String[]> vmData = _networkModel.generateVmData(userVm.getUserData(), _serviceOfferingDao.findById(userVm.getServiceOfferingId()).getName(), userVm.getDataCenterId(), userVm.getInstanceName(), vm.getHostName(), vm.getId(),
-                        vm.getUuid(), nic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) vm.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows, VirtualMachineManager.getHypervisorHostname(dest.getHost() != null ? dest.getHost().getName() : ""));
+                        vm.getUuid(), nic.getMacAddress(), userVm.getDetail("SSH.PublicKey"), (String) vm.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows, VirtualMachineManager.getHypervisorHostname(dest.getHost().getName()));
                 vm.setVmData(vmData);
                 vm.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value());
                 createConfigDriveIso(vm, dest, diskToUse);
diff --git a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
index 4adf140..00da0d3 100644
--- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
+++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java
@@ -195,7 +195,7 @@
             final IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(nic.getNetworkId(), vm.getId());
 
             Host host = _hostDao.findById(vm.getHostId());
-            String destHostname = VirtualMachineManager.getHypervisorHostname(host != null ? host.getName() : "");
+            String destHostname = VirtualMachineManager.getHypervisorHostname(host.getName());
             cmds.addCommand(
                     "vmdata",
                     generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName,
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 83261b9..bd5de22 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -27,20 +27,16 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.TimeZone;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.storage.Storage;
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
 import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@@ -457,6 +453,7 @@
 import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd;
 import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
+import org.apache.cloudstack.api.command.user.template.ListTemplateOVFProperties;
 import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd;
 import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd;
 import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
@@ -838,8 +835,6 @@
     private KeystoreManager _ksMgr;
     @Inject
     private DpdkHelper dpdkHelper;
-    @Inject
-    private PrimaryDataStoreDao _primaryDataStoreDao;
 
     private LockMasterListener _lockMasterListener;
     private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
@@ -1487,29 +1482,8 @@
         } else {
             suitablePools = allPools;
         }
-        List<StoragePool> avoidPools = new ArrayList<>();
-        if (srcVolumePool.getParent() != 0L) {
-            StoragePool datastoreCluster = _poolDao.findById(srcVolumePool.getParent());
-            avoidPools.add(datastoreCluster);
-        }
-        abstractDataStoreClustersList((List<StoragePool>) allPools, new ArrayList<StoragePool>());
-        abstractDataStoreClustersList((List<StoragePool>) suitablePools, avoidPools);
-        return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
-    }
 
-    private void abstractDataStoreClustersList(List<StoragePool> storagePools, List<StoragePool> avoidPools) {
-        Predicate<StoragePool> childDatastorePredicate = pool -> (pool.getParent() != 0);
-        List<StoragePool> childDatastores = storagePools.stream().filter(childDatastorePredicate).collect(Collectors.toList());
-        storagePools.removeAll(avoidPools);
-        if (!childDatastores.isEmpty()) {
-            storagePools.removeAll(childDatastores);
-            Set<Long> parentStoragePoolIds = childDatastores.stream().map(mo -> mo.getParent()).collect(Collectors.toSet());
-            for (Long parentStoragePoolId : parentStoragePoolIds) {
-                StoragePool parentPool = _poolDao.findById(parentStoragePoolId);
-                if (!storagePools.contains(parentPool) && !avoidPools.contains(parentPool))
-                    storagePools.add(parentPool);
-            }
-        }
+        return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools);
     }
 
     /**
@@ -3190,6 +3164,7 @@
         cmdList.add(RevokeTemplateDirectDownloadCertificateCmd.class);
         cmdList.add(ListMgmtsCmd.class);
         cmdList.add(GetUploadParamsForIsoCmd.class);
+        cmdList.add(ListTemplateOVFProperties.class);
         cmdList.add(GetRouterHealthCheckResultsCmd.class);
         cmdList.add(StartRollingMaintenanceCmd.class);
         cmdList.add(MigrateSecondaryStorageDataCmd.class);
@@ -3335,16 +3310,9 @@
         sb.and("nulltype", sb.entity().getType(), SearchCriteria.Op.IN);
 
         if (storageId != null) {
-            StoragePoolVO storagePool = _primaryDataStoreDao.findById(storageId);
-            if (storagePool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                final SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
-                volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.IN);
-                sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
-            } else {
-                final SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
-                volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
-                sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
-            }
+            final SearchBuilder<VolumeVO> volumeSearch = _volumeDao.createSearchBuilder();
+            volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ);
+            sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
         }
 
         final SearchCriteria<VMInstanceVO> sc = sb.create();
@@ -3384,14 +3352,7 @@
         }
 
         if (storageId != null) {
-            StoragePoolVO storagePool = _primaryDataStoreDao.findById(storageId);
-            if (storagePool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                List<StoragePoolVO> childDataStores = _primaryDataStoreDao.listChildStoragePoolsInDatastoreCluster(storageId);
-                List<Long> childDatastoreIds = childDataStores.stream().map(mo -> mo.getId()).collect(Collectors.toList());
-                sc.setJoinParameters("volumeSearch", "poolId", childDatastoreIds.toArray());
-            } else {
-                sc.setJoinParameters("volumeSearch", "poolId", storageId);
-            }
+            sc.setJoinParameters("volumeSearch", "poolId", storageId);
         }
 
         final Pair<List<VMInstanceVO>, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter);
diff --git a/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 1ce5b36..a2f97e8 100755
--- a/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/main/java/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -408,11 +408,11 @@
                             VMTemplateVO templateUpdate = _templateDao.createForUpdate();
                             templateUpdate.setSize(answer.getVirtualSize());
                             _templateDao.update(tmpTemplate.getId(), templateUpdate);
-                            // For multi-disk OVA, check and create data disk templates or root disks as details
+                            // For multi-disk OVA, check and create data disk templates
                             if (tmpTemplate.getFormat().equals(Storage.ImageFormat.OVA)) {
                                 final DataStore store = dataStoreManager.getDataStore(templateDataStore.getDataStoreId(), templateDataStore.getDataStoreRole());
                                 final TemplateInfo templateInfo = templateFactory.getTemplate(tmpTemplate.getId(), store);
-                                if (!templateService.createOvaDataDiskTemplates(templateInfo, template.isDeployAsIs())) {
+                                if (!templateService.createOvaDataDiskTemplates(templateInfo)) {
                                     tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.ABANDONED);
                                     tmpTemplateDataStore.setState(State.Failed);
                                     stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java
index 6224a77..3c707c3 100644
--- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java
@@ -39,12 +39,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.dc.VsphereStoragePolicyVO;
-import com.cloud.dc.dao.VsphereStoragePolicyDao;
-import com.cloud.service.dao.ServiceOfferingDetailsDao;
-import com.cloud.utils.StringUtils;
-import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateSecondaryStagingStoreCmd;
 import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd;
@@ -87,8 +81,6 @@
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.management.ManagementServerHost;
-import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao;
-import org.apache.cloudstack.storage.command.CheckDataStoreStoragePolicyComplainceCommand;
 import org.apache.cloudstack.storage.command.DettachCommand;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
@@ -182,6 +174,7 @@
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
+import com.cloud.utils.StringUtils;
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.ManagerBase;
@@ -304,12 +297,6 @@
     SnapshotService _snapshotService;
     @Inject
     StoragePoolTagsDao _storagePoolTagsDao;
-    @Inject
-    DiskOfferingDetailsDao _diskOfferingDetailsDao;
-    @Inject
-    ServiceOfferingDetailsDao _serviceOfferingDetailsDao;
-    @Inject
-    VsphereStoragePolicyDao _vsphereStoragePolicyDao;
 
     protected List<StoragePoolDiscoverer> _discoverers;
 
@@ -616,7 +603,6 @@
                 params.put("zoneId", host.getDataCenterId());
                 params.put("clusterId", host.getClusterId());
                 params.put("podId", host.getPodId());
-                params.put("hypervisorType", host.getHypervisorType());
                 params.put("url", pInfo.getPoolType().toString() + "://" + pInfo.getHost() + "/" + pInfo.getHostPath());
                 params.put("name", name);
                 params.put("localStorage", true);
@@ -702,9 +688,6 @@
                     && hypervisorType != HypervisorType.Any) {
                 throw new InvalidParameterValueException("zone wide storage pool is not supported for hypervisor type " + hypervisor);
             }
-        } else {
-            ClusterVO clusterVO = _clusterDao.findById(clusterId);
-            hypervisorType = clusterVO.getHypervisorType();
         }
 
         Map<String, String> details = extractApiParamAsMap(cmd.getDetails());
@@ -722,7 +705,6 @@
         params.put("zoneId", zone.getId());
         params.put("clusterId", clusterId);
         params.put("podId", podId);
-        params.put("hypervisorType", hypervisorType.toString());
         params.put("url", cmd.getUrl());
         params.put("tags", cmd.getTags());
         params.put("name", cmd.getStoragePoolName());
@@ -824,12 +806,6 @@
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Updating Storage Pool Tags to :" + storagePoolTags);
             }
-            if (pool.getPoolType() == StoragePoolType.DatastoreCluster) {
-                List<StoragePoolVO> childStoragePools = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-                for (StoragePoolVO childPool : childStoragePools) {
-                    _storagePoolTagsDao.persist(childPool.getId(), storagePoolTags);
-                }
-            }
             _storagePoolTagsDao.persist(pool.getId(), storagePoolTags);
         }
 
@@ -926,54 +902,10 @@
             s_logger.warn("Unable to delete storage id: " + id + " due to it is not in Maintenance state");
             throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
         }
-
-        if (sPool.getPoolType() == StoragePoolType.DatastoreCluster) {
-            // FR41 yet to handle on failure of deletion of any of the child storage pool
-            if (checkIfDataStoreClusterCanbeDeleted(sPool, forced)) {
-                Transaction.execute(new TransactionCallbackNoReturn() {
-                    @Override
-                    public void doInTransactionWithoutResult(TransactionStatus status) {
-                        List<StoragePoolVO> childStoragePools = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(sPool.getId());
-                        for (StoragePoolVO childPool : childStoragePools) {
-                            deleteDataStoreInternal(childPool, forced);
-                        }
-                    }
-                });
-            } else {
-                throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
-            }
-        }
-        return deleteDataStoreInternal(sPool, forced);
-    }
-
-    private boolean checkIfDataStoreClusterCanbeDeleted(StoragePoolVO sPool, boolean forced) {
-        List<StoragePoolVO> childStoragePools = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(sPool.getId());
-        boolean canDelete = true;
-        for (StoragePoolVO childPool : childStoragePools) {
-            Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(childPool.getId());
-            if (forced) {
-                if (vlms.first() > 0) {
-                    Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(childPool.getId());
-                    if (nonDstrdVlms.first() > 0) {
-                        canDelete = false;
-                        break;
-                    }
-                }
-            } else {
-                if (vlms.first() > 0) {
-                    canDelete = false;
-                    break;
-                }
-            }
-        }
-        return canDelete;
-    }
-
-    private boolean deleteDataStoreInternal(StoragePoolVO sPool, boolean forced) {
-        Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(sPool.getId());
+        Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(id);
         if (forced) {
             if (vlms.first() > 0) {
-                Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(sPool.getId());
+                Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(id);
                 if (nonDstrdVlms.first() > 0) {
                     throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
                 }
@@ -1009,7 +941,7 @@
         }
 
         _storagePoolDao.releaseFromLockTable(lock.getId());
-        s_logger.trace("Released lock for storage pool " + sPool.getId());
+        s_logger.trace("Released lock for storage pool " + id);
 
         DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
@@ -1538,55 +1470,11 @@
         DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
         DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-
-        if (primaryStorage.getPoolType() == StoragePoolType.DatastoreCluster) {
-            if (primaryStorage.getStatus() == StoragePoolStatus.PrepareForMaintenance) {
-                throw new CloudRuntimeException(String.format("There is already a job running for preparation for maintenance of the storage pool %s", primaryStorage.getUuid()));
-            }
-            handlePrepareDatastoreCluserMaintenance(lifeCycle, primaryStorageId);
-        }
         lifeCycle.maintain(store);
 
         return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
     }
 
-    private void handlePrepareDatastoreCluserMaintenance(DataStoreLifeCycle lifeCycle, Long primaryStorageId) {
-        StoragePoolVO datastoreCluster = _storagePoolDao.findById(primaryStorageId);
-        datastoreCluster.setStatus(StoragePoolStatus.PrepareForMaintenance);
-        _storagePoolDao.update(datastoreCluster.getId(), datastoreCluster);
-
-        // Before preparing the datastorecluster to maintenance mode, the storagepools in the datastore cluster needs to put in maintenance
-        List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(primaryStorageId);
-        Transaction.execute(new TransactionCallbackNoReturn() {
-            @Override
-            public void doInTransactionWithoutResult(TransactionStatus status) {
-                for (StoragePoolVO childDatastore : childDatastores) {
-                    // set the pool state to prepare for maintenance, so that VMs will not migrate to the storagepools in the same cluster
-                    childDatastore.setStatus(StoragePoolStatus.PrepareForMaintenance);
-                    _storagePoolDao.update(childDatastore.getId(), childDatastore);
-                }
-            }
-        });
-        for (Iterator<StoragePoolVO> iteratorChildDatastore = childDatastores.listIterator(); iteratorChildDatastore.hasNext(); ) {
-            DataStore childStore = _dataStoreMgr.getDataStore(iteratorChildDatastore.next().getId(), DataStoreRole.Primary);
-            try {
-                lifeCycle.maintain(childStore);
-            } catch (Exception e) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(String.format("Exception on maintenance preparation of one of the child datastores in datastore cluster %d with error %s", primaryStorageId, e));
-                }
-                // Set to ErrorInMaintenance state of all child storage pools and datastore cluster
-                for (StoragePoolVO childDatastore : childDatastores) {
-                    childDatastore.setStatus(StoragePoolStatus.ErrorInMaintenance);
-                    _storagePoolDao.update(childDatastore.getId(), childDatastore);
-                }
-                datastoreCluster.setStatus(StoragePoolStatus.ErrorInMaintenance);
-                _storagePoolDao.update(datastoreCluster.getId(), datastoreCluster);
-                throw new CloudRuntimeException(String.format("Failed to prepare maintenance mode for datastore cluster %d with error %s %s", primaryStorageId, e.getMessage(), e));
-            }
-        }
-    }
-
     @Override
     @DB
     public PrimaryDataStoreInfo cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException {
@@ -1609,16 +1497,6 @@
         DataStoreProvider provider = _dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName());
         DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
         DataStore store = _dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
-        if (primaryStorage.getPoolType() == StoragePoolType.DatastoreCluster) {
-            primaryStorage.setStatus(StoragePoolStatus.Up);
-            _storagePoolDao.update(primaryStorage.getId(), primaryStorage);
-            //FR41 need to handle when one of the primary stores is unable to cancel the maintenance mode
-            List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(primaryStorageId);
-            for (StoragePoolVO childDatastore : childDatastores) {
-                DataStore childStore = _dataStoreMgr.getDataStore(childDatastore.getId(), DataStoreRole.Primary);
-                lifeCycle.cancelMaintain(childStore);
-            }
-        }
         lifeCycle.cancelMaintain(store);
 
         return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary);
@@ -1983,57 +1861,6 @@
         }
     }
 
-    @Override
-    public boolean isStoragePoolComplaintWithStoragePolicy(List<Volume> volumes, StoragePool pool) throws StorageUnavailableException {
-        if (volumes == null || volumes.isEmpty()) {
-            return false;
-        }
-        List<Pair<Volume, Answer>> answers = new ArrayList<Pair<Volume, Answer>>();
-
-        for (Volume volume : volumes) {
-            String storagePolicyId = null;
-            if (volume.getVolumeType() == Type.ROOT) {
-                Long vmId = volume.getInstanceId();
-                if (vmId != null) {
-                    VMInstanceVO vm = _vmInstanceDao.findByIdIncludingRemoved(vmId);
-                    storagePolicyId = _serviceOfferingDetailsDao.getDetail(vm.getServiceOfferingId(), ApiConstants.STORAGE_POLICY);
-                }
-            } else {
-                storagePolicyId = _diskOfferingDetailsDao.getDetail(volume.getDiskOfferingId(), ApiConstants.STORAGE_POLICY);
-            }
-            if (org.apache.commons.lang.StringUtils.isNotEmpty(storagePolicyId)) {
-                VsphereStoragePolicyVO storagePolicyVO = _vsphereStoragePolicyDao.findById(Long.parseLong(storagePolicyId));
-                List<Long> hostIds = getUpHostsInPool(pool.getId());
-                Collections.shuffle(hostIds);
-
-                if (hostIds == null || hostIds.isEmpty()) {
-                    throw new StorageUnavailableException("Unable to send command to the pool " + pool.getName() + " due to there is no enabled hosts up in this cluster", pool.getId());
-                }
-                try {
-                    StorageFilerTO storageFilerTO = new StorageFilerTO(pool);
-                    CheckDataStoreStoragePolicyComplainceCommand cmd = new CheckDataStoreStoragePolicyComplainceCommand(storagePolicyVO.getPolicyId(), storageFilerTO);
-                    long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostIds.get(0), cmd);
-                    Answer answer = _agentMgr.send(targetHostId, cmd);
-                    answers.add(new Pair<>(volume, answer));
-                } catch (AgentUnavailableException e) {
-                    s_logger.debug("Unable to send storage pool command to " + pool + " via " + hostIds.get(0), e);
-                    throw new StorageUnavailableException("Unable to send command to the pool ", pool.getId());
-                } catch (OperationTimedoutException e) {
-                    s_logger.debug("Failed to process storage pool command to " + pool + " via " + hostIds.get(0), e);
-                    throw new StorageUnavailableException("Failed to process storage command to the pool ", pool.getId());
-                }
-            }
-        }
-        // check cummilative result for all volumes
-        for (Pair<Volume, Answer> answer : answers) {
-            if (!answer.second().getResult()) {
-                s_logger.debug(String.format("Storage pool %s is not compliance with storage policy for volume %s", pool.getUuid(), answer.first().getName()));
-                return false;
-            }
-        }
-        return true;
-    }
-
     private boolean checkPoolforSpace(StoragePool pool, long allocatedSizeWithTemplate, long totalAskingSize) {
         // allocated space includes templates
         StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId());
@@ -2718,15 +2545,6 @@
         return disk;
     }
 
-    @Override
-    public boolean isStoragePoolDatastoreClusterParent(StoragePool pool) {
-        List<StoragePoolVO> childStoragePools = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-        if (childStoragePools != null && !childStoragePools.isEmpty()) {
-            return true;
-        }
-        return false;
-    }
-
     private void setVolumeObjectTOThrottling(VolumeObjectTO volumeTO, final ServiceOffering offering, final DiskOffering diskOffering) {
         volumeTO.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
         volumeTO.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
diff --git a/server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java
index 3e8822e..4ffd7d8 100644
--- a/server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java
+++ b/server/src/main/java/com/cloud/storage/StoragePoolAutomationImpl.java
@@ -117,11 +117,9 @@
                 spes = primaryDataStoreDao.listBy(pool.getDataCenterId(), pool.getPodId(), pool.getClusterId(), ScopeType.CLUSTER);
             }
             for (StoragePoolVO sp : spes) {
-                if (sp.getParent() != pool.getParent() && sp.getId() != pool.getParent()) { // If Datastore cluster is tried to prepare for maintenance then child storage pools are also kept in PrepareForMaintenance mode
-                    if (sp.getStatus() == StoragePoolStatus.PrepareForMaintenance) {
-                        throw new CloudRuntimeException("Only one storage pool in a cluster can be in PrepareForMaintenance mode, " + sp.getId() +
-                                " is already in  PrepareForMaintenance mode ");
-                    }
+                if (sp.getStatus() == StoragePoolStatus.PrepareForMaintenance) {
+                    throw new CloudRuntimeException("Only one storage pool in a cluster can be in PrepareForMaintenance mode, " + sp.getId() +
+                        " is already in  PrepareForMaintenance mode ");
                 }
             }
             StoragePool storagePool = (StoragePool)store;
@@ -321,7 +319,7 @@
                 }
             } else {
                 if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("ModifyStoragePool add succeeded");
+                    s_logger.debug("ModifyStoragePool add secceeded");
                 }
             }
         }
diff --git a/server/src/main/java/com/cloud/storage/TemplateProfile.java b/server/src/main/java/com/cloud/storage/TemplateProfile.java
index b904094..304b652 100644
--- a/server/src/main/java/com/cloud/storage/TemplateProfile.java
+++ b/server/src/main/java/com/cloud/storage/TemplateProfile.java
@@ -52,7 +52,6 @@
     Boolean isDynamicallyScalable;
     TemplateType templateType;
     Boolean directDownload;
-    Boolean deployAsIs;
     Long size;
 
     public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url,
@@ -96,7 +95,7 @@
             Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, List<Long> zoneId,
 
             HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details,
-            Boolean sshKeyEnabled, Long imageStoreId, Boolean isDynamicallyScalable, TemplateType templateType, Boolean directDownload, Boolean deployAsIs) {
+            Boolean sshKeyEnabled, Long imageStoreId, Boolean isDynamicallyScalable, TemplateType templateType, Boolean directDownload) {
         this(templateId,
             userId,
             name,
@@ -123,7 +122,6 @@
         this.isDynamicallyScalable = isDynamicallyScalable;
         this.templateType = templateType;
         this.directDownload = directDownload;
-        this.deployAsIs = deployAsIs;
     }
 
     public Long getTemplateId() {
@@ -333,8 +331,4 @@
     public void setSize(Long size) {
         this.size = size;
     }
-
-    public boolean isDeployAsIs() {
-        return this.deployAsIs;
-    }
 }
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index ad3dd30..b5c33eb 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -30,7 +30,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.dc.Pod;
 import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
 import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
 import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
@@ -1501,9 +1500,8 @@
 
         UserVmVO vm = _userVmDao.findById(vmId);
         VolumeVO exstingVolumeOfVm = null;
-        VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
         List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
-        if (rootVolumesOfVm.size() > 1 && template != null && !template.isDeployAsIs()) {
+        if (rootVolumesOfVm.size() > 1) {
             throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
         } else {
             if (!rootVolumesOfVm.isEmpty()) {
@@ -1778,13 +1776,7 @@
             if (pool.getDataCenterId() != volume.getDataCenterId()) {
                 throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
             }
-            if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-                List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(storageId);
-                Collections.shuffle(childDatastores);
-                volume.setPoolId(childDatastores.get(0).getId());
-            } else {
-                volume.setPoolId(pool.getId());
-            }
+            volume.setPoolId(pool.getId());
         }
 
         if (customId != null) {
@@ -2026,14 +2018,6 @@
 
             DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
             DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
-            Map<String, String> details = new HashMap<String, String>();
-            disk.setDetails(details);
-            if (volume.getPoolId() != null) {
-                StoragePoolVO poolVO = _storagePoolDao.findById(volume.getPoolId());
-                if (poolVO.getParent() != 0L) {
-                    details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
-                }
-            }
 
             DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
 
@@ -2055,34 +2039,6 @@
             // Mark the volume as detached
             _volsDao.detachVolume(volume.getId());
 
-            if (answer != null) {
-                String datastoreName = answer.getContextParam("datastoreName");
-                if (datastoreName != null) {
-                    StoragePoolVO storagePoolVO = _storagePoolDao.findByUuid(datastoreName);
-                    if (storagePoolVO != null) {
-                        VolumeVO volumeVO = _volsDao.findById(volumeId);
-                        volumeVO.setPoolId(storagePoolVO.getId());
-                        _volsDao.update(volumeVO.getId(), volumeVO);
-                    } else {
-                        s_logger.warn(String.format("Unable to find datastore %s while updating the new datastore of the volume %d", datastoreName, volumeId));
-                    }
-                }
-
-                String volumePath = answer.getContextParam("volumePath");
-                if (volumePath != null) {
-                    VolumeVO volumeVO = _volsDao.findById(volumeId);
-                    volumeVO.setPath(volumePath);
-                    _volsDao.update(volumeVO.getId(), volumeVO);
-                }
-
-                String chainInfo = answer.getContextParam("chainInfo");
-                if (chainInfo != null) {
-                    VolumeVO volumeVO = _volsDao.findById(volumeId);
-                    volumeVO.setChainInfo(chainInfo);
-                    _volsDao.update(volumeVO.getId(), volumeVO);
-                }
-            }
-
             // volume.getPoolId() should be null if the VM we are detaching the disk from has never been started before
             if (volume.getPoolId() != null) {
                 DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary);
@@ -2236,14 +2192,6 @@
             throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode.");
         }
 
-        String poolUuid =  destPool.getUuid();
-        if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-            DataCenter dc = _entityMgr.findById(DataCenter.class, vol.getDataCenterId());
-            Pod destPoolPod = _entityMgr.findById(Pod.class, destPool.getPodId());
-
-            destPool = _volumeMgr.findChildDataStoreInDataStoreCluster(dc, destPoolPod, destPool.getClusterId(), null, null, destPool.getId());
-        }
-
         if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) {
             throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName());
         }
@@ -2282,19 +2230,6 @@
                 updateMissingRootDiskController(vm, vol.getChainInfo());
             }
         }
-
-        HypervisorType hypervisorType = _volsDao.getHypervisorType(volumeId);
-        if (hypervisorType.equals(HypervisorType.VMware)) {
-            try {
-                boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolComplaintWithStoragePolicy(Arrays.asList(vol), destPool);
-                if (!isStoragePoolStoragepolicyComplaince) {
-                    throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", poolUuid, vol.getUuid()));
-                }
-            } catch (StorageUnavailableException e) {
-                throw new CloudRuntimeException(String.format("Could not verify storage policy compliance against storage pool %s due to exception %s", destPool.getUuid(), e.getMessage()));
-            }
-        }
-
         DiskOfferingVO newDiskOffering = retrieveAndValidateNewDiskOffering(cmd);
         validateConditionsToReplaceDiskOfferingOfVolume(vol, newDiskOffering, destPool);
         if (vm != null) {
@@ -3092,14 +3027,6 @@
                     details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
                     details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
                 }
-
-                if (volumeToAttach.getPoolId() != null) {
-                    StoragePoolVO poolVO = _storagePoolDao.findById(volumeToAttach.getPoolId());
-                    if (poolVO.getParent() != 0L) {
-                        details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
-                    }
-                }
-
                 _userVmDao.loadDetails(vm);
                 Map<String, String> controllerInfo = new HashMap<String, String>();
                 controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
@@ -3128,13 +3055,7 @@
 
                     if (volumeToAttachStoragePool.isManaged() && volumeToAttach.getPath() == null) {
                         volumeToAttach.setPath(answer.getDisk().getPath());
-                        _volsDao.update(volumeToAttach.getId(), volumeToAttach);
-                    }
 
-                    String chainInfo = answer.getContextParam("chainInfo");
-                    if (chainInfo != null) {
-                        volumeToAttach = _volsDao.findById(volumeToAttach.getId());
-                        volumeToAttach.setChainInfo(chainInfo);
                         _volsDao.update(volumeToAttach.getId(), volumeToAttach);
                     }
                 } else {
diff --git a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index 1eb72e2..35ec665 100755
--- a/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -311,8 +311,7 @@
 
         if (snapshotStrategy == null) {
             s_logger.error("Unable to find snaphot strategy to handle snapshot with id '" + snapshotId + "'");
-            String errorMsg = String.format("Revert snapshot command failed for snapshot with id %d, because this command is supported only for KVM hypervisor", snapshotId);
-            throw new CloudRuntimeException(errorMsg);
+            return null;
         }
 
         boolean result = snapshotStrategy.revertSnapshot(snapshotInfo);
diff --git a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
index be8319c..0d42b76 100644
--- a/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
+++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParams.java
@@ -46,5 +46,4 @@
     boolean isDynamicallyScalable();
     boolean isRoutingType();
     boolean isDirectDownload();
-    boolean isDeployAsIs();
 }
diff --git a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
index e5bc1a3..67b04f7 100644
--- a/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
+++ b/server/src/main/java/com/cloud/storage/upload/params/UploadParamsBase.java
@@ -214,11 +214,6 @@
         return false;
     }
 
-    @Override
-    public boolean isDeployAsIs() {
-        return false;
-    }
-
     void setIso(boolean iso) {
         isIso = iso;
     }
diff --git a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
index c080ffd..80ca469 100644
--- a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
@@ -25,12 +25,6 @@
 
 import javax.inject.Inject;
 
-import com.cloud.configuration.Config;
-import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
-import com.cloud.storage.dao.VMTemplateDetailsDao;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionStatus;
 import org.apache.cloudstack.agent.directdownload.CheckUrlAnswer;
 import org.apache.cloudstack.agent.directdownload.CheckUrlCommand;
 import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
@@ -66,6 +60,7 @@
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.alert.AlertManager;
+import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.dc.dao.DataCenterDao;
@@ -94,6 +89,9 @@
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.EntityManager;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 
 public class HypervisorTemplateAdapter extends TemplateAdapterBase {
@@ -128,10 +126,6 @@
     ResourceManager resourceManager;
     @Inject
     VMTemplateDao templateDao;
-    @Inject
-    private VMTemplateDetailsDao templateDetailsDao;
-    @Inject
-    private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
 
     @Override
     public String getName() {
@@ -247,14 +241,12 @@
 
     private void createTemplateWithinZone(Long zId, TemplateProfile profile, VMTemplateVO template) {
         // find all eligible image stores for this zone scope
-        List<DataStore> imageStores = storeMgr.getImageStoresByScope(new ZoneScope(zId));
+        List<DataStore> imageStores = storeMgr.getImageStoresByScopeExcludingReadOnly(new ZoneScope(zId));
         if (imageStores == null || imageStores.size() == 0) {
             throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
         }
 
         Set<Long> zoneSet = new HashSet<Long>();
-        Collections.shuffle(imageStores);
-        // For private templates choose a random store. TODO - Have a better algorithm based on size, no. of objects, load etc.
         for (DataStore imageStore : imageStores) {
             // skip data stores for a disabled zone
             Long zoneId = imageStore.getScope().getScopeId();
@@ -314,7 +306,7 @@
                     zoneId = profile.getZoneIdList().get(0);
 
                 // find all eligible image stores for this zone scope
-                List<DataStore> imageStores = storeMgr.getImageStoresByScope(new ZoneScope(zoneId));
+                List<DataStore> imageStores = storeMgr.getImageStoresByScopeExcludingReadOnly(new ZoneScope(zoneId));
                 if (imageStores == null || imageStores.size() == 0) {
                     throw new CloudRuntimeException("Unable to find image store to download template " + profile.getTemplate());
                 }
@@ -598,12 +590,6 @@
             Pair<Class<?>, Long> tmplt = new Pair<Class<?>, Long>(VirtualMachineTemplate.class, template.getId());
             _messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, tmplt);
 
-            // Remove template details
-            templateDetailsDao.removeDetails(template.getId());
-
-            // Remove deploy-as-is details (if any)
-            templateDeployAsIsDetailsDao.removeDetails(template.getId());
-
         }
         return success;
 
diff --git a/server/src/main/java/com/cloud/template/TemplateAdapter.java b/server/src/main/java/com/cloud/template/TemplateAdapter.java
index 86dd0d3..c048cea 100644
--- a/server/src/main/java/com/cloud/template/TemplateAdapter.java
+++ b/server/src/main/java/com/cloud/template/TemplateAdapter.java
@@ -72,12 +72,13 @@
 
     boolean delete(TemplateProfile profile);
 
-    TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic,
-                            Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String accountName, Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload,
-                            boolean deployAsIs) throws ResourceAllocationException;
+    TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
+        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String accountName,
+        Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload) throws ResourceAllocationException;
 
-    TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic,
-                            Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable,
-                            TemplateType templateType, boolean directDownload, boolean deployAsIs) throws ResourceAllocationException;
+    TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
+        Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String chksum,
+        Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable,
+        TemplateType templateType, boolean directDownload) throws ResourceAllocationException;
 
 }
diff --git a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
index 8e9bab3..0e88c14 100644
--- a/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
+++ b/server/src/main/java/com/cloud/template/TemplateAdapterBase.java
@@ -23,15 +23,12 @@
 
 import javax.inject.Inject;
 
-import com.cloud.deployasis.DeployAsIsConstants;
 import com.cloud.storage.upload.params.IsoUploadParams;
 import com.cloud.storage.upload.params.TemplateUploadParams;
 import com.cloud.storage.upload.params.UploadParams;
-import com.cloud.vm.VmDetailConstants;
 import org.apache.cloudstack.api.command.user.iso.GetUploadParamsForIsoCmd;
 import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.log4j.Logger;
 
@@ -132,16 +129,16 @@
     @Override
     public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
         Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneId, HypervisorType hypervisorType, String accountName,
-        Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload, boolean deployAsIs) throws ResourceAllocationException {
+        Long domainId, String chksum, Boolean bootable, Map details, boolean directDownload) throws ResourceAllocationException {
         return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId,
-            hypervisorType, chksum, bootable, null, null, details, false, null, false, TemplateType.USER, directDownload, deployAsIs);
+            hypervisorType, chksum, bootable, null, null, details, false, null, false, TemplateType.USER, directDownload);
     }
 
     @Override
     public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url,
         Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, List<Long> zoneIdList, HypervisorType hypervisorType, String chksum,
         Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled, String imageStoreUuid, Boolean isDynamicallyScalable,
-        TemplateType templateType, boolean directDownload, boolean deployAsIs) throws ResourceAllocationException {
+        TemplateType templateType, boolean directDownload) throws ResourceAllocationException {
         //Long accountId = null;
         // parameters verification
 
@@ -170,11 +167,6 @@
             if (requiresHVM == null) {
                 requiresHVM = true;
             }
-            if (deployAsIs) {
-                GuestOS deployAsIsGuestOs = ApiDBUtils.findGuestOSByDisplayName(DeployAsIsConstants.DEFAULT_GUEST_OS_DEPLOY_AS_IS);
-                s_logger.info("Setting default guest OS for deploy-as-is template while the template registration is not completed");
-                guestOSId = deployAsIsGuestOs.getId();
-            }
         }
 
         if (isExtractable == null) {
@@ -265,7 +257,7 @@
         CallContext.current().setEventDetails("Id: " + id + " name: " + name);
         return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, imgfmt, guestOSId, zoneIdList,
             hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details,
-            sshkeyEnabled, null, isDynamicallyScalable, templateType, directDownload, deployAsIs);
+            sshkeyEnabled, null, isDynamicallyScalable, templateType, directDownload);
 
     }
 
@@ -291,23 +283,9 @@
                     + EnumUtils.listValues(HypervisorType.values()).replace("None, ", ""));
         }
 
-        Map details = cmd.getDetails();
-        if (hypervisorType == HypervisorType.VMware) {
-            if (MapUtils.isNotEmpty(details)) {
-                if (details.containsKey(VmDetailConstants.ROOT_DISK_CONTROLLER)) {
-                    s_logger.info("Ignoring the rootDiskController detail provided, as we honour what is defined in the template");
-                    details.remove(VmDetailConstants.ROOT_DISK_CONTROLLER);
-                }
-                if (details.containsKey(VmDetailConstants.NIC_ADAPTER)) {
-                    s_logger.info("Ignoring the nicAdapter detail provided, as we honour what is defined in the template");
-                    details.remove(VmDetailConstants.NIC_ADAPTER);
-                }
-            }
-        }
         return prepare(false, CallContext.current().getCallingUserId(), cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(),
                 cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), zoneId, hypervisorType, cmd.getChecksum(), true,
-                cmd.getTemplateTag(), owner, details, cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER,
-                cmd.isDirectDownload(), cmd.isDeployAsIs());
+                cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), null, cmd.isDynamicallyScalable(), isRouting ? TemplateType.ROUTING : TemplateType.USER, cmd.isDirectDownload());
 
     }
 
@@ -338,7 +316,7 @@
                 params.isExtractable(), params.getFormat(), params.getGuestOSId(), zoneList,
                 params.getHypervisorType(), params.getChecksum(), params.isBootable(), params.getTemplateTag(), owner,
                 params.getDetails(), params.isSshKeyEnabled(), params.getImageStoreUuid(),
-                params.isDynamicallyScalable(), params.isRoutingType() ? TemplateType.ROUTING : TemplateType.USER, params.isDirectDownload(), false);
+                params.isDynamicallyScalable(), params.isRoutingType() ? TemplateType.ROUTING : TemplateType.USER, params.isDirectDownload());
     }
 
     @Override
@@ -380,7 +358,7 @@
 
         return prepare(true, CallContext.current().getCallingUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, cmd.isPasswordEnabled(), true, cmd.getUrl(), cmd.isPublic(),
             cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), zoneList, HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null,
-            owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(), TemplateType.USER, cmd.isDirectDownload(), false);
+            owner, null, false, cmd.getImageStoreUuid(), cmd.isDynamicallyScalable(), TemplateType.USER, cmd.isDirectDownload());
     }
 
     protected VMTemplateVO persistTemplate(TemplateProfile profile, VirtualMachineTemplate.State initialState) {
@@ -389,7 +367,7 @@
             new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.isPublic(), profile.isFeatured(), profile.isExtractable(),
                 profile.getTemplateType(), profile.getUrl(), profile.isRequiresHVM(), profile.getBits(), profile.getAccountId(), profile.getCheckSum(),
                 profile.getDisplayText(), profile.isPasswordEnabled(), profile.getGuestOsId(), profile.isBootable(), profile.getHypervisorType(),
-                profile.getTemplateTag(), profile.getDetails(), profile.isSshKeyEnabled(), profile.IsDynamicallyScalable(), profile.isDirectDownload(), profile.isDeployAsIs());
+                profile.getTemplateTag(), profile.getDetails(), profile.isSshKeyEnabled(), profile.IsDynamicallyScalable(), profile.isDirectDownload());
         template.setState(initialState);
 
         if (profile.isDirectDownload()) {
diff --git a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
index c58b2f1..d5e1038 100755
--- a/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/main/java/com/cloud/template/TemplateManagerImpl.java
@@ -32,7 +32,6 @@
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import com.cloud.agent.api.to.DatadiskTO;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd;
@@ -617,18 +616,6 @@
 
     private void prepareTemplateInOneStoragePool(final VMTemplateVO template, final StoragePoolVO pool) {
         s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId());
-        if (pool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-            List<StoragePoolVO> childDataStores = _poolDao.listChildStoragePoolsInDatastoreCluster(pool.getId());
-            s_logger.debug("Schedule to preload template " + template.getId() + " into child datastores of DataStore cluster: " + pool.getId());
-            for (StoragePoolVO childDataStore :  childDataStores) {
-                prepareTemplateInOneStoragePoolInternal(template, childDataStore);
-            }
-        } else {
-            prepareTemplateInOneStoragePoolInternal(template, pool);
-        }
-    }
-
-    private void prepareTemplateInOneStoragePoolInternal(final VMTemplateVO template, final StoragePoolVO pool) {
         _preloadExecutor.execute(new ManagedContextRunnable() {
             @Override
             protected void runInContext() {
@@ -670,7 +657,7 @@
         VMTemplateStoragePoolVO templateStoragePoolRef = null;
         TemplateDataStoreVO templateStoreRef = null;
 
-        templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId, null);
+        templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
         if (templateStoragePoolRef != null) {
             templateStoragePoolRef.setMarkedForGC(false);
             _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
@@ -710,7 +697,7 @@
                     return null;
                 }
 
-                return _tmpltPoolDao.findByPoolTemplate(poolId, templateId, null);
+                return _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
             } catch (Exception ex) {
                 s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage");
             }
@@ -1022,7 +1009,7 @@
         }
 
         PrimaryDataStore pool = (PrimaryDataStore)_dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
-        TemplateInfo template = _tmplFactory.getTemplateOnPrimaryStorage(templatePoolRef.getTemplateId(), pool, templatePoolRef.getDeploymentOption());
+        TemplateInfo template = _tmplFactory.getTemplate(templatePoolRef.getTemplateId(), pool);
 
         try {
             if (s_logger.isDebugEnabled()) {
@@ -1898,7 +1885,7 @@
         }
         privateTemplate = new VMTemplateVO(nextTemplateId, name, ImageFormat.RAW, isPublic, featured, isExtractable,
                 TemplateType.USER, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description,
-                passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), sshKeyEnabledValue, isDynamicScalingEnabled, false, false);
+                passwordEnabledValue, guestOS.getId(), true, hyperType, templateTag, cmd.getDetails(), sshKeyEnabledValue, isDynamicScalingEnabled, false);
 
         if (sourceTemplateId != null) {
             if (s_logger.isDebugEnabled()) {
@@ -2224,16 +2211,4 @@
     public void setTemplateAdapters(List<TemplateAdapter> adapters) {
         _adapters = adapters;
     }
-
-    @Override
-    public List<DatadiskTO> getTemplateDisksOnImageStore(Long templateId, DataStoreRole role, String configurationId) {
-        TemplateInfo templateObject = _tmplFactory.getTemplate(templateId, role);
-        if (templateObject == null) {
-            String msg = String.format("Could not find template %s downloaded on store with role %s", templateId, role.toString());
-            s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
-        }
-        return _tmpltSvr.getTemplateDatadisksOnImageStore(templateObject, configurationId);
-    }
-
 }
diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
index a931159..ef76176 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -47,12 +47,8 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
-import com.cloud.agent.api.to.deployasis.OVFPropertyTO;
-import com.cloud.deployasis.UserVmDeployAsIsDetailVO;
-import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao;
 import com.cloud.exception.UnsupportedServiceException;
 import com.cloud.hypervisor.Hypervisor;
-import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -83,7 +79,6 @@
 import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
 import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
 import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import com.cloud.agent.api.to.deployasis.OVFNetworkTO;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity;
 import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao;
@@ -110,7 +105,6 @@
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.log4j.Logger;
@@ -261,9 +255,9 @@
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Storage.TemplateType;
-import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.StoragePoolStatus;
+import com.cloud.storage.TemplateOVFPropertyVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateZoneVO;
@@ -274,6 +268,7 @@
 import com.cloud.storage.dao.GuestOSCategoryDao;
 import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.TemplateOVFPropertiesDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
@@ -508,11 +503,7 @@
     @Inject
     private ResourceTagDao resourceTagDao;
     @Inject
-    private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao;
-    @Inject
-    private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
-    @Inject
-    private StorageManager storageMgr;
+    private TemplateOVFPropertiesDao templateOVFPropertiesDao;
 
     private ScheduledExecutorService _executor = null;
     private ScheduledExecutorService _vmIpFetchExecutor = null;
@@ -2508,6 +2499,15 @@
                         }
                     }
                 }
+                for (String detailName : details.keySet()) {
+                    if (detailName.startsWith(ApiConstants.OVF_PROPERTIES)) {
+                        String ovfPropKey = detailName.replace(ApiConstants.OVF_PROPERTIES + "-", "");
+                        TemplateOVFPropertyVO ovfPropertyVO = templateOVFPropertiesDao.findByTemplateAndKey(vmInstance.getTemplateId(), ovfPropKey);
+                        if (ovfPropertyVO != null && ovfPropertyVO.isPassword()) {
+                            details.put(detailName, DBEncryptionUtil.encrypt(details.get(detailName)));
+                        }
+                    }
+                }
                 vmInstance.setDetails(details);
                 _vmDao.saveDetails(vmInstance);
             }
@@ -2899,20 +2899,14 @@
         }
         s_logger.debug("Found no ongoing snapshots on volume of type ROOT, for the vm with id " + vmId);
 
-        List<VolumeVO> volumesToBeDeleted = getVolumesFromIds(cmd);
+        List<VolumeVO> volumes = getVolumesFromIds(cmd);
 
-        checkForUnattachedVolumes(vmId, volumesToBeDeleted);
-        validateVolumes(volumesToBeDeleted);
+        checkForUnattachedVolumes(vmId, volumes);
+        validateVolumes(volumes);
 
         stopVirtualMachine(vmId, VmDestroyForcestop.value());
 
-        if (vm.getHypervisorType() == HypervisorType.VMware) {
-            List<VolumeVO> allVolumes = _volsDao.findByInstance(vm.getId());
-            allVolumes.removeIf(vol -> vol.getVolumeType() == Volume.Type.ROOT);
-            detachVolumesFromVm(allVolumes);
-        } else {
-            detachVolumesFromVm(volumesToBeDeleted);
-        }
+        detachVolumesFromVm(volumes);
 
         UserVm destroyedVm = destroyVm(vmId, expunge);
         if (expunge) {
@@ -2921,7 +2915,7 @@
             }
         }
 
-        deleteVolumesFromVm(volumesToBeDeleted);
+        deleteVolumesFromVm(volumes);
 
         return destroyedVm;
     }
@@ -3313,10 +3307,56 @@
 
         List<HypervisorType> vpcSupportedHTypes = _vpcMgr.getSupportedVpcHypervisors();
         if (networkIdList == null || networkIdList.isEmpty()) {
-            NetworkVO defaultNetwork = getDefaultNetwork(zone, owner, false);
+            NetworkVO defaultNetwork = null;
+
+            // if no network is passed in
+            // Check if default virtual network offering has
+            // Availability=Required. If it's true, search for corresponding
+            // network
+            // * if network is found, use it. If more than 1 virtual network is
+            // found, throw an error
+            // * if network is not found, create a new one and use it
+
+            List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
+            if (requiredOfferings.size() < 1) {
+                throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
+                        + " to automatically create the network as a part of vm creation");
+            }
+
+            if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
+                // get Virtual networks
+                List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated);
+                if (virtualNetworks == null) {
+                    throw new InvalidParameterValueException("No (virtual) networks are found for account " + owner);
+                }
+                if (virtualNetworks.isEmpty()) {
+                    long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
+                    // Validate physical network
+                    PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
+                    if (physicalNetwork == null) {
+                        throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
+                                + requiredOfferings.get(0).getTags());
+                    }
+                    s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
+                    Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
+                            null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null, null,
+                            null);
+                    if (newNetwork != null) {
+                        defaultNetwork = _networkDao.findById(newNetwork.getId());
+                    }
+                } else if (virtualNetworks.size() > 1) {
+                    throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds");
+                } else {
+                    defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
+                }
+            } else {
+                throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
+            }
+
             if (defaultNetwork != null) {
                 networkList.add(defaultNetwork);
             }
+
         } else {
             for (Long networkId : networkIdList) {
                 NetworkVO network = _networkDao.findById(networkId);
@@ -3353,91 +3393,6 @@
                 dataDiskTemplateToDiskOfferingMap, userVmOVFPropertiesMap);
     }
 
-    private NetworkVO getNetworkToAddToNetworkList(VirtualMachineTemplate template, Account owner, HypervisorType hypervisor,
-            List<HypervisorType> vpcSupportedHTypes, Long networkId) {
-        NetworkVO network = _networkDao.findById(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Unable to find network by id " + networkId);
-        }
-        if (network.getVpcId() != null) {
-            // Only ISOs, XenServer, KVM, and VmWare template types are
-            // supported for vpc networks
-            if (template.getFormat() != ImageFormat.ISO && !vpcSupportedHTypes.contains(template.getHypervisorType())) {
-                throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + template.getHypervisorType() + " in vpc network " + network);
-            } else if (template.getFormat() == ImageFormat.ISO && !vpcSupportedHTypes.contains(hypervisor)) {
-                // Only XenServer, KVM, and VMware hypervisors are supported
-                // for vpc networks
-                throw new InvalidParameterValueException("Can't create vm of hypervisor type " + hypervisor + " in vpc network");
-            }
-        }
-
-        _networkModel.checkNetworkPermissions(owner, network);
-
-        // don't allow to use system networks
-        NetworkOffering networkOffering = _entityMgr.findById(NetworkOffering.class, network.getNetworkOfferingId());
-        if (networkOffering.isSystemOnly()) {
-            throw new InvalidParameterValueException("Network id=" + networkId + " is system only and can't be used for vm deployment");
-        }
-        return network;
-    }
-
-    private NetworkVO getDefaultNetwork(DataCenter zone, Account owner, boolean selectAny) throws InsufficientCapacityException, ResourceAllocationException {
-        NetworkVO defaultNetwork = null;
-
-        // if no network is passed in
-        // Check if default virtual network offering has
-        // Availability=Required. If it's true, search for corresponding
-        // network
-        // * if network is found, use it. If more than 1 virtual network is
-        // found, throw an error
-        // * if network is not found, create a new one and use it
-
-        List<NetworkOfferingVO> requiredOfferings = _networkOfferingDao.listByAvailability(Availability.Required, false);
-        if (requiredOfferings.size() < 1) {
-            throw new InvalidParameterValueException("Unable to find network offering with availability=" + Availability.Required
-                    + " to automatically create the network as a part of vm creation");
-        }
-
-        if (requiredOfferings.get(0).getState() == NetworkOffering.State.Enabled) {
-            // get Virtual networks
-            List<? extends Network> virtualNetworks = _networkModel.listNetworksForAccount(owner.getId(), zone.getId(), Network.GuestType.Isolated);
-            if (virtualNetworks == null) {
-                throw new InvalidParameterValueException("No (virtual) networks are found for account " + owner);
-            }
-            if (virtualNetworks.isEmpty()) {
-                defaultNetwork = createDefaultNetworkForAccount(zone, owner, requiredOfferings);
-            } else if (virtualNetworks.size() > 1 && !selectAny) {
-                throw new InvalidParameterValueException("More than 1 default Isolated networks are found for account " + owner + "; please specify networkIds");
-            } else {
-                defaultNetwork = _networkDao.findById(virtualNetworks.get(0).getId());
-            }
-        } else {
-            throw new InvalidParameterValueException("Required network offering id=" + requiredOfferings.get(0).getId() + " is not in " + NetworkOffering.State.Enabled);
-        }
-
-        return defaultNetwork;
-    }
-
-    private NetworkVO createDefaultNetworkForAccount(DataCenter zone, Account owner, List<NetworkOfferingVO> requiredOfferings)
-            throws InsufficientCapacityException, ResourceAllocationException {
-        NetworkVO defaultNetwork = null;
-        long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), requiredOfferings.get(0).getTags(), requiredOfferings.get(0).getTrafficType());
-        // Validate physical network
-        PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId);
-        if (physicalNetwork == null) {
-            throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: "
-                    + requiredOfferings.get(0).getTags());
-        }
-        s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
-        Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
-                null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null, null,
-                null);
-        if (newNetwork != null) {
-            defaultNetwork = _networkDao.findById(newNetwork.getId());
-        }
-        return defaultNetwork;
-    }
-
     private void verifyExtraDhcpOptionsNetwork(Map<String, Map<Integer, String>> dhcpOptionsMap, List<NetworkVO> networkList) throws InvalidParameterValueException {
         if (dhcpOptionsMap != null) {
             for (String networkUuid : dhcpOptionsMap.keySet()) {
@@ -3691,11 +3646,12 @@
             sshPublicKey = pair.getPublicKey();
         }
 
-        LinkedHashMap<String, List<NicProfile>> networkNicMap = new LinkedHashMap<>();
+        List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>();
+
+        LinkedHashMap<String, NicProfile> networkNicMap = new LinkedHashMap<String, NicProfile>();
 
         short defaultNetworkNumber = 0;
         boolean securityGroupEnabled = false;
-        int networkIndex = 0;
         for (NetworkVO network : networkList) {
             if ((network.getDataCenterId() != zone.getId())) {
                 if (!network.isStrechedL2Network()) {
@@ -3733,7 +3689,7 @@
             }
 
             NicProfile profile = new NicProfile(requestedIpPair.getIp4Address(), requestedIpPair.getIp6Address(), requestedIpPair.getMacAddress());
-            profile.setOrderIndex(networkIndex);
+
             if (defaultNetworkNumber == 0) {
                 defaultNetworkNumber++;
                 // if user requested specific ip for default network, add it
@@ -3760,16 +3716,13 @@
                 }
             }
 
+            networks.add(new Pair<NetworkVO, NicProfile>(network, profile));
+
             if (_networkModel.isSecurityGroupSupportedInNetwork(network)) {
                 securityGroupEnabled = true;
             }
-            List<NicProfile> profiles = networkNicMap.get(network.getUuid());
-            if (CollectionUtils.isEmpty(profiles)) {
-                profiles = new ArrayList<>();
-            }
-            profiles.add(profile);
-            networkNicMap.put(network.getUuid(), profiles);
-            networkIndex++;
+
+            networkNicMap.put(network.getUuid(), profile);
         }
 
         if (securityGroupIdList != null && !securityGroupIdList.isEmpty() && !securityGroupEnabled) {
@@ -3900,7 +3853,7 @@
 
     private UserVmVO commitUserVm(final boolean isImport, final DataCenter zone, final Host host, final Host lastHost, final VirtualMachineTemplate template, final String hostName, final String displayName, final Account owner,
                                   final Long diskOfferingId, final Long diskSize, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
-                                  final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
+                                  final long accountId, final long userId, final ServiceOffering offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, NicProfile> networkNicMap,
                                   final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
                                   final Map<String, Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
                                   final Map<String, String> userVmOVFPropertiesMap, final VirtualMachine.PowerState powerState) throws InsufficientCapacityException {
@@ -4007,7 +3960,27 @@
                 }
                 vm.setDetail(VmDetailConstants.DEPLOY_VM, "true");
 
-                persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap);
+                if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) {
+                    for (String key : userVmOVFPropertiesMap.keySet()) {
+                        String detailKey = ApiConstants.OVF_PROPERTIES + "-" + key;
+                        String value = userVmOVFPropertiesMap.get(key);
+
+                        // Sanitize boolean values to expected format and encrypt passwords
+                        if (StringUtils.isNotBlank(value)) {
+                            if (value.equalsIgnoreCase("True")) {
+                                value = "True";
+                            } else if (value.equalsIgnoreCase("False")) {
+                                value = "False";
+                            } else {
+                                TemplateOVFPropertyVO ovfPropertyVO = templateOVFPropertiesDao.findByTemplateAndKey(vm.getTemplateId(), key);
+                                if (ovfPropertyVO.isPassword()) {
+                                    value = DBEncryptionUtil.encrypt(value);
+                                }
+                            }
+                        }
+                        vm.setDetail(detailKey, value);
+                    }
+                }
 
                 _vmDao.saveDetails(vm);
                 if (!isImport) {
@@ -4052,42 +4025,9 @@
         });
     }
 
-    /**
-     * take the properties and set them on the vm.
-     * consider should we be complete, and make sure all default values are copied as well if known?
-     * I.E. iterate over the template details as well to copy any that are not defined yet.
-     */
-    private void persistVMDeployAsIsProperties(UserVmVO vm, Map<String, String> userVmOVFPropertiesMap) {
-        if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) {
-            for (String key : userVmOVFPropertiesMap.keySet()) {
-                String detailKey = key;
-                String value = userVmOVFPropertiesMap.get(key);
-
-                // Sanitize boolean values to expected format and encrypt passwords
-                if (StringUtils.isNotBlank(value)) {
-                    if (value.equalsIgnoreCase("True")) {
-                        value = "True";
-                    } else if (value.equalsIgnoreCase("False")) {
-                        value = "False";
-                    } else {
-                        OVFPropertyTO propertyTO = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key);
-                        if (propertyTO != null && propertyTO.isPassword()) {
-                            value = DBEncryptionUtil.encrypt(value);
-                        }
-                    }
-                }
-                if (s_logger.isTraceEnabled()) {
-                    s_logger.trace(String.format("setting property '%s' as '%s' with value '%s'", key, detailKey, value));
-                }
-                UserVmDeployAsIsDetailVO detail = new UserVmDeployAsIsDetailVO(vm.getId(), detailKey, value);
-                userVmDeployAsIsDetailsDao.persist(detail);
-            }
-        }
-    }
-
     private UserVmVO commitUserVm(final DataCenter zone, final VirtualMachineTemplate template, final String hostName, final String displayName, final Account owner,
             final Long diskOfferingId, final Long diskSize, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
-            final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, List<NicProfile>> networkNicMap,
+            final long accountId, final long userId, final ServiceOfferingVO offering, final boolean isIso, final String sshPublicKey, final LinkedHashMap<String, NicProfile> networkNicMap,
             final long id, final String instanceName, final String uuidName, final HypervisorType hypervisorType, final Map<String, String> customParameters, final Map<String,
             Map<Integer, String>> extraDhcpOptionMap, final Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
             Map<String, String> userVmOVFPropertiesMap) throws InsufficientCapacityException {
@@ -4416,7 +4356,7 @@
             if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
                 final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText();
                 boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
-                String destHostname = VirtualMachineManager.getHypervisorHostname(dest.getHost() != null ? dest.getHost().getName() : "");
+                String destHostname = VirtualMachineManager.getHypervisorHostname(dest.getHost().getName());
                 List<String[]> vmData = _networkModel.generateVmData(vm.getUserData(), serviceOffering, vm.getDataCenterId(), vm.getInstanceName(), vm.getHostName(), vm.getId(),
                         vm.getUuid(), defaultNic.getIPv4Address(), vm.getDetail(VmDetailConstants.SSH_PUBLIC_KEY), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows, destHostname);
                 String vmName = vm.getInstanceName();
@@ -5185,11 +5125,6 @@
             throw new InvalidParameterValueException("Unable to use template " + templateId);
         }
 
-        // Bootmode and boottype are not supported on VMWare dpeloy-as-is templates (since 4.15)
-        if (template.isDeployAsIs() && (cmd.getBootMode() != null || cmd.getBootType() != null)) {
-            throw new InvalidParameterValueException("Boot type and boot mode are not supported on VMware, as we honour what is defined in the template.");
-        }
-
         Long diskOfferingId = cmd.getDiskOfferingId();
         DiskOffering diskOffering = null;
         if (diskOfferingId != null) {
@@ -5208,12 +5143,6 @@
             }
         }
 
-        List<Long> networkIds = cmd.getNetworkIds();
-        LinkedHashMap<Integer, Long> userVmNetworkMap = getVmOvfNetworkMapping(zone, owner, template, cmd.getVmNetworkMap());
-        if (MapUtils.isNotEmpty(userVmNetworkMap)) {
-            networkIds = new ArrayList<>(userVmNetworkMap.values());
-        }
-
         String ipAddress = cmd.getIpAddress();
         String ip6Address = cmd.getIp6Address();
         String macAddress = cmd.getMacAddress();
@@ -5228,9 +5157,9 @@
         Boolean displayVm = cmd.isDisplayVm();
         String keyboard = cmd.getKeyboard();
         Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap = cmd.getDataDiskTemplateToDiskOfferingMap();
-        Map<String, String> userVmOVFProperties = cmd.getVmProperties();
+        Map<String, String> userVmOVFProperties = cmd.getVmOVFProperties();
         if (zone.getNetworkType() == NetworkType.Basic) {
-            if (networkIds != null) {
+            if (cmd.getNetworkIds() != null) {
                 throw new InvalidParameterValueException("Can't specify network Ids in Basic zone");
             } else {
                 vm = createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, getSecurityGroupIdList(cmd), owner, name, displayName, diskOfferingId,
@@ -5240,7 +5169,7 @@
             }
         } else {
             if (zone.isSecurityGroupEnabled())  {
-                vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd), owner, name,
+                vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), getSecurityGroupIdList(cmd), owner, name,
                         displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
                         cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
                         dataDiskTemplateToDiskOfferingMap, userVmOVFProperties);
@@ -5249,7 +5178,7 @@
                 if (cmd.getSecurityGroupIdList() != null && !cmd.getSecurityGroupIdList().isEmpty()) {
                     throw new InvalidParameterValueException("Can't create vm with security groups; security group feature is not enabled per zone");
                 }
-                vm = createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, name, displayName, diskOfferingId, size, group,
+                vm = createAdvancedVirtualMachine(zone, serviceOffering, template, cmd.getNetworkIds(), owner, name, displayName, diskOfferingId, size, group,
                         cmd.getHypervisor(), cmd.getHttpMethod(), userData, sshKeyPairName, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, cmd.getAffinityGroupIdList(), cmd.getDetails(),
                         cmd.getCustomId(), cmd.getDhcpOptionsMap(), dataDiskTemplateToDiskOfferingMap, userVmOVFProperties);
             }
@@ -5627,12 +5556,6 @@
         }
 
         checkDestinationHypervisorType(destPool, vm);
-        if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) {
-            DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId());
-            Pod destPoolPod = _entityMgr.findById(Pod.class, destPool.getPodId());
-
-            destPool = volumeMgr.findChildDataStoreInDataStoreCluster(dc, destPoolPod, destPool.getClusterId(), null, null, destPool.getId());
-        }
 
         _itMgr.storageMigration(vm.getUuid(), destPool);
         return _vmDao.findById(vm.getId());
@@ -6162,17 +6085,6 @@
                     }
                     volToPoolObjectMap.put(Long.valueOf(volume.getId()), Long.valueOf(pool.getId()));
                 }
-                HypervisorType hypervisorType = _volsDao.getHypervisorType(volume.getId());
-                if (hypervisorType.equals(HypervisorType.VMware)) {
-                    try {
-                        boolean isStoragePoolStoragepolicyComplaince = storageMgr.isStoragePoolComplaintWithStoragePolicy(Arrays.asList(volume), pool);
-                        if (!isStoragePoolStoragepolicyComplaince) {
-                            throw new CloudRuntimeException(String.format("Storage pool %s is not storage policy compliance with the volume %s", pool.getUuid(), volume.getUuid()));
-                        }
-                    } catch (StorageUnavailableException e) {
-                        throw new CloudRuntimeException(String.format("Could not verify storage policy compliance against storage pool %s due to exception %s", pool.getUuid(), e.getMessage()));
-                    }
-                }
             }
         }
 
@@ -6724,47 +6636,6 @@
         return _itMgr.restoreVirtualMachine(vm.getId(), newTemplateId);
     }
 
-    private VMTemplateVO getRestoreVirtualMachineTemplate(Account caller, Long newTemplateId, List<VolumeVO> rootVols, UserVmVO vm) {
-        VMTemplateVO template = null;
-        if (CollectionUtils.isNotEmpty(rootVols)) {
-            VolumeVO root = rootVols.get(0);
-            Long templateId = root.getTemplateId();
-            boolean isISO = false;
-            if (templateId == null) {
-                // Assuming that for a vm deployed using ISO, template ID is set to NULL
-                isISO = true;
-                templateId = vm.getIsoId();
-            }
-            //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
-            if (newTemplateId != null) {
-                template = _templateDao.findById(newTemplateId);
-                _accountMgr.checkAccess(caller, null, true, template);
-                if (isISO) {
-                    if (!template.getFormat().equals(ImageFormat.ISO)) {
-                        throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
-                    }
-                } else {
-                    if (template.getFormat().equals(ImageFormat.ISO)) {
-                        throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
-                    }
-                }
-            } else {
-                if (isISO && templateId == null) {
-                    throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
-                }
-                template = _templateDao.findById(templateId);
-                if (template == null) {
-                    InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
-                    ex.addProxyObject(vm.getUuid(), "vmId");
-                    ex.addProxyObject(root.getUuid(), "volumeId");
-                    throw ex;
-                }
-            }
-        }
-
-        return template;
-    }
-
     @Override
     public UserVm restoreVirtualMachine(final Account caller, final long vmId, final Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
         Long userId = caller.getId();
@@ -6790,138 +6661,160 @@
             needRestart = true;
         }
 
-        VMTemplateVO currentTemplate = _templateDao.findById(vm.getTemplateId());
         List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
         if (rootVols.isEmpty()) {
             InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid());
             ex.addProxyObject(vm.getUuid(), "vmId");
             throw ex;
         }
-        if (rootVols.size() > 1 && currentTemplate != null && !currentTemplate.isDeployAsIs()) {
+        if (rootVols.size() > 1) {
             InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid());
             ex.addProxyObject(vm.getUuid(), "vmId");
             throw ex;
         }
-
-        // If target VM has associated VM snapshots then don't allow restore of VM
-        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
-        if (vmSnapshots.size() > 0) {
-            throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
-        }
-
-        VMTemplateVO template = getRestoreVirtualMachineTemplate(caller, newTemplateId, rootVols, vm);
-        checkRestoreVmFromTemplate(vm, template);
-
-        if (needRestart) {
-            try {
-                _itMgr.stop(vm.getUuid());
-            } catch (ResourceUnavailableException e) {
-                s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
-                CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
-                ex.addProxyObject(vm.getUuid(), "vmId");
-                throw ex;
+        VolumeVO root = rootVols.get(0);
+        if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
+            Long templateId = root.getTemplateId();
+            boolean isISO = false;
+            if (templateId == null) {
+                // Assuming that for a vm deployed using ISO, template ID is set to NULL
+                isISO = true;
+                templateId = vm.getIsoId();
             }
-        }
 
-        List<Volume> newVols = new ArrayList<>();
-        for (VolumeVO root : rootVols) {
-            if ( !Volume.State.Allocated.equals(root.getState()) || newTemplateId != null ){
-                Long templateId = root.getTemplateId();
-                boolean isISO = false;
-                if (templateId == null) {
-                    // Assuming that for a vm deployed using ISO, template ID is set to NULL
-                    isISO = true;
-                    templateId = vm.getIsoId();
-                }
+            // If target VM has associated VM snapshots then don't allow restore of VM
+            List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
+            if (vmSnapshots.size() > 0) {
+                throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
+            }
 
-                /* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
-                Volume newVol = null;
-                if (newTemplateId != null) {
-                    if (isISO) {
-                        newVol = volumeMgr.allocateDuplicateVolume(root, null);
-                        vm.setIsoId(newTemplateId);
-                        vm.setGuestOSId(template.getGuestOSId());
-                        vm.setTemplateId(newTemplateId);
-                        _vmDao.update(vmId, vm);
-                    } else {
-                        newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
-                        vm.setGuestOSId(template.getGuestOSId());
-                        vm.setTemplateId(newTemplateId);
-                        _vmDao.update(vmId, vm);
+            VMTemplateVO template = null;
+            //newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
+            if (newTemplateId != null) {
+                template = _templateDao.findById(newTemplateId);
+                _accountMgr.checkAccess(caller, null, true, template);
+                if (isISO) {
+                    if (!template.getFormat().equals(ImageFormat.ISO)) {
+                        throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
                     }
                 } else {
+                    if (template.getFormat().equals(ImageFormat.ISO)) {
+                        throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
+                    }
+                }
+            } else {
+                if (isISO && templateId == null) {
+                    throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
+                }
+                template = _templateDao.findById(templateId);
+                if (template == null) {
+                    InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    ex.addProxyObject(root.getUuid(), "volumeId");
+                    throw ex;
+                }
+            }
+
+            checkRestoreVmFromTemplate(vm, template);
+
+            if (needRestart) {
+                try {
+                    _itMgr.stop(vm.getUuid());
+                } catch (ResourceUnavailableException e) {
+                    s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
+                    CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    throw ex;
+                }
+            }
+
+            /* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
+            Volume newVol = null;
+            if (newTemplateId != null) {
+                if (isISO) {
                     newVol = volumeMgr.allocateDuplicateVolume(root, null);
+                    vm.setIsoId(newTemplateId);
+                    vm.setGuestOSId(template.getGuestOSId());
+                    vm.setTemplateId(newTemplateId);
+                    _vmDao.update(vmId, vm);
+                } else {
+                    newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
+                    vm.setGuestOSId(template.getGuestOSId());
+                    vm.setTemplateId(newTemplateId);
+                    _vmDao.update(vmId, vm);
                 }
-                newVols.add(newVol);
+            } else {
+                newVol = volumeMgr.allocateDuplicateVolume(root, null);
+            }
 
-                // 1. Save usage event and update resource count for user vm volumes
-                _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
-                _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
-                // 2. Create Usage event for the newly created volume
-                UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
-                _usageEventDao.persist(usageEvent);
+            // 1. Save usage event and update resource count for user vm volumes
+            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
+            _resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
+            // 2. Create Usage event for the newly created volume
+            UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
+            _usageEventDao.persist(usageEvent);
 
-                handleManagedStorage(vm, root);
+            handleManagedStorage(vm, root);
 
-                _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
+            _volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
 
-                // Detach, destroy and create the usage event for the old root volume.
-                _volsDao.detachVolume(root.getId());
-                volumeMgr.destroyVolume(root);
+            // Detach, destroy and create the usage event for the old root volume.
+            _volsDao.detachVolume(root.getId());
+            volumeMgr.destroyVolume(root);
 
-                // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
-                if (vm.getHypervisorType() == HypervisorType.VMware) {
-                    VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
-                    if (volumeInStorage != null) {
-                        s_logger.info("Expunging volume " + root.getId() + " from primary data store");
-                        AsyncCallFuture<VolumeApiResult> future = _volService.expungeVolumeAsync(volFactory.getVolume(root.getId()));
-                        try {
-                            future.get();
-                        } catch (Exception e) {
-                            s_logger.debug("Failed to expunge volume:" + root.getId(), e);
-                        }
+            // For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
+            if (vm.getHypervisorType() == HypervisorType.VMware) {
+                VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
+                if (volumeInStorage != null) {
+                    s_logger.info("Expunging volume " + root.getId() + " from primary data store");
+                    AsyncCallFuture<VolumeApiResult> future = _volService.expungeVolumeAsync(volFactory.getVolume(root.getId()));
+                    try {
+                        future.get();
+                    } catch (Exception e) {
+                        s_logger.debug("Failed to expunge volume:" + root.getId(), e);
                     }
                 }
             }
-        }
 
-        Map<VirtualMachineProfile.Param, Object> params = null;
-        String password = null;
+            Map<VirtualMachineProfile.Param, Object> params = null;
+            String password = null;
 
-        if (template.isEnablePassword()) {
-            password = _mgr.generateRandomPassword();
-            boolean result = resetVMPasswordInternal(vmId, password);
-            if (!result) {
-                throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
+            if (template.isEnablePassword()) {
+                password = _mgr.generateRandomPassword();
+                boolean result = resetVMPasswordInternal(vmId, password);
+                if (!result) {
+                    throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
+                }
+                vm.setPassword(password);
             }
-            vm.setPassword(password);
-        }
-        if (needRestart) {
-            try {
-                if (vm.getDetail(VmDetailConstants.PASSWORD) != null) {
-                    params = new HashMap<>();
-                    params.put(VirtualMachineProfile.Param.VmPassword, password);
-                }
-                _itMgr.start(vm.getUuid(), params);
-                vm = _vmDao.findById(vmId);
-                if (template.isEnablePassword()) {
-                    // this value is not being sent to the backend; need only for api
-                    // display purposes
-                    vm.setPassword(password);
-                    if (vm.isUpdateParameters()) {
-                        vm.setUpdateParameters(false);
-                        _vmDao.loadDetails(vm);
-                        if (vm.getDetail(VmDetailConstants.PASSWORD) != null) {
-                            userVmDetailsDao.removeDetail(vm.getId(), VmDetailConstants.PASSWORD);
-                        }
-                        _vmDao.update(vm.getId(), vm);
+
+            if (needRestart) {
+                try {
+                    if (vm.getDetail(VmDetailConstants.PASSWORD) != null) {
+                        params = new HashMap<VirtualMachineProfile.Param, Object>();
+                        params.put(VirtualMachineProfile.Param.VmPassword, password);
                     }
+                    _itMgr.start(vm.getUuid(), params);
+                    vm = _vmDao.findById(vmId);
+                    if (template.isEnablePassword()) {
+                        // this value is not being sent to the backend; need only for api
+                        // display purposes
+                        vm.setPassword(password);
+                        if (vm.isUpdateParameters()) {
+                            vm.setUpdateParameters(false);
+                            _vmDao.loadDetails(vm);
+                            if (vm.getDetail(VmDetailConstants.PASSWORD) != null) {
+                                userVmDetailsDao.removeDetail(vm.getId(), VmDetailConstants.PASSWORD);
+                            }
+                            _vmDao.update(vm.getId(), vm);
+                        }
+                    }
+                } catch (Exception e) {
+                    s_logger.debug("Unable to start VM " + vm.getUuid(), e);
+                    CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
+                    ex.addProxyObject(vm.getUuid(), "vmId");
+                    throw ex;
                 }
-            } catch (Exception e) {
-                s_logger.debug("Unable to start VM " + vm.getUuid(), e);
-                CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
-                ex.addProxyObject(vm.getUuid(), "vmId");
-                throw ex;
             }
         }
 
@@ -7388,42 +7281,4 @@
             }
         }
     }
-
-    private LinkedHashMap<Integer, Long> getVmOvfNetworkMapping(DataCenter zone, Account owner, VirtualMachineTemplate template, Map<Integer, Long> vmNetworkMapping) throws InsufficientCapacityException, ResourceAllocationException {
-        LinkedHashMap<Integer, Long> mapping = new LinkedHashMap<>();
-        if (ImageFormat.OVA.equals(template.getFormat())) {
-            List<OVFNetworkTO> OVFNetworkTOList =
-                    templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(template.getId());
-            if (CollectionUtils.isNotEmpty(OVFNetworkTOList)) {
-                Network lastMappedNetwork = null;
-                for (OVFNetworkTO OVFNetworkTO : OVFNetworkTOList) {
-                    Long networkId = vmNetworkMapping.get(OVFNetworkTO.getInstanceID());
-                    if (networkId == null && lastMappedNetwork == null) {
-                        lastMappedNetwork = getNetworkForOvfNetworkMapping(zone, owner);
-                    }
-                    if (networkId == null) {
-                        networkId = lastMappedNetwork.getId();
-                    }
-                    mapping.put(OVFNetworkTO.getInstanceID(), networkId);
-                }
-            }
-        }
-        return mapping;
-    }
-
-    private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) throws InsufficientCapacityException, ResourceAllocationException {
-        Network network = null;
-        if (zone.isSecurityGroupEnabled()) {
-            network = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId());
-            if (network == null) {
-                throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid());
-            }
-        } else {
-            network = getDefaultNetwork(zone, owner, true);
-            if (network == null) {
-                throw new InvalidParameterValueException(String.format("Default network not found for zone ID: %s and account ID: %s", zone.getUuid(), owner.getUuid()));
-            }
-        }
-        return network;
-    }
-}
+}
\ No newline at end of file
diff --git a/server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java b/server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
index dcbc965..a05c4b9 100644
--- a/server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/direct/download/DirectDownloadManagerImpl.java
@@ -263,13 +263,13 @@
 
         Answer answer = sendDirectDownloadCommand(cmd, template, poolId, host);
 
-        VMTemplateStoragePoolVO sPoolRef = vmTemplatePoolDao.findByPoolTemplate(poolId, templateId, null);
+        VMTemplateStoragePoolVO sPoolRef = vmTemplatePoolDao.findByPoolTemplate(poolId, templateId);
         if (sPoolRef == null) {
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug("Not found (templateId:" + templateId + " poolId: " + poolId + ") in template_spool_ref, persisting it");
             }
             DirectDownloadAnswer ans = (DirectDownloadAnswer) answer;
-            sPoolRef = new VMTemplateStoragePoolVO(poolId, templateId, null);
+            sPoolRef = new VMTemplateStoragePoolVO(poolId, templateId);
             sPoolRef.setDownloadPercent(100);
             sPoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
             sPoolRef.setState(ObjectInDataStoreStateMachine.State.Ready);
diff --git a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
index 532f5f9..26f8675 100644
--- a/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/vm/UnmanagedVMsManagerImpl.java
@@ -103,6 +103,7 @@
 import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.Storage;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.VMTemplateStoragePoolVO;
 import com.cloud.storage.VMTemplateVO;
@@ -490,22 +491,23 @@
         final String dsPath = disk.getDatastorePath();
         final String dsType = disk.getDatastoreType();
         final String dsName = disk.getDatastoreName();
-        if (dsType != null) {
-            List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath);
+        if (dsType.equals("VMFS")) {
+            List<StoragePoolVO> pools = primaryDataStoreDao.listPoolsByCluster(cluster.getId());
+            pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId()));
             for (StoragePool pool : pools) {
-                if (pool.getDataCenterId() == zone.getId() &&
-                        (pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId()))) {
+                if (pool.getPoolType() != Storage.StoragePoolType.VMFS) {
+                    continue;
+                }
+                if (pool.getPath().endsWith(dsName)) {
                     storagePool = pool;
                     break;
                 }
             }
-        }
-
-        if (storagePool == null) {
-            List<StoragePoolVO> pools = primaryDataStoreDao.listPoolsByCluster(cluster.getId());
-            pools.addAll(primaryDataStoreDao.listByDataCenterId(zone.getId()));
+        } else {
+            List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(dsHost, dsPath);
             for (StoragePool pool : pools) {
-                if (pool.getPath().endsWith(dsName)) {
+                if (pool.getDataCenterId() == zone.getId() &&
+                        (pool.getClusterId() == null || pool.getClusterId().equals(cluster.getId()))) {
                     storagePool = pool;
                     break;
                 }
diff --git a/server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java b/server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
index d4cbf91..a6b33ed 100755
--- a/server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
+++ b/server/src/test/java/com/cloud/api/query/dao/TemplateJoinDaoImplTest.java
@@ -115,4 +115,5 @@
         ReflectionTestUtils.setField(template, "detailName", detailName);
         ReflectionTestUtils.setField(template, "detailValue", detailValue);
     }
+
 }
\ No newline at end of file
diff --git a/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java b/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
index 47180cd..bd21643 100755
--- a/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
+++ b/server/src/test/java/com/cloud/template/TemplateManagerImplTest.java
@@ -119,7 +119,6 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.anyLong;
@@ -288,7 +287,7 @@
 
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(mockTemplateStore);
 
         doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());
 
@@ -310,7 +309,7 @@
 
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(null);
         when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(null);
 
         VMTemplateStoragePoolVO returnObject = templateManager.prepareTemplateForCreate(mockTemplate, (StoragePool) mockPrimaryDataStore);
@@ -333,7 +332,7 @@
 
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(null);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(null);
         when(templateDataStoreDao.findByTemplateZoneDownloadStatus(202l, 1l, VMTemplateStorageResourceAssoc.Status.DOWNLOADED)).thenReturn(mockTemplateDataStore);
         when(storagePoolHostDao.listByHostStatus(2l, Status.Up)).thenReturn(null);
 
@@ -362,7 +361,7 @@
         when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(mockTemplateStore);
         when(primaryDataStoreDao.findById(anyLong())).thenReturn(mockPool);
 
         doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());
@@ -391,7 +390,7 @@
         when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(mockTemplateStore);
         when(primaryDataStoreDao.findById(anyLong())).thenReturn(mockPool);
 
         doNothing().when(mockTemplateStore).setMarkedForGC(anyBoolean());
@@ -433,7 +432,7 @@
         when(vmTemplateDao.findById(anyLong())).thenReturn(mockTemplate);
         when(dataStoreManager.getPrimaryDataStore(anyLong())).thenReturn(mockPrimaryDataStore);
         when(vmTemplateDao.findById(anyLong(), anyBoolean())).thenReturn(mockTemplate);
-        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong(), nullable(String.class))).thenReturn(mockTemplateStore);
+        when(vmTemplatePoolDao.findByPoolTemplate(anyLong(), anyLong())).thenReturn(mockTemplateStore);
         when(primaryDataStoreDao.findById(2l)).thenReturn(mockPool1);
         when(primaryDataStoreDao.findById(3l)).thenReturn(mockPool2);
         when(primaryDataStoreDao.findById(4l)).thenReturn(mockPool3);
diff --git a/server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java b/server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java
index d356570..e73c0c6 100644
--- a/server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java
+++ b/server/src/test/java/com/cloud/vm/DeploymentPlanningManagerImplTest.java
@@ -29,8 +29,6 @@
 import javax.naming.ConfigurationException;
 
 import com.cloud.host.Host;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.VMTemplateDao;
 import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -143,9 +141,6 @@
     @Inject
     UserVmDetailsDao vmDetailsDao;
 
-    @Inject
-    VMTemplateDao templateDao;
-
     @Mock
     Host host;
 
@@ -167,10 +162,6 @@
         Mockito.when(_plannerHostReserveDao.findById(Matchers.anyLong())).thenReturn(reservationVO);
         Mockito.when(_affinityGroupVMMapDao.countAffinityGroupsForVm(Matchers.anyLong())).thenReturn(0L);
 
-        VMTemplateVO template = Mockito.mock(VMTemplateVO.class);
-        Mockito.when(template.isDeployAsIs()).thenReturn(false);
-        Mockito.when(templateDao.findById(Mockito.anyLong())).thenReturn(template);
-
         VMInstanceVO vm = new VMInstanceVO();
         Mockito.when(vmProfile.getVirtualMachine()).thenReturn(vm);
 
@@ -465,11 +456,6 @@
             return Mockito.mock(HostGpuGroupsDao.class);
         }
 
-        @Bean
-        public VMTemplateDao vmTemplateDao() {
-            return Mockito.mock(VMTemplateDao.class);
-        }
-
         public static class Library implements TypeFilter {
 
             @Override
diff --git a/server/src/test/resources/createNetworkOffering.xml b/server/src/test/resources/createNetworkOffering.xml
index 55343ef..8dee0e8 100644
--- a/server/src/test/resources/createNetworkOffering.xml
+++ b/server/src/test/resources/createNetworkOffering.xml
@@ -60,5 +60,4 @@
     <bean id="networkOfferingDetailsDaoImpl" class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />

     <bean id="vMTemplateZoneDaoImpl" class="com.cloud.storage.dao.VMTemplateZoneDaoImpl" />

     <bean id="indirectAgentLBImpl" class="org.apache.cloudstack.agent.lb.IndirectAgentLBServiceImpl" />

-    <bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" />

 </beans>

diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 03eba4a..863376d 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -190,7 +190,6 @@
     private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
     private static final String VOLUME_ROOT_DIR = "volumes";
     private static final String POST_UPLOAD_KEY_LOCATION = "/etc/cloudstack/agent/ms-psk";
-    private static final String ORIGINAL_FILE_EXTENSION = ".orig";
 
     private static final Map<String, String> updatableConfigData = Maps.newHashMap();
     static {
@@ -392,7 +391,6 @@
 
     public Answer execute(GetDatadisksCommand cmd) {
         DataTO srcData = cmd.getData();
-        String configurationId = cmd.getConfigurationId();
         TemplateObjectTO template = (TemplateObjectTO)srcData;
         DataStoreTO srcStore = srcData.getDataStore();
         if (!(srcStore instanceof NfsTO)) {
@@ -437,7 +435,7 @@
 
             Script command = new Script("cp", _timeout, s_logger);
             command.add(ovfFilePath);
-            command.add(ovfFilePath + ORIGINAL_FILE_EXTENSION);
+            command.add(ovfFilePath + ".orig");
             String result = command.execute();
             if (result != null) {
                 String msg = "Unable to rename original OVF, error msg: " + result;
@@ -447,7 +445,7 @@
             s_logger.debug("Reading OVF " + ovfFilePath + " to retrive the number of disks present in OVA");
             OVFHelper ovfHelper = new OVFHelper();
 
-            List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfoFromFile(ovfFilePath, configurationId);
+            List<DatadiskTO> disks = ovfHelper.getOVFVolumeInfo(ovfFilePath);
             return new GetDatadisksAnswer(disks);
         } catch (Exception e) {
             String msg = "Get Datadisk Template Count failed due to " + e.getMessage();
@@ -505,7 +503,7 @@
                         throw new Exception(msg);
                     }
                     command = new Script("cp", _timeout, s_logger);
-                    command.add(ovfFilePath + ORIGINAL_FILE_EXTENSION);
+                    command.add(ovfFilePath + ".orig");
                     command.add(newTmplDirAbsolute);
                     result = command.execute();
                     if (result != null) {
@@ -519,7 +517,7 @@
             // Create OVF for the disk
             String newOvfFilePath = newTmplDirAbsolute + File.separator + ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1);
             OVFHelper ovfHelper = new OVFHelper();
-            ovfHelper.rewriteOVFFileForSingleDisk(ovfFilePath + ORIGINAL_FILE_EXTENSION, newOvfFilePath, diskName);
+            ovfHelper.rewriteOVFFile(ovfFilePath + ".orig", newOvfFilePath, diskName);
 
             postCreatePrivateTemplate(newTmplDirAbsolute, templateId, templateUniqueName, physicalSize, virtualSize);
             writeMetaOvaForTemplate(newTmplDirAbsolute, ovfFilePath.substring(ovfFilePath.lastIndexOf(File.separator) + 1), diskName, templateUniqueName, physicalSize);
diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
index 7ce252a..c31bc9b 100644
--- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -37,7 +37,7 @@
 
 import javax.naming.ConfigurationException;
 
-import com.cloud.agent.api.to.OVFInformationTO;
+import com.cloud.agent.api.storage.OVFPropertyTO;
 import com.cloud.storage.template.Processor;
 import com.cloud.storage.template.S3TemplateDownloader;
 import com.cloud.storage.template.TemplateDownloader;
@@ -62,6 +62,7 @@
 import org.apache.cloudstack.storage.NfsMountManagerImpl.PathParser;
 import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
 import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.storage.DownloadAnswer;
@@ -126,7 +127,7 @@
         private long templatePhysicalSize;
         private final long id;
         private final ResourceType resourceType;
-        private OVFInformationTO ovfInformationTO;
+        private List<OVFPropertyTO> ovfProperties;
 
         public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
                 String installPathPrefix, ResourceType resourceType) {
@@ -222,12 +223,12 @@
             this.checksum = checksum;
         }
 
-        public OVFInformationTO getOvfInformationTO() {
-            return ovfInformationTO;
+        public List<OVFPropertyTO> getOvfProperties() {
+            return ovfProperties;
         }
 
-        public void setOvfInformationTO(OVFInformationTO ovfInformationTO) {
-            this.ovfInformationTO = ovfInformationTO;
+        public void setOvfProperties(List<OVFPropertyTO> ovfProperties) {
+            this.ovfProperties = ovfProperties;
         }
     }
 
@@ -508,7 +509,7 @@
         while (en.hasNext()) {
             Processor processor = en.next();
 
-            FormatInfo info;
+            FormatInfo info = null;
             try {
                 info = processor.process(resourcePath, null, templateName, this._processTimeout);
             } catch (InternalErrorException e) {
@@ -522,8 +523,8 @@
                 }
                 dnld.setTemplatesize(info.virtualSize);
                 dnld.setTemplatePhysicalSize(info.size);
-                if (info.ovfInformationTO != null) {
-                    dnld.setOvfInformationTO(info.ovfInformationTO);
+                if (CollectionUtils.isNotEmpty(info.ovfProperties)) {
+                    dnld.setOvfProperties(info.ovfProperties);
                 }
                 break;
             }
@@ -825,8 +826,8 @@
             answer =
                     new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
                             getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
-            if (dj.getOvfInformationTO() != null) {
-                answer.setOvfInformationTO(dj.getOvfInformationTO());
+            if (CollectionUtils.isNotEmpty(dj.getOvfProperties())) {
+                answer.setOvfProperties(dj.getOvfProperties());
             }
             jobs.remove(jobId);
             return answer;
diff --git a/test/integration/smoke/test_kubernetes_clusters.py b/test/integration/smoke/test_kubernetes_clusters.py
index 2867409..2b7638d 100644
--- a/test/integration/smoke/test_kubernetes_clusters.py
+++ b/test/integration/smoke/test_kubernetes_clusters.py
@@ -240,8 +240,8 @@
 
         if validateList(templates)[0] != PASS:
             details = None
-            if hypervisor in ["vmware"]:
-                details = [{"keyboard": "us"}]
+            if hypervisor in ["vmware"] and "details" in cks_template:
+                details = cks_template["details"]
             template = Template.register(cls.apiclient, cks_template, zoneid=cls.zone.id, hypervisor=hypervisor.lower(), randomize_name=False, details=details)
             template.download(cls.apiclient)
             return template
diff --git a/test/integration/smoke/test_nested_virtualization.py b/test/integration/smoke/test_nested_virtualization.py
index 10dcf89..c10dd2f 100644
--- a/test/integration/smoke/test_nested_virtualization.py
+++ b/test/integration/smoke/test_nested_virtualization.py
@@ -97,61 +97,51 @@
                 config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization.perVM", "true")
                 self.logger.debug("Updated global setting vmware.nested.virtualization.perVM to true")
                 rollback_nv_per_vm = True
+                
+        # 2) Deploy a vm
+        virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            mode=self.services['mode']
+        )
+        self.assert_(virtual_machine is not None, "VM failed to deploy")
+        self.assert_(virtual_machine.state == 'Running', "VM is not running")
+        self.logger.debug("Deployed vm: %s" % virtual_machine.id)
+        
+        isolated_network = Network.create(
+            self.apiclient,
+            self.services["isolated_network"],
+            self.account.name,
+            self.account.domainid,
+            networkofferingid=self.isolated_network_offering.id)
 
-        try:
-            # 2) Deploy a vm
-            virtual_machine = VirtualMachine.create(
-                self.apiclient,
-                self.services["small"],
-                accountid=self.account.name,
-                domainid=self.account.domainid,
-                serviceofferingid=self.service_offering.id,
-                mode=self.services['mode']
-            )
-            self.assert_(virtual_machine is not None, "VM failed to deploy")
-            self.assert_(virtual_machine.state == 'Running', "VM is not running")
-            self.logger.debug("Deployed vm: %s" % virtual_machine.id)
+        virtual_machine.add_nic(self.apiclient, isolated_network.id)
+        
+        # 3) SSH into vm
+        ssh_client = virtual_machine.get_ssh_client()
 
-            isolated_network = Network.create(
-                self.apiclient,
-                self.services["isolated_network"],
-                self.account.name,
-                self.account.domainid,
-                networkofferingid=self.isolated_network_offering.id)
-
-            virtual_machine.stop(self.apiclient)
-            virtual_machine.add_nic(self.apiclient, isolated_network.id)
-            virtual_machine.start(self.apiclient)
-
-            # 3) SSH into vm
-            ssh_client = virtual_machine.get_ssh_client()
-
-            if ssh_client:
-                # run ping test
-                result = ssh_client.execute("cat /proc/cpuinfo | grep flags")
-                self.logger.debug(result)
-            else:
-                self.fail("Failed to setup ssh connection to %s" % virtual_machine.public_ip)
-
-            # 4) Revert configurations, if needed
-            self.rollback_nested_configurations(rollback_nv, rollback_nv_per_vm)
-
-            #5) Check for CPU flags: vmx for Intel and svm for AMD indicates nested virtualization is enabled
-            self.assert_(result is not None, "Empty result for CPU flags")
-            res = str(result)
-            self.assertTrue('vmx' in res or 'svm' in res)
-        except Exception as e:
-            self.debug('Error=%s' % e)
-            self.rollback_nested_configurations(rollback_nv, rollback_nv_per_vm)
-            raise e
-
-    def rollback_nested_configurations(self, rollback_nv, rollback_nv_per_vm):
+        if ssh_client:
+            # run ping test
+            result = ssh_client.execute("cat /proc/cpuinfo | grep flags")
+            self.logger.debug(result)
+        else:
+            self.fail("Failed to setup ssh connection to %s" % virtual_machine.public_ip)
+            
+        # 4) Revert configurations, if needed
         if rollback_nv:
             config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization", "false")
             self.logger.debug("Reverted global setting vmware.nested.virtualization back to false")
         if rollback_nv_per_vm:
-            config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization.perVM", "false")
+            config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization", "false")
             self.logger.debug("Reverted global setting vmware.nested.virtualization.perVM back to false")
+            
+        #5) Check for CPU flags: vmx for Intel and svm for AMD indicates nested virtualization is enabled
+        self.assert_(result is not None, "Empty result for CPU flags")
+        res = str(result)
+        self.assertTrue('vmx' in res or 'svm' in res)
 
     @classmethod
     def tearDownClass(cls):
diff --git a/test/integration/smoke/test_storage_policy.py b/test/integration/smoke/test_storage_policy.py
deleted file mode 100644
index a7a5f8d..0000000
--- a/test/integration/smoke/test_storage_policy.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-""" Test for VMWare storage policies
-"""
-# Import Local Modules
-from nose.plugins.attrib import attr
-from marvin.cloudstackTestCase import cloudstackTestCase
-from marvin.lib.utils import cleanup_resources
-from marvin.lib.base import (Account,
-                             VirtualMachine,
-                             ServiceOffering,
-                             NetworkOffering,
-                             Network,
-                             Volume,
-                             DiskOffering)
-from marvin.lib.common import (get_zone,
-                               get_domain,
-                               get_test_template)
-from marvin.cloudstackAPI import (importVsphereStoragePolicies,
-                                  listVsphereStoragePolicies,
-                                  listVsphereStoragePolicyCompatiblePools)
-
-
-class TestVMWareStoragePolicies(cloudstackTestCase):
-
-    @classmethod
-    def setUpClass(cls):
-
-        cls.testClient = super(TestVMWareStoragePolicies, cls).getClsTestClient()
-        cls.apiclient = cls.testClient.getApiClient()
-
-        cls.testdata = cls.testClient.getParsedTestDataConfig()
-        # Get Zone, Domain and templates
-        cls.domain = get_domain(cls.apiclient)
-        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
-        cls._cleanup = []
-        cls.hypervisor = cls.testClient.getHypervisorInfo()
-        cls.network_offering = NetworkOffering.create(
-            cls.apiclient,
-            cls.testdata["l2-network_offering"],
-        )
-        cls.network_offering.update(cls.apiclient, state='Enabled')
-        cls.template = get_test_template(
-            cls.apiclient,
-            cls.zone.id,
-            cls.hypervisor,
-        )
-        cls._cleanup.append(cls.network_offering)
-        return
-
-    @classmethod
-    def tearDownClass(cls):
-        try:
-            cleanup_resources(cls.apiclient, reversed(cls._cleanup))
-        except Exception as e:
-            raise Exception("Warning: Exception during cleanup : %s" % e)
-
-    def setUp(self):
-
-        self.dbclient = self.testClient.getDbConnection()
-        self.hypervisor = self.testClient.getHypervisorInfo()
-        self.testdata["virtual_machine"]["zoneid"] = self.zone.id
-        self.testdata["virtual_machine"]["template"] = self.template.id
-        self.account = Account.create(
-            self.apiclient,
-            self.testdata["account"],
-            domainid=self.domain.id
-        )
-        self.cleanup = []
-        self.cleanup.append(self.account)
-        return
-
-    def tearDown(self):
-        try:
-            self.debug("Cleaning up the resources")
-            cleanup_resources(self.apiclient, reversed(self.cleanup))
-            self.debug("Cleanup complete!")
-        except Exception as e:
-            self.debug("Warning! Exception in tearDown: %s" % e)
-
-    def import_vmware_storage_policies(self, apiclient):
-        cmd = importVsphereStoragePolicies.importVsphereStoragePoliciesCmd()
-        cmd.zoneid = self.zone.id
-        return apiclient.importVsphereStoragePolicies(cmd)
-
-    def list_storage_policies(self, apiclient):
-        cmd = listVsphereStoragePolicies.listVsphereStoragePoliciesCmd()
-        cmd.zoneid = self.zone.id
-        return apiclient.listVsphereStoragePolicies(cmd)
-
-    def list_storage_policy_compatible_pools(self, apiclient, policyid):
-        cmd = listVsphereStoragePolicyCompatiblePools.listVsphereStoragePolicyCompatiblePoolsCmd()
-        cmd.zoneid = self.zone.id
-        cmd.policyid = policyid
-        return apiclient.listVsphereStoragePolicyCompatiblePools(cmd)
-
-    def create_volume(self, apiclient):
-        cmd = create
-
-    @attr(
-        tags=[
-            "advanced",
-            "eip",
-            "advancedns",
-            "basic",
-            "sg"],
-        required_hardware="true")
-    def test_01_import_storage_policies(self):
-        """Test VMWare storage policies
-        """
-
-        # Validate the following:
-        # 1. Import VMWare storage policies - the command should return non-zero result
-        # 2. List current VMWare storage policies - the command should return non-zero result
-        # 3. Create service offering with first of the imported policies
-        # 4. Create disk offering with first of the imported policies
-        # 5. Create VM using the already created service offering
-        # 6. Create volume using the already created disk offering
-        # 7. Attach this volume to our VM
-        # 8. Detach the volume from our VM
-
-        self.hypervisor = self.testClient.getHypervisorInfo()
-        if self.hypervisor.lower() != "vmware":
-            self.skipTest(
-                "VMWare storage policies feature is not supported on %s" %
-                self.hypervisor.lower())
-
-        self.debug("Importing VMWare storage policies")
-        imported_policies = self.import_vmware_storage_policies(self.apiclient)
-
-        if len(imported_policies) == 0:
-            self.skipTest("There are no VMWare storage policies")
-
-        self.debug("Listing VMWare storage policies")
-        listed_policies = self.list_storage_policies(self.apiclient)
-
-        self.assertNotEqual(
-            len(listed_policies),
-            0,
-            "Check if list of storage policies is not zero"
-        )
-
-        self.assertEqual(
-            len(imported_policies),
-            len(listed_policies),
-            "Check if the number of imported policies is identical to the number of listed policies"
-        )
-
-        selected_policy = None
-        for imported_policy in imported_policies:
-            compatible_pools = self.list_storage_policy_compatible_pools(self.apiclient, imported_policy.id)
-            if compatible_pools and len(compatible_pools) > 0:
-                selected_policy = imported_policy
-                break
-
-        if not selected_policy:
-            self.skipTest("There are no compatible storage pools with the imported policies")
-
-        # Create service offering with the first storage policy from the list
-        service_offering = ServiceOffering.create(
-            self.apiclient,
-            self.testdata["service_offering"],
-            storagepolicy=selected_policy.id
-        )
-        self.cleanup.append(service_offering)
-
-        # Create disk offering with the first storage policy from the list
-        disk_offering = DiskOffering.create(
-            self.apiclient,
-            self.testdata["disk_offering"],
-            storagepolicy=selected_policy.id
-        )
-        self.cleanup.append(disk_offering)
-
-        l2_network = Network.create(
-            self.apiclient,
-            self.testdata["l2-network"],
-            zoneid=self.zone.id,
-            networkofferingid=self.network_offering.id
-        )
-        self.cleanup.append(l2_network)
-
-        virtual_machine = VirtualMachine.create(
-            self.apiclient,
-            self.testdata["small"],
-            templateid=self.template.id,
-            accountid=self.account.name,
-            domainid=self.account.domainid,
-            zoneid=self.zone.id,
-            networkids=l2_network.id,
-            serviceofferingid=service_offering.id,
-        )
-        self.cleanup.append(virtual_machine)
-
-        vms = VirtualMachine.list(
-            self.apiclient,
-            id=virtual_machine.id,
-            listall=True
-        )
-        self.assertEqual(
-            isinstance(vms, list),
-            True,
-            "listVirtualMachines returned invalid object in response."
-        )
-        self.assertNotEqual(
-            len(vms),
-            0,
-            "listVirtualMachines returned empty list."
-        )
-        self.debug("Deployed VM on host: %s" % vms[0].hostid)
-
-        volume = Volume.create(
-            self.apiclient,
-            self.testdata["volume"],
-            account=self.account.name,
-            domainid=self.account.domainid,
-            zoneid=self.zone.id,
-            diskofferingid=disk_offering.id
-           )
-        self.cleanup.append(volume)
-
-        list_volume_response = Volume.list(
-            self.apiclient,
-            id=volume.id
-        )
-        self.assertEqual(
-            isinstance(list_volume_response, list),
-            True,
-            "Check list response returns a valid list"
-        )
-        self.assertNotEqual(
-            list_volume_response,
-            None,
-            "Check if volume exists in ListVolumes"
-        )
-        return
diff --git a/test/integration/smoke/test_templates.py b/test/integration/smoke/test_templates.py
index dd724b8..ae34f76 100644
--- a/test/integration/smoke/test_templates.py
+++ b/test/integration/smoke/test_templates.py
@@ -77,15 +77,16 @@
         if "vmware" in self.hypervisor.lower():
             self.test_template = registerTemplate.registerTemplateCmd()
             self.test_template = registerTemplate.registerTemplateCmd()
-            self.test_template.checksum = "{SHA-1}" + "3c00872599c6e1e46a358aac51080db88266cf5c"
+            self.test_template.checksum = "{SHA-1}" + "178639bd5ec089a27f6d39025be28c3de5d9393b"
             self.test_template.hypervisor = self.hypervisor
             self.test_template.zoneid = self.zone.id
             self.test_template.name = 'test sha-2333'
             self.test_template.displaytext = 'test sha-1'
             self.test_template.url = "http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-vmware.ova"
             self.test_template.format = "OVA"
-            self.md5 = "27f3c56a8c7ec7b2f3ff2199f7078006"
-            self.sha256 = "a7b04c1eb507f3f5de844bda352df1ea5e20335b465409493ca6ae07dfd0a158"
+            self.test_template.ostypeid = self.getOsType("Other Linux (64-bit)")
+            self.md5 = "3c23ac66bac7888dc7c972783646c644"
+            self.sha256 = "97aaa096d419522158c54f83eb61d9242d9f6bca9166fd4030d73683d647c7e7"
 
         if "xen" in self.hypervisor.lower():
             self.test_template = registerTemplate.registerTemplateCmd()
diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py
index 08668e4..68ec359 100644
--- a/test/integration/smoke/test_vm_life_cycle.py
+++ b/test/integration/smoke/test_vm_life_cycle.py
@@ -27,9 +27,7 @@
                                   migrateVirtualMachine,
                                   migrateVirtualMachineWithVolume,
                                   unmanageVirtualMachine,
-                                  listUnmanagedInstances,
-                                  listNics,
-                                  listVolumes)
+                                  listUnmanagedInstances)
 from marvin.lib.utils import *
 
 from marvin.lib.base import (Account,
@@ -47,17 +45,13 @@
 from marvin.lib.common import (get_domain,
                                get_zone,
                                get_suitable_test_template,
-                               get_test_ovf_templates,
                                list_hosts,
-                               list_virtual_machines,
-                               get_vm_vapp_configs)
+                               list_virtual_machines)
 from marvin.codes import FAILED, PASS
 from nose.plugins.attrib import attr
 from marvin.lib.decoratorGenerators import skipTestIf
 # Import System modules
 import time
-import json
-from operator import itemgetter
 
 _multiprocess_shared_ = True
 
@@ -1685,273 +1679,3 @@
             "PowerOn",
             "Unmanaged VM is still running"
         )
-
-
-class TestVAppsVM(cloudstackTestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        testClient = super(TestVAppsVM, cls).getClsTestClient()
-        cls.apiclient = testClient.getApiClient()
-        cls.services = testClient.getParsedTestDataConfig()
-        cls.hypervisor = testClient.getHypervisorInfo()
-        cls._cleanup = []
-
-        # Get Zone, Domain and templates
-        cls.domain = get_domain(cls.apiclient)
-        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
-        cls.services['mode'] = cls.zone.networktype
-
-        cls.hypervisorNotSupported = cls.hypervisor.lower() != "vmware"
-
-        if cls.hypervisorNotSupported == False:
-
-            cls.account = Account.create(
-                cls.apiclient,
-                cls.services["account"],
-                domainid=cls.domain.id
-            )
-
-            cls.templates = get_test_ovf_templates(
-                cls.apiclient,
-                cls.zone.id,
-                cls.services['test_ovf_templates'],
-                cls.hypervisor
-            )
-            if len(cls.templates) == 0:
-                assert False, "get_test_ovf_templates() failed to return templates"
-
-            cls.custom_offering = ServiceOffering.create(
-                cls.apiclient,
-                cls.services["custom_service_offering"]
-            )
-
-            cls.isolated_network_offering = NetworkOffering.create(
-                cls.apiclient,
-                cls.services["isolated_network_offering"],
-            )
-            cls.isolated_network_offering.update(cls.apiclient, state='Enabled')
-
-            cls.l2_network_offering = NetworkOffering.create(
-                cls.apiclient,
-                cls.services["l2-network_offering"],
-            )
-            cls.l2_network_offering.update(cls.apiclient, state='Enabled')
-
-            cls._cleanup = [
-                cls.account,
-                cls.custom_offering,
-                cls.isolated_network_offering,
-                cls.l2_network_offering
-            ]
-
-            # Uncomment when tests are finished, to cleanup the test templates
-            for template in cls.templates:
-                cls._cleanup.append(template)
-
-    @classmethod
-    def tearDownClass(cls):
-        try:
-            cleanup_resources(cls.apiclient, cls._cleanup)
-        except Exception as e:
-            raise Exception("Warning: Exception during class cleanup : %s" % e)
-
-    def setUp(self):
-        self.apiclient = self.testClient.getApiClient()
-        self.cleanup = []
-
-    def tearDown(self):
-        try:
-            cleanup_resources(self.apiclient, self.cleanup)
-        except Exception as e:
-            raise Exception("Warning: Exception during cleanup : %s" % e)
-
-    def get_ova_parsed_information_from_template(self, template):
-        if not template:
-            return None
-        details = template.details.__dict__
-        configurations = []
-        disks = []
-        isos = []
-        networks = []
-        for propKey in details:
-            if propKey.startswith('ACS-configuration'):
-                configurations.append(json.loads(details[propKey]))
-            elif propKey.startswith('ACS-disk'):
-                detail = json.loads(details[propKey])
-                if detail['isIso'] == True:
-                    isos.append(detail)
-                else:
-                    disks.append(detail)
-            elif propKey.startswith('ACS-network'):
-                networks.append(json.loads(details[propKey]))
-
-        return configurations, disks, isos, networks
-
-    def verify_nics(self, nic_networks, vm_id):
-        cmd = listNics.listNicsCmd()
-        cmd.virtualmachineid = vm_id
-        vm_nics =  self.apiclient.listNics(cmd)
-        self.assertEqual(
-            isinstance(vm_nics, list),
-            True,
-            "Check listNics response returns a valid list"
-        )
-        self.assertEqual(
-            len(nic_networks),
-            len(vm_nics),
-            msg="VM NIC count is different, expected = {}, result = {}".format(len(nic_networks), len(vm_nics))
-        )
-        nic_networks.sort(key=itemgetter('nic')) # CS will create NIC in order of InstanceID. Check network order
-        vm_nics.sort(key=itemgetter('deviceid'))
-        for i in range(len(vm_nics)):
-            nic = vm_nics[i]
-            nic_network = nic_networks[i]
-            self.assertEqual(
-                nic.networkid,
-                nic_network["network"],
-                msg="VM NIC(InstanceID: {}) network mismatch, expected = {}, result = {}".format(nic_network["nic"], nic_network["network"], nic.networkid)
-            )
-
-    def verify_disks(self, template_disks, vm_id):
-        cmd = listVolumes.listVolumesCmd()
-        cmd.virtualmachineid = vm_id
-        cmd.listall = True
-        vm_volumes =  self.apiclient.listVolumes(cmd)
-        self.assertEqual(
-            isinstance(vm_volumes, list),
-            True,
-            "Check listVolumes response returns a valid list"
-        )
-        self.assertEqual(
-            len(template_disks),
-            len(vm_volumes),
-            msg="VM volumes count is different, expected = {}, result = {}".format(len(template_disks), len(vm_volumes))
-        )
-        template_disks.sort(key=itemgetter('diskNumber'))
-        vm_volumes.sort(key=itemgetter('deviceid'))
-        for j in range(len(vm_volumes)):
-            volume = vm_volumes[j]
-            disk = template_disks[j]
-            self.assertEqual(
-                volume.size,
-                disk["virtualSize"],
-                msg="VM Volume(diskNumber: {}) network mismatch, expected = {}, result = {}".format(disk["diskNumber"], disk["virtualSize"], volume.size)
-            )
-
-    @attr(tags=["advanced", "advancedns", "smoke", "sg", "dev"], required_hardware="false")
-    @skipTestIf("hypervisorNotSupported")
-    def test_01_vapps_vm_cycle(self):
-        """
-        Test the following for all found ovf templates:
-        1. Deploy VM
-        2. Verify VM has correct properties
-        3. Verify VM has correct disks
-        4. Verify VM has correct nics
-        5. Destroy VM
-        """
-
-        for template in self.templates:
-            configurations, disks, isos, network = self.get_ova_parsed_information_from_template(template)
-
-            if configurations:
-                conf = configurations[0]
-                items = conf['hardwareItems']
-                cpu_speed = 1000
-                cpu_number = 0
-                memory = 0
-                for item in items:
-                    if item['resourceType'] == 'Memory':
-                        memory = item['virtualQuantity']
-                    elif item['resourceType'] == 'Processor':
-                        cpu_number = item['virtualQuantity']
-
-            nicnetworklist = []
-            networks = []
-            vm_service = self.services["virtual_machine_vapps"][template.name]
-            network_mappings = vm_service["nicnetworklist"]
-            for network_mapping in network_mappings:
-                network_service = self.services["isolated_network"]
-                network_offering_id = self.isolated_network_offering.id
-                if network_mapping["network"] == 'l2':
-                    network_service = self.services["l2-network"]
-                    network_offering_id = self.l2_network_offering.id
-                network = Network.create(
-                    self.apiclient,
-                    network_service,
-                    networkofferingid=network_offering_id,
-                    accountid=self.account.name,
-                    domainid=self.account.domainid,
-                    zoneid=self.zone.id)
-                networks.append(network)
-                for interface in network_mapping["nic"]:
-                    nicnetworklist.append({"nic": interface, "network": network.id})
-
-            vm = VirtualMachine.create(
-                self.apiclient,
-                vm_service,
-                accountid=self.account.name,
-                domainid=self.account.domainid,
-                templateid=template.id,
-                serviceofferingid=self.custom_offering.id,
-                zoneid=self.zone.id,
-                customcpunumber=cpu_number,
-                customcpuspeed=cpu_speed,
-                custommemory=memory,
-                properties=vm_service['properties'],
-                nicnetworklist=nicnetworklist
-            )
-
-            list_vm_response = VirtualMachine.list(
-                self.apiclient,
-                id=vm.id
-            )
-            self.debug(
-                "Verify listVirtualMachines response for virtual machine: %s" \
-                % vm.id
-            )
-            self.assertEqual(
-                isinstance(list_vm_response, list),
-                True,
-                "Check list response returns a valid list"
-            )
-            self.assertNotEqual(
-                len(list_vm_response),
-                0,
-                "Check VM available in List Virtual Machines"
-            )
-            vm_response = list_vm_response[0]
-            self.assertEqual(
-                vm_response.id,
-                vm.id,
-                "Check virtual machine id in listVirtualMachines"
-            )
-            self.assertEqual(
-                vm_response.name,
-                vm.name,
-                "Check virtual machine name in listVirtualMachines"
-            )
-            self.assertEqual(
-                vm_response.state,
-                'Running',
-                msg="VM is not in Running state"
-            )
-
-            # Verify nics
-            self.verify_nics(nicnetworklist, vm.id)
-            # Verify disks
-            self.verify_disks(disks, vm.id)
-            # Verify properties
-            original_properties = vm_service['properties']
-            vm_properties = get_vm_vapp_configs(self.apiclient, self.config, self.zone, vm.instancename)
-            for property in original_properties:
-                if property["key"] in vm_properties:
-                    self.assertEqual(
-                        vm_properties[property["key"]],
-                        property["value"],
-                        "Check VM property %s with original value" % property["key"]
-                    )
-
-            cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
-            cmd.id = vm.id
-            self.apiclient.destroyVirtualMachine(cmd)
diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py
index 0b0702a..ca1c44f 100644
--- a/tools/apidoc/gen_toc.py
+++ b/tools/apidoc/gen_toc.py
@@ -196,10 +196,8 @@
     'KubernetesSupportedVersion': 'Kubernetes Service',
     'KubernetesCluster': 'Kubernetes Service',
     'UnmanagedInstance': 'Virtual Machine',
-    'Rolling': 'Rolling Maintenance',
-    'importVsphereStoragePolicies' : 'vSphere storage policies',
-    'listVsphereStoragePolicies' : 'vSphere storage policies'
-}
+    'Rolling': 'Rolling Maintenance'
+    }
 
 
 categories = {}
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 436c656..4708717 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -986,60 +986,7 @@
             "ispublic": "True"
         }
     },
-    "test_ovf_templates": [
-        {
-            "name": "test-ovf",
-            "displaytext": "test-ovf",
-            "format": "ova",
-            "hypervisor": "vmware",
-            "ostype": "Other Linux (64-bit)",
-            "url": "http://172.17.0.1/machina-2dd-iso.ova",
-            "deployasis": "True",
-            "requireshvm": "True",
-            "ispublic": "True"
-        }
-    ],
-    "virtual_machine_vapps": {
-        "test-ovf": {
-            "name": "testvm-vapps",
-            "displayname": "Test VM vApps",
-            "properties": [
-                {
-                    "key": "used.by.admin",
-                    "value": "marvin"
-                },
-                {
-                    "key": "use.type",
-                    "value": "test"
-                },
-                {
-                    "key": "usefull.property",
-                    "value": "True"
-                }
-            ],
-            "nicnetworklist": [
-                {
-                    "network": "l2",
-                    "nic": [15, 18]
-                },
-                {
-                    "network": "l2",
-                    "nic": [16]
-                },
-                {
-                    "network": "l2",
-                    "nic": [17]
-                }
-            ]
-        }
-    },
-    "custom_service_offering": {
-        "name": "Custom Service Offering for vApps",
-        "displaytext": "Custom Service Offering for vApps",
-        "cpunumber": "",
-        "cpuspeed": "",
-        "memory": ""
-    },
+
     "coreos_volume": {
         "diskname": "Volume_core",
         "urlvmware":"http://dl.openvm.eu/cloudstack/coreos/x86_64/coreos_production_cloudstack_image-vmware.ova",
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 6bb7b66..73c96d7 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -521,8 +521,7 @@
                hostid=None, keypair=None, ipaddress=None, mode='default',
                method='GET', hypervisor=None, customcpunumber=None,
                customcpuspeed=None, custommemory=None, rootdisksize=None,
-               rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={},
-               properties=None, nicnetworklist=None):
+               rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={}):
         """Create the instance"""
 
         cmd = deployVirtualMachine.deployVirtualMachineCmd()
@@ -651,12 +650,6 @@
         elif macaddress in services:
             cmd.macaddress = services["macaddress"]
 
-        if properties:
-            cmd.properties = properties
-
-        if nicnetworklist:
-            cmd.nicnetworklist = nicnetworklist
-
         virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
 
         if 'password' in virtual_machine.__dict__.keys():
@@ -1397,24 +1390,22 @@
         elif "hypervisor" in services:
             cmd.hypervisor = services["hypervisor"]
 
-        if cmd.hypervisor.lower() not in ["vmware"]:
-            # Since version 4.15 VMware templates honour the guest OS defined in the template
-            if "ostypeid" in services:
-                cmd.ostypeid = services["ostypeid"]
-            elif "ostype" in services:
-                # Find OSTypeId from Os type
-                sub_cmd = listOsTypes.listOsTypesCmd()
-                sub_cmd.description = services["ostype"]
-                ostypes = apiclient.listOsTypes(sub_cmd)
+        if "ostypeid" in services:
+            cmd.ostypeid = services["ostypeid"]
+        elif "ostype" in services:
+            # Find OSTypeId from Os type
+            sub_cmd = listOsTypes.listOsTypesCmd()
+            sub_cmd.description = services["ostype"]
+            ostypes = apiclient.listOsTypes(sub_cmd)
 
-                if not isinstance(ostypes, list):
-                    raise Exception(
-                        "Unable to find Ostype id with desc: %s" %
-                        services["ostype"])
-                cmd.ostypeid = ostypes[0].id
-            else:
+            if not isinstance(ostypes, list):
                 raise Exception(
-                    "Unable to find Ostype is required for registering template")
+                    "Unable to find Ostype id with desc: %s" %
+                    services["ostype"])
+            cmd.ostypeid = ostypes[0].id
+        else:
+            raise Exception(
+                "Unable to find Ostype is required for registering template")
 
         cmd.url = services["url"]
 
diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py
index fc9c72d..1c873a3 100644
--- a/tools/marvin/marvin/lib/common.py
+++ b/tools/marvin/marvin/lib/common.py
@@ -395,74 +395,6 @@
     return FAILED
 
 
-def get_test_ovf_templates(apiclient, zone_id=None, test_ovf_templates=None, hypervisor=None):
-    """
-    @Name : get_test_ovf_templates
-    @Desc : Retrieves the list of test ovf templates used to running tests. When the template
-            is missing it will be download at most one in a zone for a hypervisor.
-    @Input : returns a list of templates
-    """
-    result = []
-
-    if test_ovf_templates is None:
-        test_ovf_templates = test_data["test_ovf_templates"]
-    if test_ovf_templates is None:
-        return result
-    if hypervisor is None:
-        return result
-    hypervisor = hypervisor.lower()
-    if hypervisor != 'vmware':
-        return result
-
-    for test_template in test_ovf_templates:
-
-        cmd = listTemplates.listTemplatesCmd()
-        cmd.name = test_template['name']
-        cmd.templatefilter = 'all'
-        if zone_id is not None:
-            cmd.zoneid = zone_id
-        if hypervisor is not None:
-            cmd.hypervisor = hypervisor
-        templates = apiclient.listTemplates(cmd)
-
-        if validateList(templates)[0] != PASS:
-            template = Template.register(apiclient, test_template, zoneid=zone_id, hypervisor=hypervisor.lower(), randomize_name=False)
-            template.download(apiclient)
-            retries = 3
-            while (template.details == None or len(template.details.__dict__) == 0) and retries > 0:
-                time.sleep(10)
-                template_list = Template.list(apiclient, id=template.id, zoneid=zone_id, templatefilter='all')
-                if isinstance(template_list, list):
-                    template = Template(template_list[0].__dict__)
-                retries = retries - 1
-            if template.details == None or len(template.details.__dict__) == 0:
-                template.delete(apiclient)
-            else:
-                result.append(template)
-
-        if templates:
-            for template in templates:
-                if template.isready and template.ispublic and template.details != None and len(template.details.__dict__) > 0:
-                    result.append(template.__dict__)
-
-    return result
-
-def get_vm_vapp_configs(apiclient, config, setup_zone, vm_name):
-    zoneDetailsInConfig = [zone for zone in config.zones
-                           if zone.name == setup_zone.name][0]
-    vcenterusername = zoneDetailsInConfig.vmwaredc.username
-    vcenterpassword = zoneDetailsInConfig.vmwaredc.password
-    vcenterip = zoneDetailsInConfig.vmwaredc.vcenter
-    vcenterObj = Vcenter(
-        vcenterip,
-        vcenterusername,
-        vcenterpassword)
-
-    vms = vcenterObj.get_vms(vm_name)
-    if vms:
-        return vms[0]['vm']['properties']
-
-
 def get_windows_template(
         apiclient, zone_id=None, ostype_desc=None, template_filter="featured", template_type='USER',
         template_id=None, template_name=None, account=None, domain_id=None, project_id=None,
diff --git a/tools/marvin/marvin/lib/vcenter.py b/tools/marvin/marvin/lib/vcenter.py
index 78ca50e..d14f364 100644
--- a/tools/marvin/marvin/lib/vcenter.py
+++ b/tools/marvin/marvin/lib/vcenter.py
@@ -114,12 +114,6 @@
             for network in obj.network:
                 vm_details['networks'].append({'name': network.name})
         vm_details['raw'] = obj
-        vm_details['properties'] = {}
-        config = obj.config
-        if config and config.vAppConfig:
-            for prop in config.vAppConfig.property:
-                vm_details['properties'][prop.id] = prop.value
-
         return vm_details
 
     def parse_details(self, obj, vimtype):
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index a801a6b..7f29f2b 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -711,7 +711,7 @@
         externalLink: ''
     },
     helpPrimaryStorageProtocol: {
-        desc: 'For XenServer, choose NFS, iSCSI, or PreSetup. For KVM, choose NFS, SharedMountPoint, RDB, CLVM or Gluster. For vSphere, choose PreSetup (VMFS or iSCSI or FiberChannel or vSAN or vVols) or NFS. For Hyper-V, choose SMB/CIFS. For LXC, choose NFS or SharedMountPoint. For OVM, choose NFS or ocfs2.',
+        desc: 'For XenServer, choose NFS, iSCSI, or PreSetup. For KVM, choose NFS, SharedMountPoint, RDB, CLVM or Gluster. For vSphere, choose VMFS (iSCSI or FiberChannel) or NFS. For Hyper-V, choose SMB/CIFS. For LXC, choose NFS or SharedMountPoint. For OVM, choose NFS or ocfs2.',
         externalLink: ''
     },
     helpPrimaryStorageServer: {
diff --git a/ui/scripts/instanceWizard.js b/ui/scripts/instanceWizard.js
index 466db99..f06cd90 100644
--- a/ui/scripts/instanceWizard.js
+++ b/ui/scripts/instanceWizard.js
@@ -965,6 +965,17 @@
                     }
                 });
 
+                if (selectedTemplateObj) {
+                    $.ajax({
+                        url: createURL("listTemplateOvfProperties&id=" + selectedTemplateObj.id),
+                        dataType: "json",
+                        async: false,
+                        success: function(json) {
+                            ovfProps = json.listtemplateovfpropertiesresponse.ovfproperty;
+                        }
+                    });
+                }
+
                 var $step = $('.step.sshkeyPairs:visible');
                 if (ovfProps == null || ovfProps.length === 0) {
                     $step.addClass('next-skip-ovf-properties');
@@ -973,6 +984,15 @@
                 }
             },
 
+            // Step PRE-8: Configure OVF Properties (if available) for the template
+            function(args) {
+                args.response.success({
+                    data: {
+                        ovfProperties: ovfProps
+                    }
+                });
+            },
+
             // Step 8: Review
             function(args) {
                 var $step = $('.step.review:visible');
@@ -1034,8 +1054,8 @@
                     }
                 });
                 for (var k = 0; k < deployOvfProperties.length; k++) {
-                    deployVmData["properties[" + k + "].key"] = deployOvfProperties[k].key;
-                    deployVmData["properties[" + k + "].value"] = deployOvfProperties[k].value;
+                    deployVmData["ovfproperties[" + k + "].key"] = deployOvfProperties[k].key;
+                    deployVmData["ovfproperties[" + k + "].value"] = deployOvfProperties[k].value;
                 }
             }
 
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index ca0eb7e..418ce53 100755
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -18735,8 +18735,8 @@
                                                     description: "nfs"
                                                 });
                                                 items.push({
-                                                    id: "presetup",
-                                                    description: "presetup"
+                                                    id: "vmfs",
+                                                    description: "vmfs"
                                                 });
                                                 items.push({
                                                     id: "custom",
@@ -18885,7 +18885,7 @@
                                                     $form.find('.form-item[rel=rbdsecret]').hide();
 
                                                     $form.find('.form-item[rel=glustervolume]').hide();
-                                                } else if (protocol == "PreSetup" && selectedClusterObj.hypervisortype != "VMware") {
+                                                } else if (protocol == "PreSetup") {
                                                     $form.find('.form-item[rel=server]').hide();
                                                     $form.find('.form-item[rel=server]').find(".value").find("input").val("localhost");
 
@@ -18983,7 +18983,7 @@
                                                     $form.find('.form-item[rel=rbdsecret]').hide();
 
                                                     $form.find('.form-item[rel=glustervolume]').hide();
-                                                } else if (protocol == "presetup" && selectedClusterObj.hypervisortype == "VMware") {
+                                                } else if (protocol == "vmfs") {
                                                     $form.find('.form-item[rel=server]').css('display', 'inline-block');
                                                     $form.find('.form-item[rel=server]').find(".value").find("input").val("");
 
@@ -19408,7 +19408,7 @@
                                         array1.push("&details[0].user=" + args.data.smbUsername);
                                         array1.push("&details[1].password=" + encodeURIComponent(args.data.smbPassword));
                                         array1.push("&details[2].domain=" + args.data.smbDomain);
-                                    } else if (args.data.protocol == "PreSetup" && selectedClusterObj.hypervisortype != "VMware") {
+                                    } else if (args.data.protocol == "PreSetup") {
                                         var path = args.data.path;
                                         if (path.substring(0, 1) != "/")
                                             path = "/" + path;
@@ -19434,12 +19434,12 @@
                                         var rbdid = args.data.rbdid;
                                         var rbdsecret = args.data.rbdsecret;
                                         url = rbdURL(rbdmonitor, rbdpool, rbdid, rbdsecret);
-                                    } else if (args.data.protocol == "presetup" && selectedClusterObj.hypervisortype == "VMware") {
+                                    } else if (args.data.protocol == "vmfs") {
                                         var path = args.data.vCenterDataCenter;
                                         if (path.substring(0, 1) != "/")
                                             path = "/" + path;
                                         path += "/" + args.data.vCenterDataStore;
-                                        url = presetupURL("dummy", path);
+                                        url = vmfsURL("dummy", path);
                                     } else if (args.data.protocol == "gluster") {
                                         var glustervolume = args.data.glustervolume;
 
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index 8660c5c..1516286 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -245,8 +245,8 @@
                                             args.$select.change(function() {
                                                 var $form = $(this).closest('form');
                                                 if ($(this).val() == "VMware") {
-                                                    $form.find('.form-item[rel=rootDiskControllerType]').hide();
-                                                    $form.find('.form-item[rel=nicAdapterType]').hide();
+                                                    $form.find('.form-item[rel=rootDiskControllerType]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=nicAdapterType]').css('display', 'inline-block');
                                                     $form.find('.form-item[rel=keyboardType]').css('display', 'inline-block');
                                                     $form.find('.form-item[rel=xenserverToolsVersion61plus]').hide();
                                                     $form.find('.form-item[rel=rootDiskControllerTypeKVM]').hide();
@@ -1823,7 +1823,18 @@
                             }
                         },
                         tabFilter: function (args) {
+                            $.ajax({
+                                url: createURL("listTemplateOvfProperties&id=" + args.context.templates[0].id),
+                                dataType: "json",
+                                async: false,
+                                success: function(json) {
+                                    ovfprops = json.listtemplateovfpropertiesresponse.ovfproperty;
+                                }
+                            });
                             var hiddenTabs = [];
+                            if (ovfprops == null || ovfprops.length === 0) {
+                                hiddenTabs.push("ovfpropertiestab");
+                            }
                             return hiddenTabs;
                         },
                         tabs: {
@@ -2594,7 +2605,57 @@
 										}
 									}
 								})
-							}
+							},
+
+                            /**
+                             * OVF properties tab (only displayed when OVF properties are available)
+                             */
+                            ovfpropertiestab: {
+                                title: 'label.ovf.properties',
+                                listView: {
+                                    id: 'ovfproperties',
+                                    fields: {
+                                        label: {
+                                            label: 'label.label'
+                                        },
+                                        description: {
+                                            label: 'label.description'
+                                        },
+                                        value: {
+                                            label: 'label.value'
+                                        }
+                                    },
+                                    hideSearchBar: true,
+                                    dataProvider: function(args) {
+                                        $.ajax({
+                                            url: createURL("listTemplateOvfProperties"),
+                                            data: {
+                                                id: args.context.templates[0].id
+                                            },
+                                            success: function(json) {
+                                                var ovfprops = json.listtemplateovfpropertiesresponse.ovfproperty;
+                                                var listDetails = [];
+                                                for (index in ovfprops){
+                                                    var prop = ovfprops[index];
+                                                    var det = {};
+                                                    det['label'] = prop['label'];
+                                                    det['description'] = prop['description'];
+                                                    det['value'] = prop['value'];
+                                                    listDetails.push(det);
+                                                }
+                                                args.response.success({
+                                                    data: listDetails
+                                                });
+                                            },
+
+                                            error: function(json) {
+                                                args.response.error(parseXMLHttpResponse(json));
+                                            }
+                                        });
+
+                                    }
+                                }
+                            }
 						}
                     }
                 }
diff --git a/ui/scripts/ui-custom/instanceWizard.js b/ui/scripts/ui-custom/instanceWizard.js
index 2004257..4aefa97 100644
--- a/ui/scripts/ui-custom/instanceWizard.js
+++ b/ui/scripts/ui-custom/instanceWizard.js
@@ -172,20 +172,10 @@
                                             .html(qualifier)
                                         propertyField.append(option);
                                     });
-                                } else if (qualifiers.includes("MinLen") || qualifiers.includes("MaxLen") ) {
-                                    var split = qualifiers.split(",");
-                                    var minLen = 0;
-                                    var maxLen = 524288; /* 524288 being the default according to w3schools */
-                                    for ( var i = 0; i < split.length; i++ ) {
-                                        if (split[i].startsWith("MaxLen")) {
-                                            maxLen = split[i].replace("MaxLen(","").replace(")","");
-                                        } else if (split[i].startsWith("MinLen")) {
-                                            minLen = split[i].replace("MinLen(","").replace(")","");
-                                        }
-                                    }
+                                } else if (qualifiers.startsWith("MaxLen")) {
+                                    var length = qualifiers.replace("MaxLen(","").slice(0,-1);
                                     propertyField = $('<input id=ovf-property-'+key+'>')
-                                        .attr({pattern : '.{' + minLen + ',' + maxLen + '}'})
-                                        .attr({type: fieldType})
+                                        .attr({maxlength : length, type: fieldType})
                                         .addClass('name').val(_s(this[fields.value]))
                                 }
                             } else {
diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js
index b7e5d01..f4d0e5d 100755
--- a/ui/scripts/zoneWizard.js
+++ b/ui/scripts/zoneWizard.js
@@ -1434,8 +1434,8 @@
                                     description: "nfs"
                                 });
                                 items.push({
-                                    id: "presetup",
-                                    description: "presetup"
+                                    id: "vmfs",
+                                    description: "vmfs"
                                 });
                                 args.response.success({
                                     data: items
@@ -1576,7 +1576,7 @@
                                     $form.find('[rel=rbdsecret]').hide();
 
                                     $form.find('[rel=glustervolume]').hide();
-                                } else if (protocol == "PreSetup" && selectedClusterObj.hypervisortype != "VMware") {
+                                } else if (protocol == "PreSetup") {
                                     $form.find('[rel=server]').hide();
                                     $form.find('[rel=server]').find(".value").find("input").val("localhost");
 
@@ -1649,7 +1649,7 @@
                                     $form.find('[rel=rbdsecret]').hide();
 
                                     $form.find('[rel=glustervolume]').hide();
-                                } else if (protocol == "presetup" && selectedClusterObj.hypervisortype == "VMware") {
+                                } else if (protocol == "vmfs") {
                                     $form.find('[rel=server]').css('display', 'block');
                                     $form.find('[rel=server]').find(".value").find("input").val("");
 
@@ -4529,7 +4529,7 @@
                         array1.push("&details[0].user=" + args.data.primaryStorage.smbUsername);
                         array1.push("&details[1].password=" + encodeURIComponent(args.data.primaryStorage.smbPassword));
                         array1.push("&details[2].domain=" + args.data.primaryStorage.smbDomain);
-                    } else if (args.data.primaryStorage.protocol == "PreSetup" && selectedClusterObj.hypervisortype != "VMware") {
+                    } else if (args.data.primaryStorage.protocol == "PreSetup") {
                         var path = args.data.primaryStorage.path;
                         if (path.substring(0, 1) != "/")
                             path = "/" + path;
@@ -4555,12 +4555,12 @@
                         var rbdid = args.data.primaryStorage.rbdid;
                         var rbdsecret = args.data.primaryStorage.rbdsecret;
                         url = rbdURL(rbdmonitor, rbdpool, rbdid, rbdsecret);
-                    } else if (args.data.primaryStorage.protocol == "presetup" && selectedClusterObj.hypervisortype == "VMware") {
+                    } else if (args.data.primaryStorage.protocol == "vmfs") {
                         var path = args.data.primaryStorage.vCenterDataCenter;
                         if (path.substring(0, 1) != "/")
                             path = "/" + path;
                         path += "/" + args.data.primaryStorage.vCenterDataStore;
-                        url = presetupURL("dummy", path);
+                        url = vmfsURL("dummy", path);
                     } else {
                         var iqn = args.data.primaryStorage.iqn;
                         if (iqn.substring(0, 1) != "/")
diff --git a/utils/pom.xml b/utils/pom.xml
index 75c9cd4..8a745aa 100755
--- a/utils/pom.xml
+++ b/utils/pom.xml
@@ -178,10 +178,6 @@
             <artifactId>jackson-databind</artifactId>
             <version>${cs.jackson.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-compress</artifactId>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/utils/src/main/java/com/cloud/utils/compression/CompressionUtil.java b/utils/src/main/java/com/cloud/utils/compression/CompressionUtil.java
deleted file mode 100644
index 20f0bc8..0000000
--- a/utils/src/main/java/com/cloud/utils/compression/CompressionUtil.java
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.utils.compression;
-
-import org.apache.log4j.Logger;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-
-public class CompressionUtil {
-
-    private static final Logger s_logger = Logger.getLogger(CompressionUtil.class);
-
-    public byte[] compressString(String inputStr) throws IOException {
-        ByteArrayOutputStream obj = new ByteArrayOutputStream();
-        GZIPOutputStream gzip = new GZIPOutputStream(obj);
-        gzip.write(inputStr.getBytes(StandardCharsets.UTF_8));
-        gzip.close();
-        return obj.toByteArray();
-    }
-
-    public String decompressByteArary(byte[] compressed) throws IOException {
-        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressed));
-        BufferedReader bf = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8));
-        String line = bf.readLine();
-        StringBuilder builder = new StringBuilder();
-        while (line != null) {
-            builder.append(line);
-            line = bf.readLine();
-            if (line != null) {
-                builder.append("\n");
-            }
-        }
-        return builder.toString();
-    }
-}
diff --git a/utils/src/test/java/com/cloud/utils/compression/CompressionUtilTest.java b/utils/src/test/java/com/cloud/utils/compression/CompressionUtilTest.java
deleted file mode 100644
index e247d6c..0000000
--- a/utils/src/test/java/com/cloud/utils/compression/CompressionUtilTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-//
-package com.cloud.utils.compression;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.io.IOException;
-
-public class CompressionUtilTest {
-
-    private CompressionUtil util = new CompressionUtil();
-
-    private String testEula = "END USER LICENSE AGREEMENT\n" +
-            "\n" +
-            "IMPORTANT: PLEASE READ THIS END USER LICENSE AGREEMENT CAREFULLY. IT IS VERY IMPORTANT THAT YOU CHECK THAT YOU ARE PURCHASING CISCO SOFTWARE OR EQUIPMENT FROM AN APPROVED SOURCE AND THAT YOU, OR THE ENTITY YOU REPRESENT (COLLECTIVELY, THE \"CUSTOMER\") HAVE BEEN REGISTERED AS THE END USER FOR THE PURPOSES OF THIS CISCO END USER LICENSE AGREEMENT. IF YOU ARE NOT REGISTERED AS THE END USER YOU HAVE NO LICENSE TO USE THE SOFTWARE AND THE LIMITED WARRANTY IN THIS END USER LICENSE AGREEMENT DOES NOT APPLY. ASSUMING YOU HAVE PURCHASED FROM AN APPROVED SOURCE, DOWNLOADING, INSTALLING OR USING CISCO OR CISCO-SUPPLIED SOFTWARE CONSTITUTES ACCEPTANCE OF THIS AGREEMENT.\n" +
-            "\n" +
-            "CISCO SYSTEMS, INC. OR ITS AFFILIATE LICENSING THE SOFTWARE (\"CISCO\") IS WILLING TO LICENSE THIS SOFTWARE TO YOU ONLY UPON THE CONDITION THAT YOU PURCHASED THE SOFTWARE FROM AN APPROVED SOURCE AND THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS END USER LICENSE AGREEMENT PLUS ANY ADDITIONAL LIMITATIONS ON THE LICENSE SET FORTH IN A SUPPLEMENTAL LICENSE AGREEMENT ACCOMPANYING THE PRODUCT, MADE AVAILABLE AT THE TIME OF YOUR ORDER, OR POSTED ON THE CISCO WEBSITE AT www.cisco.com/go/terms (COLLECTIVELY THE \"AGREEMENT\"). TO THE EXTENT OF ANY CONFLICT BETWEEN THE TERMS OF THIS END USER LICENSE AGREEMENT AND ANY SUPPLEMENTAL LICENSE AGREEMENT, THE SUPPLEMENTAL " +
-            "LICENSE AGREEMENT SHALL APPLY. BY DOWNLOADING, INSTALLING, OR USING THE SOFTWARE, YOU ARE REPRESENTING THAT YOU PURCHASED THE SOFTWARE FROM AN APPROVED SOURCE AND BINDING YOURSELF TO THE AGREEMENT. IF YOU DO NOT AGREE TO ALL OF THE TERMS OF THE AGREEMENT, THEN CISCO IS UNWILLING TO LICENSE THE SOFTWARE TO YOU AND (A) YOU MAY NOT DOWNLOAD, INSTALL OR USE THE SOFTWARE, AND (B) YOU MAY RETURN THE SOFTWARE (INCLUDING ANY UNOPENED CD PACKAGE AND ANY WRITTEN MATERIALS) FOR A FULL REFUND, OR, IF THE SOFTWARE AND WRITTEN MATERIALS ARE SUPPLIED AS PART OF ANOTHER PRODUCT, YOU MAY RETURN THE ENTIRE PRODUCT FOR A FULL REFUND. YOUR RIGHT TO RETURN AND REFUND EXPIRES 30 " +
-            "DAYS AFTER PURCHASE FROM AN APPROVED SOURCE, AND APPLIES ONLY IF YOU ARE THE ORIGINAL AND REGISTERED END USER PURCHASER. FOR THE PURPOSES OF THIS END USER LICENSE AGREEMENT, AN \"APPROVED SOURCE\" MEANS (A) CISCO; OR (B) A DISTRIBUTOR OR SYSTEMS INTEGRATOR AUTHORIZED BY CISCO TO DISTRIBUTE / SELL CISCO EQUIPMENT, SOFTWARE AND SERVICES WITHIN YOUR TERRITORY TO END USERS; OR (C) A RESELLER AUTHORIZED BY ANY SUCH DISTRIBUTOR OR SYSTEMS INTEGRATOR IN ACCORDANCE WITH THE TERMS OF THE DISTRIBUTOR'S AGREEMENT WITH CISCO TO DISTRIBUTE / SELL THE CISCO EQUIPMENT, SOFTWARE AND SERVICES WITHIN YOUR TERRITORY TO END USERS.\n" +
-            "\n" +
-            "THE FOLLOWING TERMS OF THE AGREEMENT GOVERN CUSTOMER'S USE OF THE SOFTWARE (DEFINED BELOW), EXCEPT TO THE EXTENT: (A) THERE IS A SEPARATE SIGNED CONTRACT BETWEEN CUSTOMER AND CISCO GOVERNING CUSTOMER'S USE OF THE SOFTWARE, OR (B) THE SOFTWARE INCLUDES A SEPARATE \"CLICK-ACCEPT\" LICENSE AGREEMENT OR THIRD PARTY LICENSE AGREEMENT AS PART OF THE INSTALLATION OR DOWNLOAD PROCESS GOVERNING CUSTOMER'S USE OF THE SOFTWARE. TO THE EXTENT OF A CONFLICT BETWEEN THE PROVISIONS OF THE FOREGOING DOCUMENTS, THE ORDER OF PRECEDENCE SHALL BE (1)THE SIGNED CONTRACT, (2) THE CLICK-ACCEPT AGREEMENT OR THIRD PARTY LICENSE AGREEMENT, AND (3) THE AGREEMENT. FOR PURPOSES OF THE " +
-            "AGREEMENT, \"SOFTWARE\" SHALL MEAN COMPUTER PROGRAMS, INCLUDING FIRMWARE AND COMPUTER PROGRAMS EMBEDDED IN CISCO EQUIPMENT, AS PROVIDED TO CUSTOMER BY AN APPROVED SOURCE, AND ANY UPGRADES, UPDATES, BUG FIXES OR MODIFIED VERSIONS THERETO (COLLECTIVELY, \"UPGRADES\"), ANY OF THE SAME WHICH HAS BEEN RELICENSED UNDER THE CISCO SOFTWARE TRANSFER AND RE-LICENSING POLICY (AS MAY BE AMENDED BY CISCO FROM TIME TO TIME) OR BACKUP COPIES OF ANY OF THE FOREGOING.\n" +
-            "\n" +
-            "License. Conditioned upon compliance with the terms and conditions of the Agreement, Cisco grants to Customer a nonexclusive and nontransferable license to use for Customer's internal business purposes the Software and the Documentation for which Customer has paid the required license fees to an Approved Source. \"Documentation\" means written information (whether contained in user or technical manuals, training materials, specifications or otherwise) pertaining to the Software and made available by an Approved Source with the Software in any manner (including on CD-Rom, or on-line). In order to use the Software, Customer may be required to input a registration number or product authorization key and register Customer's copy of the Software online at Cisco's website to obtain the necessary license key or license file.\n" +
-            "\n" +
-            "Customer's license to use the Software shall be limited to, and Customer shall not use the Software in excess of, a single hardware chassis or card or such other limitations as are set forth in the applicable Supplemental License Agreement or in the applicable purchase order which has been accepted by an Approved Source and for which Customer has paid to an Approved Source the required license fee (the \"Purchase Order\").\n" +
-            "\n" +
-            "Unless otherwise expressly provided in the Documentation or any applicable Supplemental License Agreement, Customer shall use the Software solely as embedded in, for execution on, or (where the applicable Documentation permits installation on non-Cisco equipment) for communication with Cisco equipment owned or leased by Customer and used for Customer's internal business purposes. No other licenses are granted by implication, estoppel or otherwise.\n" +
-            "\n" +
-            "For evaluation or beta copies for which Cisco does not charge a license fee, the above requirement to pay license fees does not apply.\n" +
-            "\n" +
-            "General Limitations. This is a license, not a transfer of title, to the Software and Documentation, and Cisco retains ownership of all copies of the Software and Documentation. Customer acknowledges that the Software and Documentation contain trade secrets of Cisco or its suppliers or licensors, including but not limited to the specific internal design and structure of individual programs and associated interface information. Except as otherwise expressly provided under the Agreement, Customer shall only use the Software in connection with the use of Cisco equipment purchased by the Customer from an Approved Source and Customer shall have no right, and Customer specifically agrees not to:\n" +
-            "\n" +
-            "(i) transfer, assign or sublicense its license rights to any other person or entity (other than in compliance with any Cisco relicensing/transfer policy then in force), or use the Software on Cisco equipment not purchased by the Customer from an Approved Source or on secondhand Cisco equipment, and Customer acknowledges that any attempted transfer, assignment, sublicense or use shall be void;\n" +
-            "\n" +
-            "(ii) make error corrections to or otherwise modify or adapt the Software or create derivative works based upon the Software, or permit third parties to do the same;\n" +
-            "\n" +
-            "(iii) reverse engineer or decompile, decrypt, disassemble or otherwise reduce the Software to human-readable form, except to the extent otherwise expressly permitted under applicable law notwithstanding this restriction or except to the extent that Cisco is legally required to permit such specific activity pursuant to any applicable open source license;\n" +
-            "\n" +
-            "(iv) publish any results of benchmark tests run on the Software;\n" +
-            "\n" +
-            "(v) use or permit the Software to be used to perform services for third parties, whether on a service bureau or time sharing basis or otherwise, without the express written authorization of Cisco; or\n" +
-            "\n" +
-            "(vi) disclose, provide, or otherwise make available trade secrets contained within the Software and Documentation in any form to any third party without the prior written consent of Cisco. Customer shall implement reasonable security measures to protect such trade secrets.\n" +
-            "\n" +
-            "To the extent required by applicable law, and at Customer's written request, Cisco shall provide Customer with the interface information needed to achieve interoperability between the Software and another independently created program, on payment of Cisco's applicable fee, if any. Customer shall observe strict obligations of confidentiality with respect to such information and shall use such information in compliance with any applicable terms and conditions upon which Cisco makes such information available.\n" +
-            "\n" +
-            "Software, Upgrades and Additional Copies. NOTWITHSTANDING ANY OTHER PROVISION OF THE AGREEMENT: (1) CUSTOMER HAS NO LICENSE OR RIGHT TO MAKE OR USE ANY ADDITIONAL COPIES OR UPGRADES UNLESS CUSTOMER, AT THE TIME OF MAKING OR ACQUIRING SUCH COPY OR UPGRADE, ALREADY HOLDS A VALID LICENSE TO THE ORIGINAL SOFTWARE AND HAS PAID THE APPLICABLE FEE TO AN APPROVED SOURCE FOR THE UPGRADE OR ADDITIONAL COPIES; (2) USE OF UPGRADES IS LIMITED TO CISCO EQUIPMENT SUPPLIED BY AN APPROVED SOURCE FOR WHICH CUSTOMER IS THE ORIGINAL END USER PURCHASER OR LESSEE OR OTHERWISE HOLDS A VALID LICENSE TO USE THE SOFTWARE WHICH IS BEING UPGRADED; AND (3) THE MAKING AND USE OF ADDITIONAL COPIES IS LIMITED TO NECESSARY BACKUP PURPOSES ONLY.\n" +
-            "\n" +
-            "Proprietary Notices. Customer agrees to maintain and reproduce all copyright, proprietary, and other notices on all copies, in any form, of the Software in the same form and manner that such copyright and other proprietary notices are included on the Software. Except as expressly authorized in the Agreement, Customer shall not make any copies or duplicates of any Software without the prior written permission of Cisco.\n" +
-            "\n" +
-            "Term and Termination. The Agreement and the license granted herein shall remain effective until terminated. Customer may terminate the Agreement and the license at any time by destroying all copies of Software and any Documentation. Customer's rights under the Agreement will terminate immediately without notice from Cisco if Customer fails to comply with any provision of the Agreement. Upon termination, Customer shall destroy all copies of Software and Documentation in its possession or control. All confidentiality obligations of Customer, " +
-            "all restrictions and limitations imposed on the Customer under the section titled \"General Limitations\" and all limitations of liability and disclaimers and restrictions of warranty shall survive termination of this Agreement. In addition, the provisions of the sections titled \"U.S. Government End User Purchasers\" and \"General Terms Applicable to the Limited Warranty Statement and End User License Agreement\" shall survive termination of the Agreement.\n" +
-            "\n" +
-            "Customer Records. Customer grants to Cisco and its independent accountants the right to examine Customer's books, records and accounts during Customer's normal business hours to verify compliance with this Agreement. In the event such audit discloses non-compliance with this Agreement, Customer shall promptly pay to Cisco the appropriate license fees, plus the reasonable cost of conducting the audit.\n" +
-            "\n" +
-            "Export, Re-Export, Transfer and Use Controls. The Software, Documentation and technology or direct products thereof (hereafter referred to as Software and Technology), supplied by Cisco under the Agreement are subject to export controls under the laws and regulations of the United States (\"U.S.\") and any other applicable countries' laws and regulations. Customer shall comply with such laws and regulations governing export, re-export, import, transfer and use of Cisco Software and Technology and will obtain all required U.S. and local authorizations, permits, or licenses. Cisco and Customer each agree to provide the other information, support documents, and assistance as may reasonably be required by the other in connection with securing authorizations or licenses. Information regarding compliance with export, re-export, transfer and use may be located at the following URL: www.cisco.com/web/about/doing_business/legal/global_export_trade/general_export/contract_compliance.html\n" +
-            "\n" +
-            "U.S. Government End User Purchasers. The Software and Documentation qualify as \"commercial items,\" as that term is defined at Federal Acquisition Regulation (\"FAR\") (48 C.F.R.) 2.101, consisting of \"commercial computer software\" and \"commercial computer software documentation\" as such terms are used in FAR 12.212. Consistent with FAR 12.212 and DoD FAR Supp. 227.7202-1 through 227.7202-4, and notwithstanding any other FAR or other contractual clause to the contrary in any agreement into which the Agreement may be incorporated, Customer may provide to Government end user or, if the Agreement is direct, Government end user will acquire, the Software and Documentation with only those rights set forth in the Agreement. Use of either the Software or Documentation or both constitutes agreement by the Government that the Software and Documentation are \"commercial computer software\" and \"commercial " +
-            "computer software documentation,\" and constitutes acceptance of the rights and restrictions herein.\n" +
-            "\n" +
-            "Identified Components; Additional Terms. The Software may contain or be delivered with one or more components, which may include third-party components, identified by Cisco in the Documentation, readme.txt file, third-party click-accept or elsewhere (e.g. on www.cisco.com) (the \"Identified Component(s)\") as being subject to different license agreement terms, disclaimers of warranties, limited warranties or other terms and conditions (collectively, \"Additional Terms\") than those set forth herein. You agree to the applicable Additional Terms for any such Identified Component(s).\n" +
-            "\n" +
-            "Limited Warranty\n" +
-            "\n" +
-            "Subject to the limitations and conditions set forth herein, Cisco warrants that commencing from the date of shipment to Customer (but in case of resale by an Approved Source other than Cisco, commencing not more than ninety (90) days after original shipment by Cisco), and continuing for a period of the longer of (a) ninety (90) days or (b) the warranty period (if any) expressly set forth as applicable specifically to software in the warranty card accompanying the product of which the Software is a part (the \"Product\") (if any): (a) the media on which the Software is furnished will be free of defects in materials and workmanship under normal use; and (b) the Software substantially conforms to the Documentation. The date of shipment of a Product by Cisco is set forth " +
-            "on the packaging material in which the Product is shipped. Except for the foregoing, the Software is provided \"AS IS\". This limited warranty extends only to the Software purchased from an Approved Source by a Customer who is the first registered end user. Customer's sole and exclusive remedy and the entire liability of Cisco and its suppliers under this limited warranty will be (i) replacement of defective media and/or (ii) at Cisco's option, repair, replacement, or refund of the purchase price of the Software, in both cases subject to the condition that any error or defect constituting a breach of this limited warranty is reported to the Approved Source supplying the Software to Customer, within the warranty period. Cisco or the Approved Source supplying the Software to Customer may, at its option, require return of the Software and/or Documentation as a condition to the remedy. " +
-            "In no event does Cisco warrant that the Software is error free or that Customer will be able to operate the Software without problems or interruptions. In addition, due to the continual development of new techniques for intruding upon and attacking networks, Cisco does not warrant that the Software or any equipment, system or network on which the Software is used will be free of vulnerability to intrusion or attack.\n" +
-            "\n" +
-            "Restrictions. This warranty does not apply if the Software, Product or any other equipment upon which the Software is authorized to be used (a) has been altered, except by Cisco or its authorized representative, (b) has not been installed, operated, repaired, or maintained in accordance with instructions supplied by Cisco, (c) has been subjected to abnormal physical or electrical stress, abnormal environmental conditions, misuse, negligence, or accident; or (d) is licensed for beta, evaluation, testing or demonstration purposes. The Software warranty also does not apply to (e) any temporary Software modules; (f) any Software not posted on Cisco's Software Center; (g) any Software that Cisco expressly provides on an \"AS IS\" basis on Cisco's Software Center; (h) any Software for which an Approved Source does not receive a license fee; and (i) Software supplied by any third party which is not an Approved Source.\n" +
-            "\n" +
-            "DISCLAIMER OF WARRANTY\n" +
-            "\n" +
-            "EXCEPT AS SPECIFIED IN THIS WARRANTY SECTION, ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS, AND WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OR CONDITION OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, SATISFACTORY QUALITY, NON-INTERFERENCE, ACCURACY OF INFORMATIONAL CONTENT, OR ARISING FROM A COURSE OF DEALING, LAW, USAGE, OR TRADE PRACTICE, ARE HEREBY EXCLUDED TO THE EXTENT ALLOWED BY APPLICABLE LAW AND ARE EXPRESSLY DISCLAIMED BY CISCO, ITS SUPPLIERS AND LICENSORS. TO THE EXTENT THAT ANY OF THE SAME CANNOT BE EXCLUDED, SUCH IMPLIED CONDITION, REPRESENTATION AND/OR WARRANTY IS LIMITED IN DURATION TO THE EXPRESS WARRANTY PERIOD REFERRED TO IN THE \"LIMITED WARRANTY\" SECTION ABOVE. BECAUSE SOME STATES OR JURISDICTIONS " +
-            "DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY LASTS, THE ABOVE LIMITATION MAY NOT APPLY IN SUCH STATES. THIS WARRANTY GIVES CUSTOMER SPECIFIC LEGAL RIGHTS, AND CUSTOMER MAY ALSO HAVE OTHER RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION. This disclaimer and exclusion shall apply even if the express warranty set forth above fails of its essential purpose.\n" +
-            "\n" +
-            "Disclaimer of Liabilities-Limitation of Liability. IF YOU ACQUIRED THE SOFTWARE IN THE UNITED STATES, LATIN AMERICA, CANADA, JAPAN OR THE CARIBBEAN, NOTWITHSTANDING ANYTHING ELSE IN THE AGREEMENT TO THE CONTRARY, ALL LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS COLLECTIVELY, TO CUSTOMER, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY OR OTHERWISE, SHALL NOT EXCEED THE PRICE PAID BY CUSTOMER TO ANY APPROVED SOURCE FOR THE SOFTWARE THAT GAVE RISE TO THE CLAIM OR IF THE SOFTWARE IS PART OF ANOTHER PRODUCT, THE PRICE PAID FOR SUCH OTHER PRODUCT. THIS LIMITATION OF LIABILITY FOR SOFTWARE IS CUMULATIVE AND NOT PER INCIDENT (I.E. THE EXISTENCE OF TWO OR MORE CLAIMS WILL NOT ENLARGE THIS LIMIT).\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN EUROPE, THE MIDDLE EAST, AFRICA, ASIA OR OCEANIA, NOTWITHSTANDING ANYTHING ELSE IN THE AGREEMENT TO THE CONTRARY, ALL LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS COLLECTIVELY, TO CUSTOMER, WHETHER IN CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY OR OTHERWISE, SHALL NOT EXCEED THE PRICE PAID BY CUSTOMER TO CISCO FOR THE SOFTWARE THAT GAVE RISE TO THE CLAIM OR IF THE SOFTWARE IS PART OF ANOTHER PRODUCT, THE PRICE PAID FOR SUCH OTHER PRODUCT. THIS LIMITATION OF LIABILITY FOR SOFTWARE IS CUMULATIVE AND NOT PER INCIDENT (I.E. THE EXISTENCE OF TWO OR MORE CLAIMS WILL NOT ENLARGE THIS LIMIT). NOTHING IN THE AGREEMENT SHALL LIMIT (I) THE LIABILITY OF CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS TO CUSTOMER FOR PERSONAL " +
-            "INJURY OR DEATH CAUSED BY THEIR NEGLIGENCE, (II) CISCO'S LIABILITY FOR FRAUDULENT MISREPRESENTATION, OR (III) ANY LIABILITY OF CISCO WHICH CANNOT BE EXCLUDED UNDER APPLICABLE LAW.\n" +
-            "\n" +
-            "Disclaimer of Liabilities-Waiver of Consequential Damages and Other Losses. IF YOU ACQUIRED THE SOFTWARE IN THE UNITED STATES, LATIN AMERICA, THE CARIBBEAN OR CANADA, REGARDLESS OF WHETHER ANY REMEDY SET FORTH HEREIN FAILS OF ITS ESSENTIAL PURPOSE OR OTHERWISE, IN NO EVENT WILL CISCO OR ITS SUPPLIERS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE OR OTHERWISE AND EVEN IF CISCO OR ITS SUPPLIERS OR LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN JAPAN, EXCEPT FOR LIABILITY ARISING OUT OF OR IN CONNECTION WITH DEATH OR PERSONAL INJURY, FRAUDULENT MISREPRESENTATION, AND REGARDLESS OF WHETHER ANY REMEDY SET FORTH HEREIN FAILS OF ITS ESSENTIAL PURPOSE OR OTHERWISE, IN NO EVENT WILL CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE OR OTHERWISE AND EVEN IF CISCO OR ANY APPROVED SOURCE OR THEIR SUPPLIERS OR LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n" +
-            "\n" +
-            "IF YOU ACQUIRED THE SOFTWARE IN EUROPE, THE MIDDLE EAST, AFRICA, ASIA OR OCEANIA, IN NO EVENT WILL CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS, BE LIABLE FOR ANY LOST REVENUE, LOST PROFIT, OR LOST OR DAMAGED DATA, BUSINESS INTERRUPTION, LOSS OF CAPITAL, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR PUNITIVE DAMAGES, HOWSOEVER ARISING, INCLUDING, WITHOUT LIMITATION, IN CONTRACT, TORT (INCLUDING NEGLIGENCE) OR WHETHER ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF, IN EACH CASE, CISCO, ITS AFFILIATES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, SUPPLIERS AND LICENSORS, HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES OR JURISDICTIONS DO NOT ALLOW LIMITATION OR EXCLUSION OF CONSEQUENTIAL OR INCIDENTAL" +
-            " DAMAGES, THE ABOVE LIMITATION MAY NOT FULLY APPLY TO YOU. THE FOREGOING EXCLUSION SHALL NOT APPLY TO ANY LIABILITY ARISING OUT OF OR IN CONNECTION WITH: (I) DEATH OR PERSONAL INJURY, (II) FRAUDULENT MISREPRESENTATION, OR (III) CISCO'S LIABILITY IN CONNECTION WITH ANY TERMS THAT CANNOT BE EXCLUDED UNDER APPLICABLE LAW.\n" +
-            "\n" +
-            "Customer acknowledges and agrees that Cisco has set its prices and entered into the Agreement in reliance upon the disclaimers of warranty and the limitations of liability set forth herein, that the same reflect an allocation of risk between the parties (including the risk that a contract remedy may fail of its essential purpose and cause consequential loss), and that the same form an essential basis of the bargain between the parties.\n" +
-            "\n" +
-            "Controlling Law, Jurisdiction. If you acquired, by reference to the address on the purchase order accepted by the Approved Source, the Software in the United States, Latin America, or the Caribbean, the Agreement and warranties (\"Warranties\") are controlled by and construed under the laws of the State of California, United States of America, notwithstanding any conflicts of law provisions; and the state and federal courts of California shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in Canada, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the Province of Ontario, Canada, notwithstanding any conflicts of law provisions; and the courts of the " +
-            "Province of Ontario shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in Europe, the Middle East, Africa, Asia or Oceania (excluding Australia), unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of England, notwithstanding any conflicts of law provisions; and the English courts shall have exclusive jurisdiction over any " +
-            "claim arising under the Agreement or Warranties. In addition, if the Agreement is controlled by the laws of England, no person who is not a party to the Agreement shall be entitled to enforce or take the benefit of any of its terms under the Contracts (Rights of Third Parties) Act 1999. If you acquired the Software in Japan, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of Japan, notwithstanding any conflicts of law provisions; and the Tokyo District Court of Japan shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in Australia, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the " +
-            "State of New South Wales, Australia, notwithstanding any conflicts of law provisions; and the State and federal courts of New South Wales shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties. If you acquired the Software in any other country, unless expressly prohibited by local law, the Agreement and Warranties are controlled by and construed under the laws of the State of California, United States of America, " +
-            "notwithstanding any conflicts of law provisions; and the state and federal courts of California shall have exclusive jurisdiction over any claim arising under the Agreement or Warranties.\n" +
-            "\n" +
-            "For all countries referred to above, the parties specifically disclaim the application of the UN Convention on Contracts for the International Sale of Goods. Notwithstanding the foregoing, either party may seek interim injunctive relief in any court of appropriate jurisdiction with respect to any alleged breach of such party's intellectual property or proprietary rights. If any portion hereof is found to be void or unenforceable, the remaining provisions of the Agreement and Warranties shall remain in full force and effect. Except as expressly provided herein, the Agreement constitutes the entire agreement between the parties with respect to the license of the Software and Documentation and supersedes any conflicting or additional terms contained in any Purchase Order or elsewhere, all of which terms are excluded. The Agreement has been written in the English language, and the parties agree that the English version will govern.\n" +
-            "\n" +
-            "Product warranty terms and other information applicable to Cisco products are available at the following URL: www.cisco.com/go/warranty\n" +
-            "\n" +
-            "Cisco and the Cisco logo are trademarks or registered trademarks of Cisco and/or its affiliates in the U.S. and other countries. To view a list of Cisco trademarks, go to this URL: www.cisco.com/go/trademarks. Third-party trademarks mentioned are the property of their respective owners. The use of the word partner does not imply a partnership relationship between Cisco and any other company. (1110R)\n" +
-            "\n" +
-            "© 1998, 2001, 2003, 2008-2014 Cisco Systems, Inc. All rights reserved.";
-
-    @Test
-    public void testCompressDecompressString() throws IOException {
-        byte[] compressed = util.compressString(testEula);
-        String decompressed = util.decompressByteArary(compressed);
-        Assert.assertEquals(decompressed, testEula);
-    }
-}
diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml
index ef03d9a..c84580f 100644
--- a/vmware-base/pom.xml
+++ b/vmware-base/pom.xml
@@ -75,11 +75,5 @@
             <version>${cs.jaxws.version}</version>
             <type>pom</type>
         </dependency>
-        <dependency>
-            <groupId>com.cloud.com.vmware</groupId>
-            <artifactId>vmware-pbm</artifactId>
-            <version>${cs.vmware.api.version}</version>
-            <scope>compile</scope>
-        </dependency>
     </dependencies>
 </project>
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
index 1bcebc9..92b05f2 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/ClusterMO.java
@@ -386,7 +386,7 @@
     }
 
     @Override
-    public void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, String configurationId) throws Exception {
+    public void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption) throws Exception {
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - importVmFromOVF(). target MOR: " + _mor.getValue() + ", ovfFilePath: " + ovfFilePath + ", vmName: " + vmName +
                     ", datastore: " + dsMo.getMor().getValue() + ", diskOption: " + diskOption);
@@ -397,7 +397,7 @@
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - importVmFromOVF(). resource pool: " + morRp.getValue());
 
-        HypervisorHostHelper.importVmFromOVF(this, ovfFilePath, vmName, dsMo, diskOption, morRp, null, configurationId);
+        HypervisorHostHelper.importVmFromOVF(this, ovfFilePath, vmName, dsMo, diskOption, morRp, null);
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - importVmFromOVF() done");
@@ -423,7 +423,7 @@
     }
 
     @Override
-    public ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid, boolean createBaseFolder) throws Exception {
+    public ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid) throws Exception {
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - mountDatastore(). target MOR: " + _mor.getValue() + ", vmfs: " + vmfsDatastore + ", poolHost: " + poolHostAddress +
@@ -435,7 +435,7 @@
         if (hosts != null && hosts.size() > 0) {
             for (ManagedObjectReference morHost : hosts) {
                 HostMO hostMo = new HostMO(_context, morHost);
-                morDs = hostMo.mountDatastore(vmfsDatastore, poolHostAddress, poolHostPort, poolPath, poolUuid, true);
+                morDs = hostMo.mountDatastore(vmfsDatastore, poolHostAddress, poolHostPort, poolPath, poolUuid);
                 if (morDsFirst == null)
                     morDsFirst = morDs;
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
index af89757..b0b91fb 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
@@ -186,20 +186,6 @@
         return null;
     }
 
-    public ManagedObjectReference listDatastore(String name) throws Exception {
-        assert (name != null);
-
-        List<ObjectContent> ocs = getDatastorePropertiesOnDatacenter(new String[] {"name"});
-        if (ocs != null) {
-            for (ObjectContent oc : ocs) {
-                if (oc.getPropSet().get(0).getVal().toString().equals(name)) {
-                    return oc.getObj();
-                }
-            }
-        }
-        return null;
-    }
-
     public ManagedObjectReference findHost(String name) throws Exception {
         List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
index 804af62..1e065a1 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatastoreMO.java
@@ -16,10 +16,11 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import com.cloud.exception.CloudException;
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.cloud.utils.Pair;
-import com.vmware.pbm.PbmProfile;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
 import com.vmware.vim25.DatastoreHostMount;
 import com.vmware.vim25.DatastoreSummary;
 import com.vmware.vim25.FileInfo;
@@ -34,10 +35,10 @@
 import com.vmware.vim25.PropertySpec;
 import com.vmware.vim25.SelectionSpec;
 import com.vmware.vim25.TraversalSpec;
-import org.apache.log4j.Logger;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.cloud.exception.CloudException;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.utils.Pair;
 
 import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
 
@@ -63,7 +64,7 @@
         return _name;
     }
 
-    public DatastoreSummary getDatastoreSummary() throws Exception {
+    public DatastoreSummary getSummary() throws Exception {
         return (DatastoreSummary)_context.getVimClient().getDynamicProperty(_mor, "summary");
     }
 
@@ -136,16 +137,6 @@
             fullPath = String.format("[%s] %s", datastoreName, path);
 
         _context.getService().makeDirectory(morFileManager, fullPath, morDc, true);
-
-        int retry = 2;
-        for (int i = 0; i < retry; i++) {
-            DatastoreFile datastoreFile = new DatastoreFile(fullPath);
-            if (!folderExists(String.format("[%s]", datastoreName), datastoreFile.getFileName())) {
-                _context.getService().makeDirectory(morFileManager, fullPath, morDc, true);
-            } else {
-                return;
-            }
-        }
     }
 
     String getDatastoreRootPath() throws Exception {
@@ -269,17 +260,6 @@
         if (!DatastoreFile.isFullDatastorePath(destFullPath))
             destFullPath = String.format("[%s] %s", destDsName, destFilePath);
 
-        DatastoreMO srcDsMo = new DatastoreMO(_context, morDestDs);
-        try {
-            if (!srcDsMo.fileExists(srcFullPath)) {
-                s_logger.error(String.format("Cannot move file to destination datastore due to file %s does not exists", srcFullPath));
-                return false;
-            }
-        } catch (Exception e) {
-            s_logger.error(String.format("Cannot move file to destination datastore due to file %s due to exeception %s", srcFullPath, e.getMessage()));
-            return false;
-        }
-
         ManagedObjectReference morTask = _context.getService().moveDatastoreFileTask(morFileManager, srcFullPath, morSrcDc, destFullPath, morDestDc, forceOverwrite);
 
         boolean result = _context.getVimClient().waitForTask(morTask);
@@ -287,11 +267,52 @@
             _context.waitForTaskProgressDone(morTask);
             return true;
         } else {
-            s_logger.error("VMware moveDatastoreFile_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            s_logger.error("VMware moveDatgastoreFile_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
         }
         return false;
     }
 
+    public String[] getVmdkFileChain(String rootVmdkDatastoreFullPath) throws Exception {
+        Pair<DatacenterMO, String> dcPair = getOwnerDatacenter();
+
+        List<String> files = new ArrayList<>();
+        files.add(rootVmdkDatastoreFullPath);
+
+        String currentVmdkFullPath = rootVmdkDatastoreFullPath;
+        while (true) {
+            String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), currentVmdkFullPath);
+            byte[] content = getContext().getResourceContent(url);
+            if (content == null || content.length == 0)
+                break;
+
+            VmdkFileDescriptor descriptor = new VmdkFileDescriptor();
+            descriptor.parse(content);
+
+            String parentFileName = descriptor.getParentFileName();
+            if (parentFileName == null)
+                break;
+
+            if (parentFileName.startsWith("/")) {
+                // when parent file is not at the same directory as it is, assume it is at parent directory
+                // this is only valid in Apache CloudStack primary storage deployment
+                DatastoreFile dsFile = new DatastoreFile(currentVmdkFullPath);
+                String dir = dsFile.getDir();
+                if (dir != null && dir.lastIndexOf('/') > 0)
+                    dir = dir.substring(0, dir.lastIndexOf('/'));
+                else
+                    dir = "";
+
+                currentVmdkFullPath = new DatastoreFile(dsFile.getDatastoreName(), dir, parentFileName.substring(parentFileName.lastIndexOf('/') + 1)).getPath();
+                files.add(currentVmdkFullPath);
+            } else {
+                currentVmdkFullPath = DatastoreFile.getCompanionDatastorePath(currentVmdkFullPath, parentFileName);
+                files.add(currentVmdkFullPath);
+            }
+        }
+
+        return files.toArray(new String[0]);
+    }
+
     @Deprecated
     public String[] listDirContent(String path) throws Exception {
         String fullPath = path;
@@ -406,8 +427,6 @@
                     s_logger.info("Found file " + fileName + " in datastore at " + absoluteFileName);
                     if (parentFolderPath.endsWith("]"))
                         absoluteFileName += " ";
-                    else if (!parentFolderPath.endsWith("/"))
-                        absoluteFileName +="/";
                     absoluteFileName += fi.getPath();
                     if(isValidCloudStackFolderPath(parentFolderPath, searchExcludedFolders)) {
                         return absoluteFileName;
@@ -446,19 +465,4 @@
         }
         return isAccessible;
     }
-
-    public boolean isDatastoreStoragePolicyComplaint(String storagePolicyId) throws Exception {
-        PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(_context);
-        PbmProfile profile = profMgrMo.getStorageProfile(storagePolicyId);
-
-        PbmPlacementSolverMO placementSolverMo = new PbmPlacementSolverMO(_context);
-        boolean isDatastoreCompatible = placementSolverMo.isDatastoreCompatibleWithStorageProfile(_mor, profile);
-
-        return isDatastoreCompatible;
-    }
-
-    public String getDatastoreType() throws Exception {
-        DatastoreSummary summary = _context.getVimClient().getDynamicProperty(getMor(), "summary");
-        return summary.getType();
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
index 30798e3..f38f610 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostDatastoreSystemMO.java
@@ -16,7 +16,11 @@
 // under the License.
 package com.cloud.hypervisor.vmware.mo;
 
-import com.cloud.hypervisor.vmware.util.VmwareContext;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import com.vmware.vim25.CustomFieldStringValue;
 import com.vmware.vim25.DatastoreInfo;
 import com.vmware.vim25.DynamicProperty;
@@ -31,18 +35,12 @@
 import com.vmware.vim25.ObjectSpec;
 import com.vmware.vim25.PropertyFilterSpec;
 import com.vmware.vim25.PropertySpec;
-import com.vmware.vim25.RetrieveOptions;
-import com.vmware.vim25.RetrieveResult;
-import com.vmware.vim25.SelectionSpec;
 import com.vmware.vim25.TraversalSpec;
 import com.vmware.vim25.VmfsDatastoreCreateSpec;
 import com.vmware.vim25.VmfsDatastoreExpandSpec;
 import com.vmware.vim25.VmfsDatastoreOption;
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import com.cloud.hypervisor.vmware.util.VmwareContext;
 
 public class HostDatastoreSystemMO extends BaseMO {
 
@@ -55,14 +53,6 @@
     }
 
     public ManagedObjectReference findDatastore(String name) throws Exception {
-        ManagedObjectReference morDatastore = findSpecificDatastore(name);
-        if (morDatastore == null) {
-            morDatastore = findDatastoreCluster(name);
-        }
-        return morDatastore;
-    }
-
-    public ManagedObjectReference findSpecificDatastore(String name) throws Exception {
         // added Apache CloudStack specific name convention, we will use custom field "cloud.uuid" as datastore name as well
         CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager());
         int key = cfmMo.getCustomFieldKey("Datastore", CustomFieldConstants.CLOUD_UUID);
@@ -89,33 +79,6 @@
         return null;
     }
 
-    public ManagedObjectReference findDatastoreCluster(String name) throws Exception {
-        // added Apache CloudStack specific name convention, we will use custom field "cloud.uuid" as datastore name as well
-        CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager());
-        int key = cfmMo.getCustomFieldKey("StoragePod", CustomFieldConstants.CLOUD_UUID);
-        assert (key != 0);
-
-        List<ObjectContent> ocs = getDatastoreClusterPropertiesOnHostDatastoreSystem(new String[] {"name", String.format("value[%d]", key)});
-        if (ocs != null) {
-            for (ObjectContent oc : ocs) {
-                if (oc.getPropSet().get(0).getVal().equals(name))
-                    return oc.getObj();
-
-                if (oc.getPropSet().size() > 1) {
-                    DynamicProperty prop = oc.getPropSet().get(1);
-                    if (prop != null && prop.getVal() != null) {
-                        if (prop.getVal() instanceof CustomFieldStringValue) {
-                            String val = ((CustomFieldStringValue)prop.getVal()).getValue();
-                            if (val.equalsIgnoreCase(name))
-                                return oc.getObj();
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
     public List<HostUnresolvedVmfsVolume> queryUnresolvedVmfsVolumes() throws Exception {
         return _context.getService().queryUnresolvedVmfsVolumes(_mor);
     }
@@ -288,90 +251,4 @@
 
         return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
     }
-
-    public List<ObjectContent> getDatastoreClusterPropertiesOnHostDatastoreSystem(String[] propertyPaths) throws Exception {
-        ManagedObjectReference retVal = null;
-        // Create Property Spec
-        PropertySpec propertySpec = new PropertySpec();
-        propertySpec.setAll(Boolean.FALSE);
-        propertySpec.setType("StoragePod");
-        propertySpec.getPathSet().addAll(Arrays.asList(propertyPaths));
-
-        // Now create Object Spec
-        ObjectSpec objectSpec = new ObjectSpec();
-        objectSpec.setObj(getContext().getRootFolder());
-        objectSpec.setSkip(Boolean.TRUE);
-        objectSpec.getSelectSet().addAll(
-                Arrays.asList(getStorageTraversalSpec()));
-
-        // Create PropertyFilterSpec using the PropertySpec and ObjectPec
-        // created above.
-        PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
-        propertyFilterSpec.getPropSet().add(propertySpec);
-        propertyFilterSpec.getObjectSet().add(objectSpec);
-
-        List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>();
-        listpfs.add(propertyFilterSpec);
-        return retrievePropertiesAllObjects(listpfs);
-    }
-
-    private SelectionSpec[] getStorageTraversalSpec() {
-        // create a traversal spec that start from root folder
-
-        SelectionSpec ssFolders = new SelectionSpec();
-        ssFolders.setName("visitFolders");
-
-        TraversalSpec datacenterSpec = new TraversalSpec();
-        datacenterSpec.setName("dcTodf");
-        datacenterSpec.setType("Datacenter");
-        datacenterSpec.setPath("datastoreFolder");
-        datacenterSpec.setSkip(Boolean.FALSE);
-        datacenterSpec.getSelectSet().add(ssFolders);
-
-        TraversalSpec visitFolder = new TraversalSpec();
-        visitFolder.setType("Folder");
-        visitFolder.setName("visitFolders");
-        visitFolder.setPath("childEntity");
-        visitFolder.setSkip(Boolean.FALSE);
-
-        List<SelectionSpec> ssSpecList = new ArrayList<SelectionSpec>();
-        ssSpecList.add(datacenterSpec);
-        ssSpecList.add(ssFolders);
-
-        visitFolder.getSelectSet().addAll(ssSpecList);
-        return (new SelectionSpec[]{visitFolder});
-    }
-
-    private List<ObjectContent> retrievePropertiesAllObjects(
-            List<PropertyFilterSpec> listpfs) throws Exception {
-
-        RetrieveOptions propObjectRetrieveOpts = new RetrieveOptions();
-
-        List<ObjectContent> listobjcontent = new ArrayList<ObjectContent>();
-
-        RetrieveResult rslts =
-                getContext().getService().retrievePropertiesEx(getContext().getServiceContent().getPropertyCollector(), listpfs,
-                        propObjectRetrieveOpts);
-        if (rslts != null && rslts.getObjects() != null
-                && !rslts.getObjects().isEmpty()) {
-            listobjcontent.addAll(rslts.getObjects());
-        }
-        String token = null;
-        if (rslts != null && rslts.getToken() != null) {
-            token = rslts.getToken();
-        }
-        while (token != null && !token.isEmpty()) {
-            rslts =
-                    getContext().getService().continueRetrievePropertiesEx(getContext().getServiceContent().getPropertyCollector(), token);
-            token = null;
-            if (rslts != null) {
-                token = rslts.getToken();
-                if (rslts.getObjects() != null && !rslts.getObjects().isEmpty()) {
-                    listobjcontent.addAll(rslts.getObjects());
-                }
-            }
-        }
-        return listobjcontent;
-    }
-
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
index 0457039..c248f7a 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -760,7 +760,7 @@
         return dsList;
     }
 
-    public void importVmFromOVF(String ovfFilePath, String vmName, String datastoreName, String diskOption, String configurationId) throws Exception {
+    public void importVmFromOVF(String ovfFilePath, String vmName, String datastoreName, String diskOption) throws Exception {
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - importVmFromOVF(). target MOR: " + _mor.getValue() + ", ovfFilePath: " + ovfFilePath + ", vmName: " + vmName +
                     ",datastoreName: " + datastoreName + ", diskOption: " + diskOption);
@@ -769,19 +769,19 @@
         if (dsMo == null)
             throw new Exception("Invalid datastore name: " + datastoreName);
 
-        importVmFromOVF(ovfFilePath, vmName, dsMo, diskOption, configurationId);
+        importVmFromOVF(ovfFilePath, vmName, dsMo, diskOption);
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - importVmFromOVF() done");
     }
 
     @Override
-    public void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, String configurationId) throws Exception {
+    public void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption) throws Exception {
 
         ManagedObjectReference morRp = getHyperHostOwnerResourcePool();
         assert (morRp != null);
 
-        HypervisorHostHelper.importVmFromOVF(this, ovfFilePath, vmName, dsMo, diskOption, morRp, _mor, configurationId);
+        HypervisorHostHelper.importVmFromOVF(this, ovfFilePath, vmName, dsMo, diskOption, morRp, _mor);
     }
 
     @Override
@@ -836,13 +836,12 @@
     }
 
     @Override
-    public ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid, boolean createBaseFolder) throws Exception {
+    public ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid) throws Exception {
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - mountDatastore(). target MOR: " + _mor.getValue() + ", vmfs: " + vmfsDatastore + ", poolHost: " + poolHostAddress +
                     ", poolHostPort: " + poolHostPort + ", poolPath: " + poolPath + ", poolUuid: " + poolUuid);
 
-        DatastoreMO dsMo = null;
         HostDatastoreSystemMO hostDatastoreSystemMo = getHostDatastoreSystemMO();
         ManagedObjectReference morDatastore = hostDatastoreSystemMo.findDatastore(poolUuid);
         if (morDatastore == null) {
@@ -869,30 +868,22 @@
                         s_logger.trace("vCenter API trace - mountDatastore() done(failed)");
                     throw new Exception(msg);
                 }
-                dsMo = new DatastoreMO(_context, morDatastore);
             } else {
                 morDatastore = _context.getDatastoreMorByPath(poolPath);
                 if (morDatastore == null) {
-                    morDatastore = findDatastore(_context.getDatastoreNameFromPath(poolPath));
-                    if (morDatastore == null) {
-                        String msg = "Unable to create VMFS datastore. host: " + poolHostAddress + ", port: " + poolHostPort + ", path: " + poolPath + ", uuid: " + poolUuid;
-                        s_logger.error(msg);
+                    String msg = "Unable to create VMFS datastore. host: " + poolHostAddress + ", port: " + poolHostPort + ", path: " + poolPath + ", uuid: " + poolUuid;
+                    s_logger.error(msg);
 
-                        if (s_logger.isTraceEnabled())
-                            s_logger.trace("vCenter API trace - mountDatastore() done(failed)");
-                        throw new Exception(msg);
-                    }
+                    if (s_logger.isTraceEnabled())
+                        s_logger.trace("vCenter API trace - mountDatastore() done(failed)");
+                    throw new Exception(msg);
                 }
 
-                dsMo = new DatastoreMO(_context, morDatastore);
+                DatastoreMO dsMo = new DatastoreMO(_context, morDatastore);
                 dsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, poolUuid);
             }
         }
 
-        if (dsMo != null && !"StoragePod".equals(morDatastore.getType()) && createBaseFolder) {
-            HypervisorHostHelper.createBaseFolderInDatastore(dsMo, this);
-        }
-
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - mountDatastore() done(successfully)");
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index 37d97ae..1242d25 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -37,17 +37,6 @@
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-import com.vmware.vim25.ConcurrentAccessFaultMsg;
-import com.vmware.vim25.DuplicateNameFaultMsg;
-import com.vmware.vim25.FileFaultFaultMsg;
-import com.vmware.vim25.InsufficientResourcesFaultFaultMsg;
-import com.vmware.vim25.InvalidDatastoreFaultMsg;
-import com.vmware.vim25.InvalidNameFaultMsg;
-import com.vmware.vim25.InvalidStateFaultMsg;
-import com.vmware.vim25.OutOfBoundsFaultMsg;
-import com.vmware.vim25.RuntimeFaultFaultMsg;
-import com.vmware.vim25.TaskInProgressFaultMsg;
-import com.vmware.vim25.VmConfigFaultFaultMsg;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
@@ -65,7 +54,6 @@
 import com.cloud.hypervisor.vmware.util.VmwareHelper;
 import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.offering.NetworkOffering;
-import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.utils.ActionDelegate;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -150,8 +138,6 @@
     private static final String UNTAGGED_VLAN_NAME = "untagged";
     private static final String VMDK_PACK_DIR = "ova";
     private static final String OVA_OPTION_KEY_BOOTDISK = "cloud.ova.bootdisk";
-    public static final String VSPHERE_DATASTORE_BASE_FOLDER = "fcd";
-    public static final String VSPHERE_DATASTORE_HIDDEN_FOLDER = ".hidden";
 
     public static VirtualMachineMO findVmFromObjectContent(VmwareContext context, ObjectContent[] ocs, String name, String instanceNameCustomField) {
 
@@ -1479,7 +1465,7 @@
         if (vmInternalCSName == null)
             vmInternalCSName = vmName;
 
-        VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse, false);
+        VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse);
 
         String recommendedController = host.getRecommendedDiskController(guestOsIdentifier);
         String newRootDiskController = controllerInfo.first();
@@ -1574,35 +1560,20 @@
      * - If the cluster hardware version is not set, check datacenter hardware version. If it is set, then it is set to vmConfig
      * - In case both cluster and datacenter hardware version are not set, hardware version is not set to vmConfig
      */
-    public static void setVMHardwareVersion(VirtualMachineConfigSpec vmConfig, ClusterMO clusterMO, DatacenterMO datacenterMO) throws Exception {
-        String version = getNewVMHardwareVersion(clusterMO, datacenterMO);
-        if (StringUtils.isNotBlank(version)) {
-            vmConfig.setVersion(version);
-        }
-    }
-
-    /**
-     * Return the VM hardware version based on the information retrieved by the cluster and datacenter:
-     * - If the cluster hardware version is set, then return this hardware version
-     * - If the cluster hardware version is not set, check datacenter hardware version. If it is set, then return it
-     * - In case both cluster and datacenter hardware version are not set, return null
-     */
-    public static String getNewVMHardwareVersion(ClusterMO clusterMO, DatacenterMO datacenterMO) throws Exception {
-        String version = null;
+    protected static void setVMHardwareVersion(VirtualMachineConfigSpec vmConfig, ClusterMO clusterMO, DatacenterMO datacenterMO) throws Exception {
         ClusterConfigInfoEx clusterConfigInfo = clusterMO != null ? clusterMO.getClusterConfigInfo() : null;
         String clusterHardwareVersion = clusterConfigInfo != null ? clusterConfigInfo.getDefaultHardwareVersionKey() : null;
         if (StringUtils.isNotBlank(clusterHardwareVersion)) {
             s_logger.debug("Cluster hardware version found: " + clusterHardwareVersion + ". Creating VM with this hardware version");
-            version = clusterHardwareVersion;
+            vmConfig.setVersion(clusterHardwareVersion);
         } else {
             DatacenterConfigInfo datacenterConfigInfo = datacenterMO != null ? datacenterMO.getDatacenterConfigInfo() : null;
             String datacenterHardwareVersion = datacenterConfigInfo != null ? datacenterConfigInfo.getDefaultHardwareVersionKey() : null;
             if (StringUtils.isNotBlank(datacenterHardwareVersion)) {
                 s_logger.debug("Datacenter hardware version found: " + datacenterHardwareVersion + ". Creating VM with this hardware version");
-                version = datacenterHardwareVersion;
+                vmConfig.setVersion(datacenterHardwareVersion);
             }
         }
-        return version;
     }
 
     private static VirtualDeviceConfigSpec getControllerSpec(String diskController, int busNum) {
@@ -1641,9 +1612,6 @@
         if (morCluster != null)
             hyperHost = new ClusterMO(hyperHost.getContext(), morCluster);
 
-        if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL") && !vmName.startsWith(CustomFieldConstants.CLOUD_UUID)) {
-            vmName = CustomFieldConstants.CLOUD_UUID + "-" + vmName;
-        }
         VirtualMachineMO workingVM = null;
         VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
         vmConfig.setName(vmName);
@@ -1743,11 +1711,6 @@
         return url;
     }
 
-    /**
-     * removes the NetworkSection element from the {ovfString} if it is an ovf xml file
-     * @param ovfString input string
-     * @return like the input string but if xml elements by name {NetworkSection} removed
-     */
     public static String removeOVFNetwork(final String ovfString)  {
         if (ovfString == null || ovfString.isEmpty()) {
             return ovfString;
@@ -1782,12 +1745,8 @@
         return ovfString;
     }
 
-    /**
-     * deploys a new VM from a ovf spec. It ignores network, defaults locale to 'US'
-     * @throws Exception shoud be a VmwareResourceException
-     */
     public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, ManagedObjectReference morRp,
-                                       ManagedObjectReference morHost, String configurationId) throws CloudRuntimeException, IOException {
+            ManagedObjectReference morHost) throws Exception {
 
         assert (morRp != null);
 
@@ -1795,34 +1754,24 @@
         importSpecParams.setHostSystem(morHost);
         importSpecParams.setLocale("US");
         importSpecParams.setEntityName(vmName);
-        String deploymentOption = StringUtils.isNotBlank(configurationId) ? configurationId : "";
-        importSpecParams.setDeploymentOption(deploymentOption);
+        importSpecParams.setDeploymentOption("");
         importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc
 
         String ovfDescriptor = removeOVFNetwork(HttpNfcLeaseMO.readOvfContent(ovfFilePath));
         VmwareContext context = host.getContext();
-        OvfCreateImportSpecResult ovfImportResult = null;
-        try {
-            ovfImportResult = context.getService().createImportSpec(context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, dsMo.getMor(), importSpecParams);
-        } catch (ConcurrentAccessFaultMsg
-                | FileFaultFaultMsg
-                | InvalidDatastoreFaultMsg
-                | InvalidStateFaultMsg
-                | RuntimeFaultFaultMsg
-                | TaskInProgressFaultMsg
-                | VmConfigFaultFaultMsg error) {
-            throw new CloudRuntimeException("ImportSpec creation failed", error);
-        }
+        OvfCreateImportSpecResult ovfImportResult =
+                context.getService().createImportSpec(context.getServiceContent().getOvfManager(), ovfDescriptor, morRp, dsMo.getMor(), importSpecParams);
+
         if (ovfImportResult == null) {
             String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + vmName + ", diskOption: " + diskOption;
             s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
+            throw new Exception(msg);
         }
         if(!ovfImportResult.getError().isEmpty()) {
             for (LocalizedMethodFault fault : ovfImportResult.getError()) {
                 s_logger.error("createImportSpec error: " + fault.getLocalizedMessage());
             }
-            throw new CloudRuntimeException("Failed to create an import spec from " + ovfFilePath + ". Check log for details.");
+            throw new CloudException("Failed to create an import spec from " + ovfFilePath + ". Check log for details.");
         }
 
         if (!ovfImportResult.getWarning().isEmpty()) {
@@ -1831,55 +1780,22 @@
             }
         }
 
-        DatacenterMO dcMo = null;
-        try {
-            dcMo = new DatacenterMO(context, host.getHyperHostDatacenter());
-        } catch (Exception e) {
-            throw new CloudRuntimeException(String.format("no datacenter for host '%s' available in context", context.getServerAddress()), e);
-        }
-        ManagedObjectReference folderMO = null;
-        try {
-            folderMO = dcMo.getVmFolder();
-        } catch (Exception e) {
-            throw new CloudRuntimeException("no management handle for VmFolder", e);
-        }
-        ManagedObjectReference morLease = null;
-        try {
-            morLease = context.getService().importVApp(morRp, ovfImportResult.getImportSpec(), folderMO, morHost);
-        } catch (DuplicateNameFaultMsg
-                | FileFaultFaultMsg
-                | InsufficientResourcesFaultFaultMsg
-                | InvalidDatastoreFaultMsg
-                | InvalidNameFaultMsg
-                | OutOfBoundsFaultMsg
-                | RuntimeFaultFaultMsg
-                | VmConfigFaultFaultMsg fault) {
-            throw new CloudRuntimeException("import vApp failed",fault);
-        }
+        DatacenterMO dcMo = new DatacenterMO(context, host.getHyperHostDatacenter());
+        ManagedObjectReference morLease = context.getService().importVApp(morRp, ovfImportResult.getImportSpec(), dcMo.getVmFolder(), morHost);
         if (morLease == null) {
             String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: " + vmName + ", diskOption: " + diskOption;
             s_logger.error(msg);
-            throw new CloudRuntimeException(msg);
+            throw new Exception(msg);
         }
         boolean importSuccess = true;
         final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease);
-        HttpNfcLeaseState state = null;
-        try {
-            state = leaseMo.waitState(new HttpNfcLeaseState[] {HttpNfcLeaseState.READY, HttpNfcLeaseState.ERROR});
-        } catch (Exception e) {
-            throw new CloudRuntimeException("exception while waiting for leaseMO", e);
-        }
+        HttpNfcLeaseState state = leaseMo.waitState(new HttpNfcLeaseState[] {HttpNfcLeaseState.READY, HttpNfcLeaseState.ERROR});
         try {
             if (state == HttpNfcLeaseState.READY) {
                 final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult);
                 File ovfFile = new File(ovfFilePath);
 
-                HttpNfcLeaseInfo httpNfcLeaseInfo = null;
-                try {
-                    httpNfcLeaseInfo = leaseMo.getLeaseInfo();
-                } catch (Exception e) {
-                    throw new CloudRuntimeException("error waiting for lease info", e);
-                }
+                HttpNfcLeaseInfo httpNfcLeaseInfo = leaseMo.getLeaseInfo();
                 List<HttpNfcLeaseDeviceUrl> deviceUrls = httpNfcLeaseInfo.getDeviceUrl();
                 long bytesAlreadyWritten = 0;
 
@@ -1890,7 +1806,6 @@
                         for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) {
                             if (deviceKey.equals(ovfFileItem.getDeviceId())) {
                                 String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath();
-                                s_logger.info("Uploading file: " + absoluteFile);
                                 File f = new File(absoluteFile);
                                 if (f.exists()){
                                     String urlToPost = deviceUrl.getUrl();
@@ -1910,44 +1825,31 @@
                     String erroMsg = "File upload task failed to complete due to: " + e.getMessage();
                     s_logger.error(erroMsg);
                     importSuccess = false; // Set flag to cleanup the stale template left due to failed import operation, if any
-                    throw new CloudRuntimeException(erroMsg, e);
+                    throw new Exception(erroMsg, e);
                 } catch (Throwable th) {
                     String errorMsg = "throwable caught during file upload task: " + th.getMessage();
                     s_logger.error(errorMsg);
                     importSuccess = false; // Set flag to cleanup the stale template left due to failed import operation, if any
-                    throw new CloudRuntimeException(errorMsg, th);
+                    throw new Exception(errorMsg, th);
                 } finally {
                     progressReporter.close();
                 }
                 if (bytesAlreadyWritten == totalBytes) {
-                    try {
-                        leaseMo.updateLeaseProgress(100);
-                    } catch (Exception e) {
-                        throw new CloudRuntimeException("error while waiting for lease update", e);
-                    }
+                    leaseMo.updateLeaseProgress(100);
                 }
             } else if (state == HttpNfcLeaseState.ERROR) {
-                LocalizedMethodFault error = null;
-                try {
-                    error = leaseMo.getLeaseError();
-                } catch (Exception e) {
-                    throw new CloudRuntimeException("error getting lease error", e);
-                }
+                LocalizedMethodFault error = leaseMo.getLeaseError();
                 MethodFault fault = error.getFault();
                 String erroMsg = "Object creation on vCenter failed due to: Exception: " + fault.getClass().getName() + ", message: " + error.getLocalizedMessage();
                 s_logger.error(erroMsg);
-                throw new CloudRuntimeException(erroMsg);
+                throw new Exception(erroMsg);
             }
         } finally {
-            try {
-                if (!importSuccess) {
-                    s_logger.error("Aborting the lease on " + vmName + " after import operation failed.");
-                    leaseMo.abortLease();
-                } else {
-                    leaseMo.completeLease();
-                }
-            } catch (Exception e) {
-                throw new CloudRuntimeException("error completing lease", e);
+            if (!importSuccess) {
+                s_logger.error("Aborting the lease on " + vmName + " after import operation failed.");
+                leaseMo.abortLease();
+            } else {
+                leaseMo.completeLease();
             }
         }
     }
@@ -2182,29 +2084,4 @@
         return DiskControllerType.getType(controller) == DiskControllerType.ide;
     }
 
-    public static void createBaseFolder(DatastoreMO dsMo, VmwareHypervisorHost hyperHost, StoragePoolType poolType) throws Exception {
-        if (poolType != null && poolType == StoragePoolType.DatastoreCluster) {
-            StoragepodMO storagepodMO = new StoragepodMO(hyperHost.getContext(), dsMo.getMor());
-            List<ManagedObjectReference> datastoresInCluster = storagepodMO.getDatastoresInDatastoreCluster();
-            for (ManagedObjectReference datastore : datastoresInCluster) {
-                DatastoreMO childDsMo = new DatastoreMO(hyperHost.getContext(), datastore);
-                createBaseFolderInDatastore(childDsMo, hyperHost);
-            }
-        } else {
-            createBaseFolderInDatastore(dsMo, hyperHost);
-        }
-    }
-
-    public static void createBaseFolderInDatastore(DatastoreMO dsMo, VmwareHypervisorHost hyperHost) throws Exception {
-        String dsPath = String.format("[%s]", dsMo.getName());
-        String folderPath = String.format("[%s] %s", dsMo.getName(), VSPHERE_DATASTORE_BASE_FOLDER);
-        String hiddenFolderPath = String.format("%s/%s", folderPath, VSPHERE_DATASTORE_HIDDEN_FOLDER);
-
-        if (!dsMo.folderExists(dsPath, VSPHERE_DATASTORE_BASE_FOLDER)) {
-            s_logger.info(String.format("vSphere datastore base folder: %s does not exist, now creating on datastore: %s", VSPHERE_DATASTORE_BASE_FOLDER, dsMo.getName()));
-            dsMo.makeDirectory(folderPath, hyperHost.getHyperHostDatacenter());
-            // Adding another directory so vCentre doesn't remove the fcd directory when it's empty
-            dsMo.makeDirectory(hiddenFolderPath, hyperHost.getHyperHostDatacenter());
-        }
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmPlacementSolverMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmPlacementSolverMO.java
deleted file mode 100644
index 3eb909f..0000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmPlacementSolverMO.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.mo;
-
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.vmware.pbm.PbmPlacementCompatibilityResult;
-import com.vmware.pbm.PbmPlacementHub;
-import com.vmware.pbm.PbmProfile;
-import com.vmware.pbm.PbmProfileId;
-import com.vmware.vim25.ManagedObjectReference;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.log4j.Logger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PbmPlacementSolverMO extends BaseMO {
-
-    private static final Logger LOGGER = Logger.getLogger(PbmPlacementSolverMO.class);
-
-    public PbmPlacementSolverMO (VmwareContext context) {
-        super(context, context.getPbmServiceContent().getPlacementSolver());
-    }
-
-    public PbmPlacementSolverMO(VmwareContext context, ManagedObjectReference morPlacementSolver) {
-        super(context, morPlacementSolver);
-    }
-
-    public PbmPlacementSolverMO(VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public boolean isDatastoreCompatibleWithStorageProfile(ManagedObjectReference dsMor, PbmProfile profile) throws Exception {
-        boolean isDatastoreCompatibleWithStorageProfile = false;
-
-        PbmPlacementHub placementHub = new PbmPlacementHub();
-        placementHub.setHubId(dsMor.getValue());
-        placementHub.setHubType(dsMor.getType());
-
-        List<PbmPlacementHub> placementHubList = new ArrayList<PbmPlacementHub>();
-        placementHubList.add(placementHub);
-        PbmProfileId profileId = profile.getProfileId();
-        List<PbmPlacementCompatibilityResult> placementCompatibilityResultList = _context.getPbmService().pbmCheckCompatibility(_mor, placementHubList, profileId);
-        if (CollectionUtils.isNotEmpty(placementCompatibilityResultList)) {
-            for (PbmPlacementCompatibilityResult placementResult : placementCompatibilityResultList) {
-                // Check for error and warning
-                if (CollectionUtils.isEmpty(placementResult.getError()) && CollectionUtils.isEmpty(placementResult.getWarning())) {
-                    isDatastoreCompatibleWithStorageProfile = true;
-                }
-            }
-        }
-        return isDatastoreCompatibleWithStorageProfile;
-    }
-}
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java
deleted file mode 100644
index 38f18d7..0000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/PbmProfileManagerMO.java
+++ /dev/null
@@ -1,104 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.mo;
-
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.vmware.pbm.PbmCapabilityProfile;
-import com.vmware.pbm.PbmProfile;
-import com.vmware.pbm.PbmProfileCategoryEnum;
-import com.vmware.pbm.PbmProfileId;
-import com.vmware.pbm.PbmProfileResourceType;
-import com.vmware.pbm.PbmProfileResourceTypeEnum;
-import com.vmware.vim25.ManagedObjectReference;
-
-import com.vmware.vim25.VirtualMachineDefinedProfileSpec;
-import org.apache.log4j.Logger;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class PbmProfileManagerMO extends BaseMO {
-
-    private static final Logger LOGGER = Logger.getLogger(PbmProfileManagerMO.class);
-
-    public PbmProfileManagerMO (VmwareContext context) {
-        super(context, context.getPbmServiceContent().getProfileManager());
-    }
-
-    public PbmProfileManagerMO (VmwareContext context, ManagedObjectReference morProfileMgr) {
-        super(context, morProfileMgr);
-    }
-
-    public PbmProfileManagerMO (VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public List<PbmProfileId> getStorageProfileIds() throws Exception {
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Querying vCenter " + _context.getServerAddress() + " for profiles");
-        }
-        List<PbmProfileId> profileIds = _context.getPbmService().pbmQueryProfile(_mor, getStorageResourceType(), null);
-        return profileIds;
-    }
-
-    public List<PbmProfile> getStorageProfiles() throws Exception {
-        List<PbmProfileId> profileIds = getStorageProfileIds();
-        List<PbmProfile> profiles = _context.getPbmService().pbmRetrieveContent(_mor, profileIds);
-
-        List<PbmProfile> requirementCategoryProfiles = profiles.stream()
-                .filter(x -> ((PbmCapabilityProfile)x).getProfileCategory().equals(PbmProfileCategoryEnum.REQUIREMENT.toString()))
-                .collect(Collectors.toList());
-        return requirementCategoryProfiles;
-    }
-
-    public PbmProfile getStorageProfile(String storageProfileId) throws Exception {
-        List<PbmProfileId> profileIds = getStorageProfileIds();
-
-        PbmProfileId profileId = profileIds.stream()
-                .filter(x -> x.getUniqueId().equals(storageProfileId))
-                .findFirst().orElse(null);
-
-        if (profileId == null) {
-            String errMsg = String.format("Storage profile with id %s not found", storageProfileId);
-            LOGGER.debug(errMsg);
-            throw new CloudRuntimeException(errMsg);
-        }
-
-        List<PbmProfile> profile = _context.getPbmService().pbmRetrieveContent(_mor, Collections.singletonList(profileId));
-        return profile.get(0);
-    }
-
-    private PbmProfileResourceType getStorageResourceType() {
-        PbmProfileResourceType resourceType = new PbmProfileResourceType();
-        resourceType.setResourceType(PbmProfileResourceTypeEnum.STORAGE.value());
-        return resourceType;
-    }
-
-
-    public VirtualMachineDefinedProfileSpec getProfileSpec(String profileId) throws Exception {
-        VirtualMachineDefinedProfileSpec profileSpec = new VirtualMachineDefinedProfileSpec();
-        PbmProfile profile = getStorageProfile(profileId);
-        profileSpec.setProfileId(profile.getProfileId().getUniqueId());
-        return profileSpec;
-    }
-
-}
-
-
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/StoragepodMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/StoragepodMO.java
deleted file mode 100644
index afa3a02..0000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/StoragepodMO.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package com.cloud.hypervisor.vmware.mo;
-
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-import com.vmware.vim25.ManagedObjectReference;
-import com.vmware.vim25.StoragePodSummary;
-import org.apache.log4j.Logger;
-
-import java.util.List;
-
-public class StoragepodMO extends BaseMO {
-
-    private static final Logger LOGGER = Logger.getLogger(StoragepodMO.class);
-
-    public StoragepodMO(VmwareContext context, ManagedObjectReference mor) {
-        super(context, mor);
-    }
-
-    public StoragepodMO(VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public StoragePodSummary getDatastoreClusterSummary() throws Exception {
-        return (StoragePodSummary)_context.getVimClient().getDynamicProperty(_mor, "summary");
-    }
-
-    public List<ManagedObjectReference> getDatastoresInDatastoreCluster() throws Exception {
-        List<ManagedObjectReference> datastoresInCluster = _context.getVimClient().getDynamicProperty(_mor, "childEntity");
-        return datastoresInCluster;
-    }
-
-}
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java
index 9cf9d95..65c6a6b 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/TaskMO.java
@@ -77,8 +77,4 @@
 
         return sb.toString();
     }
-
-    public static TaskInfo getTaskInfo(VmwareContext context, ManagedObjectReference morTask) throws Exception {
-        return (TaskInfo)context.getVimClient().getDynamicProperty(morTask, "info");
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index 5f61b31..b050796 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -35,7 +35,6 @@
 import java.util.concurrent.Future;
 
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 
 import com.google.gson.Gson;
@@ -105,7 +104,6 @@
 import com.vmware.vim25.VirtualMachineSnapshotTree;
 import com.vmware.vim25.VirtualSCSIController;
 import com.vmware.vim25.VirtualSCSISharing;
-import com.vmware.vim25.VirtualMachineDefinedProfileSpec;
 
 import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
@@ -228,15 +226,11 @@
                                         s_logger.info("msg id: " + msg.getId());
                                         s_logger.info("msg text: " + msg.getText());
                                     }
-                                    String logMsg = "Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId();
                                     if ("msg.uuid.altered".equalsIgnoreCase(msg.getId())) {
-                                        s_logger.info(logMsg + ", we will automatically answer as 'moved it' to address out of band HA for the VM");
+                                        s_logger.info("Found that VM has a pending question that we need to answer programmatically, question id: " + msg.getId()
+                                                + ", we will automatically answer as 'moved it' to address out of band HA for the VM");
                                         vmMo.answerVM(question.getId(), "1");
                                         break;
-                                    } else if (msg.getId().equalsIgnoreCase("msg.cpuid.noVHVQuestion")) {
-                                        s_logger.info(logMsg + ", automatically answering 'yes'");
-                                        vmMo.answerVM(question.getId(), "0");
-                                        break;
                                     }
                                 }
                             }
@@ -306,7 +300,7 @@
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
-                        s_logger.debug("[ignored] interrupted while powering of vm.");
+                        s_logger.debug("[ignored] interupted while powering of vm.");
                     }
                 }
 
@@ -339,7 +333,7 @@
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
-                    s_logger.debug("[ignored] interrupted while powering of vm unconditionally.");
+                    s_logger.debug("[ignored] interupted while powering of vm unconditionaly.");
                 }
             }
             return true;
@@ -373,7 +367,7 @@
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
-                    s_logger.debug("[ignored] interrupted while pausing after power off.");
+                    s_logger.debug("[ignored] interupted while pausing after power off.");
                 }
             } else {
                 break;
@@ -732,44 +726,6 @@
         return false;
     }
 
-    public boolean createFullCloneWithSpecificDisk(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs, Pair<VirtualDisk, String> volumeDeviceInfo)
-            throws Exception {
-
-        assert (morFolder != null);
-        assert (morResourcePool != null);
-        assert (morDs != null);
-        VirtualDisk requiredDisk = volumeDeviceInfo.first();
-
-        VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
-        List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(1);
-        VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
-        loc.setDatastore(morDs);
-        loc.setDiskId(requiredDisk.getKey());
-        loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
-        diskLocator.add(loc);
-
-        rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
-        rSpec.getDisk().addAll(diskLocator);
-        rSpec.setPool(morResourcePool);
-
-        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
-        cloneSpec.setPowerOn(false);
-        cloneSpec.setTemplate(false);
-        cloneSpec.setLocation(rSpec);
-
-        ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
-
-        boolean result = _context.getVimClient().waitForTask(morTask);
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            return true;
-        } else {
-            s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return false;
-    }
-
     public boolean createFullClone(String cloneName, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs)
             throws Exception {
 
@@ -1148,13 +1104,13 @@
     }
 
     // vmdkDatastorePath: [datastore name] vmdkFilePath
-    public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception {
-        createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey, vSphereStoragePolicyId);
+    public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectReference morDs, int controllerKey) throws Exception {
+        createDisk(vmdkDatastorePath, VirtualDiskType.THIN, VirtualDiskMode.PERSISTENT, null, sizeInMb, morDs, controllerKey);
     }
 
     // vmdkDatastorePath: [datastore name] vmdkFilePath
     public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, long sizeInMb,
-                           ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception {
+                           ManagedObjectReference morDs, int controllerKey) throws Exception {
 
         if (s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - createDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + vmdkDatastorePath + ", sizeInMb: " + sizeInMb +
@@ -1219,14 +1175,7 @@
         deviceConfigSpec.setDevice(newDisk);
         deviceConfigSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.CREATE);
         deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-        if (!StringUtils.isEmpty(vSphereStoragePolicyId)) {
-            PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(getContext());
-            VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(vSphereStoragePolicyId);
-            deviceConfigSpec.getProfile().add(diskProfileSpec);
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", vSphereStoragePolicyId, vmdkDatastorePath));
-            }
-        }
+
         reConfigSpec.getDeviceChange().add(deviceConfigSpec);
 
         ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
@@ -1244,18 +1193,7 @@
             s_logger.trace("vCenter API trace - createDisk() done(successfully)");
     }
 
-    public void updateVmdkAdapter(String vmdkFileName, String diskController) throws Exception {
-
-        DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
-        VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
-        if (vmdkAdapterType == VmdkAdapterType.none) {
-            String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
-                    vmdkFileName + "] with controller : " + diskControllerType;
-            s_logger.debug(message);
-            throw new Exception(message);
-        }
-
-        String newAdapterType = vmdkAdapterType.toString();
+    public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception {
         Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
         VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
         boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
@@ -1300,11 +1238,7 @@
         }
     }
 
-    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
-        attachDisk(vmdkDatastorePathChain, morDs, null, null);
-    }
-
-    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController, String vSphereStoragePolicyId) throws Exception {
+    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs, String diskController) throws Exception {
 
         if(s_logger.isTraceEnabled())
             s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: "
@@ -1326,33 +1260,30 @@
             controllerKey = getIDEControllerKey(ideDeviceCount);
             unitNumber = getFreeUnitNumberOnIDEController(controllerKey);
         } else {
-            if (StringUtils.isNotBlank(diskController)) {
-                controllerKey = getScsiDiskControllerKey(diskController);
-            } else {
-                controllerKey = getScsiDeviceControllerKey();
-            }
+            controllerKey = getScsiDiskControllerKey(diskController);
             unitNumber = -1;
         }
-
         synchronized (_mor.getValue().intern()) {
             VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey, vmdkDatastorePathChain, morDs, unitNumber, 1);
-            if (StringUtils.isNotBlank(diskController)) {
-                String vmdkFileName = vmdkDatastorePathChain[0];
-                updateVmdkAdapter(vmdkFileName, diskController);
+            controllerKey = newDisk.getControllerKey();
+            unitNumber = newDisk.getUnitNumber();
+            VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking();
+            String vmdkFileName = backingInfo.getFileName();
+            DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
+            VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
+            if (vmdkAdapterType == VmdkAdapterType.none) {
+                String message = "Failed to attach disk due to invalid vmdk adapter type for vmdk file [" +
+                    vmdkFileName + "] with controller : " + diskControllerType;
+                s_logger.debug(message);
+                throw new Exception(message);
             }
+            updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString());
             VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
             VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
 
             deviceConfigSpec.setDevice(newDisk);
             deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-            if (!StringUtils.isEmpty(vSphereStoragePolicyId)) {
-                PbmProfileManagerMO profMgrMo = new PbmProfileManagerMO(getContext());
-                VirtualMachineDefinedProfileSpec diskProfileSpec = profMgrMo.getProfileSpec(vSphereStoragePolicyId);
-                deviceConfigSpec.getProfile().add(diskProfileSpec);
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(String.format("Adding vSphere storage profile: %s to volume [%s]", vSphereStoragePolicyId, vmdkDatastorePathChain[0]));
-                }
-            }
+
             reConfigSpec.getDeviceChange().add(deviceConfigSpec);
 
             ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
@@ -1386,6 +1317,69 @@
 
     }
 
+    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) +
+                    ", datastore: " + morDs.getValue());
+
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1);
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
+    public void attachDisk(Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain, int controllerKey) throws Exception {
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain));
+
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, controllerKey, vmdkDatastorePathChain, -1, 1);
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context, morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if (s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
     // vmdkDatastorePath: [datastore name] vmdkFilePath
     public List<Pair<String, ManagedObjectReference>> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception {
 
@@ -1797,7 +1791,7 @@
                                 command.add((new File(name).getName()));
                             }
 
-                            s_logger.info("Package OVA with command: " + command.toString());
+                            s_logger.info("Package OVA with commmand: " + command.toString());
                             command.execute();
 
                             // to be safe, physically test existence of the target OVA file
@@ -1810,7 +1804,7 @@
                             success = true;
                         }
                     }
-                    s_logger.info("volss: copy vmdk and ovf file finished " + System.currentTimeMillis());
+                    s_logger.info("volss: copy vmdk and ovf file finishes " + System.currentTimeMillis());
                 } catch (Throwable e) {
                     s_logger.error("Unexpected exception ", e);
                 } finally {
@@ -2491,6 +2485,7 @@
                                     String deviceNumbering = getDeviceBusName(devices, device);
 
                                     s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
+
                                     return new Pair<>((VirtualDisk)device, deviceNumbering);
                                 }
 
@@ -2561,15 +2556,15 @@
                             if (matchExactly) {
                                 if (backingBaseName.equalsIgnoreCase(srcBaseName)) {
                                     String deviceNumbering = getDeviceBusName(devices, device);
-                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
 
+                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
                                     return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
                                 }
                             } else {
                                 if (backingBaseName.contains(trimmedSrcBaseName)) {
                                     String deviceNumbering = getDeviceBusName(devices, device);
-                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
 
+                                    s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering);
                                     return new Pair<VirtualDisk, String>((VirtualDisk)device, deviceNumbering);
                                 }
                             }
@@ -2633,6 +2628,7 @@
                     VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
                     if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
                         VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
+
                         while (diskBackingInfo != null) {
                             String deviceBusName = getDeviceBusName(devices, device);
                             builder.addDisk(deviceBusName, diskBackingInfo.getFileName());
@@ -3493,29 +3489,4 @@
         }
         return false;
     }
-
-    /**
-     * Upgrades this virtual machine's virtual hardware to the latest revision that is supported by the virtual machine's current host.
-     * @param version If specified, upgrade to that specified version. If not specified, upgrade to the most current virtual hardware supported on the host.
-     * @return true if success, false if not
-     */
-    public boolean upgradeVirtualHardwareVersion(String version) {
-        try {
-            String targetHwVersion = StringUtils.isNotBlank(version) ? version : "the highest available";
-            s_logger.info("Upgrading the VM hardware version to " + targetHwVersion);
-            ManagedObjectReference morTask = _context.getService().upgradeVMTask(_mor, version);
-            boolean result = _context.getVimClient().waitForTask(morTask);
-            if (result) {
-                _context.waitForTaskProgressDone(morTask);
-            } else {
-                s_logger.error("VMware upgradeVMTask failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-                return false;
-            }
-            return true;
-        } catch (Exception e) {
-            String msg = "Attempted to upgrade VM hardware version failed: " + e.getMessage();
-            s_logger.error(msg, e);
-            return false;
-        }
-    }
 }
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java
deleted file mode 100644
index d5f4eb3..0000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualStorageObjectManagerMO.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.mo;
-
-import com.vmware.vim25.ID;
-import com.vmware.vim25.TaskInfo;
-import com.vmware.vim25.VStorageObject;
-import com.vmware.vim25.VirtualDiskType;
-import com.vmware.vim25.VslmCreateSpec;
-import com.vmware.vim25.VslmCreateSpecDiskFileBackingSpec;
-import org.apache.log4j.Logger;
-
-import com.vmware.vim25.ManagedObjectReference;
-
-import com.cloud.hypervisor.vmware.util.VmwareContext;
-
-public class VirtualStorageObjectManagerMO extends BaseMO {
-    @SuppressWarnings("unused")
-    private static final Logger LOGGER = Logger.getLogger(VirtualStorageObjectManagerMO.class);
-
-    public VirtualStorageObjectManagerMO(VmwareContext context) {
-        super(context, context.getServiceContent().getVStorageObjectManager());
-    }
-
-    public VirtualStorageObjectManagerMO(VmwareContext context, ManagedObjectReference morDiskMgr) {
-        super(context, morDiskMgr);
-    }
-
-    public VirtualStorageObjectManagerMO(VmwareContext context, String morType, String morValue) {
-        super(context, morType, morValue);
-    }
-
-    public VStorageObject registerVirtualDisk(DatastoreFile datastoreFile, String name, String dcName) throws Exception {
-        StringBuilder sb = new StringBuilder();
-        //https://10.2.2.254/folder/i-2-4-VM/89e3756d9b7444dc92388eb36ddd026b.vmdk?dcPath=datacenter-21&dsName=c84e4af9b6ac33e887a25d9242650091
-        sb.append("https://").append(_context.getServerAddress()).append("/folder/");
-        sb.append(datastoreFile.getRelativePath());
-        sb.append("?dcPath=");
-        sb.append(dcName);
-        sb.append("&dsName=");
-        sb.append(datastoreFile.getDatastoreName());
-        return _context.getService().registerDisk(_mor, sb.toString(), name);
-    }
-
-    public VStorageObject retrieveVirtualDisk (ID id, ManagedObjectReference morDS) throws Exception {
-        return _context.getService().retrieveVStorageObject(_mor, id, morDS);
-    }
-
-    public VStorageObject createDisk(ManagedObjectReference morDS, VirtualDiskType diskType, long currentSizeInBytes, String datastoreFilepath, String filename) throws Exception {
-        long currentSizeInMB = currentSizeInBytes/(1024*1024);
-
-        VslmCreateSpecDiskFileBackingSpec diskFileBackingSpec = new VslmCreateSpecDiskFileBackingSpec();
-        diskFileBackingSpec.setDatastore(morDS);
-        diskFileBackingSpec.setProvisioningType(diskType.value());
-        // path should be just the folder name. For example, instead of '[datastore1] folder1/filename.vmdk' you would just do 'folder1'.
-        // path is introduced from 6.7. In 6.5 disk will be created in the default folder "fcd"
-        diskFileBackingSpec.setPath(null);
-
-        VslmCreateSpec vslmCreateSpec = new VslmCreateSpec();
-        vslmCreateSpec.setBackingSpec(diskFileBackingSpec);
-        vslmCreateSpec.setCapacityInMB(currentSizeInMB);
-        vslmCreateSpec.setName(filename);
-
-        ManagedObjectReference morTask = _context.getService().createDiskTask(_mor, vslmCreateSpec);
-        boolean result = _context.getVimClient().waitForTask(morTask);
-
-        VStorageObject vStorageObject = null;
-        if (result) {
-            _context.waitForTaskProgressDone(morTask);
-            //_context.getService().reconcileDatastoreInventoryTask(_mor, morDS);
-            TaskInfo taskInfo = TaskMO.getTaskInfo(_context, morTask);
-            vStorageObject = (VStorageObject)taskInfo.getResult();
-
-        } else {
-            LOGGER.error("VMware CreateDisk_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
-        }
-
-        return vStorageObject;
-    }
-}
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
index ff0a7d3..f602c46 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
@@ -35,8 +35,6 @@
     }
 
     public static VmdkAdapterType getType(String vmdkAdapterType) {
-        if (vmdkAdapterType == null)
-            return VmdkAdapterType.none;
         if (vmdkAdapterType.equalsIgnoreCase("ide")) {
             return VmdkAdapterType.ide;
         } else if (vmdkAdapterType.equalsIgnoreCase("lsilogic")) {
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
index 7ede78f..556efd7 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
@@ -31,7 +31,6 @@
     private static final Logger s_logger = Logger.getLogger(VmdkFileDescriptor.class);
     private static final String VMDK_PROPERTY_CREATE_TYPE = "createType";
     private static final String VMDK_CREATE_TYPE_VMFSSPARSE = "vmfsSparse";
-    private static final String VMDK_CREATE_TYPE_SESPARSE = "SEsparse";
     private static final String VMDK_PROPERTY_ADAPTER_TYPE = "ddb.adapterType";
 
     private Properties _properties = new Properties();
@@ -90,7 +89,7 @@
 
     public boolean isVmfsSparseFile() {
         String vmdkCreateType = _properties.getProperty(VMDK_PROPERTY_CREATE_TYPE);
-        if (vmdkCreateType.equalsIgnoreCase(VMDK_CREATE_TYPE_VMFSSPARSE) || vmdkCreateType.equalsIgnoreCase(VMDK_CREATE_TYPE_SESPARSE)) {
+        if (vmdkCreateType.equalsIgnoreCase(VMDK_CREATE_TYPE_VMFSSPARSE)) {
             return true;
         }
         return false;
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
index ce2f178..f99384a 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
@@ -65,13 +65,13 @@
                           int memoryReserveMB, String guestOsIdentifier, ManagedObjectReference morDs, boolean snapshotDirToParent,
                           Pair<String, String> controllerInfo, Boolean systemVm) throws Exception;
 
-    void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption, String configurationId) throws Exception;
+    void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption) throws Exception;
 
     ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws Exception;
 
     ObjectContent[] getDatastorePropertiesOnHyperHost(String[] propertyPaths) throws Exception;
 
-    ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid, boolean createBaseFolder) throws Exception;
+    ManagedObjectReference mountDatastore(boolean vmfsDatastore, String poolHostAddress, int poolHostPort, String poolPath, String poolUuid) throws Exception;
 
     void unmountDatastore(String poolUuid) throws Exception;
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VcenterSessionHandler.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VcenterSessionHandler.java
deleted file mode 100644
index 9efab7b..0000000
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VcenterSessionHandler.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package com.cloud.hypervisor.vmware.util;
-
-import java.util.Set;
-
-import javax.xml.namespace.QName;
-import javax.xml.soap.SOAPElement;
-import javax.xml.soap.SOAPException;
-import javax.xml.soap.SOAPHeader;
-import javax.xml.ws.handler.MessageContext;
-import javax.xml.ws.handler.soap.SOAPHandler;
-import javax.xml.ws.handler.soap.SOAPMessageContext;
-
-import org.apache.log4j.Logger;
-import org.w3c.dom.DOMException;
-
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class VcenterSessionHandler implements SOAPHandler<SOAPMessageContext> {
-    public static final Logger s_logger = Logger.getLogger(VcenterSessionHandler.class);
-    private final String vcSessionCookie;
-
-    public VcenterSessionHandler(String vcSessionCookie) {
-        this.vcSessionCookie = vcSessionCookie;
-    }
-
-    @Override
-    public boolean handleMessage(SOAPMessageContext smc) {
-        if (isOutgoingMessage(smc)) {
-            try {
-                SOAPHeader header = getSOAPHeader(smc);
-
-                SOAPElement vcsessionHeader = header.addChildElement(new javax.xml.namespace.QName("#",
-                        "vcSessionCookie"));
-                vcsessionHeader.setValue(vcSessionCookie);
-
-            } catch (DOMException e) {
-                s_logger.debug(e);
-                throw new CloudRuntimeException(e);
-            } catch (SOAPException e) {
-                s_logger.debug(e);
-                throw new CloudRuntimeException(e);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void close(MessageContext arg0) {
-    }
-
-    @Override
-    public boolean handleFault(SOAPMessageContext arg0) {
-        return false;
-    }
-
-    @Override
-    public Set<QName> getHeaders() {
-        return null;
-    }
-
-    SOAPHeader getSOAPHeader(SOAPMessageContext smc) throws SOAPException {
-        return smc.getMessage().getSOAPPart().getEnvelope().getHeader() == null ? smc
-                .getMessage().getSOAPPart().getEnvelope().addHeader()
-                : smc.getMessage().getSOAPPart().getEnvelope().getHeader();
-    }
-
-    boolean isOutgoingMessage(SOAPMessageContext smc) {
-        Boolean outboundProperty = (Boolean)smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
-        return outboundProperty;
-    }
-
-}
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
index 2395ccf..3d80ffd 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java
@@ -17,11 +17,8 @@
 package com.cloud.hypervisor.vmware.util;
 
 import java.lang.reflect.Method;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -32,16 +29,9 @@
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.WebServiceException;
 import javax.xml.ws.handler.MessageContext;
-import javax.xml.ws.handler.Handler;
-import javax.xml.ws.handler.HandlerResolver;
-import javax.xml.ws.handler.PortInfo;
-
 
 import org.apache.cloudstack.utils.security.SSLUtils;
 import org.apache.cloudstack.utils.security.SecureSSLSocketFactory;
-import com.vmware.pbm.PbmPortType;
-import com.vmware.pbm.PbmService;
-import com.vmware.pbm.PbmServiceInstanceContent;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Element;
 
@@ -111,7 +101,6 @@
             HttpsURLConnection.setDefaultHostnameVerifier(hv);
 
             vimService = new VimService();
-            pbmService = new PbmService();
         } catch (Exception e) {
             s_logger.info("[ignored]"
                     + "failed to trust all certificates blindly: ", e);
@@ -131,16 +120,8 @@
     }
 
     private final ManagedObjectReference svcInstRef = new ManagedObjectReference();
-    private final ManagedObjectReference pbmSvcInstRef = new ManagedObjectReference();
-
     private static VimService vimService;
-    private static PbmService pbmService;
-    private PbmServiceInstanceContent pbmServiceContent;
     private VimPortType vimPort;
-    private PbmPortType pbmPort;
-    private static final String PBM_SERVICE_INSTANCE_TYPE = "PbmServiceInstance";
-    private static final String PBM_SERVICE_INSTANCE_VALUE = "ServiceInstance";
-
     private String serviceCookie;
     private final static String SVC_INST_NAME = "ServiceInstance";
     private int vCenterSessionTimeout = 1200000; // Timeout in milliseconds
@@ -195,38 +176,10 @@
         cookieValue = tokenizer.nextToken();
         String pathData = "$" + tokenizer.nextToken();
         serviceCookie = "$Version=\"1\"; " + cookieValue + "; " + pathData;
-        Map<String, List<String>> map = new HashMap<String, List<String>>();
-        map.put("Cookie", Collections.singletonList(serviceCookie));
-        ((BindingProvider)vimPort).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, map);
-        pbmConnect(url, cookieValue);
+
         isConnected = true;
     }
 
-    private void pbmConnect(String url, String cookieValue) throws Exception {
-        URI uri = new URI(url);
-        String pbmurl = "https://" + uri.getHost() + "/pbm";
-        String[] tokens = cookieValue.split("=");
-        String extractedCookie = tokens[1];
-
-        HandlerResolver soapHandlerResolver = new HandlerResolver() {
-            @Override
-            public List<Handler> getHandlerChain(PortInfo portInfo) {
-                VcenterSessionHandler VcSessionHandler = new VcenterSessionHandler(extractedCookie);
-                List<Handler> handlerChain = new ArrayList<Handler>();
-                handlerChain.add((Handler)VcSessionHandler);
-                return handlerChain;
-            }
-        };
-        pbmService.setHandlerResolver(soapHandlerResolver);
-
-        pbmSvcInstRef.setType(PBM_SERVICE_INSTANCE_TYPE);
-        pbmSvcInstRef.setValue(PBM_SERVICE_INSTANCE_VALUE);
-        pbmPort = pbmService.getPbmPort();
-        Map<String, Object> pbmCtxt = ((BindingProvider)pbmPort).getRequestContext();
-        pbmCtxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
-        pbmCtxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, pbmurl);
-    }
-
     /**
      * Disconnects the user session.
      *
@@ -259,24 +212,6 @@
     }
 
     /**
-     * @return PBM service instance
-     */
-    public PbmPortType getPbmService() {
-        return pbmPort;
-    }
-
-    /**
-     * @return Service instance content
-     */
-    public PbmServiceInstanceContent getPbmServiceContent() {
-        try {
-            return pbmPort.pbmRetrieveServiceContent(pbmSvcInstRef);
-        } catch (com.vmware.pbm.RuntimeFaultFaultMsg e) {
-        }
-        return null;
-    }
-
-    /**
      * @return cookie used in service connection
      */
     public String getServiceCookie() {
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java
index af44962..9b477ae 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareContext.java
@@ -20,8 +20,6 @@
 import com.cloud.hypervisor.vmware.mo.DatastoreFile;
 import com.cloud.utils.ActionDelegate;
 import com.cloud.utils.StringUtils;
-import com.vmware.pbm.PbmPortType;
-import com.vmware.pbm.PbmServiceInstanceContent;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.ObjectContent;
 import com.vmware.vim25.ObjectSpec;
@@ -150,14 +148,6 @@
         return _vimClient.getServiceContent();
     }
 
-    public PbmPortType getPbmService() {
-        return _vimClient.getPbmService();
-    }
-
-    public PbmServiceInstanceContent getPbmServiceContent() {
-        return _vimClient.getPbmServiceContent();
-    }
-
     public ManagedObjectReference getPropertyCollector() {
         return _vimClient.getPropCol();
     }
@@ -321,24 +311,6 @@
         return dcMo.findDatastore(tokens[1]);
     }
 
-    // path in format of <datacenter name>/<datastore name>
-    public String getDatastoreNameFromPath(String inventoryPath) throws Exception {
-        assert (inventoryPath != null);
-
-        String[] tokens;
-        if (inventoryPath.startsWith("/"))
-            tokens = inventoryPath.substring(1).split("/");
-        else
-            tokens = inventoryPath.split("/");
-
-        if (tokens == null || tokens.length != 2) {
-            s_logger.error("Invalid datastore inventory path. path: " + inventoryPath);
-            return null;
-        }
-
-        return tokens[1];
-    }
-
     public void waitForTaskProgressDone(ManagedObjectReference morTask) throws Exception {
         while (true) {
             TaskInfo tinfo = (TaskInfo)_vimClient.getDynamicProperty(morTask, "info");
@@ -367,32 +339,32 @@
         out.close();
     }
 
-    public void uploadFile(String httpMethod, String urlString, String localFileName) throws Exception {
-        HttpURLConnection conn = getRawHTTPConnection(urlString);
+    public void uploadFile(String urlString, String localFileFullName) throws Exception {
+        uploadFile(urlString, new File(localFileFullName));
+    }
 
-        conn.setDoOutput(true);
-        conn.setUseCaches(false);
-
-        conn.setChunkedStreamingMode(ChunkSize);
-        conn.setRequestMethod(httpMethod);
-        conn.setRequestProperty("Connection", "Keep-Alive");
-        String contentType = "application/octet-stream";
-        conn.setRequestProperty("Content-Type", contentType);
-        conn.setRequestProperty("Content-Length", Long.toString(new File(localFileName).length()));
-        connectWithRetry(conn);
+    public void uploadFile(String urlString, File localFile) throws Exception {
+        HttpURLConnection conn = getHTTPConnection(urlString, "PUT");
         OutputStream out = null;
         InputStream in = null;
         BufferedReader br = null;
 
         try {
             out = conn.getOutputStream();
-            in = new FileInputStream(localFileName);
+            in = new FileInputStream(localFile);
             byte[] buf = new byte[ChunkSize];
             int len = 0;
             while ((len = in.read(buf)) > 0) {
                 out.write(buf, 0, len);
             }
             out.flush();
+
+            br = new BufferedReader(new InputStreamReader(conn.getInputStream(), getCharSetFromConnection(conn)));
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("Upload " + urlString + " response: " + line);
+            }
         } finally {
             if (in != null)
                 in.close();
@@ -402,7 +374,6 @@
 
             if (br != null)
                 br.close();
-            conn.disconnect();
         }
     }
 
@@ -427,14 +398,8 @@
 
         conn.setChunkedStreamingMode(ChunkSize);
         conn.setRequestMethod(httpMethod);
-        if (urlString.endsWith(".iso")) {
-            conn.setRequestProperty("Overwrite", "t");
-        }
         conn.setRequestProperty("Connection", "Keep-Alive");
-        String contentType = urlString.endsWith(".iso") ?
-                "application/octet-stream" :
-                "application/x-vnd.vmware-streamVmdk";
-        conn.setRequestProperty("Content-Type", contentType);
+        conn.setRequestProperty("Content-Type", "application/x-vnd.vmware-streamVmdk");
         conn.setRequestProperty("Content-Length", Long.toString(new File(localFileName).length()));
         connectWithRetry(conn);
 
diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
index 424027b..181b2ef 100644
--- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
+++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
@@ -25,7 +25,6 @@
 import java.io.StringWriter;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.List;
@@ -76,9 +75,7 @@
 import com.vmware.vim25.VirtualVmxnet3;
 
 import com.cloud.hypervisor.vmware.mo.DiskControllerType;
-import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.HostMO;
-import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
 import com.cloud.hypervisor.vmware.mo.LicenseAssignmentManagerMO;
 import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
 import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
@@ -215,46 +212,35 @@
     }
 
     // vmdkDatastorePath: [datastore name] vmdkFilePath
-    public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
-                                                  ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception {
+    public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePath, int sizeInMb, ManagedObjectReference morDs,
+            int deviceNumber, int contextNumber) throws Exception {
 
-        assert (vmdkDatastorePathChain != null);
-        assert (vmdkDatastorePathChain.length >= 1);
+        VirtualDisk disk = new VirtualDisk();
 
-        VirtualDisk disk;
-        VirtualDiskFlatVer2BackingInfo backingInfo;
-        if (device != null) {
-            disk = device;
-            backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking();
-        } else {
-            disk = new VirtualDisk();
-            backingInfo = new VirtualDiskFlatVer2BackingInfo();
-            backingInfo.setDatastore(morDs);
-            backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
-            disk.setBacking(backingInfo);
+        VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
+        backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
+        backingInfo.setThinProvisioned(true);
+        backingInfo.setEagerlyScrub(false);
+        backingInfo.setDatastore(morDs);
+        backingInfo.setFileName(vmdkDatastorePath);
+        disk.setBacking(backingInfo);
 
-            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
-            if (controllerKey < 0)
-                controllerKey = ideControllerKey;
-            if (deviceNumber < 0) {
-                deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
-            }
-
-            disk.setControllerKey(controllerKey);
-            disk.setKey(-contextNumber);
-            disk.setUnitNumber(deviceNumber);
-
-            VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
-            connectInfo.setConnected(true);
-            connectInfo.setStartConnected(true);
-            disk.setConnectable(connectInfo);
+        int ideControllerKey = vmMo.getIDEDeviceControllerKey();
+        if (controllerKey < 0)
+            controllerKey = ideControllerKey;
+        if (deviceNumber < 0) {
+            deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
         }
+        disk.setControllerKey(controllerKey);
 
-        backingInfo.setFileName(vmdkDatastorePathChain[0]);
-        if (vmdkDatastorePathChain.length > 1) {
-            String[] parentDisks = Arrays.copyOfRange(vmdkDatastorePathChain, 1, vmdkDatastorePathChain.length);
-            setParentBackingInfo(backingInfo, morDs, parentDisks);
-        }
+        disk.setKey(-contextNumber);
+        disk.setUnitNumber(deviceNumber);
+        disk.setCapacityInKB(sizeInMb * 1024);
+
+        VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
+        connectInfo.setConnected(true);
+        connectInfo.setStartConnected(true);
+        disk.setConnectable(connectInfo);
 
         return disk;
     }
@@ -328,6 +314,96 @@
         return disk;
     }
 
+    // vmdkDatastorePath: [datastore name] vmdkFilePath
+    public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[],
+            ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception {
+
+        assert (vmdkDatastorePathChain != null);
+        assert (vmdkDatastorePathChain.length >= 1);
+
+        VirtualDisk disk;
+        VirtualDiskFlatVer2BackingInfo backingInfo;
+        if (device != null) {
+            disk = device;
+            backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking();
+        } else {
+            disk = new VirtualDisk();
+            backingInfo = new VirtualDiskFlatVer2BackingInfo();
+            backingInfo.setDatastore(morDs);
+            backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
+            disk.setBacking(backingInfo);
+
+            int ideControllerKey = vmMo.getIDEDeviceControllerKey();
+            if (controllerKey < 0)
+                controllerKey = ideControllerKey;
+            if (deviceNumber < 0) {
+                deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
+            }
+
+            disk.setControllerKey(controllerKey);
+            disk.setKey(-contextNumber);
+            disk.setUnitNumber(deviceNumber);
+
+            VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
+            connectInfo.setConnected(true);
+            connectInfo.setStartConnected(true);
+            disk.setConnectable(connectInfo);
+        }
+
+        backingInfo.setFileName(vmdkDatastorePathChain[0]);
+        if (vmdkDatastorePathChain.length > 1) {
+            String[] parentDisks = new String[vmdkDatastorePathChain.length - 1];
+            for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++)
+                parentDisks[i] = vmdkDatastorePathChain[i + 1];
+
+            setParentBackingInfo(backingInfo, morDs, parentDisks);
+        }
+
+        return disk;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, Pair<String, ManagedObjectReference>[] vmdkDatastorePathChain,
+            int deviceNumber, int contextNumber) throws Exception {
+
+        assert (vmdkDatastorePathChain != null);
+        assert (vmdkDatastorePathChain.length >= 1);
+
+        VirtualDisk disk = new VirtualDisk();
+
+        VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo();
+        backingInfo.setDatastore(vmdkDatastorePathChain[0].second());
+        backingInfo.setFileName(vmdkDatastorePathChain[0].first());
+        backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value());
+        if (vmdkDatastorePathChain.length > 1) {
+            Pair<String, ManagedObjectReference>[] parentDisks = new Pair[vmdkDatastorePathChain.length - 1];
+            for (int i = 0; i < vmdkDatastorePathChain.length - 1; i++)
+                parentDisks[i] = vmdkDatastorePathChain[i + 1];
+
+            setParentBackingInfo(backingInfo, parentDisks);
+        }
+
+        disk.setBacking(backingInfo);
+
+        int ideControllerKey = vmMo.getIDEDeviceControllerKey();
+        if (controllerKey < 0)
+            controllerKey = ideControllerKey;
+        if (deviceNumber < 0) {
+            deviceNumber = vmMo.getNextDeviceNumber(controllerKey);
+        }
+
+        disk.setControllerKey(controllerKey);
+        disk.setKey(-contextNumber);
+        disk.setUnitNumber(deviceNumber);
+
+        VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo();
+        connectInfo.setConnected(true);
+        connectInfo.setStartConnected(true);
+        disk.setConnectable(connectInfo);
+
+        return disk;
+    }
+
     private static void setParentBackingInfo(VirtualDiskFlatVer2BackingInfo backingInfo, ManagedObjectReference morDs, String[] parentDatastorePathList) {
 
         VirtualDiskFlatVer2BackingInfo parentBacking = new VirtualDiskFlatVer2BackingInfo();
@@ -534,7 +610,7 @@
     }
 
     public static void setBasicVmConfig(VirtualMachineConfigSpec vmConfig, int cpuCount, int cpuSpeedMHz, int cpuReservedMhz, int memoryMB, int memoryReserveMB,
-                                        String guestOsIdentifier, boolean limitCpuUse, boolean deployAsIs) {
+            String guestOsIdentifier, boolean limitCpuUse) {
 
         // VM config basics
         vmConfig.setMemoryMB((long)memoryMB);
@@ -560,11 +636,7 @@
         memInfo.setReservation((long)memoryReserveMB);
         vmConfig.setMemoryAllocation(memInfo);
 
-        if (!deployAsIs) {
-            // Deploy as-is uses the cloned VM guest OS
-            vmConfig.setGuestId(guestOsIdentifier);
-        }
-
+        vmConfig.setGuestId(guestOsIdentifier);
     }
 
     public static VirtualDevice prepareUSBControllerDevice() {
@@ -698,13 +770,9 @@
         return hotplugSupportedByLicense;
     }
 
-    public static String getVCenterSafeUuid(DatastoreMO dsMo) throws Exception{
+    public static String getVCenterSafeUuid() {
         // Object name that is greater than 32 is not safe in vCenter
-        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
-        if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
-            return CustomFieldConstants.CLOUD_UUID + "-" + uuid;
-        }
-        return uuid;
+        return UUID.randomUUID().toString().replaceAll("-", "");
     }
 
     public static String getRecommendedDiskControllerFromDescriptor(GuestOsDescriptor guestOsDescriptor) throws Exception {